Added camera enabling and disabling
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
TV_APP V1.0.1 - Tournament and League Management System
|
||||
TV_APP V1.0.2 - Tournament and League Management System
|
||||
Flask web application for managing tournaments with multi-camera streaming
|
||||
"""
|
||||
|
||||
@@ -87,8 +87,8 @@ def archive_league(league_data):
|
||||
def create_league(enabled_players, tournament_type):
|
||||
return Tournament.create_league(enabled_players, tournament_type)
|
||||
|
||||
def create_draft(enabled_players, tournament_type='20_targets', league_tournament_number=None):
|
||||
return Tournament.create_draft(enabled_players, tournament_type, league_tournament_number)
|
||||
def create_draft(enabled_players, tournament_type='20_targets', league_tournament_number=None, active_slots=None):
|
||||
return Tournament.create_draft(enabled_players, tournament_type, league_tournament_number, active_slots)
|
||||
|
||||
def create_results_structure(tournament_data):
|
||||
return Tournament.create_results_structure(tournament_data)
|
||||
@@ -826,14 +826,18 @@ def index():
|
||||
if current_round_data:
|
||||
tournament_titles = {}
|
||||
players = current_round_data['players']
|
||||
|
||||
for i in range(6): # Always 6 positions
|
||||
if i < len(players):
|
||||
tournament_titles[str(i + 1)] = players[i]['name']
|
||||
disabled_cameras = settings.get('disabled_cameras', [])
|
||||
current_language = get_current_language()
|
||||
player_idx = 0
|
||||
for i in range(6):
|
||||
cam_id = str(i + 1)
|
||||
if i + 1 in disabled_cameras:
|
||||
tournament_titles[cam_id] = 'Prazno' if current_language == 'sl' else 'Empty'
|
||||
elif player_idx < len(players):
|
||||
tournament_titles[cam_id] = players[player_idx]['name']
|
||||
player_idx += 1
|
||||
else:
|
||||
# Use "Prazno" for Slovenian, "Empty" for English
|
||||
current_language = get_current_language()
|
||||
tournament_titles[str(i + 1)] = 'Prazno' if current_language == 'sl' else 'Empty'
|
||||
tournament_titles[cam_id] = 'Prazno' if current_language == 'sl' else 'Empty'
|
||||
|
||||
# Create a copy of settings with tournament titles
|
||||
display_settings = settings.copy()
|
||||
@@ -1071,9 +1075,11 @@ def tournament_draft():
|
||||
if not tournament_state:
|
||||
return redirect('/tournament')
|
||||
|
||||
settings = load_settings()
|
||||
return render_template('draft.html',
|
||||
tournament=tournament_state,
|
||||
league=league_state)
|
||||
league=league_state,
|
||||
disabled_cameras=settings.get('disabled_cameras', []))
|
||||
|
||||
@app.route('/results/calculator')
|
||||
def results_calculator():
|
||||
@@ -1244,6 +1250,9 @@ def update_settings():
|
||||
if 'display_options' in new_settings:
|
||||
current_settings['display_options'].update(new_settings['display_options'])
|
||||
|
||||
if 'disabled_cameras' in new_settings:
|
||||
current_settings['disabled_cameras'] = new_settings['disabled_cameras']
|
||||
|
||||
# Save updated settings
|
||||
if save_settings(current_settings):
|
||||
return jsonify({'status': 'success', 'settings': current_settings})
|
||||
@@ -1414,10 +1423,14 @@ def start_league_tournament():
|
||||
|
||||
# Start next tournament
|
||||
league_state['current_tournament'] = current_tournament + 1
|
||||
settings = load_settings()
|
||||
disabled = settings.get('disabled_cameras', [])
|
||||
active_slots = [i for i in range(1, 7) if i not in disabled]
|
||||
tournament_data = create_draft(
|
||||
participating_players,
|
||||
league_state['tournament_type'],
|
||||
league_state['current_tournament']
|
||||
league_state['current_tournament'],
|
||||
active_slots
|
||||
)
|
||||
|
||||
# Save states
|
||||
@@ -1474,7 +1487,10 @@ def start_tournament():
|
||||
if len(enabled_players) < 1:
|
||||
return jsonify({'status': 'error', 'message': 'Need at least 1 enabled player'}), 400
|
||||
|
||||
tournament_data = create_draft(enabled_players, tournament_type)
|
||||
settings = load_settings()
|
||||
disabled = settings.get('disabled_cameras', [])
|
||||
active_slots = [i for i in range(1, 7) if i not in disabled]
|
||||
tournament_data = create_draft(enabled_players, tournament_type, active_slots=active_slots)
|
||||
|
||||
if save_tournament_state(tournament_data):
|
||||
# Create results structure when tournament starts
|
||||
@@ -1996,13 +2012,19 @@ def get_camera_titles():
|
||||
titles = {}
|
||||
|
||||
if current_round_data:
|
||||
# Tournament active - use player names
|
||||
# Tournament active - use player names, skip disabled cameras
|
||||
players = current_round_data['players']
|
||||
disabled_cameras = settings.get('disabled_cameras', [])
|
||||
player_idx = 0
|
||||
for i in range(6):
|
||||
if i < len(players):
|
||||
titles[str(i + 1)] = players[i]['name']
|
||||
cam_id = str(i + 1)
|
||||
if i + 1 in disabled_cameras:
|
||||
titles[cam_id] = 'Empty'
|
||||
elif player_idx < len(players):
|
||||
titles[cam_id] = players[player_idx]['name']
|
||||
player_idx += 1
|
||||
else:
|
||||
titles[str(i + 1)] = 'Empty'
|
||||
titles[cam_id] = 'Empty'
|
||||
else:
|
||||
# No tournament - use configured titles
|
||||
titles = settings['camera_titles']
|
||||
@@ -2541,4 +2563,4 @@ def set_language(language):
|
||||
}), 400
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', port=4000, debug=True)
|
||||
app.run(host='0.0.0.0', port=5000, debug=True)
|
||||
+10
-6
@@ -42,19 +42,22 @@ class Tournament:
|
||||
return league_data
|
||||
|
||||
@staticmethod
|
||||
def create_draft(enabled_players, tournament_type='20_targets', league_tournament_number=None):
|
||||
"""Create draft groups of 6 players and organize rounds"""
|
||||
def create_draft(enabled_players, tournament_type='20_targets', league_tournament_number=None, active_slots=None):
|
||||
"""Create draft groups organized by shooting positions and organize rounds"""
|
||||
if len(enabled_players) < 1:
|
||||
return None
|
||||
|
||||
slots = sorted(active_slots) if active_slots else list(range(1, NUM_CAMERAS + 1))
|
||||
positions = len(slots)
|
||||
|
||||
# Shuffle players for random grouping
|
||||
players_copy = enabled_players.copy()
|
||||
random.shuffle(players_copy)
|
||||
|
||||
# Create groups of up to 6
|
||||
# Create groups of up to positions
|
||||
groups = []
|
||||
for i in range(0, len(players_copy), NUM_CAMERAS):
|
||||
group = players_copy[i:i + NUM_CAMERAS]
|
||||
for i in range(0, len(players_copy), positions):
|
||||
group = players_copy[i:i + positions]
|
||||
groups.append(group)
|
||||
|
||||
# Create rounds
|
||||
@@ -72,7 +75,8 @@ class Tournament:
|
||||
'total_players': len(enabled_players),
|
||||
'total_rounds': len(rounds),
|
||||
'current_round': 1,
|
||||
'tournament_type': tournament_type
|
||||
'tournament_type': tournament_type,
|
||||
'active_slots': slots
|
||||
}
|
||||
|
||||
if league_tournament_number:
|
||||
|
||||
+2
-1
@@ -34,7 +34,8 @@ DEFAULT_SETTINGS = {
|
||||
'display_options': {
|
||||
'show_titles': True,
|
||||
'title_size': 1.1
|
||||
}
|
||||
},
|
||||
'disabled_cameras': []
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -12,5 +12,6 @@
|
||||
"title_size": 1.4,
|
||||
"target_number_size": 1.7
|
||||
},
|
||||
"tv_view": "cameras"
|
||||
"tv_view": "cameras",
|
||||
"disabled_cameras": []
|
||||
}
|
||||
+43
-43
@@ -3,32 +3,32 @@
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Domen Pleterski",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Nik Pleterski",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Ivan Tandler",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Mateja Pleterski",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "Jože Verhnjak",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "Mateja Senica",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
@@ -38,27 +38,27 @@
|
||||
{
|
||||
"id": 8,
|
||||
"name": "Franc Žigart",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "Janez Božič",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "Mitja Čeh",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "Rado Kefer",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "Matej Kvasnik",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
@@ -68,57 +68,57 @@
|
||||
{
|
||||
"id": 14,
|
||||
"name": "Karli Proje",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "Jan Pleterski",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"name": "Silvo Poročnik",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"name": "Dušan Onuk",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "Matjaž Pleterski",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "Franc Rizmal",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"name": "Jože Preglav",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"name": "Marko Blimen",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"name": "Doris Fesel",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"name": "Robi Krautberger",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"name": "Jože Verdinek",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
@@ -128,12 +128,12 @@
|
||||
{
|
||||
"id": 26,
|
||||
"name": "Jakob Herman",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 27,
|
||||
"name": "Janez Mrak",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 28,
|
||||
@@ -148,12 +148,12 @@
|
||||
{
|
||||
"id": 30,
|
||||
"name": "Maja Hirtl",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 31,
|
||||
"name": "Dejan Kučnik",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 32,
|
||||
@@ -163,27 +163,27 @@
|
||||
{
|
||||
"id": 33,
|
||||
"name": "Namir Uzunović",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 34,
|
||||
"name": "Jože Planinšec",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 35,
|
||||
"name": "Vanja Kolar",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 36,
|
||||
"name": "Klara Wankmuller",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 37,
|
||||
"name": "Milan Stramec",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 38,
|
||||
@@ -193,27 +193,27 @@
|
||||
{
|
||||
"id": 39,
|
||||
"name": "Tia Sudar",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 40,
|
||||
"name": "Jaka Cvar",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 41,
|
||||
"name": "Tadej Štruc",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 42,
|
||||
"name": "Jure Glaser",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 43,
|
||||
"name": "Marko Pokržnik",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 44,
|
||||
@@ -223,37 +223,37 @@
|
||||
{
|
||||
"id": 45,
|
||||
"name": "Lidija Blimen",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 46,
|
||||
"name": "Tijana Štumpfl",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 47,
|
||||
"name": "Ljuba Mršak",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 48,
|
||||
"name": "Janja Salcman",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 49,
|
||||
"name": "Jolanda Verhnjak",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 50,
|
||||
"name": "Vid Ravnjak",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 51,
|
||||
"name": "Robi Ovčar",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,777 @@
|
||||
{
|
||||
"tournament": {
|
||||
"rounds": [
|
||||
{
|
||||
"round_number": 1,
|
||||
"players": [
|
||||
{
|
||||
"id": 29,
|
||||
"name": "Alen Kolar",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 32,
|
||||
"name": "David Strniša",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 44,
|
||||
"name": "Anka Kačnik",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 38,
|
||||
"name": "Bojan Sudar",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"name": "Andrej Herman",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 28,
|
||||
"name": "Anže Kolar",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"status": "pending"
|
||||
},
|
||||
{
|
||||
"round_number": 2,
|
||||
"players": [
|
||||
{
|
||||
"id": 13,
|
||||
"name": "Angelca Mrak",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "Branko Pokeržnik",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"status": "waiting"
|
||||
}
|
||||
],
|
||||
"created_at": "2026-04-19T14:50:47.646818",
|
||||
"total_players": 8,
|
||||
"total_rounds": 2,
|
||||
"current_round": 1,
|
||||
"tournament_type": "20_targets"
|
||||
},
|
||||
"results": {
|
||||
"tournament_id": "2026-04-19T14:50:47.646818",
|
||||
"tournament_type": "20_targets",
|
||||
"participants": {
|
||||
"29": {
|
||||
"name": "Alen Kolar",
|
||||
"targets": {
|
||||
"1": {
|
||||
"shot1": 5,
|
||||
"shot2": 3
|
||||
},
|
||||
"2": {
|
||||
"shot1": 6,
|
||||
"shot2": 3
|
||||
},
|
||||
"3": {
|
||||
"shot1": 9,
|
||||
"shot2": 2
|
||||
},
|
||||
"4": {
|
||||
"shot1": 10,
|
||||
"shot2": 10
|
||||
},
|
||||
"5": {
|
||||
"shot1": 10,
|
||||
"shot2": 0
|
||||
},
|
||||
"6": {
|
||||
"shot1": 8,
|
||||
"shot2": 4
|
||||
},
|
||||
"7": {
|
||||
"shot1": 4,
|
||||
"shot2": 9
|
||||
},
|
||||
"8": {
|
||||
"shot1": 2,
|
||||
"shot2": 10
|
||||
},
|
||||
"9": {
|
||||
"shot1": 4,
|
||||
"shot2": 4
|
||||
},
|
||||
"10": {
|
||||
"shot1": 9,
|
||||
"shot2": 3
|
||||
},
|
||||
"11": {
|
||||
"shot1": 7,
|
||||
"shot2": 6
|
||||
},
|
||||
"12": {
|
||||
"shot1": 3,
|
||||
"shot2": 4
|
||||
},
|
||||
"13": {
|
||||
"shot1": 5,
|
||||
"shot2": 2
|
||||
},
|
||||
"14": {
|
||||
"shot1": 10,
|
||||
"shot2": 2
|
||||
},
|
||||
"15": {
|
||||
"shot1": 10,
|
||||
"shot2": 1
|
||||
},
|
||||
"16": {
|
||||
"shot1": 8,
|
||||
"shot2": 2
|
||||
},
|
||||
"17": {
|
||||
"shot1": 3,
|
||||
"shot2": 2
|
||||
},
|
||||
"18": {
|
||||
"shot1": 0,
|
||||
"shot2": 2
|
||||
},
|
||||
"19": {
|
||||
"shot1": 10,
|
||||
"shot2": 3
|
||||
},
|
||||
"20": {
|
||||
"shot1": 9,
|
||||
"shot2": 0
|
||||
}
|
||||
},
|
||||
"total_score": 204,
|
||||
"completed": true,
|
||||
"joker_selected": false
|
||||
},
|
||||
"32": {
|
||||
"name": "David Strniša",
|
||||
"targets": {
|
||||
"1": {
|
||||
"shot1": 1,
|
||||
"shot2": 3
|
||||
},
|
||||
"2": {
|
||||
"shot1": 4,
|
||||
"shot2": 6
|
||||
},
|
||||
"3": {
|
||||
"shot1": 7,
|
||||
"shot2": 8
|
||||
},
|
||||
"4": {
|
||||
"shot1": 10,
|
||||
"shot2": 5
|
||||
},
|
||||
"5": {
|
||||
"shot1": 2,
|
||||
"shot2": 1
|
||||
},
|
||||
"6": {
|
||||
"shot1": 9,
|
||||
"shot2": 6
|
||||
},
|
||||
"7": {
|
||||
"shot1": 9,
|
||||
"shot2": 2
|
||||
},
|
||||
"8": {
|
||||
"shot1": 2,
|
||||
"shot2": 10
|
||||
},
|
||||
"9": {
|
||||
"shot1": 1,
|
||||
"shot2": 7
|
||||
},
|
||||
"10": {
|
||||
"shot1": 6,
|
||||
"shot2": 1
|
||||
},
|
||||
"11": {
|
||||
"shot1": 4,
|
||||
"shot2": 10
|
||||
},
|
||||
"12": {
|
||||
"shot1": 1,
|
||||
"shot2": 7
|
||||
},
|
||||
"13": {
|
||||
"shot1": 4,
|
||||
"shot2": 0
|
||||
},
|
||||
"14": {
|
||||
"shot1": 10,
|
||||
"shot2": 3
|
||||
},
|
||||
"15": {
|
||||
"shot1": 0,
|
||||
"shot2": 7
|
||||
},
|
||||
"16": {
|
||||
"shot1": 2,
|
||||
"shot2": 10
|
||||
},
|
||||
"17": {
|
||||
"shot1": 5,
|
||||
"shot2": 10
|
||||
},
|
||||
"18": {
|
||||
"shot1": 2,
|
||||
"shot2": 7
|
||||
},
|
||||
"19": {
|
||||
"shot1": 4,
|
||||
"shot2": 0
|
||||
},
|
||||
"20": {
|
||||
"shot1": 10,
|
||||
"shot2": 0
|
||||
}
|
||||
},
|
||||
"total_score": 196,
|
||||
"completed": true,
|
||||
"joker_selected": false
|
||||
},
|
||||
"44": {
|
||||
"name": "Anka Kačnik",
|
||||
"targets": {
|
||||
"1": {
|
||||
"shot1": 8,
|
||||
"shot2": 3
|
||||
},
|
||||
"2": {
|
||||
"shot1": 2,
|
||||
"shot2": 10
|
||||
},
|
||||
"3": {
|
||||
"shot1": 10,
|
||||
"shot2": 9
|
||||
},
|
||||
"4": {
|
||||
"shot1": 9,
|
||||
"shot2": 8
|
||||
},
|
||||
"5": {
|
||||
"shot1": 1,
|
||||
"shot2": 5
|
||||
},
|
||||
"6": {
|
||||
"shot1": 3,
|
||||
"shot2": 1
|
||||
},
|
||||
"7": {
|
||||
"shot1": 5,
|
||||
"shot2": 9
|
||||
},
|
||||
"8": {
|
||||
"shot1": 7,
|
||||
"shot2": 1
|
||||
},
|
||||
"9": {
|
||||
"shot1": 9,
|
||||
"shot2": 7
|
||||
},
|
||||
"10": {
|
||||
"shot1": 4,
|
||||
"shot2": 0
|
||||
},
|
||||
"11": {
|
||||
"shot1": 6,
|
||||
"shot2": 5
|
||||
},
|
||||
"12": {
|
||||
"shot1": 5,
|
||||
"shot2": 6
|
||||
},
|
||||
"13": {
|
||||
"shot1": 1,
|
||||
"shot2": 8
|
||||
},
|
||||
"14": {
|
||||
"shot1": 2,
|
||||
"shot2": 1
|
||||
},
|
||||
"15": {
|
||||
"shot1": 5,
|
||||
"shot2": 8
|
||||
},
|
||||
"16": {
|
||||
"shot1": 10,
|
||||
"shot2": 5
|
||||
},
|
||||
"17": {
|
||||
"shot1": 3,
|
||||
"shot2": 1
|
||||
},
|
||||
"18": {
|
||||
"shot1": 1,
|
||||
"shot2": 8
|
||||
},
|
||||
"19": {
|
||||
"shot1": 5,
|
||||
"shot2": 8
|
||||
},
|
||||
"20": {
|
||||
"shot1": 6,
|
||||
"shot2": 8
|
||||
}
|
||||
},
|
||||
"total_score": 213,
|
||||
"completed": true,
|
||||
"joker_selected": false
|
||||
},
|
||||
"38": {
|
||||
"name": "Bojan Sudar",
|
||||
"targets": {
|
||||
"1": {
|
||||
"shot1": 10,
|
||||
"shot2": 4
|
||||
},
|
||||
"2": {
|
||||
"shot1": 6,
|
||||
"shot2": 5
|
||||
},
|
||||
"3": {
|
||||
"shot1": 10,
|
||||
"shot2": 9
|
||||
},
|
||||
"4": {
|
||||
"shot1": 9,
|
||||
"shot2": 7
|
||||
},
|
||||
"5": {
|
||||
"shot1": 0,
|
||||
"shot2": 8
|
||||
},
|
||||
"6": {
|
||||
"shot1": 2,
|
||||
"shot2": 6
|
||||
},
|
||||
"7": {
|
||||
"shot1": 0,
|
||||
"shot2": 2
|
||||
},
|
||||
"8": {
|
||||
"shot1": 1,
|
||||
"shot2": 2
|
||||
},
|
||||
"9": {
|
||||
"shot1": 0,
|
||||
"shot2": 7
|
||||
},
|
||||
"10": {
|
||||
"shot1": 7,
|
||||
"shot2": 9
|
||||
},
|
||||
"11": {
|
||||
"shot1": 3,
|
||||
"shot2": 9
|
||||
},
|
||||
"12": {
|
||||
"shot1": 7,
|
||||
"shot2": 8
|
||||
},
|
||||
"13": {
|
||||
"shot1": 8,
|
||||
"shot2": 10
|
||||
},
|
||||
"14": {
|
||||
"shot1": 9,
|
||||
"shot2": 1
|
||||
},
|
||||
"15": {
|
||||
"shot1": 5,
|
||||
"shot2": 5
|
||||
},
|
||||
"16": {
|
||||
"shot1": 1,
|
||||
"shot2": 5
|
||||
},
|
||||
"17": {
|
||||
"shot1": 5,
|
||||
"shot2": 4
|
||||
},
|
||||
"18": {
|
||||
"shot1": 8,
|
||||
"shot2": 9
|
||||
},
|
||||
"19": {
|
||||
"shot1": 0,
|
||||
"shot2": 4
|
||||
},
|
||||
"20": {
|
||||
"shot1": 1,
|
||||
"shot2": 6
|
||||
}
|
||||
},
|
||||
"total_score": 212,
|
||||
"completed": true,
|
||||
"joker_selected": false
|
||||
},
|
||||
"25": {
|
||||
"name": "Andrej Herman",
|
||||
"targets": {
|
||||
"1": {
|
||||
"shot1": 8,
|
||||
"shot2": 3
|
||||
},
|
||||
"2": {
|
||||
"shot1": 9,
|
||||
"shot2": 6
|
||||
},
|
||||
"3": {
|
||||
"shot1": 7,
|
||||
"shot2": 9
|
||||
},
|
||||
"4": {
|
||||
"shot1": 2,
|
||||
"shot2": 2
|
||||
},
|
||||
"5": {
|
||||
"shot1": 10,
|
||||
"shot2": 0
|
||||
},
|
||||
"6": {
|
||||
"shot1": 8,
|
||||
"shot2": 7
|
||||
},
|
||||
"7": {
|
||||
"shot1": 10,
|
||||
"shot2": 4
|
||||
},
|
||||
"8": {
|
||||
"shot1": 9,
|
||||
"shot2": 6
|
||||
},
|
||||
"9": {
|
||||
"shot1": 4,
|
||||
"shot2": 2
|
||||
},
|
||||
"10": {
|
||||
"shot1": 2,
|
||||
"shot2": 10
|
||||
},
|
||||
"11": {
|
||||
"shot1": 7,
|
||||
"shot2": 7
|
||||
},
|
||||
"12": {
|
||||
"shot1": 0,
|
||||
"shot2": 5
|
||||
},
|
||||
"13": {
|
||||
"shot1": 4,
|
||||
"shot2": 9
|
||||
},
|
||||
"14": {
|
||||
"shot1": 6,
|
||||
"shot2": 7
|
||||
},
|
||||
"15": {
|
||||
"shot1": 1,
|
||||
"shot2": 6
|
||||
},
|
||||
"16": {
|
||||
"shot1": 5,
|
||||
"shot2": 1
|
||||
},
|
||||
"17": {
|
||||
"shot1": 4,
|
||||
"shot2": 9
|
||||
},
|
||||
"18": {
|
||||
"shot1": 2,
|
||||
"shot2": 7
|
||||
},
|
||||
"19": {
|
||||
"shot1": 6,
|
||||
"shot2": 6
|
||||
},
|
||||
"20": {
|
||||
"shot1": 1,
|
||||
"shot2": 1
|
||||
}
|
||||
},
|
||||
"total_score": 212,
|
||||
"completed": true,
|
||||
"joker_selected": false
|
||||
},
|
||||
"28": {
|
||||
"name": "Anže Kolar",
|
||||
"targets": {
|
||||
"1": {
|
||||
"shot1": 4,
|
||||
"shot2": 10
|
||||
},
|
||||
"2": {
|
||||
"shot1": 4,
|
||||
"shot2": 0
|
||||
},
|
||||
"3": {
|
||||
"shot1": 2,
|
||||
"shot2": 0
|
||||
},
|
||||
"4": {
|
||||
"shot1": 10,
|
||||
"shot2": 8
|
||||
},
|
||||
"5": {
|
||||
"shot1": 5,
|
||||
"shot2": 0
|
||||
},
|
||||
"6": {
|
||||
"shot1": 1,
|
||||
"shot2": 0
|
||||
},
|
||||
"7": {
|
||||
"shot1": 6,
|
||||
"shot2": 1
|
||||
},
|
||||
"8": {
|
||||
"shot1": 8,
|
||||
"shot2": 3
|
||||
},
|
||||
"9": {
|
||||
"shot1": 7,
|
||||
"shot2": 9
|
||||
},
|
||||
"10": {
|
||||
"shot1": 4,
|
||||
"shot2": 2
|
||||
},
|
||||
"11": {
|
||||
"shot1": 8,
|
||||
"shot2": 7
|
||||
},
|
||||
"12": {
|
||||
"shot1": 10,
|
||||
"shot2": 1
|
||||
},
|
||||
"13": {
|
||||
"shot1": 1,
|
||||
"shot2": 10
|
||||
},
|
||||
"14": {
|
||||
"shot1": 2,
|
||||
"shot2": 3
|
||||
},
|
||||
"15": {
|
||||
"shot1": 10,
|
||||
"shot2": 6
|
||||
},
|
||||
"16": {
|
||||
"shot1": 0,
|
||||
"shot2": 7
|
||||
},
|
||||
"17": {
|
||||
"shot1": 6,
|
||||
"shot2": 1
|
||||
},
|
||||
"18": {
|
||||
"shot1": 8,
|
||||
"shot2": 10
|
||||
},
|
||||
"19": {
|
||||
"shot1": 2,
|
||||
"shot2": 0
|
||||
},
|
||||
"20": {
|
||||
"shot1": 2,
|
||||
"shot2": 8
|
||||
}
|
||||
},
|
||||
"total_score": 186,
|
||||
"completed": true,
|
||||
"joker_selected": false
|
||||
},
|
||||
"13": {
|
||||
"name": "Angelca Mrak",
|
||||
"targets": {
|
||||
"1": {
|
||||
"shot1": 9,
|
||||
"shot2": 5
|
||||
},
|
||||
"2": {
|
||||
"shot1": 2,
|
||||
"shot2": 3
|
||||
},
|
||||
"3": {
|
||||
"shot1": 3,
|
||||
"shot2": 0
|
||||
},
|
||||
"4": {
|
||||
"shot1": 2,
|
||||
"shot2": 1
|
||||
},
|
||||
"5": {
|
||||
"shot1": 4,
|
||||
"shot2": 1
|
||||
},
|
||||
"6": {
|
||||
"shot1": 6,
|
||||
"shot2": 8
|
||||
},
|
||||
"7": {
|
||||
"shot1": 8,
|
||||
"shot2": 9
|
||||
},
|
||||
"8": {
|
||||
"shot1": 3,
|
||||
"shot2": 4
|
||||
},
|
||||
"9": {
|
||||
"shot1": 3,
|
||||
"shot2": 1
|
||||
},
|
||||
"10": {
|
||||
"shot1": 10,
|
||||
"shot2": 9
|
||||
},
|
||||
"11": {
|
||||
"shot1": 6,
|
||||
"shot2": 10
|
||||
},
|
||||
"12": {
|
||||
"shot1": 3,
|
||||
"shot2": 10
|
||||
},
|
||||
"13": {
|
||||
"shot1": 2,
|
||||
"shot2": 5
|
||||
},
|
||||
"14": {
|
||||
"shot1": 10,
|
||||
"shot2": 5
|
||||
},
|
||||
"15": {
|
||||
"shot1": 7,
|
||||
"shot2": 2
|
||||
},
|
||||
"16": {
|
||||
"shot1": 6,
|
||||
"shot2": 7
|
||||
},
|
||||
"17": {
|
||||
"shot1": 0,
|
||||
"shot2": 6
|
||||
},
|
||||
"18": {
|
||||
"shot1": 6,
|
||||
"shot2": 0
|
||||
},
|
||||
"19": {
|
||||
"shot1": 8,
|
||||
"shot2": 6
|
||||
},
|
||||
"20": {
|
||||
"shot1": 5,
|
||||
"shot2": 2
|
||||
}
|
||||
},
|
||||
"total_score": 197,
|
||||
"completed": true,
|
||||
"joker_selected": false
|
||||
},
|
||||
"7": {
|
||||
"name": "Branko Pokeržnik",
|
||||
"targets": {
|
||||
"1": {
|
||||
"shot1": 5,
|
||||
"shot2": 0
|
||||
},
|
||||
"2": {
|
||||
"shot1": 7,
|
||||
"shot2": 0
|
||||
},
|
||||
"3": {
|
||||
"shot1": 1,
|
||||
"shot2": 9
|
||||
},
|
||||
"4": {
|
||||
"shot1": 0,
|
||||
"shot2": 4
|
||||
},
|
||||
"5": {
|
||||
"shot1": 9,
|
||||
"shot2": 2
|
||||
},
|
||||
"6": {
|
||||
"shot1": 0,
|
||||
"shot2": 8
|
||||
},
|
||||
"7": {
|
||||
"shot1": 9,
|
||||
"shot2": 8
|
||||
},
|
||||
"8": {
|
||||
"shot1": 8,
|
||||
"shot2": 10
|
||||
},
|
||||
"9": {
|
||||
"shot1": 1,
|
||||
"shot2": 4
|
||||
},
|
||||
"10": {
|
||||
"shot1": 5,
|
||||
"shot2": 1
|
||||
},
|
||||
"11": {
|
||||
"shot1": 10,
|
||||
"shot2": 9
|
||||
},
|
||||
"12": {
|
||||
"shot1": 1,
|
||||
"shot2": 7
|
||||
},
|
||||
"13": {
|
||||
"shot1": 8,
|
||||
"shot2": 10
|
||||
},
|
||||
"14": {
|
||||
"shot1": 3,
|
||||
"shot2": 1
|
||||
},
|
||||
"15": {
|
||||
"shot1": 4,
|
||||
"shot2": 4
|
||||
},
|
||||
"16": {
|
||||
"shot1": 5,
|
||||
"shot2": 3
|
||||
},
|
||||
"17": {
|
||||
"shot1": 6,
|
||||
"shot2": 3
|
||||
},
|
||||
"18": {
|
||||
"shot1": 4,
|
||||
"shot2": 4
|
||||
},
|
||||
"19": {
|
||||
"shot1": 4,
|
||||
"shot2": 9
|
||||
},
|
||||
"20": {
|
||||
"shot1": 0,
|
||||
"shot2": 9
|
||||
}
|
||||
},
|
||||
"total_score": 195,
|
||||
"completed": true,
|
||||
"joker_selected": false
|
||||
}
|
||||
},
|
||||
"tournament_finished": true,
|
||||
"created_at": "2026-04-19T14:50:47.646988",
|
||||
"finished_at": "2026-04-19T14:51:31.954362"
|
||||
},
|
||||
"archived_at": "2026-04-19T14:51:31.954403"
|
||||
}
|
||||
@@ -0,0 +1,777 @@
|
||||
{
|
||||
"tournament": {
|
||||
"rounds": [
|
||||
{
|
||||
"round_number": 1,
|
||||
"players": [
|
||||
{
|
||||
"id": 28,
|
||||
"name": "Anže Kolar",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 32,
|
||||
"name": "David Strniša",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "Branko Pokeržnik",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 38,
|
||||
"name": "Bojan Sudar",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"name": "Andrej Herman",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "Angelca Mrak",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"status": "pending"
|
||||
},
|
||||
{
|
||||
"round_number": 2,
|
||||
"players": [
|
||||
{
|
||||
"id": 29,
|
||||
"name": "Alen Kolar",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 44,
|
||||
"name": "Anka Kačnik",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"status": "waiting"
|
||||
}
|
||||
],
|
||||
"created_at": "2026-04-19T14:52:03.834406",
|
||||
"total_players": 8,
|
||||
"total_rounds": 2,
|
||||
"current_round": 1,
|
||||
"tournament_type": "20_targets"
|
||||
},
|
||||
"results": {
|
||||
"tournament_id": "2026-04-19T14:52:03.834406",
|
||||
"tournament_type": "20_targets",
|
||||
"participants": {
|
||||
"28": {
|
||||
"name": "Anže Kolar",
|
||||
"targets": {
|
||||
"1": {
|
||||
"shot1": 4,
|
||||
"shot2": 2
|
||||
},
|
||||
"2": {
|
||||
"shot1": 9,
|
||||
"shot2": 0
|
||||
},
|
||||
"3": {
|
||||
"shot1": 0,
|
||||
"shot2": 8
|
||||
},
|
||||
"4": {
|
||||
"shot1": 10,
|
||||
"shot2": 2
|
||||
},
|
||||
"5": {
|
||||
"shot1": 4,
|
||||
"shot2": 10
|
||||
},
|
||||
"6": {
|
||||
"shot1": 10,
|
||||
"shot2": 3
|
||||
},
|
||||
"7": {
|
||||
"shot1": 9,
|
||||
"shot2": 8
|
||||
},
|
||||
"8": {
|
||||
"shot1": 6,
|
||||
"shot2": 9
|
||||
},
|
||||
"9": {
|
||||
"shot1": 2,
|
||||
"shot2": 6
|
||||
},
|
||||
"10": {
|
||||
"shot1": 2,
|
||||
"shot2": 8
|
||||
},
|
||||
"11": {
|
||||
"shot1": 3,
|
||||
"shot2": 6
|
||||
},
|
||||
"12": {
|
||||
"shot1": 7,
|
||||
"shot2": 5
|
||||
},
|
||||
"13": {
|
||||
"shot1": 6,
|
||||
"shot2": 8
|
||||
},
|
||||
"14": {
|
||||
"shot1": 5,
|
||||
"shot2": 7
|
||||
},
|
||||
"15": {
|
||||
"shot1": 4,
|
||||
"shot2": 3
|
||||
},
|
||||
"16": {
|
||||
"shot1": 10,
|
||||
"shot2": 7
|
||||
},
|
||||
"17": {
|
||||
"shot1": 1,
|
||||
"shot2": 7
|
||||
},
|
||||
"18": {
|
||||
"shot1": 5,
|
||||
"shot2": 9
|
||||
},
|
||||
"19": {
|
||||
"shot1": 7,
|
||||
"shot2": 1
|
||||
},
|
||||
"20": {
|
||||
"shot1": 2,
|
||||
"shot2": 8
|
||||
}
|
||||
},
|
||||
"total_score": 223,
|
||||
"completed": true,
|
||||
"joker_selected": false
|
||||
},
|
||||
"32": {
|
||||
"name": "David Strniša",
|
||||
"targets": {
|
||||
"1": {
|
||||
"shot1": 8,
|
||||
"shot2": 1
|
||||
},
|
||||
"2": {
|
||||
"shot1": 6,
|
||||
"shot2": 10
|
||||
},
|
||||
"3": {
|
||||
"shot1": 1,
|
||||
"shot2": 5
|
||||
},
|
||||
"4": {
|
||||
"shot1": 9,
|
||||
"shot2": 7
|
||||
},
|
||||
"5": {
|
||||
"shot1": 0,
|
||||
"shot2": 8
|
||||
},
|
||||
"6": {
|
||||
"shot1": 5,
|
||||
"shot2": 8
|
||||
},
|
||||
"7": {
|
||||
"shot1": 2,
|
||||
"shot2": 3
|
||||
},
|
||||
"8": {
|
||||
"shot1": 5,
|
||||
"shot2": 10
|
||||
},
|
||||
"9": {
|
||||
"shot1": 10,
|
||||
"shot2": 9
|
||||
},
|
||||
"10": {
|
||||
"shot1": 9,
|
||||
"shot2": 7
|
||||
},
|
||||
"11": {
|
||||
"shot1": 3,
|
||||
"shot2": 2
|
||||
},
|
||||
"12": {
|
||||
"shot1": 5,
|
||||
"shot2": 6
|
||||
},
|
||||
"13": {
|
||||
"shot1": 0,
|
||||
"shot2": 2
|
||||
},
|
||||
"14": {
|
||||
"shot1": 2,
|
||||
"shot2": 1
|
||||
},
|
||||
"15": {
|
||||
"shot1": 8,
|
||||
"shot2": 8
|
||||
},
|
||||
"16": {
|
||||
"shot1": 0,
|
||||
"shot2": 2
|
||||
},
|
||||
"17": {
|
||||
"shot1": 8,
|
||||
"shot2": 6
|
||||
},
|
||||
"18": {
|
||||
"shot1": 4,
|
||||
"shot2": 0
|
||||
},
|
||||
"19": {
|
||||
"shot1": 9,
|
||||
"shot2": 1
|
||||
},
|
||||
"20": {
|
||||
"shot1": 9,
|
||||
"shot2": 2
|
||||
}
|
||||
},
|
||||
"total_score": 201,
|
||||
"completed": true,
|
||||
"joker_selected": false
|
||||
},
|
||||
"7": {
|
||||
"name": "Branko Pokeržnik",
|
||||
"targets": {
|
||||
"1": {
|
||||
"shot1": 2,
|
||||
"shot2": 2
|
||||
},
|
||||
"2": {
|
||||
"shot1": 5,
|
||||
"shot2": 4
|
||||
},
|
||||
"3": {
|
||||
"shot1": 1,
|
||||
"shot2": 9
|
||||
},
|
||||
"4": {
|
||||
"shot1": 1,
|
||||
"shot2": 1
|
||||
},
|
||||
"5": {
|
||||
"shot1": 2,
|
||||
"shot2": 4
|
||||
},
|
||||
"6": {
|
||||
"shot1": 3,
|
||||
"shot2": 8
|
||||
},
|
||||
"7": {
|
||||
"shot1": 10,
|
||||
"shot2": 6
|
||||
},
|
||||
"8": {
|
||||
"shot1": 3,
|
||||
"shot2": 9
|
||||
},
|
||||
"9": {
|
||||
"shot1": 0,
|
||||
"shot2": 7
|
||||
},
|
||||
"10": {
|
||||
"shot1": 6,
|
||||
"shot2": 6
|
||||
},
|
||||
"11": {
|
||||
"shot1": 9,
|
||||
"shot2": 0
|
||||
},
|
||||
"12": {
|
||||
"shot1": 4,
|
||||
"shot2": 7
|
||||
},
|
||||
"13": {
|
||||
"shot1": 1,
|
||||
"shot2": 5
|
||||
},
|
||||
"14": {
|
||||
"shot1": 3,
|
||||
"shot2": 6
|
||||
},
|
||||
"15": {
|
||||
"shot1": 2,
|
||||
"shot2": 3
|
||||
},
|
||||
"16": {
|
||||
"shot1": 2,
|
||||
"shot2": 8
|
||||
},
|
||||
"17": {
|
||||
"shot1": 0,
|
||||
"shot2": 3
|
||||
},
|
||||
"18": {
|
||||
"shot1": 7,
|
||||
"shot2": 5
|
||||
},
|
||||
"19": {
|
||||
"shot1": 7,
|
||||
"shot2": 1
|
||||
},
|
||||
"20": {
|
||||
"shot1": 8,
|
||||
"shot2": 8
|
||||
}
|
||||
},
|
||||
"total_score": 178,
|
||||
"completed": true,
|
||||
"joker_selected": false
|
||||
},
|
||||
"38": {
|
||||
"name": "Bojan Sudar",
|
||||
"targets": {
|
||||
"1": {
|
||||
"shot1": 3,
|
||||
"shot2": 1
|
||||
},
|
||||
"2": {
|
||||
"shot1": 8,
|
||||
"shot2": 5
|
||||
},
|
||||
"3": {
|
||||
"shot1": 3,
|
||||
"shot2": 0
|
||||
},
|
||||
"4": {
|
||||
"shot1": 6,
|
||||
"shot2": 5
|
||||
},
|
||||
"5": {
|
||||
"shot1": 8,
|
||||
"shot2": 10
|
||||
},
|
||||
"6": {
|
||||
"shot1": 5,
|
||||
"shot2": 5
|
||||
},
|
||||
"7": {
|
||||
"shot1": 3,
|
||||
"shot2": 2
|
||||
},
|
||||
"8": {
|
||||
"shot1": 5,
|
||||
"shot2": 1
|
||||
},
|
||||
"9": {
|
||||
"shot1": 0,
|
||||
"shot2": 0
|
||||
},
|
||||
"10": {
|
||||
"shot1": 10,
|
||||
"shot2": 5
|
||||
},
|
||||
"11": {
|
||||
"shot1": 1,
|
||||
"shot2": 10
|
||||
},
|
||||
"12": {
|
||||
"shot1": 8,
|
||||
"shot2": 0
|
||||
},
|
||||
"13": {
|
||||
"shot1": 4,
|
||||
"shot2": 0
|
||||
},
|
||||
"14": {
|
||||
"shot1": 7,
|
||||
"shot2": 10
|
||||
},
|
||||
"15": {
|
||||
"shot1": 7,
|
||||
"shot2": 5
|
||||
},
|
||||
"16": {
|
||||
"shot1": 3,
|
||||
"shot2": 5
|
||||
},
|
||||
"17": {
|
||||
"shot1": 3,
|
||||
"shot2": 4
|
||||
},
|
||||
"18": {
|
||||
"shot1": 1,
|
||||
"shot2": 10
|
||||
},
|
||||
"19": {
|
||||
"shot1": 4,
|
||||
"shot2": 9
|
||||
},
|
||||
"20": {
|
||||
"shot1": 0,
|
||||
"shot2": 10
|
||||
}
|
||||
},
|
||||
"total_score": 186,
|
||||
"completed": true,
|
||||
"joker_selected": false
|
||||
},
|
||||
"25": {
|
||||
"name": "Andrej Herman",
|
||||
"targets": {
|
||||
"1": {
|
||||
"shot1": 2,
|
||||
"shot2": 0
|
||||
},
|
||||
"2": {
|
||||
"shot1": 1,
|
||||
"shot2": 8
|
||||
},
|
||||
"3": {
|
||||
"shot1": 2,
|
||||
"shot2": 1
|
||||
},
|
||||
"4": {
|
||||
"shot1": 9,
|
||||
"shot2": 7
|
||||
},
|
||||
"5": {
|
||||
"shot1": 4,
|
||||
"shot2": 3
|
||||
},
|
||||
"6": {
|
||||
"shot1": 7,
|
||||
"shot2": 0
|
||||
},
|
||||
"7": {
|
||||
"shot1": 2,
|
||||
"shot2": 5
|
||||
},
|
||||
"8": {
|
||||
"shot1": 1,
|
||||
"shot2": 7
|
||||
},
|
||||
"9": {
|
||||
"shot1": 8,
|
||||
"shot2": 0
|
||||
},
|
||||
"10": {
|
||||
"shot1": 8,
|
||||
"shot2": 4
|
||||
},
|
||||
"11": {
|
||||
"shot1": 10,
|
||||
"shot2": 10
|
||||
},
|
||||
"12": {
|
||||
"shot1": 2,
|
||||
"shot2": 5
|
||||
},
|
||||
"13": {
|
||||
"shot1": 5,
|
||||
"shot2": 0
|
||||
},
|
||||
"14": {
|
||||
"shot1": 10,
|
||||
"shot2": 10
|
||||
},
|
||||
"15": {
|
||||
"shot1": 0,
|
||||
"shot2": 5
|
||||
},
|
||||
"16": {
|
||||
"shot1": 10,
|
||||
"shot2": 3
|
||||
},
|
||||
"17": {
|
||||
"shot1": 4,
|
||||
"shot2": 6
|
||||
},
|
||||
"18": {
|
||||
"shot1": 2,
|
||||
"shot2": 5
|
||||
},
|
||||
"19": {
|
||||
"shot1": 2,
|
||||
"shot2": 9
|
||||
},
|
||||
"20": {
|
||||
"shot1": 6,
|
||||
"shot2": 5
|
||||
}
|
||||
},
|
||||
"total_score": 188,
|
||||
"completed": true,
|
||||
"joker_selected": false
|
||||
},
|
||||
"13": {
|
||||
"name": "Angelca Mrak",
|
||||
"targets": {
|
||||
"1": {
|
||||
"shot1": 4,
|
||||
"shot2": 0
|
||||
},
|
||||
"2": {
|
||||
"shot1": 4,
|
||||
"shot2": 3
|
||||
},
|
||||
"3": {
|
||||
"shot1": 10,
|
||||
"shot2": 0
|
||||
},
|
||||
"4": {
|
||||
"shot1": 8,
|
||||
"shot2": 0
|
||||
},
|
||||
"5": {
|
||||
"shot1": 2,
|
||||
"shot2": 4
|
||||
},
|
||||
"6": {
|
||||
"shot1": 5,
|
||||
"shot2": 8
|
||||
},
|
||||
"7": {
|
||||
"shot1": 9,
|
||||
"shot2": 1
|
||||
},
|
||||
"8": {
|
||||
"shot1": 7,
|
||||
"shot2": 9
|
||||
},
|
||||
"9": {
|
||||
"shot1": 7,
|
||||
"shot2": 8
|
||||
},
|
||||
"10": {
|
||||
"shot1": 5,
|
||||
"shot2": 5
|
||||
},
|
||||
"11": {
|
||||
"shot1": 0,
|
||||
"shot2": 3
|
||||
},
|
||||
"12": {
|
||||
"shot1": 1,
|
||||
"shot2": 0
|
||||
},
|
||||
"13": {
|
||||
"shot1": 7,
|
||||
"shot2": 10
|
||||
},
|
||||
"14": {
|
||||
"shot1": 8,
|
||||
"shot2": 7
|
||||
},
|
||||
"15": {
|
||||
"shot1": 8,
|
||||
"shot2": 1
|
||||
},
|
||||
"16": {
|
||||
"shot1": 7,
|
||||
"shot2": 8
|
||||
},
|
||||
"17": {
|
||||
"shot1": 10,
|
||||
"shot2": 7
|
||||
},
|
||||
"18": {
|
||||
"shot1": 8,
|
||||
"shot2": 7
|
||||
},
|
||||
"19": {
|
||||
"shot1": 1,
|
||||
"shot2": 6
|
||||
},
|
||||
"20": {
|
||||
"shot1": 7,
|
||||
"shot2": 5
|
||||
}
|
||||
},
|
||||
"total_score": 210,
|
||||
"completed": true,
|
||||
"joker_selected": false
|
||||
},
|
||||
"29": {
|
||||
"name": "Alen Kolar",
|
||||
"targets": {
|
||||
"1": {
|
||||
"shot1": 3,
|
||||
"shot2": 0
|
||||
},
|
||||
"2": {
|
||||
"shot1": 3,
|
||||
"shot2": 5
|
||||
},
|
||||
"3": {
|
||||
"shot1": 3,
|
||||
"shot2": 5
|
||||
},
|
||||
"4": {
|
||||
"shot1": 2,
|
||||
"shot2": 6
|
||||
},
|
||||
"5": {
|
||||
"shot1": 3,
|
||||
"shot2": 0
|
||||
},
|
||||
"6": {
|
||||
"shot1": 2,
|
||||
"shot2": 9
|
||||
},
|
||||
"7": {
|
||||
"shot1": 8,
|
||||
"shot2": 8
|
||||
},
|
||||
"8": {
|
||||
"shot1": 5,
|
||||
"shot2": 0
|
||||
},
|
||||
"9": {
|
||||
"shot1": 9,
|
||||
"shot2": 8
|
||||
},
|
||||
"10": {
|
||||
"shot1": 9,
|
||||
"shot2": 7
|
||||
},
|
||||
"11": {
|
||||
"shot1": 8,
|
||||
"shot2": 5
|
||||
},
|
||||
"12": {
|
||||
"shot1": 4,
|
||||
"shot2": 2
|
||||
},
|
||||
"13": {
|
||||
"shot1": 1,
|
||||
"shot2": 5
|
||||
},
|
||||
"14": {
|
||||
"shot1": 9,
|
||||
"shot2": 0
|
||||
},
|
||||
"15": {
|
||||
"shot1": 3,
|
||||
"shot2": 7
|
||||
},
|
||||
"16": {
|
||||
"shot1": 5,
|
||||
"shot2": 10
|
||||
},
|
||||
"17": {
|
||||
"shot1": 0,
|
||||
"shot2": 2
|
||||
},
|
||||
"18": {
|
||||
"shot1": 8,
|
||||
"shot2": 5
|
||||
},
|
||||
"19": {
|
||||
"shot1": 0,
|
||||
"shot2": 9
|
||||
},
|
||||
"20": {
|
||||
"shot1": 0,
|
||||
"shot2": 10
|
||||
}
|
||||
},
|
||||
"total_score": 188,
|
||||
"completed": true,
|
||||
"joker_selected": false
|
||||
},
|
||||
"44": {
|
||||
"name": "Anka Kačnik",
|
||||
"targets": {
|
||||
"1": {
|
||||
"shot1": 5,
|
||||
"shot2": 3
|
||||
},
|
||||
"2": {
|
||||
"shot1": 5,
|
||||
"shot2": 1
|
||||
},
|
||||
"3": {
|
||||
"shot1": 0,
|
||||
"shot2": 3
|
||||
},
|
||||
"4": {
|
||||
"shot1": 4,
|
||||
"shot2": 8
|
||||
},
|
||||
"5": {
|
||||
"shot1": 5,
|
||||
"shot2": 8
|
||||
},
|
||||
"6": {
|
||||
"shot1": 10,
|
||||
"shot2": 10
|
||||
},
|
||||
"7": {
|
||||
"shot1": 0,
|
||||
"shot2": 5
|
||||
},
|
||||
"8": {
|
||||
"shot1": 8,
|
||||
"shot2": 10
|
||||
},
|
||||
"9": {
|
||||
"shot1": 5,
|
||||
"shot2": 1
|
||||
},
|
||||
"10": {
|
||||
"shot1": 5,
|
||||
"shot2": 2
|
||||
},
|
||||
"11": {
|
||||
"shot1": 8,
|
||||
"shot2": 6
|
||||
},
|
||||
"12": {
|
||||
"shot1": 8,
|
||||
"shot2": 9
|
||||
},
|
||||
"13": {
|
||||
"shot1": 6,
|
||||
"shot2": 5
|
||||
},
|
||||
"14": {
|
||||
"shot1": 0,
|
||||
"shot2": 4
|
||||
},
|
||||
"15": {
|
||||
"shot1": 5,
|
||||
"shot2": 7
|
||||
},
|
||||
"16": {
|
||||
"shot1": 6,
|
||||
"shot2": 5
|
||||
},
|
||||
"17": {
|
||||
"shot1": 1,
|
||||
"shot2": 10
|
||||
},
|
||||
"18": {
|
||||
"shot1": 5,
|
||||
"shot2": 6
|
||||
},
|
||||
"19": {
|
||||
"shot1": 1,
|
||||
"shot2": 8
|
||||
},
|
||||
"20": {
|
||||
"shot1": 3,
|
||||
"shot2": 7
|
||||
}
|
||||
},
|
||||
"total_score": 208,
|
||||
"completed": true,
|
||||
"joker_selected": false
|
||||
}
|
||||
},
|
||||
"tournament_finished": true,
|
||||
"created_at": "2026-04-19T14:52:03.834609",
|
||||
"finished_at": "2026-04-19T14:52:41.243912"
|
||||
},
|
||||
"archived_at": "2026-04-19T14:52:41.243969"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,318 @@
|
||||
{
|
||||
"rounds": [
|
||||
{
|
||||
"round_number": 1,
|
||||
"players": [
|
||||
{
|
||||
"id": 14,
|
||||
"name": "Karli Proje",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"name": "Robi Krautberger",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "Rado Kefer",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 43,
|
||||
"name": "Marko Pokržnik",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "Branko Pokeržnik",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "Janez Božič",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"round_number": 2,
|
||||
"players": [
|
||||
{
|
||||
"id": 39,
|
||||
"name": "Tia Sudar",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"name": "Silvo Poročnik",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 31,
|
||||
"name": "Dejan Kučnik",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "Mitja Čeh",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 48,
|
||||
"name": "Janja Salcman",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 50,
|
||||
"name": "Vid Ravnjak",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"round_number": 3,
|
||||
"players": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Domen Pleterski",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 35,
|
||||
"name": "Vanja Kolar",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 36,
|
||||
"name": "Klara Wankmuller",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 46,
|
||||
"name": "Tijana Štumpfl",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 34,
|
||||
"name": "Jože Planinšec",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Ivan Tandler",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"round_number": 4,
|
||||
"players": [
|
||||
{
|
||||
"id": 26,
|
||||
"name": "Jakob Herman",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"name": "Andrej Herman",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 30,
|
||||
"name": "Maja Hirtl",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Mateja Pleterski",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 29,
|
||||
"name": "Alen Kolar",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "Jože Verhnjak",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"round_number": 5,
|
||||
"players": [
|
||||
{
|
||||
"id": 44,
|
||||
"name": "Anka Kačnik",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 42,
|
||||
"name": "Jure Glaser",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 45,
|
||||
"name": "Lidija Blimen",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 32,
|
||||
"name": "David Strniša",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 51,
|
||||
"name": "Robi Ovčar",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 41,
|
||||
"name": "Tadej Štruc",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"round_number": 6,
|
||||
"players": [
|
||||
{
|
||||
"id": 13,
|
||||
"name": "Angelca Mrak",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"name": "Jože Verdinek",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 49,
|
||||
"name": "Jolanda Verhnjak",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "Matjaž Pleterski",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 40,
|
||||
"name": "Jaka Cvar",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "Franc Rizmal",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"status": "pending"
|
||||
},
|
||||
{
|
||||
"round_number": 7,
|
||||
"players": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Nik Pleterski",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"name": "Dušan Onuk",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 28,
|
||||
"name": "Anže Kolar",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"name": "Marko Blimen",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"name": "Jože Preglav",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"name": "Doris Fesel",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"status": "waiting"
|
||||
},
|
||||
{
|
||||
"round_number": 8,
|
||||
"players": [
|
||||
{
|
||||
"id": 15,
|
||||
"name": "Jan Pleterski",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "Mateja Senica",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "Franc Žigart",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "Matej Kvasnik",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"name": "Namir Uzunović",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 38,
|
||||
"name": "Bojan Sudar",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"status": "waiting"
|
||||
},
|
||||
{
|
||||
"round_number": 9,
|
||||
"players": [
|
||||
{
|
||||
"id": 37,
|
||||
"name": "Milan Stramec",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 27,
|
||||
"name": "Janez Mrak",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 47,
|
||||
"name": "Ljuba Mršak",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"status": "waiting"
|
||||
}
|
||||
],
|
||||
"created_at": "2026-04-22T17:12:17.015870",
|
||||
"total_players": 51,
|
||||
"total_rounds": 9,
|
||||
"current_round": 6,
|
||||
"tournament_type": "20_targets"
|
||||
}
|
||||
@@ -348,7 +348,7 @@
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.player-id {
|
||||
.player-id {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -645,11 +645,13 @@
|
||||
</div>
|
||||
|
||||
<div class="positions-container">
|
||||
{% for position in range(1, 7) %}
|
||||
{% set player = round.players[position-1] if position <= round.players|length else none %}
|
||||
{% set slots = tournament.active_slots if tournament.active_slots else range(1, 7) %}
|
||||
{% for idx in range(slots|length) %}
|
||||
{% set slot_num = slots[idx] %}
|
||||
{% set player = round.players[idx] if idx < round.players|length else none %}
|
||||
<div class="position-card {{ 'filled' if player else 'empty' }}">
|
||||
<div class="position-header">
|
||||
<div class="position-number">{{ position }}</div>
|
||||
<div class="position-number">{{ slot_num }}</div>
|
||||
</div>
|
||||
<div class="position-body">
|
||||
{% if player %}
|
||||
|
||||
+246
-91
@@ -124,28 +124,21 @@
|
||||
height: calc(100vh - 50px);
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-template-rows: repeat(2, 1fr);
|
||||
gap: 20px;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
align-content: stretch;
|
||||
}
|
||||
|
||||
.camera-card {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.camera-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
@@ -189,12 +182,7 @@
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* Calculate optimal size to fit within grid cell */
|
||||
@supports (width: min(100%, calc((100vh - 50px - 20px) / 2 - 60px) * 4 / 3)) {
|
||||
.stream-wrapper {
|
||||
width: min(100%, calc(((100vh - 50px - 20px) / 2 - 60px) * 4 / 3));
|
||||
}
|
||||
}
|
||||
/* stream-wrapper width is set dynamically via JS (reshapeGrid) */
|
||||
|
||||
.stream-placeholder {
|
||||
position: absolute;
|
||||
@@ -263,35 +251,7 @@
|
||||
background: linear-gradient(90deg, #999 0%, #999 60px, #1a1a1a 60px);
|
||||
}
|
||||
|
||||
.camera-card:hover .card-header {
|
||||
background: linear-gradient(90deg, #1e7e34 0%, #1e7e34 60px, #2d2d2d 60px);
|
||||
border-bottom-color: #28a745;
|
||||
}
|
||||
|
||||
/* Tooltip for camera cards */
|
||||
.camera-card::after {
|
||||
content: attr(data-tooltip);
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
color: white;
|
||||
padding: 6px 12px;
|
||||
border-radius: 4px;
|
||||
font-size: 0.85rem;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: all 0.2s ease;
|
||||
pointer-events: none;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.camera-card:hover::after {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateX(-50%) translateY(-5px);
|
||||
}
|
||||
|
||||
/* Settings Panel */
|
||||
#overlay {
|
||||
@@ -491,6 +451,157 @@
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
/* Camera settings panel components */
|
||||
.cam-setting-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px 0;
|
||||
font-size: 0.9rem;
|
||||
color: #495057;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #e9ecef;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.cam-setting-toggle input[type="checkbox"] {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
cursor: pointer;
|
||||
accent-color: #28a745;
|
||||
}
|
||||
|
||||
.cam-slider-row {
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.cam-slider-label {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 0.85rem;
|
||||
color: #495057;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.cam-slider-value {
|
||||
font-weight: 600;
|
||||
color: #28a745;
|
||||
}
|
||||
|
||||
.cam-slider {
|
||||
width: 100%;
|
||||
accent-color: #28a745;
|
||||
}
|
||||
|
||||
.cam-list {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.cam-row {
|
||||
border: 1.5px solid #dee2e6;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.cam-row--disabled {
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.cam-row-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 8px 12px;
|
||||
background: #f8f9fa;
|
||||
border-bottom: 1px solid #e9ecef;
|
||||
}
|
||||
|
||||
.cam-row-label {
|
||||
font-size: 0.85rem;
|
||||
font-weight: 600;
|
||||
color: #495057;
|
||||
}
|
||||
|
||||
.cam-row .camera-input {
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
padding: 10px 12px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.cam-row .camera-input:focus {
|
||||
border: none;
|
||||
box-shadow: inset 0 0 0 2px #28a745;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.cam-row .camera-input:hover:not(:focus) {
|
||||
border: none;
|
||||
box-shadow: inset 0 0 0 2px #28a74580;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
/* Toggle switch */
|
||||
.cam-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cam-toggle input[type="checkbox"] {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.cam-toggle-track {
|
||||
width: 36px;
|
||||
height: 20px;
|
||||
background: #dc3545;
|
||||
border-radius: 10px;
|
||||
position: relative;
|
||||
transition: background 0.2s ease;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.cam-toggle input:checked ~ .cam-toggle-track {
|
||||
background: #28a745;
|
||||
}
|
||||
|
||||
.cam-toggle-thumb {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background: white;
|
||||
border-radius: 50%;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.cam-toggle input:checked ~ .cam-toggle-track .cam-toggle-thumb {
|
||||
transform: translateX(16px);
|
||||
}
|
||||
|
||||
.cam-toggle-text {
|
||||
font-size: 0.78rem;
|
||||
font-weight: 600;
|
||||
color: #28a745;
|
||||
min-width: 22px;
|
||||
}
|
||||
|
||||
.cam-toggle-text--off {
|
||||
color: #dc3545;
|
||||
}
|
||||
|
||||
.tournament-status-info {
|
||||
background: #f0f8ff;
|
||||
border: 2px solid #28a745;
|
||||
@@ -539,7 +650,6 @@
|
||||
.grid {
|
||||
height: calc(100vh - 100px);
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: repeat(6, 1fr);
|
||||
gap: 15px;
|
||||
padding: 20px;
|
||||
}
|
||||
@@ -549,9 +659,6 @@
|
||||
padding: 10px 12px 10px 0;
|
||||
}
|
||||
|
||||
.camera-card:hover .card-header {
|
||||
background: linear-gradient(90deg, #1e7e34 0%, #1e7e34 50px, #2d2d2d 50px);
|
||||
}
|
||||
|
||||
.target-number {
|
||||
width: 50px;
|
||||
@@ -611,9 +718,6 @@
|
||||
padding: 8px 10px 8px 0;
|
||||
}
|
||||
|
||||
.camera-card:hover .card-header {
|
||||
background: linear-gradient(90deg, #1e7e34 0%, #1e7e34 45px, #2d2d2d 45px);
|
||||
}
|
||||
|
||||
.target-number {
|
||||
width: 45px;
|
||||
@@ -719,46 +823,48 @@
|
||||
<div class="settings-group" id="displayOptionsGroup">
|
||||
<h4 data-i18n="league.camera">Kamera</h4>
|
||||
|
||||
<div style="margin-bottom: 15px;">
|
||||
<label style="display: flex; align-items: center; gap: 8px; cursor: pointer;">
|
||||
<input type="checkbox" id="toggleTitles" {% if settings.display_options.show_titles %}checked{% endif %} onchange="toggleTitles()" style="width: 18px; height: 18px;">
|
||||
<span data-i18n="camera.show_card_titles">Prikaiž Naslove Kartic</span>
|
||||
</label>
|
||||
<!-- Display toggles -->
|
||||
<label class="cam-setting-toggle">
|
||||
<input type="checkbox" id="toggleTitles" {% if settings.display_options.show_titles %}checked{% endif %} onchange="toggleTitles()">
|
||||
<span data-i18n="camera.show_card_titles">Prikaži Naslove Kartic</span>
|
||||
</label>
|
||||
|
||||
<!-- Sliders -->
|
||||
<div class="cam-slider-row">
|
||||
<div class="cam-slider-label">
|
||||
<span data-i18n="camera.title_text_size">Naslov</span>
|
||||
<span class="cam-slider-value"><span id="titleSizeValue">{{ settings.display_options.title_size }}</span>rem</span>
|
||||
</div>
|
||||
<input type="range" id="titleSize" class="cam-slider" min="0.8" max="2.5" step="0.1"
|
||||
value="{{ settings.display_options.title_size }}" oninput="adjustTitleSize(this.value)">
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 15px;">
|
||||
<label style="display: block; margin-bottom: 8px; font-weight: bold; color: #333;">
|
||||
<span data-i18n="camera.title_text_size">Velikost Besedila Naslova</span>: <span id="titleSizeValue">{{ settings.display_options.title_size }}</span>rem
|
||||
</label>
|
||||
<input type="range"
|
||||
id="titleSize"
|
||||
min="0.8"
|
||||
max="2.5"
|
||||
step="0.1"
|
||||
value="{{ settings.display_options.title_size }}"
|
||||
oninput="adjustTitleSize(this.value)"
|
||||
style="width: 100%;">
|
||||
<div class="cam-slider-row">
|
||||
<div class="cam-slider-label">
|
||||
<span data-i18n="camera.target_number_size">Številka</span>
|
||||
<span class="cam-slider-value"><span id="targetNumberSizeValue">{{ settings.display_options.get('target_number_size', settings.display_options.title_size) }}</span>rem</span>
|
||||
</div>
|
||||
<input type="range" id="targetNumberSize" class="cam-slider" min="0.8" max="2.5" step="0.1"
|
||||
value="{{ settings.display_options.get('target_number_size', settings.display_options.title_size) }}" oninput="adjustTargetNumberSize(this.value)">
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 15px;">
|
||||
<label style="display: block; margin-bottom: 8px; font-weight: bold; color: #333;">
|
||||
<span data-i18n="camera.target_number_size">Velikost Števila Tarče</span>: <span id="targetNumberSizeValue">{{ settings.display_options.get('target_number_size', settings.display_options.title_size) }}</span>rem
|
||||
</label>
|
||||
<input type="range"
|
||||
id="targetNumberSize"
|
||||
min="0.8"
|
||||
max="2.5"
|
||||
step="0.1"
|
||||
value="{{ settings.display_options.get('target_number_size', settings.display_options.title_size) }}"
|
||||
oninput="adjustTargetNumberSize(this.value)"
|
||||
style="width: 100%;">
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 20px;">
|
||||
<h5 data-i18n="camera.titles">Naslovi Kamer</h5>
|
||||
<!-- Camera rows -->
|
||||
<div class="cam-list">
|
||||
{% for i in range(1, 7) %}
|
||||
<div style="margin-bottom: 15px;">
|
||||
<label style="display: block; margin-bottom: 8px; font-weight: 500; color: #495057; font-size: 0.9rem;"><span data-i18n="camera.camera">Kamera</span> {{ i }}:</label>
|
||||
{% set is_disabled = i in settings.get('disabled_cameras', []) %}
|
||||
<div class="cam-row {% if is_disabled %}cam-row--disabled{% endif %}" id="cameraSettingsRow{{ i }}">
|
||||
<div class="cam-row-header">
|
||||
<span class="cam-row-label"><span data-i18n="camera.camera">Kamera</span> {{ i }}</span>
|
||||
<label class="cam-toggle" id="cameraToggleLabel{{ i }}">
|
||||
<input type="checkbox" id="cameraEnabled{{ i }}"
|
||||
{% if not is_disabled %}checked{% endif %}
|
||||
onchange="toggleCamera({{ i }}, this.checked)">
|
||||
<span class="cam-toggle-track">
|
||||
<span class="cam-toggle-thumb"></span>
|
||||
</span>
|
||||
<span class="cam-toggle-text {% if is_disabled %}cam-toggle-text--off{% endif %}" id="cameraStatusText{{ i }}">{% if is_disabled %}Off{% else %}On{% endif %}</span>
|
||||
</label>
|
||||
</div>
|
||||
<input type="text"
|
||||
id="titleInput{{ i }}"
|
||||
value="{{ settings.camera_titles[i|string] }}"
|
||||
@@ -779,7 +885,8 @@
|
||||
|
||||
<div class="grid">
|
||||
{% for i in range(1, 7) %}
|
||||
<div class="camera-card" onclick="openCameraFullscreen({{ i }})" data-camera-id="{{ i }}" data-tooltip="" data-i18n-tooltip="camera.click_to_view_fullscreen">
|
||||
<div class="camera-card" data-camera-id="{{ i }}"
|
||||
{% if i in settings.get('disabled_cameras', []) %}style="display:none;"{% endif %}>
|
||||
<div class="stream-wrapper">
|
||||
<div class="card-header">
|
||||
<div class="target-number">{{ i }}</div>
|
||||
@@ -1174,6 +1281,58 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle camera enabled/disabled
|
||||
function reshapeGrid() {
|
||||
const grid = document.querySelector('.grid');
|
||||
if (!grid) return;
|
||||
const activeCount = document.querySelectorAll('.camera-card:not([style*="display: none"]):not([style*="display:none"])').length;
|
||||
let cols;
|
||||
if (activeCount <= 1) cols = 1;
|
||||
else if (activeCount === 2) cols = 2;
|
||||
else if (activeCount === 3) cols = 3;
|
||||
else if (activeCount === 4) cols = 2;
|
||||
else cols = 3;
|
||||
const rows = Math.ceil(activeCount / cols);
|
||||
grid.style.gridTemplateColumns = `repeat(${cols}, 1fr)`;
|
||||
|
||||
// Recompute stream-wrapper max-width so cards fill available height at 4:3
|
||||
// gap=20px, padding=20px each side, header~40px, toolbar=50px
|
||||
const gap = 20;
|
||||
const padding = 40;
|
||||
const toolbar = 50;
|
||||
const headerH = 40;
|
||||
const availH = (window.innerHeight - toolbar - padding - gap * (rows - 1)) / rows - headerH;
|
||||
const maxW = availH * (4 / 3);
|
||||
document.querySelectorAll('.stream-wrapper').forEach(w => {
|
||||
w.style.width = `min(100%, ${maxW}px)`;
|
||||
});
|
||||
}
|
||||
|
||||
function toggleCamera(index, enabled) {
|
||||
const card = document.querySelector(`.camera-card[data-camera-id="${index}"]`);
|
||||
const titleInput = document.getElementById(`titleInput${index}`);
|
||||
const label = document.getElementById(`cameraToggleLabel${index}`);
|
||||
const statusText = document.getElementById(`cameraStatusText${index}`);
|
||||
|
||||
const row = document.getElementById(`cameraSettingsRow${index}`);
|
||||
|
||||
if (enabled) {
|
||||
if (card) card.style.display = '';
|
||||
if (row) row.classList.remove('cam-row--disabled');
|
||||
if (statusText) { statusText.textContent = 'On'; statusText.classList.remove('cam-toggle-text--off'); }
|
||||
currentSettings.disabled_cameras = (currentSettings.disabled_cameras || []).filter(c => c !== index);
|
||||
} else {
|
||||
if (card) card.style.display = 'none';
|
||||
if (row) row.classList.add('cam-row--disabled');
|
||||
if (statusText) { statusText.textContent = 'Off'; statusText.classList.add('cam-toggle-text--off'); }
|
||||
if (!currentSettings.disabled_cameras) currentSettings.disabled_cameras = [];
|
||||
if (!currentSettings.disabled_cameras.includes(index)) currentSettings.disabled_cameras.push(index);
|
||||
}
|
||||
|
||||
reshapeGrid();
|
||||
saveSettings({ disabled_cameras: currentSettings.disabled_cameras });
|
||||
}
|
||||
|
||||
// Toggle titles
|
||||
function toggleTitles() {
|
||||
const show = document.getElementById('toggleTitles').checked;
|
||||
@@ -1236,12 +1395,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Open camera fullscreen
|
||||
function openCameraFullscreen(cameraId) {
|
||||
const customTitle = currentSettings.camera_titles[cameraId.toString()] || `Camera ${cameraId}`;
|
||||
window.location.href = `/fullscreen/${cameraId}?title=${encodeURIComponent(customTitle)}`;
|
||||
}
|
||||
|
||||
// Apply current settings
|
||||
function applyCurrentSettings() {
|
||||
// Apply title visibility
|
||||
@@ -1460,6 +1613,8 @@
|
||||
setInterval(updateDateTime, 1000);
|
||||
updateRoundNavigation();
|
||||
applyCurrentSettings();
|
||||
reshapeGrid();
|
||||
window.addEventListener('resize', reshapeGrid);
|
||||
addTouchFeedback();
|
||||
|
||||
// Initialize language selector after i18n is ready
|
||||
|
||||
Reference in New Issue
Block a user