Merge branch 'master' of git.hjp.at:hjp/meeat

This commit is contained in:
Peter J. Holzer 2022-12-08 14:17:32 +01:00
commit 134b117d44
11 changed files with 477 additions and 43 deletions

99
app.py
View File

@ -176,14 +176,43 @@ def vote_date():
result = instantrunoff_forward(meet_id, "date") result = instantrunoff_forward(meet_id, "date")
log.debug("result = %s", result) log.debug("result = %s", result)
return render_template("date_vote_fragment.html", dates=dates, result=result) csr.execute(
"""
select distinct email, short
from date_vote
join date on date_vote.date = date.id
join bod on date_vote.bod = bod.id
where meet = %s
order by email
""",
(meet_id,))
voters = csr.fetchall()
return render_template(
"date_vote_fragment.html",
dates=dates, result=result, voters=voters)
@app.get("/result/<int:meet_id>/date") @app.get("/result/<int:meet_id>/date")
def result_date(meet_id): def result_date(meet_id):
result = instantrunoff_forward(meet_id, "date") result = instantrunoff_forward(meet_id, "date")
log.debug("result = %s", result) log.debug("result = %s", result)
return render_template("date_result_fragment.html", result=result) csr = get_cursor()
csr.execute(
"""
select distinct email, short
from date_vote
join date on date_vote.date = date.id
join bod on date_vote.bod = bod.id
where meet = %s
order by email
""",
(meet_id,))
voters = csr.fetchall()
return render_template(
"date_result_fragment.html",
result=result, voters=voters)
@ -225,14 +254,43 @@ def vote_time():
result = instantrunoff_forward(meet_id, "time") result = instantrunoff_forward(meet_id, "time")
log.debug("result = %s", result) log.debug("result = %s", result)
return render_template("time_vote_fragment.html", times=times, result=result) csr.execute(
"""
select distinct email, short
from time_vote
join time on time_vote.time = time.id
join bod on time_vote.bod = bod.id
where meet = %s
order by email
""",
(meet_id,))
voters = csr.fetchall()
return render_template(
"time_vote_fragment.html",
times=times, result=result, voters=voters)
@app.get("/result/<int:meet_id>/time") @app.get("/result/<int:meet_id>/time")
def result_time(meet_id): def result_time(meet_id):
result = instantrunoff_forward(meet_id, "time") result = instantrunoff_forward(meet_id, "time")
log.debug("result = %s", result) log.debug("result = %s", result)
return render_template("time_result_fragment.html", result=result) csr = get_cursor()
csr.execute(
"""
select distinct email, short
from time_vote
join time on time_vote.time = time.id
join bod on time_vote.bod = bod.id
where meet = %s
order by email
""",
(meet_id,))
voters = csr.fetchall()
return render_template(
"time_result_fragment.html",
result=result, voters=voters)
@app.post("/vote/place") @app.post("/vote/place")
def vote_place(): def vote_place():
@ -272,7 +330,21 @@ def vote_place():
result = instantrunoff_forward(meet_id, "place") result = instantrunoff_forward(meet_id, "place")
log.debug("result = %s", result) log.debug("result = %s", result)
return render_template("place_vote_fragment.html", places=places, result=result) csr.execute(
"""
select distinct email, short
from place_vote
join place on place_vote.place = place.id
join bod on place_vote.bod = bod.id
where meet = %s
order by email
""",
(meet_id,))
voters = csr.fetchall()
return render_template(
"place_vote_fragment.html",
places=places, result=result, voters=voters)
@app.get("/result/<int:meet_id>/place") @app.get("/result/<int:meet_id>/place")
@ -280,7 +352,22 @@ def result_place(meet_id):
result = instantrunoff_forward(meet_id, "place") result = instantrunoff_forward(meet_id, "place")
log.debug("result = %s", result) log.debug("result = %s", result)
return render_template("place_result_fragment.html", result=result) csr = get_cursor()
csr.execute(
"""
select distinct email, short
from place_vote
join place on place_vote.place = place.id
join bod on place_vote.bod = bod.id
where meet = %s
order by email
""",
(meet_id,))
voters = csr.fetchall()
return render_template(
"place_result_fragment.html",
result=result, voters=voters)
@app.get("/result/<int:meet_id>/date/ballot") @app.get("/result/<int:meet_id>/date/ballot")

153
static/meeat-0.svg Normal file
View File

@ -0,0 +1,153 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="200"
height="100"
viewBox="0 0 52.916665 26.458334"
version="1.1"
id="svg5"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
sodipodi:docname="meeat-0.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="px"
showgrid="true"
units="px"
width="200px"
showguides="true"
inkscape:guide-bbox="true"
inkscape:snap-grids="true"
inkscape:zoom="6.3144636"
inkscape:cx="108.79784"
inkscape:cy="23.279887"
inkscape:window-width="1637"
inkscape:window-height="1352"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="layer1">
<inkscape:grid
type="xygrid"
id="grid824"
empspacing="10" />
<sodipodi:guide
position="26.458333,2.6458334"
orientation="1,0"
id="guide25202" />
<sodipodi:guide
position="18.520833,5.2916668"
orientation="0,-1"
id="guide29516" />
</sodipodi:namedview>
<defs
id="defs2" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<text
xml:space="preserve"
style="font-size:25.4px;line-height:1.25;font-family:Impact;-inkscape-font-specification:Impact;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
x="26.458332"
y="21.166666"
id="text32600"><tspan
sodipodi:role="line"
id="tspan32598"
style="stroke-width:0.264583;-inkscape-font-specification:Impact;font-family:Impact;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
x="26.458332"
y="21.166666" /></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16.9333px;line-height:1.25;font-family:Impact;-inkscape-font-specification:'Impact Bold';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583"
x="26.458332"
y="21.166666"
id="text45384"><tspan
sodipodi:role="line"
id="tspan45382"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Impact;-inkscape-font-specification:'Impact Bold';stroke-width:0.264583"
x="26.458332"
y="21.166666">MEAT</tspan><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Impact;-inkscape-font-specification:'Impact Bold';stroke-width:0.264583"
x="26.458332"
y="42.33329"
id="tspan48192">MEET</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16.9333px;line-height:1.25;font-family:Impact;-inkscape-font-specification:Impact;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583"
x="26.433376"
y="5.2022796"
id="text53774"><tspan
sodipodi:role="line"
id="tspan53772"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Impact;-inkscape-font-specification:Impact;stroke-width:0.264583"
x="26.433376"
y="5.2022796">E</tspan></text>
<text
xml:space="preserve"
style="font-size:16.9333px;line-height:1.25;font-family:Impact;-inkscape-font-specification:Impact;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583"
x="15.908848"
y="5.3659472"
id="text60758"><tspan
sodipodi:role="line"
id="tspan60756"
style="stroke-width:0.264583"
x="15.908848"
y="5.3659472">M</tspan></text>
<text
xml:space="preserve"
style="font-size:16.9333px;line-height:1.25;font-family:Impact;-inkscape-font-specification:Impact;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583"
x="34.386887"
y="5.4468637"
id="text62690"><tspan
sodipodi:role="line"
id="tspan62688"
style="stroke-width:0.264583"
x="34.386887"
y="5.4468637">A</tspan></text>
<text
xml:space="preserve"
style="font-size:16.9333px;line-height:1.25;font-family:Impact;-inkscape-font-specification:Impact;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583"
x="42.336185"
y="5.3340197"
id="text63834"><tspan
sodipodi:role="line"
id="tspan63832"
style="stroke-width:0.264583"
x="42.336185"
y="5.3340197">T</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16.9333px;line-height:1.25;font-family:Impact;-inkscape-font-specification:Impact;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583"
x="26.463411"
y="5.2722306"
id="text67436"><tspan
sodipodi:role="line"
id="tspan67434"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Impact;-inkscape-font-specification:Impact;stroke-width:0.264583"
x="26.463411"
y="5.2722306">E</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16.9333px;line-height:1.25;font-family:Impact;-inkscape-font-specification:Impact;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583"
x="34.398586"
y="5.4443774"
id="text67436-7"><tspan
sodipodi:role="line"
id="tspan67434-4"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Impact;-inkscape-font-specification:Impact;stroke-width:0.264583"
x="34.398586"
y="5.4443774">E</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.6 KiB

115
static/meeat-1.svg Normal file
View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="200"
height="100"
viewBox="0 0 52.916665 26.458334"
version="1.1"
id="svg5"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
sodipodi:docname="meeat-0.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="px"
showgrid="true"
units="px"
width="200px"
showguides="true"
inkscape:guide-bbox="true"
inkscape:snap-grids="true"
inkscape:zoom="6.3144636"
inkscape:cx="108.79784"
inkscape:cy="23.279887"
inkscape:window-width="1637"
inkscape:window-height="1352"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="layer1">
<inkscape:grid
type="xygrid"
id="grid824"
empspacing="10" />
<sodipodi:guide
position="26.458333,2.6458334"
orientation="1,0"
id="guide25202" />
<sodipodi:guide
position="18.520833,5.2916668"
orientation="0,-1"
id="guide29516" />
</sodipodi:namedview>
<defs
id="defs2" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<text
xml:space="preserve"
style="font-size:17px;line-height:1.25;font-family:Impact;-inkscape-font-specification:Impact;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583"
x="15"
y="20"
id="text60758"><tspan
sodipodi:role="line"
id="tspan60756"
style="stroke-width:0.264583"
x="15"
y="20">M</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17px;line-height:1.25;font-family:Impact;-inkscape-font-specification:Impact;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583"
x="25"
y="20"
id="text53774"><tspan
sodipodi:role="line"
id="tspan53772"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Impact;-inkscape-font-specification:Impact;stroke-width:0.264583"
x="25"
y="20">E</tspan></text>
<text
xml:space="preserve"
style="font-size:17px;line-height:1.25;font-family:Impact;-inkscape-font-specification:Impact;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583"
x="34"
y="20"
id="text62690"><tspan
sodipodi:role="line"
id="tspan62688"
style="stroke-width:0.264583"
x="34"
y="20">A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17px;line-height:1.25;font-family:Impact;-inkscape-font-specification:Impact;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583"
x="34"
y="20"
id="text67436-7"><tspan
sodipodi:role="line"
id="tspan67434-4"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Impact;-inkscape-font-specification:Impact;stroke-width:0.264583"
x="34"
y="20">E</tspan></text>
<text
xml:space="preserve"
style="font-size:17px;line-height:1.25;font-family:Impact;-inkscape-font-specification:Impact;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583"
x="42"
y="20"
id="text63834"><tspan
sodipodi:role="line"
id="tspan63832"
style="stroke-width:0.264583"
x="42"
y="20">T</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -1,5 +1,16 @@
body { body {
font-family: sans; font-family: sans;
margin: 0;
}
header {
height: 100px;
}
h1 {
padding-top: 19px;
margin-top: 0px;
margin-left: 200px;
} }
.sortable { .sortable {
@ -33,7 +44,8 @@ p {
#hello, #voters { #hello, #voters {
grid-column: 1 / 3; grid-column: 1 / 3;
} }
h1, h2 {
h2 {
grid-column: 1 / 3; grid-column: 1 / 3;
line-height: 1.1em; line-height: 1.1em;
} }
@ -65,3 +77,53 @@ h1, h2 {
padding: 1em; padding: 1em;
background-color: hsl(240, 10%, 80%); background-color: hsl(240, 10%, 80%);
} }
.logo {
position: absolute;
outline: 1px solid lime;
}
.logo-1 {
animation-name: fadeoutin;
animation-duration: 10s;
animation-iteration-count: infinite;
}
.logo-2 {
animation-name: fadeinout;
animation-duration: 10s;
animation-iteration-count: infinite;
}
@keyframes fadeinout {
0% {
opacity: 0%
}
10% {
opacity: 100%
}
50% {
opacity: 100%
}
60% {
opacity: 0%
}
100% {
opacity: 0%
}
}
@keyframes fadeoutin {
0% {
opacity: 100%
}
10% {
opacity: 0%
}
50% {
opacity: 0%
}
60% {
opacity: 100%
}
100% {
opacity: 100%
}
}

View File

@ -1,7 +1,8 @@
<div id="r-day" hx-swap-oob="true"> <div id="r-day" hx-swap-oob="true">
Ergebnis ({% for v in voters %}{{ v.short or v.email }}{% if not loop.last %}, {% endif %}{% endfor %}):
{% for r in result %} {% for r in result %}
<div class="result-item"> <div class="result-item">
{{ r.display or r.date }} {{ loop.index }}. {{ r.display or r.date }}
</div> </div>
{% endfor %} {% endfor %}
</div> </div>

View File

@ -1,13 +1,14 @@
{% for d in dates %} {% for d in dates %}
<div class="sort-item"> <div class="sort-item">
{{ d.display or d.date }} {{ loop.index }}. {{ d.display or d.date }}
<input type="hidden" name="date" value="{{d.id}}"> <input type="hidden" name="date" value="{{d.id}}">
</div> </div>
{% endfor %} {% endfor %}
<div id="r-day" hx-swap-oob="true"> <div id="r-day" hx-swap-oob="true">
Ergebnis ({% for v in voters %}{{ v.short or v.email }}{% if not loop.last %}, {% endif %}{% endfor %}):
{% for r in result %} {% for r in result %}
<div class="result-item"> <div class="result-item">
{{ r.display or r.date }} {{ loop.index }}. {{ r.display or r.date }}
</div> </div>
{% endfor %} {% endfor %}
</div> </div>

View File

@ -1,7 +1,8 @@
<div id="r-place" hx-swap-oob="true"> <div id="r-place" hx-swap-oob="true">
Ergebnis ({% for v in voters %}{{ v.short or v.email }}{% if not loop.last %}, {% endif %}{% endfor %}):
{% for r in result %} {% for r in result %}
<div class="result-item"> <div class="result-item">
{{ r.name }} {{ loop.index }}. {{ r.name }}
</div> </div>
{% endfor %} {% endfor %}
</div> </div>

View File

@ -1,13 +1,14 @@
{% for d in places %} {% for d in places %}
<div class="sort-item"> <div class="sort-item">
{{ d.name }} {{ loop.index }}. {{ d.name }}
<input type="hidden" name="place" value="{{d.id}}"> <input type="hidden" name="place" value="{{d.id}}">
</div> </div>
{% endfor %} {% endfor %}
<div id="r-place" hx-swap-oob="true"> <div id="r-place" hx-swap-oob="true">
Ergebnis ({% for v in voters %}{{ v.short or v.email }}{% if not loop.last %}, {% endif %}{% endfor %}):
{% for r in result %} {% for r in result %}
<div class="result-item"> <div class="result-item">
{{ r.name }} {{ loop.index }}. {{ r.name }}
</div> </div>
{% endfor %} {% endfor %}
</div> </div>

View File

@ -1,7 +1,8 @@
<div id="r-time" hx-swap-oob="true"> <div id="r-time" hx-swap-oob="true">
Ergebnis ({% for v in voters %}{{ v.short or v.email }}{% if not loop.last %}, {% endif %}{% endfor %}):
{% for r in result %} {% for r in result %}
<div class="result-item"> <div class="result-item">
{{ r.display or r.time }} {{ loop.index }}. {{ r.display or r.time }}
</div> </div>
{% endfor %} {% endfor %}
</div> </div>

View File

@ -1,13 +1,14 @@
{% for d in times %} {% for d in times %}
<div class="sort-item"> <div class="sort-item">
{{ d.display or d.time }} {{ loop.index }}. {{ d.display or d.time }}
<input type="hidden" name="time" value="{{d.id}}"> <input type="hidden" name="time" value="{{d.id}}">
</div> </div>
{% endfor %} {% endfor %}
<div id="r-time" hx-swap-oob="true"> <div id="r-time" hx-swap-oob="true">
Ergebnis ({% for v in voters %}{{ v.short or v.email }}{% if not loop.last %}, {% endif %}{% endfor %}):
{% for r in result %} {% for r in result %}
<div class="result-item"> <div class="result-item">
{{ r.display or r.time }} {{ loop.index }}. {{ r.display or r.time }}
</div> </div>
{% endfor %} {% endfor %}
</div> </div>

View File

@ -8,6 +8,11 @@
<link rel="stylesheet" href="/static/style.css"> <link rel="stylesheet" href="/static/style.css">
</head> </head>
<body> <body>
<header>
<img src="/static/meat.svg" class="logo logo-1">
<img src="/static/meet.svg" class="logo logo-2">
<h1> {{ meet.title }} </h1>
</header>
<div class="voteform"> <div class="voteform">
<p id="hello">Hallo, {{ session.user.email }}!</p> <p id="hello">Hallo, {{ session.user.email }}!</p>
<p id="voters"> <p id="voters">
@ -16,49 +21,55 @@
{{ voter.email }}{% if not loop.last %},{% endif %} {{ voter.email }}{% if not loop.last %},{% endif %}
{% endfor %} {% endfor %}
</p> </p>
<h1>
{{ meet.title }}
</h1>
<h2 id="h-day"> <h2 id="h-day">
An welchem Tag? An welchem Tag?
<a href="/result/{{meet.id}}/date/ballot">[details]</a> <a href="/result/{{meet.id}}/date/ballot">[details]</a>
</h2> </h2>
<div>
Ordne die Optionen nach Präferenz:
<form id="v-day" class="sortable" hx-post="/vote/date" hx-trigger="end"> <form id="v-day" class="sortable" hx-post="/vote/date" hx-trigger="end">
{% for d in dates %} {% for d in dates %}
<div class="sort-item"> <div class="sort-item">
{{ d.display or d.date }} {{ loop.index }}. {{ d.display or d.date }}
<input type="hidden" name="date" value="{{d.id}}"> <input type="hidden" name="date" value="{{d.id}}">
</div> </div>
{% endfor %} {% endfor %}
</form> </form>
</div>
<div id="r-day" hx-get="/result/{{meet.id}}/date" hx-trigger="load"> <div id="r-day" hx-get="/result/{{meet.id}}/date" hx-trigger="load">
</div> </div>
<h2 id="h-time"> <h2 id="h-time">
Zu welcher Zeit? Zu welcher Zeit?
<a href="/result/{{meet.id}}/time/ballot">[details]</a> <a href="/result/{{meet.id}}/time/ballot">[details]</a>
</h2> </h2>
<div>
Ordne die Optionen nach Präferenz:
<form id="v-time" class="sortable" hx-post="/vote/time" hx-trigger="end"> <form id="v-time" class="sortable" hx-post="/vote/time" hx-trigger="end">
{% for d in times %} {% for d in times %}
<div class="sort-item"> <div class="sort-item">
{{ d.display or d.time }} {{ loop.index }}. {{ d.display or d.time }}
<input type="hidden" name="time" value="{{d.id}}"> <input type="hidden" name="time" value="{{d.id}}">
</div> </div>
{% endfor %} {% endfor %}
</form> </form>
</div>
<div id="r-time" hx-get="/result/{{meet.id}}/time" hx-trigger="load"> <div id="r-time" hx-get="/result/{{meet.id}}/time" hx-trigger="load">
</div> </div>
<h2 id="h-place"> <h2 id="h-place">
An welchem Ort? An welchem Ort?
<a href="/result/{{meet.id}}/place/ballot">[details]</a> <a href="/result/{{meet.id}}/place/ballot">[details]</a>
</h2> </h2>
<div>
Ordne die Optionen nach Präferenz:
<form id="v-place" class="sortable" hx-post="/vote/place" hx-trigger="end"> <form id="v-place" class="sortable" hx-post="/vote/place" hx-trigger="end">
{% for d in places %} {% for d in places %}
<div class="sort-item"> <div class="sort-item">
{{ d.name }} {{ loop.index }}. {{ d.name }}
<input type="hidden" name="place" value="{{d.id}}"> <input type="hidden" name="place" value="{{d.id}}">
</div> </div>
{% endfor %} {% endfor %}
</form> </form>
</div>
<div id="r-place" hx-get="/result/{{meet.id}}/place" hx-trigger="load"> <div id="r-place" hx-get="/result/{{meet.id}}/place" hx-trigger="load">
</div> </div>
</div> </div>