diff --git a/api/db.js b/api/db.js index 667878c..8b9de04 100644 --- a/api/db.js +++ b/api/db.js @@ -68,6 +68,8 @@ export const AVATAR = Object.freeze({ NAME: Symbol("name"), BEP: Symbol("bep"), CEP: Symbol("cep"), + GENDER: Symbol("gender_id"), + HEAD: Symbol("head_id"), }); export const WEAPONSTAT = Object.freeze({ @@ -348,12 +350,24 @@ export async function get_weaponstats_by_avatar(id) { } } -export async function get_killstats() { +export async function get_avatar(id) { try { - const kills = await pool.query('SELECT count(killactivity.killer_id), killactivity.killer_id, avatar.name, avatar.bep, avatar.cep, avatar.faction_id' + + const avatar = await pool.query('SELECT id, name, faction_id, bep, cep, gender_id, head_id FROM avatar WHERE id=$1', [id]) + return avatar.rows[0]; + } catch (e) { + if (e.code) + e.code = pg_error_inv[e.code] + throw e; + } +} + +export async function get_top_kills() { + try { + const kills = await pool.query('SELECT count(killactivity.killer_id), killactivity.killer_id, avatar.name, avatar.bep,' + + ' avatar.cep, avatar.faction_id, avatar.gender_id, avatar.head_id' + ' FROM killactivity' + ' INNER JOIN avatar ON killactivity.killer_id = avatar.id' + - ' GROUP BY killactivity.killer_id, avatar.name, avatar.bep, avatar.cep, avatar.faction_id' + + ' GROUP BY killactivity.killer_id, avatar.name, avatar.bep, avatar.cep, avatar.faction_id, avatar.gender_id, avatar.head_id' + ' ORDER BY count(killer_id) DESC') return kills.rows; } catch (e) { @@ -363,6 +377,37 @@ export async function get_killstats() { } } +export async function get_avatar_kd_byDate(id) { + try { + const kd = await pool.query("SELECT TO_CHAR(timestamp, 'FMMon DD, YYYY') AS date," + + ' SUM(CASE WHEN killer_id = $1 THEN 1 ELSE 0 END)::int AS kills,' + + ' SUM(CASE WHEN victim_id = $1 THEN 1 ELSE 0 END)::int AS deaths' + + ' FROM killactivity GROUP BY date HAVING' + + ' SUM(CASE WHEN killer_id = $1 THEN 1 ELSE 0 END) > 0 OR SUM(CASE WHEN victim_id = $1 THEN 1 ELSE 0 END) > 0' + + ' ORDER BY date DESC', [id]) + return kd.rows; + } catch (e) { + if (e.code) + e.code = pg_error_inv[e.code] + throw e; + } +} + +export async function get_top_kills_byDate() { + try { + const kills = await pool.query('WITH RankedKills AS (SELECT COUNT(*)::int AS kill_count,' + + ' killer_id, DATE(timestamp) AS kill_date, ROW_NUMBER() OVER (PARTITION BY killer_id ORDER BY COUNT(*) DESC)::int AS row_num' + + ' FROM killactivity GROUP BY killer_id, DATE(timestamp)) SELECT rk.kill_count, rk.killer_id,' + + " TO_CHAR(rk.kill_date, 'FMMon DD, YYYY') AS f_kill_date, rk.row_num, av.name, av.faction_id FROM RankedKills rk" + + ' JOIN avatar av ON rk.killer_id = av.id WHERE rk.row_num = 1 ORDER BY rk.kill_count DESC LIMIT 50') + return kills.rows; + } catch (e) { + if (e.code) + e.code = pg_error_inv[e.code] + throw e; + } +} + export async function get_characters_by_account(account_id) { try { const characters = await pool.query('SELECT * FROM avatar WHERE account_id=$1 AND deleted=false', [account_id]) diff --git a/api/stats.js b/api/stats.js index ce210ca..594bf6a 100644 --- a/api/stats.js +++ b/api/stats.js @@ -58,9 +58,9 @@ api.get('/char_stats_cep/:batch', async (req, res, next) => { } }); -api.get('/char_stats_kills', async (req, res, next) => { +api.get('/top_kills', async (req, res, next) => { try { - const kills = await db.get_killstats(); + const kills = await db.get_top_kills(); res.status(200).json({ kills: kills }); } catch (e) { console.log(e); @@ -68,4 +68,58 @@ api.get('/char_stats_kills', async (req, res, next) => { } }); +api.get('/top_kills_byDate', async (req, res, next) => { + try { + const kills = await db.get_top_kills_byDate(); + res.status(200).json({ kills: kills }); + } catch (e) { + console.log(e); + res.status(500).json({ message: 'error' }); + } +}); + +api.get('/weaponstats/:avatar', async (req, res, next) => { + const avatar = req.params.avatar; + + try { + const weapons = await db.get_weaponstats_by_avatar(avatar); + res.status(200).json({ weapons: weapons }); + } catch (e) { + console.log(e); + res.status(500).json({ message: 'error' }); + } +}); + +api.get('/avatar/:avatar', async (req, res, next) => { + const avatar = req.params.avatar; + + try { + const avatarData = await db.get_avatar(avatar); + res.status(200).json({ + id: avatarData.id, + name: avatarData.name, + bep: avatarData.bep, + cep: avatarData.cep, + faction: avatarData.faction_id, + gender: avatarData.gender_id, + head: avatarData.head_id + }); + } catch (e) { + console.log(e); + res.status(500).json({ message: 'error' }); + } +}); + +api.get('/avatar/:avatar/kd_byDate', async (req, res, next) => { + const avatar = req.params.avatar; + + try { + const kd = await db.get_avatar_kd_byDate(avatar); + res.status(200).json({ kd: kd }); + } catch (e) { + console.log(e); + res.status(500).json({ message: 'error' }); + } +}); + export default api; \ No newline at end of file diff --git a/api/user.js b/api/user.js index d81f4e6..6ade53e 100644 --- a/api/user.js +++ b/api/user.js @@ -62,16 +62,4 @@ api.get('/user/:user/logins', NEED_SESSION, async (req, res, next) => { } }); -api.get('/avatar/:avatar/weaponstats', async (req, res, next) => { - const avatar = req.params.avatar; - - try { - const weapons = await db.get_weaponstats_by_avatar(avatar); - res.status(200).json({ weapons: weapons }); - } catch (e) { - console.log(e); - res.status(500).json({ message: 'error' }); - } -}); - export default api; diff --git a/app/player.js b/app/player.js deleted file mode 100644 index afe0bf6..0000000 --- a/app/player.js +++ /dev/null @@ -1,5 +0,0 @@ -import { writable } from 'svelte/store'; -import axios from 'axios' - -// Create a writable store to hold the selected player data -export const selectedPlayer = writable({}); \ No newline at end of file diff --git a/app/statFunctions.js b/app/statFunctions.js new file mode 100644 index 0000000..d81ae76 --- /dev/null +++ b/app/statFunctions.js @@ -0,0 +1,217 @@ + + export const bepRanges = [ + { rank: 1, minBEP: 0, maxBEP: 999 }, + { rank: 2, minBEP: 1000, maxBEP: 2999 }, + { rank: 3, minBEP: 3000, maxBEP: 7499 }, + { rank: 4, minBEP: 7500, maxBEP: 14999 }, + { rank: 5, minBEP: 15000, maxBEP: 29999 }, + { rank: 6, minBEP: 30000, maxBEP: 44999 }, + { rank: 7, minBEP: 45000, maxBEP: 67499 }, + { rank: 8, minBEP: 67500, maxBEP: 101249 }, + { rank: 9, minBEP: 101250, maxBEP: 126562 }, + { rank: 10, minBEP: 126563, maxBEP: 158202 }, + { rank: 11, minBEP: 158203, maxBEP: 197753 }, + { rank: 12, minBEP: 197754, maxBEP: 247191 }, + { rank: 13, minBEP: 247192, maxBEP: 308989 }, + { rank: 14, minBEP: 308990, maxBEP: 386238 }, + { rank: 15, minBEP: 368239, maxBEP: 482797 }, + { rank: 16, minBEP: 482798, maxBEP: 603496 }, + { rank: 17, minBEP: 603497, maxBEP: 754370 }, + { rank: 18, minBEP: 754371, maxBEP: 942963 }, + { rank: 19, minBEP: 942964, maxBEP: 1178704 }, + { rank: 20, minBEP: 1178705, maxBEP: 1438019 }, + { rank: 21, minBEP: 1438020, maxBEP: 1710300 }, + { rank: 22, minBEP: 1710301, maxBEP: 1988026 }, + { rank: 23, minBEP: 1988027, maxBEP: 2286230 }, + { rank: 24, minBEP: 2286231, maxBEP: 2583440 }, + { rank: 25, minBEP: 2583441, maxBEP: 2908441 }, + { rank: 26, minBEP: 2908442, maxBEP: 3237941 }, + { rank: 27, minBEP: 3237942, maxBEP: 3618441 }, + { rank: 28, minBEP: 3618442, maxBEP: 3988841 }, + { rank: 29, minBEP: 3988842, maxBEP: 4479541 }, + { rank: 30, minBEP: 4479542, maxBEP: 5027341 }, + { rank: 31, minBEP: 5027342, maxBEP: 5789641 }, + { rank: 32, minBEP: 5789642, maxBEP: 6861341 }, + { rank: 33, minBEP: 6861342, maxBEP: 8229241 }, + { rank: 34, minBEP: 8229242, maxBEP: 10000541 }, + { rank: 35, minBEP: 10000542, maxBEP: 11501741 }, + { rank: 36, minBEP: 11501742, maxBEP: 12982641 }, + { rank: 37, minBEP: 12982642, maxBEP: 14897141 }, + { rank: 38, minBEP: 14897142, maxBEP: 16894541 }, + { rank: 39, minBEP: 16894542, maxBEP: 19994541 } + ]; + + // Define command rank ranges + export const cepRanges = [ + { rank: 0, minCEP: 0, maxCEP: 9999 }, + { rank: 1, minCEP: 10000, maxCEP: 49999 }, + { rank: 2, minCEP: 50000, maxCEP: 149999 }, + { rank: 3, minCEP: 150000, maxCEP: 299999 }, + { rank: 4, minCEP: 300000, maxCEP: 599999 } + ]; + + // Function to calculate rank based on BEP + export function calculateBr(bep) { + // Iterate through rank ranges to find the appropriate rank + for (const range of bepRanges) { + if (bep >= range.minBEP && bep <= range.maxBEP) { + return range.rank; + } + } + // Default rank if BEP doesn't match any range + return 40; + } + + // Function to calculate rank based on CEP + export function calculateCr(cep) { + // Iterate through rank ranges to find the appropriate rank + for (const range of cepRanges) { + if (cep >= range.minCEP && cep <= range.maxCEP) { + return range.rank; + } + } + // Default rank if CEP doesn't match any range + return 5; + } + + export function getFactionIcon(factionId) { + if (factionId === 0) { + return "/img/tr_icon.png"; + } else if (factionId === 1) { + return "/img/nc_icon.png"; + } else { + return "/img/vs_icon.png"; + } + } + + export function getFactionName(factionId) { + if (factionId === 0) { + return "Terran Republic"; + } else if (factionId === 1) { + return "New Conglomerate"; + } else { + return "Vanu Sovereignty"; + } + } + + // Function to get weapon name from id + export function getWeaponName(weapon_id) { + // Iterate through weapons + for (const weapon of weaponNames) { + if (weapon_id === weapon.id) { + return weapon.name; + } + } + // Missing + return "unknown"; + } + +export const weaponNames = [ +{ id: 55, name: 'Spear' }, +{ id: 56, name: 'Stinger' }, +{ id: 57, name: 'Eraser' }, +{ id: 140, name: 'Beamer' }, +{ id: 146, name: 'Bolt Driver' }, +{ id: 148, name: 'Boomer' }, +{ id: 175, name: 'Knife (TR)' }, +{ id: 177, name: 'chaingun_p type weapon' }, +{ id: 233, name: 'Cycler' }, +{ id: 299, name: 'Dragon' }, +{ id: 304, name: 'Sweeper' }, +{ id: 324, name: 'Knife (VS)' }, +{ id: 334, name: 'Frag Grenade' }, +{ id: 345, name: 'Gauss' }, +{ id: 396, name: 'Heavy Scout Rifle' }, +{ id: 398, name: 'hellfire type weapon' }, +{ id: 406, name: 'Phoenix' }, +{ id: 407, name: 'AMP' }, +{ id: 411, name: 'Scatter Pistol' }, +{ id: 421, name: 'katana type weapon' }, +{ id: 425, name: 'Lancer' }, +{ id: 429, name: 'Lasher' }, +{ id: 462, name: 'Maelstrom' }, +{ id: 468, name: 'Knife (NC)' }, +{ id: 556, name: 'Mini-Chaingun' }, +{ id: 587, name: 'Falcon MAX' }, +{ id: 588, name: 'Scattercannon MAX' }, +{ id: 589, name: 'Sparrow MAX' }, +{ id: 599, name: 'Scorpion' }, +{ id: 673, name: 'Decimator' }, +{ id: 680, name: 'Plasma Grenade' }, +{ id: 701, name: 'Pulsar' }, +{ id: 706, name: 'Punisher' }, +{ id: 714, name: 'Jackhammer' }, +{ id: 716, name: 'Radiator' }, +{ id: 730, name: 'Repeater' }, +{ id: 737, name: 'Rocklet Rifle' }, +{ id: 747, name: 'scythe type weapon' }, +{ id: 761, name: 'six_shooter type weapon' }, +{ id: 817, name: 'Spiker' }, +{ id: 838, name: 'Striker' }, +{ id: 845, name: 'Suppressor' }, +{ id: 864, name: 'Thumper' }, +{ id: 888, name: 'Burster MAX' }, +{ id: 889, name: 'Dual Cycler MAX' }, +{ id: 890, name: 'Pounder MAX' }, +{ id: 968, name: 'Comet MAX' }, +{ id: 969, name: 'Quasar MAX' }, +{ id: 970, name: 'Starfire MAX' }, +{ id: 1003, name: 'winchester type weapon' }, +{ id: 46, name: 'AMS' }, +{ id: 60, name: 'ANT' }, +{ id: 62, name: 'BIG BUS' }, +{ id: 66, name: 'Vindicator' }, +{ id: 67, name: 'Juggernaut' }, +{ id: 68, name: 'Leviathan' }, +{ id: 79, name: 'Aphelion' }, +{ id: 83, name: 'Eclipse' }, +{ id: 84, name: 'Aphelion' }, +{ id: 118, name: 'Aurora' }, +{ id: 135, name: 'Battlewagon?' }, +{ id: 179, name: 'Colossus' }, +{ id: 199, name: 'Invader' }, +{ id: 200, name: 'Colossus' }, +{ id: 239, name: 'Deliverer' }, +{ id: 259, name: 'Dropship?' }, +{ id: 294, name: 'Flail' }, +{ id: 335, name: 'Fury' }, +{ id: 338, name: 'Galaxy Gunship' }, +{ id: 353, name: 'BFR' }, +{ id: 432, name: 'Liberator' }, +{ id: 441, name: 'Light Gunship?' }, +{ id: 446, name: 'Lightning' }, +{ id: 459, name: 'Lodestar' }, +{ id: 470, name: 'Magrider' }, +{ id: 480, name: 'Manned Turret' }, +{ id: 532, name: 'Medium Transport?' }, +{ id: 572, name: 'Mosquito' }, +{ id: 632, name: 'Peregrine' }, +{ id: 642, name: 'Eagle' }, +{ id: 643, name: 'Peregrine' }, +{ id: 671, name: 'Phantasm' }, +{ id: 685, name: 'Manned Field Turret' }, +{ id: 686, name: 'Osprey' }, +{ id: 687, name: 'Avenger' }, +{ id: 688, name: 'Orion' }, +{ id: 697, name: 'Prowler' }, +{ id: 707, name: 'Basilisk' }, +{ id: 710, name: 'Wraith' }, +{ id: 741, name: 'Router' }, +{ id: 759, name: 'Shuttle' }, +{ id: 784, name: 'Skyguard' }, +{ id: 819, name: 'Cerebus Turret' }, +{ id: 825, name: 'Shadow Turret' }, +{ id: 826, name: 'Spitfire Turret' }, +{ id: 847, name: 'Switchblade' }, +{ id: 849, name: 'Trap' }, +{ id: 860, name: 'Testobject?' }, +{ id: 862, name: 'Three Man Heavy Buggy?' }, +{ id: 865, name: 'Thunderer' }, +{ id: 896, name: 'Two Man Buggy?' }, +{ id: 898, name: 'Two Man Heavy Buggy?' }, +{ id: 900, name: 'Two Man Hover Buggy?' }, +{ id: 923, name: 'Vanguard' }, +{ id: 943, name: 'Sentry Turret' }, +{ id: 986, name: 'Vulture' }, +{ id: 997, name: 'Wasp' } +] \ No newline at end of file diff --git a/app/views/Avatar.svelte b/app/views/Avatar.svelte index b1fd281..97ff65d 100644 --- a/app/views/Avatar.svelte +++ b/app/views/Avatar.svelte @@ -2,31 +2,68 @@ import { onMount } from 'svelte'; import axios from 'axios' import Alert from '../components/Alert' - import FactionIcon from '../components/FactionIcon' - import { selectedPlayer } from '../player'; + import { bepRanges, cepRanges, calculateBr, calculateCr, getFactionIcon, getFactionName, + weaponNames, getWeaponName } from '../statFunctions'; onMount(() => { get_iWeaponStats(); + get_avatar(); + get_avatarKdByDate(); }); - let player; // Define player variable to hold player data + export let params; + let iWeapons = []; + let vehicles = []; let alert; + let avatar = {}; let iWeaponsKillsSum + let vehicleKillsSum + let kdByDate = []; + let url = params.id || avatar.id + let face; + let totalKills + let totalDeaths - // Subscribe to the selectedPlayer store to get the selected player data - selectedPlayer.subscribe(value => { - player = value; // Assign selected player data to player variable - }); + const weaponstatsUrl = "/api/weaponstats/"+url + const avatarUrl = "/api/avatar/"+url + const avatarKdUrl = "/api/avatar/"+url+"/kd_byDate" - const url = "/api/avatar/"+$selectedPlayer.id+"/weaponstats" + async function get_avatar() { + try { + const resp = await axios.get(avatarUrl); + avatar = resp.data + const head = avatar.gender.toString() + avatar.head.toString(); + face = "/img/faces/" + head + ".png"; + // Reset alert message if needed + alert.message(""); + } catch (e) { + console.log(e); + alert.message("Failed to fetch stats from server"); + } + } + + async function get_avatarKdByDate() { + try { + const resp = await axios.get(avatarKdUrl); + const stats = resp.data; + kdByDate = stats.kd; + totalKills = kdByDate.reduce((total, kd) => total + kd.kills, 0); + totalDeaths = kdByDate.reduce((total, kd) => total + kd.deaths, 0); + // Reset alert message if needed + alert.message(""); + } catch (e) { + console.log(e); + alert.message("Failed to fetch stats from server"); + } + } async function get_iWeaponStats() { try { - const ids = [55, 56, 57, 140, 146, 175, 233, 299, 304, 324, 334, 345, 396, 406, + const ids = [55, 56, 57, 140, 146, 148, 175, 233, 299, 304, 324, 334, 345, 396, 406, 407, 411, 425, 429, 462, 468, 556, 587, 588, 589, 599, 673, 680, 701, 706, 714, 716, 730, 737, 817, 838, 845, 864, 888, 889, 890, 968, 969, 970]; - const resp = await axios.get(url); + const resp = await axios.get(weaponstatsUrl); const stats = resp.data; const filteredWeapons = stats.weapons.filter(weapon => { return ids.includes(weapon.weapon_id); @@ -57,6 +94,16 @@ iWeapons = filteredWeapons; iWeaponsKillsSum = iWeapons.reduce((total, weapon) => total + weapon.kills, 0); + + const vIds = [46, 60, 62, 66, 67, 68, 79, 83, 84, 118, 135, 179, 199, 200, 239, 259, 294, 335, 338, + 353, 432, 441, 446, 459, 470, 480, 532, 572, 632, 642, 643, 671, 685, 686, 687, 688, 697, + 707, 710, 741, 759, 784, 819, 825, 826, 847, 849, 860, 862, 865, 896, 898, 900, 923, 943, 986, 997]; + const filteredVehicles = stats.weapons.filter(weapon => { + return vIds.includes(weapon.weapon_id); + }); + + vehicles = filteredVehicles; + vehicleKillsSum = vehicles.reduce((total, weapon) => total + weapon.kills, 0); // Reset alert message if needed alert.message(""); } catch (e) { @@ -65,208 +112,13 @@ } } - // Function to get weapon name from id - function getWeaponName(weapon_id) { - // Iterate through weapons - for (const weapon of weaponNames) { - if (weapon_id === weapon.id) { - return weapon.name; - } - } - // Missing - return "unknown"; - } - -const weaponNames = [ -{ id: 2, name: '12mm_chaingun type weapon' }, -{ id: 8, name: '15mm_chaingun type weapon' }, -{ id: 12, name: '20mm_cannon type weapon' }, -{ id: 13, name: '20mm_cannon_deliverer type weapon' }, -{ id: 14, name: '20mm_cannon_dropship type weapon' }, -{ id: 15, name: '20mm_cannon_dropship_l type weapon' }, -{ id: 23, name: '75mm_cannon type weapon' }, -{ id: 24, name: '75mm_lightning type weapon' }, -{ id: 32, name: 'ace type weapon' }, -{ id: 33, name: 'ace_deployable type weapon' }, -{ id: 39, name: 'advanced_ace type weapon' }, -{ id: 40, name: 'advanced_missile_launcher_t type weapon' }, -{ id: 55, name: 'Spear' }, -{ id: 56, name: 'Stinger' }, -{ id: 57, name: 'Eraser' }, -{ id: 63, name: 'apc_ballgun_l type weapon' }, -{ id: 64, name: 'apc_ballgun_r type weapon' }, -{ id: 69, name: 'apc_weapon_systema type weapon' }, -{ id: 70, name: 'apc_weapon_systemb type weapon' }, -{ id: 71, name: 'apc_weapon_systemc type weapon' }, -{ id: 72, name: 'apc_weapon_systemc_nc type weapon' }, -{ id: 73, name: 'apc_weapon_systemc_tr type weapon' }, -{ id: 74, name: 'apc_weapon_systemc_vs type weapon' }, -{ id: 75, name: 'apc_weapon_systemd type weapon' }, -{ id: 76, name: 'apc_weapon_systemd_nc type weapon' }, -{ id: 77, name: 'apc_weapon_systemd_tr type weapon' }, -{ id: 78, name: 'apc_weapon_systemd_vs type weapon' }, -{ id: 85, name: 'aphelion_immolation_cannon type weapon' }, -{ id: 88, name: 'aphelion_laser type weapon' }, -{ id: 90, name: 'aphelion_laser_left type weapon' }, -{ id: 92, name: 'aphelion_laser_right type weapon' }, -{ id: 98, name: 'aphelion_plasma_rocket_pod type weapon' }, -{ id: 100, name: 'aphelion_ppa type weapon' }, -{ id: 102, name: 'aphelion_ppa_left type weapon' }, -{ id: 104, name: 'aphelion_ppa_right type weapon' }, -{ id: 105, name: 'aphelion_starfire type weapon' }, -{ id: 107, name: 'aphelion_starfire_left type weapon' }, -{ id: 109, name: 'aphelion_starfire_right type weapon' }, -{ id: 119, name: 'aurora_weapon_systema type weapon' }, -{ id: 120, name: 'aurora_weapon_systemb type weapon' }, -{ id: 136, name: 'battlewagon_weapon_systema type weapon' }, -{ id: 137, name: 'battlewagon_weapon_systemb type weapon' }, -{ id: 138, name: 'battlewagon_weapon_systemc type weapon' }, -{ id: 139, name: 'battlewagon_weapon_systemd type weapon' }, -{ id: 140, name: 'Beamer' }, -{ id: 146, name: 'Bolt Driver' }, -{ id: 175, name: 'Knife (TR)' }, -{ id: 177, name: 'chaingun_p type weapon' }, -{ id: 185, name: 'colossus_burster type weapon' }, -{ id: 187, name: 'colossus_burster_left type weapon' }, -{ id: 189, name: 'colossus_burster_right type weapon' }, -{ id: 190, name: 'colossus_chaingun type weapon' }, -{ id: 192, name: 'colossus_chaingun_left type weapon' }, -{ id: 194, name: 'colossus_chaingun_right type weapon' }, -{ id: 196, name: 'colossus_cluster_bomb_pod type weapon' }, -{ id: 198, name: 'colossus_dual_100mm_cannons type weapon' }, -{ id: 204, name: 'colossus_tank_cannon type weapon' }, -{ id: 206, name: 'colossus_tank_cannon_left type weapon' }, -{ id: 208, name: 'colossus_tank_cannon_right type weapon' }, -{ id: 233, name: 'Cycler' }, -{ id: 234, name: 'cycler_v2 type weapon' }, -{ id: 235, name: 'cycler_v3 type weapon' }, -{ id: 236, name: 'cycler_v4 type weapon' }, -{ id: 262, name: 'dropship_rear_turret type weapon' }, -{ id: 274, name: 'energy_gun type weapon' }, -{ id: 276, name: 'energy_gun_nc type weapon' }, -{ id: 278, name: 'energy_gun_tr type weapon' }, -{ id: 280, name: 'energy_gun_vs type weapon' }, -{ id: 298, name: 'flail_weapon type weapon' }, -{ id: 299, name: 'Dragon' }, -{ id: 304, name: 'Sweeper' }, -{ id: 306, name: 'flux_cannon_thresher type weapon' }, -{ id: 309, name: 'fluxpod type weapon' }, -{ id: 324, name: 'Knife (VS)' }, -{ id: 334, name: 'Frag Grenade' }, -{ id: 336, name: 'fury_weapon_systema type weapon' }, -{ id: 339, name: 'galaxy_gunship_cannon type weapon' }, -{ id: 340, name: 'galaxy_gunship_gun type weapon' }, -{ id: 342, name: 'galaxy_gunship_tailgun type weapon' }, -{ id: 345, name: 'Gauss' }, -{ id: 346, name: 'gauss_cannon type weapon' }, -{ id: 371, name: 'grenade_launcher_marauder type weapon' }, -{ id: 394, name: 'heavy_rail_beam_magrider type weapon' }, -{ id: 396, name: 'Heavy Scout Rifle' }, -{ id: 398, name: 'hellfire type weapon' }, -{ id: 406, name: 'Phoenix' }, -{ id: 407, name: 'AMP' }, -{ id: 411, name: 'Scatter Pistol' }, -{ id: 421, name: 'katana type weapon' }, -{ id: 425, name: 'Lancer' }, -{ id: 429, name: 'Lasher' }, -{ id: 433, name: 'liberator_25mm_cannon type weapon' }, -{ id: 435, name: 'liberator_bomb_bay type weapon' }, -{ id: 440, name: 'iberator_weapon_system type weapon' }, -{ id: 445, name: 'lightgunship_weapon_system type weapon' }, -{ id: 448, name: 'lightning_weapon_system type weapon' }, -{ id: 462, name: 'Maelstrom' }, -{ id: 468, name: 'Knife (NC)' }, -{ id: 534, name: 'mediumtransport_weapon_systemA type weapon' }, -{ id: 535, name: 'mediumtransport_weapon_systemB type weapon' }, -{ id: 556, name: 'Mini-Chaingun' }, -{ id: 587, name: 'Falcon MAX' }, -{ id: 588, name: 'Scattercannon MAX' }, -{ id: 589, name: 'Sparrow MAX' }, -{ id: 599, name: 'Scorpion' }, -{ id: 628, name: 'particle_beam_magrider type weapon' }, -{ id: 629, name: 'pellet_gun type weapon' }, -{ id: 636, name: 'peregrine_dual_machine_gun type weapon' }, -{ id: 638, name: 'peregrine_dual_machine_gun_left type weapon' }, -{ id: 640, name: 'peregrine_dual_machine_gun_right type weapon' }, -{ id: 641, name: 'peregrine_dual_rocket_pods type weapon' }, -{ id: 644, name: 'peregrine_mechhammer type weapon' }, -{ id: 646, name: 'peregrine_mechhammer_left type weapon' }, -{ id: 648, name: 'peregrine_mechhammer_right type weapon' }, -{ id: 652, name: 'peregrine_particle_cannon type weapon' }, -{ id: 658, name: 'peregrine_sparrow type weapon' }, -{ id: 660, name: 'peregrine_sparrow_left type weapon' }, -{ id: 662, name: 'peregrine_sparrow_right type weapon' }, -{ id: 666, name: 'phalanx_avcombo type weapon' }, -{ id: 668, name: 'phalanx_flakcombo type weapon' }, -{ id: 670, name: 'phalanx_sgl_hevgatcan type weapon' }, -{ id: 672, name: 'phantasm_12mm_machinegun type weapon' }, -{ id: 673, name: 'Decimator' }, -{ id: 680, name: 'Plasma Grenade' }, -{ id: 699, name: 'prowler_weapon_systemA type weapon' }, -{ id: 700, name: 'prowler_weapon_systemB type weapon' }, -{ id: 701, name: 'Pulsar' }, -{ id: 705, name: 'pulsed_particle_accelerator type weapon' }, -{ id: 706, name: 'Punisher' }, -{ id: 709, name: 'quadassault_weapon_system type weapon' }, -{ id: 714, name: 'Jackhammer' }, -{ id: 716, name: 'Radiator' }, -{ id: 730, name: 'Repeater' }, -{ id: 737, name: 'Rocklet Rifle' }, -{ id: 740, name: 'rotarychaingun_mosquito type weapon' }, -{ id: 743, name: 'router_telepad type weapon' }, -{ id: 747, name: 'scythe type weapon' }, -{ id: 761, name: 'six_shooter type weapon' }, -{ id: 788, name: 'skyguard_weapon_system type weapon' }, -{ id: 817, name: 'Spiker' }, -{ id: 822, name: 'spitfire_aa_weapon type weapon' }, -{ id: 827, name: 'spitfire_weapon type weapon' }, -{ id: 838, name: 'Striker' }, -{ id: 845, name: 'Suppressor' }, -{ id: 864, name: 'Thumper' }, -{ id: 866, name: 'thunderer_weapon_systema type weapon' }, -{ id: 867, name: 'thunderer_weapon_systemb type weapon' }, -{ id: 888, name: 'Burster MAX' }, -{ id: 889, name: 'Dual Cycler MAX' }, -{ id: 890, name: 'Pounder MAX' }, -{ id: 927, name: 'vanguard_weapon_system type weapon' }, -{ id: 945, name: 'vanu_sentry_turret_weapon type weapon' }, -{ id: 968, name: 'Comet MAX' }, -{ id: 969, name: 'Quasar MAX' }, -{ id: 970, name: 'Starfire MAX' }, -{ id: 987, name: 'vulture_bomb_bay type weapon' }, -{ id: 990, name: 'vulture_nose_weapon_system type weapon' }, -{ id: 992, name: 'vulture_tail_cannon type weapon' }, -{ id: 1002, name: 'wasp_weapon_system type weapon' }, -{ id: 1003, name: 'winchester type weapon' } -] - - function getFactionIcon(factionId) { - if (factionId === 0) { - return "/img/tr_icon.png"; - } else if (factionId === 1) { - return "/img/nc_icon.png"; - } else { - return "/img/vs_icon.png"; - } - } - - function getFactionName(factionId) { - if (factionId === 0) { - return "Terran Republic"; - } else if (factionId === 1) { - return "New Conglomerate"; - } else { - return "Vanu Sovereignty"; - } - } - Player Stats - +
- + + + +
@@ -274,20 +126,33 @@ const weaponNames = [
- Character Name: {$selectedPlayer.name}
- Empire: {getFactionName($selectedPlayer.faction_id)}
+ Character Name: {avatar.name}
+ Empire: {getFactionName(avatar.faction)}
{selectedPlayer.faction_id}{avatar.faction}/
{face} not found
- Battle Rank: {$selectedPlayer.br}
- Command Rank: {$selectedPlayer.cr}
+ Battle Rank: {calculateBr(avatar.bep)}
+ Command Rank: {calculateCr(avatar.cep)}
+ Kills: {totalKills}
+ Deaths: {totalDeaths}
+ KDR: + {#if totalDeaths !== 0} + {(totalKills / totalDeaths).toFixed(2)} + {:else} + {totalKills} + {/if}
+
+Kills by Weapon - Total: {iWeaponsKillsSum} @@ -310,4 +175,42 @@ const weaponNames = [ {/each}
Weapon
- Total Kills: {iWeaponsKillsSum} +Kills by Vehicle - Total: {vehicleKillsSum} + + + + + + + {#each vehicles as veh} + + + + + {/each} + +
VehicleKills
{getWeaponName(veh.weapon_id)}{veh.kills}
+Daily Stats + + + + + + + + + {#each kdByDate as date} + + + + + + + {/each} + +
DateKillsDeathsKDR
{date.date}{date.kills}{date.deaths}{#if date.deaths !== 0} + {(date.kills / date.deaths).toFixed(2)} + {:else} + {date.kills} + {/if} +
diff --git a/app/views/Leaderboard.svelte b/app/views/Leaderboard.svelte index 1a3ac6c..0dff3e0 100644 --- a/app/views/Leaderboard.svelte +++ b/app/views/Leaderboard.svelte @@ -2,18 +2,19 @@ import { onMount } from 'svelte'; import axios from 'axios' import Alert from '../components/Alert' - import FactionIcon from '../components/FactionIcon' - import { selectedPlayer } from '../player'; + import { bepRanges, cepRanges, calculateBr, calculateCr, getFactionIcon } from '../statFunctions'; onMount(() => { get_BEPleaderboard(); get_CEPleaderboard(); get_kills(); + get_topDateKills(); }); let bepPlayers = []; let cepPlayers = []; let kills = []; + let dateKills = []; let alert; async function get_BEPleaderboard() { @@ -44,7 +45,7 @@ async function get_kills() { try { - const resp = await axios.get("/api/char_stats_kills"); + const resp = await axios.get("/api/top_kills"); const stats = resp.data; kills = stats.kills; // Reset alert message if needed @@ -55,101 +56,19 @@ } } - // Define battle rank ranges - const rankRanges = [ - { rank: 1, minBEP: 0, maxBEP: 999 }, - { rank: 2, minBEP: 1000, maxBEP: 2999 }, - { rank: 3, minBEP: 3000, maxBEP: 7499 }, - { rank: 4, minBEP: 7500, maxBEP: 14999 }, - { rank: 5, minBEP: 15000, maxBEP: 29999 }, - { rank: 6, minBEP: 30000, maxBEP: 44999 }, - { rank: 7, minBEP: 45000, maxBEP: 67499 }, - { rank: 8, minBEP: 67500, maxBEP: 101249 }, - { rank: 9, minBEP: 101250, maxBEP: 126562 }, - { rank: 10, minBEP: 126563, maxBEP: 158202 }, - { rank: 11, minBEP: 158203, maxBEP: 197753 }, - { rank: 12, minBEP: 197754, maxBEP: 247191 }, - { rank: 13, minBEP: 247192, maxBEP: 308989 }, - { rank: 14, minBEP: 308990, maxBEP: 386238 }, - { rank: 15, minBEP: 368239, maxBEP: 482797 }, - { rank: 16, minBEP: 482798, maxBEP: 603496 }, - { rank: 17, minBEP: 603497, maxBEP: 754370 }, - { rank: 18, minBEP: 754371, maxBEP: 942963 }, - { rank: 19, minBEP: 942964, maxBEP: 1178704 }, - { rank: 20, minBEP: 1178705, maxBEP: 1438019 }, - { rank: 21, minBEP: 1438020, maxBEP: 1710300 }, - { rank: 22, minBEP: 1710301, maxBEP: 1988026 }, - { rank: 23, minBEP: 1988027, maxBEP: 2286230 }, - { rank: 24, minBEP: 2286231, maxBEP: 2583440 }, - { rank: 25, minBEP: 2583441, maxBEP: 2908441 }, - { rank: 26, minBEP: 2908442, maxBEP: 3237941 }, - { rank: 27, minBEP: 3237942, maxBEP: 3618441 }, - { rank: 28, minBEP: 3618442, maxBEP: 3988841 }, - { rank: 29, minBEP: 3988842, maxBEP: 4479541 }, - { rank: 30, minBEP: 4479542, maxBEP: 5027341 }, - { rank: 31, minBEP: 5027342, maxBEP: 5789641 }, - { rank: 32, minBEP: 5789642, maxBEP: 6861341 }, - { rank: 33, minBEP: 6861342, maxBEP: 8229241 }, - { rank: 34, minBEP: 8229242, maxBEP: 10000541 }, - { rank: 35, minBEP: 10000542, maxBEP: 11501741 }, - { rank: 36, minBEP: 11501742, maxBEP: 12982641 }, - { rank: 37, minBEP: 12982642, maxBEP: 14897141 }, - { rank: 38, minBEP: 14897142, maxBEP: 16894541 }, - { rank: 39, minBEP: 16894542, maxBEP: 19994541 } - ]; - - // Define command rank ranges - const crRankRanges = [ - { rank: 0, minCEP: 0, maxCEP: 9999 }, - { rank: 1, minCEP: 10000, maxCEP: 49999 }, - { rank: 2, minCEP: 50000, maxCEP: 149999 }, - { rank: 3, minCEP: 150000, maxCEP: 299999 }, - { rank: 4, minCEP: 300000, maxCEP: 599999 } - ]; - - - function getFactionIcon(factionId) { - if (factionId === 0) { - return "/img/tr_icon.png"; - } else if (factionId === 1) { - return "/img/nc_icon.png"; - } else { - return "/img/vs_icon.png"; + async function get_topDateKills() { + try { + const resp = await axios.get("/api/top_kills_byDate"); + const stats = resp.data; + dateKills = stats.kills; + // Reset alert message if needed + alert.message(""); + } catch (e) { + console.log(e); + alert.message("Failed to fetch stats from server"); } } - // Function to calculate rank based on BEP - function calculateRank(bep) { - // Iterate through rank ranges to find the appropriate rank - for (const range of rankRanges) { - if (bep >= range.minBEP && bep <= range.maxBEP) { - return range.rank; - } - } - // Default rank if BEP doesn't match any range - return 40; - } - - // Function to calculate rank based on CEP - function calculateCrRank(cep) { - // Iterate through rank ranges to find the appropriate rank - for (const range of crRankRanges) { - if (cep >= range.minCEP && cep <= range.maxCEP) { - return range.rank; - } - } - // Default rank if CEP doesn't match any range - return 5; - } - - const handleClick = (clickedPlayer) => { - selectedPlayer.set({id: clickedPlayer.id, name: clickedPlayer.name, faction_id: clickedPlayer.faction_id, br: calculateRank(clickedPlayer.bep), cr: calculateCrRank(clickedPlayer.cep)}); -}; - - const handleKillClick = (clickedPlayer) => { - selectedPlayer.set({id: clickedPlayer.killer_id, name: clickedPlayer.name, faction_id: clickedPlayer.faction_id, br: calculateRank(clickedPlayer.bep), cr: calculateCrRank(clickedPlayer.cep)}); -}; - @@ -167,6 +86,9 @@ +
@@ -184,10 +106,10 @@ {$index + 1} {player.faction_id} - handleClick(player)}>{player.name} + {player.name} - {calculateRank(player.bep)} - {calculateCrRank(player.cep)} + {calculateBr(player.bep)} + {calculateCr(player.cep)} {/each} @@ -208,10 +130,10 @@ {$index + 1} {player.faction_id} - handleClick(player)}>{player.name} + {player.name} - {calculateRank(player.bep)} - {calculateCrRank(player.cep)} + {calculateBr(player.bep)} + {calculateCr(player.cep)} {/each} @@ -233,14 +155,39 @@ {$index + 1} {killer.faction_id} - handleKillClick(killer)}>{killer.name} + {killer.name} {killer.count} - {calculateRank(killer.bep)} - {calculateCrRank(killer.cep)} + {calculateBr(killer.bep)} + {calculateCr(killer.cep)} {/each}
+ +
+ Top 50 Characters Most Daily Kills + + + + + + + + + {#each dateKills as player, $index} + + + + + + + {/each} + +
#DateNameKills
{$index + 1}{player.f_kill_date} + {player.faction_id} + {player.name} + {player.kill_count}
+
\ No newline at end of file diff --git a/public/img/faces/10.png b/public/img/faces/10.png new file mode 100644 index 0000000..e579bf7 Binary files /dev/null and b/public/img/faces/10.png differ diff --git a/public/img/faces/11.png b/public/img/faces/11.png new file mode 100644 index 0000000..44a06a9 Binary files /dev/null and b/public/img/faces/11.png differ diff --git a/public/img/faces/110.png b/public/img/faces/110.png new file mode 100644 index 0000000..554cea7 Binary files /dev/null and b/public/img/faces/110.png differ diff --git a/public/img/faces/116.png b/public/img/faces/116.png new file mode 100644 index 0000000..783d3ea Binary files /dev/null and b/public/img/faces/116.png differ diff --git a/public/img/faces/117.png b/public/img/faces/117.png new file mode 100644 index 0000000..754b34b Binary files /dev/null and b/public/img/faces/117.png differ diff --git a/public/img/faces/118.png b/public/img/faces/118.png new file mode 100644 index 0000000..e002535 Binary files /dev/null and b/public/img/faces/118.png differ diff --git a/public/img/faces/119.png b/public/img/faces/119.png new file mode 100644 index 0000000..6d62c43 Binary files /dev/null and b/public/img/faces/119.png differ diff --git a/public/img/faces/12.png b/public/img/faces/12.png new file mode 100644 index 0000000..0537615 Binary files /dev/null and b/public/img/faces/12.png differ diff --git a/public/img/faces/120.png b/public/img/faces/120.png new file mode 100644 index 0000000..6705a45 Binary files /dev/null and b/public/img/faces/120.png differ diff --git a/public/img/faces/121.png b/public/img/faces/121.png new file mode 100644 index 0000000..29af0b3 Binary files /dev/null and b/public/img/faces/121.png differ diff --git a/public/img/faces/122.png b/public/img/faces/122.png new file mode 100644 index 0000000..b9b34e1 Binary files /dev/null and b/public/img/faces/122.png differ diff --git a/public/img/faces/123.png b/public/img/faces/123.png new file mode 100644 index 0000000..f595c65 Binary files /dev/null and b/public/img/faces/123.png differ diff --git a/public/img/faces/124.png b/public/img/faces/124.png new file mode 100644 index 0000000..84647d4 Binary files /dev/null and b/public/img/faces/124.png differ diff --git a/public/img/faces/125.png b/public/img/faces/125.png new file mode 100644 index 0000000..b3f2a92 Binary files /dev/null and b/public/img/faces/125.png differ diff --git a/public/img/faces/126.png b/public/img/faces/126.png new file mode 100644 index 0000000..0321f4f Binary files /dev/null and b/public/img/faces/126.png differ diff --git a/public/img/faces/13.png b/public/img/faces/13.png new file mode 100644 index 0000000..fb1b28a Binary files /dev/null and b/public/img/faces/13.png differ diff --git a/public/img/faces/132.png b/public/img/faces/132.png new file mode 100644 index 0000000..519fca3 Binary files /dev/null and b/public/img/faces/132.png differ diff --git a/public/img/faces/133.png b/public/img/faces/133.png new file mode 100644 index 0000000..e50739b Binary files /dev/null and b/public/img/faces/133.png differ diff --git a/public/img/faces/134.png b/public/img/faces/134.png new file mode 100644 index 0000000..ac4cccc Binary files /dev/null and b/public/img/faces/134.png differ diff --git a/public/img/faces/135.png b/public/img/faces/135.png new file mode 100644 index 0000000..efc10d3 Binary files /dev/null and b/public/img/faces/135.png differ diff --git a/public/img/faces/136.png b/public/img/faces/136.png new file mode 100644 index 0000000..769fbd3 Binary files /dev/null and b/public/img/faces/136.png differ diff --git a/public/img/faces/137.png b/public/img/faces/137.png new file mode 100644 index 0000000..e2775f9 Binary files /dev/null and b/public/img/faces/137.png differ diff --git a/public/img/faces/138.png b/public/img/faces/138.png new file mode 100644 index 0000000..6c2fb11 Binary files /dev/null and b/public/img/faces/138.png differ diff --git a/public/img/faces/139.png b/public/img/faces/139.png new file mode 100644 index 0000000..37194e8 Binary files /dev/null and b/public/img/faces/139.png differ diff --git a/public/img/faces/14.png b/public/img/faces/14.png new file mode 100644 index 0000000..edb0f08 Binary files /dev/null and b/public/img/faces/14.png differ diff --git a/public/img/faces/140.png b/public/img/faces/140.png new file mode 100644 index 0000000..b5798c4 Binary files /dev/null and b/public/img/faces/140.png differ diff --git a/public/img/faces/141.png b/public/img/faces/141.png new file mode 100644 index 0000000..6a23672 Binary files /dev/null and b/public/img/faces/141.png differ diff --git a/public/img/faces/142.png b/public/img/faces/142.png new file mode 100644 index 0000000..f03cfc4 Binary files /dev/null and b/public/img/faces/142.png differ diff --git a/public/img/faces/148.png b/public/img/faces/148.png new file mode 100644 index 0000000..154f366 Binary files /dev/null and b/public/img/faces/148.png differ diff --git a/public/img/faces/149.png b/public/img/faces/149.png new file mode 100644 index 0000000..0ee1ab3 Binary files /dev/null and b/public/img/faces/149.png differ diff --git a/public/img/faces/15.png b/public/img/faces/15.png new file mode 100644 index 0000000..e1a17b1 Binary files /dev/null and b/public/img/faces/15.png differ diff --git a/public/img/faces/150.png b/public/img/faces/150.png new file mode 100644 index 0000000..ecc8239 Binary files /dev/null and b/public/img/faces/150.png differ diff --git a/public/img/faces/151.png b/public/img/faces/151.png new file mode 100644 index 0000000..740a754 Binary files /dev/null and b/public/img/faces/151.png differ diff --git a/public/img/faces/152.png b/public/img/faces/152.png new file mode 100644 index 0000000..ad0db9c Binary files /dev/null and b/public/img/faces/152.png differ diff --git a/public/img/faces/153.png b/public/img/faces/153.png new file mode 100644 index 0000000..37ec32b Binary files /dev/null and b/public/img/faces/153.png differ diff --git a/public/img/faces/154.png b/public/img/faces/154.png new file mode 100644 index 0000000..73a5550 Binary files /dev/null and b/public/img/faces/154.png differ diff --git a/public/img/faces/155.png b/public/img/faces/155.png new file mode 100644 index 0000000..440fbd0 Binary files /dev/null and b/public/img/faces/155.png differ diff --git a/public/img/faces/156.png b/public/img/faces/156.png new file mode 100644 index 0000000..dd656fc Binary files /dev/null and b/public/img/faces/156.png differ diff --git a/public/img/faces/157.png b/public/img/faces/157.png new file mode 100644 index 0000000..9a80469 Binary files /dev/null and b/public/img/faces/157.png differ diff --git a/public/img/faces/158.png b/public/img/faces/158.png new file mode 100644 index 0000000..e4734b2 Binary files /dev/null and b/public/img/faces/158.png differ diff --git a/public/img/faces/16.png b/public/img/faces/16.png new file mode 100644 index 0000000..5c0debb Binary files /dev/null and b/public/img/faces/16.png differ diff --git a/public/img/faces/164.png b/public/img/faces/164.png new file mode 100644 index 0000000..a5a0a8c Binary files /dev/null and b/public/img/faces/164.png differ diff --git a/public/img/faces/165.png b/public/img/faces/165.png new file mode 100644 index 0000000..03a7416 Binary files /dev/null and b/public/img/faces/165.png differ diff --git a/public/img/faces/166.png b/public/img/faces/166.png new file mode 100644 index 0000000..aabc8b8 Binary files /dev/null and b/public/img/faces/166.png differ diff --git a/public/img/faces/167.png b/public/img/faces/167.png new file mode 100644 index 0000000..eceb984 Binary files /dev/null and b/public/img/faces/167.png differ diff --git a/public/img/faces/168.png b/public/img/faces/168.png new file mode 100644 index 0000000..66dfa65 Binary files /dev/null and b/public/img/faces/168.png differ diff --git a/public/img/faces/169.png b/public/img/faces/169.png new file mode 100644 index 0000000..6beab4c Binary files /dev/null and b/public/img/faces/169.png differ diff --git a/public/img/faces/17.png b/public/img/faces/17.png new file mode 100644 index 0000000..cda6259 Binary files /dev/null and b/public/img/faces/17.png differ diff --git a/public/img/faces/170.png b/public/img/faces/170.png new file mode 100644 index 0000000..252640f Binary files /dev/null and b/public/img/faces/170.png differ diff --git a/public/img/faces/171.png b/public/img/faces/171.png new file mode 100644 index 0000000..9dabf39 Binary files /dev/null and b/public/img/faces/171.png differ diff --git a/public/img/faces/172.png b/public/img/faces/172.png new file mode 100644 index 0000000..3243f5a Binary files /dev/null and b/public/img/faces/172.png differ diff --git a/public/img/faces/173.png b/public/img/faces/173.png new file mode 100644 index 0000000..df2c8f2 Binary files /dev/null and b/public/img/faces/173.png differ diff --git a/public/img/faces/174.png b/public/img/faces/174.png new file mode 100644 index 0000000..bf1bcfc Binary files /dev/null and b/public/img/faces/174.png differ diff --git a/public/img/faces/18.png b/public/img/faces/18.png new file mode 100644 index 0000000..11e7ef3 Binary files /dev/null and b/public/img/faces/18.png differ diff --git a/public/img/faces/19.png b/public/img/faces/19.png new file mode 100644 index 0000000..81e82ce Binary files /dev/null and b/public/img/faces/19.png differ diff --git a/public/img/faces/20.png b/public/img/faces/20.png new file mode 100644 index 0000000..8b40cb3 Binary files /dev/null and b/public/img/faces/20.png differ diff --git a/public/img/faces/21.png b/public/img/faces/21.png new file mode 100644 index 0000000..857fd2c Binary files /dev/null and b/public/img/faces/21.png differ diff --git a/public/img/faces/216.png b/public/img/faces/216.png new file mode 100644 index 0000000..e83966f Binary files /dev/null and b/public/img/faces/216.png differ diff --git a/public/img/faces/217.png b/public/img/faces/217.png new file mode 100644 index 0000000..ccec83a Binary files /dev/null and b/public/img/faces/217.png differ diff --git a/public/img/faces/218.png b/public/img/faces/218.png new file mode 100644 index 0000000..1d172c2 Binary files /dev/null and b/public/img/faces/218.png differ diff --git a/public/img/faces/219.png b/public/img/faces/219.png new file mode 100644 index 0000000..9f316bd Binary files /dev/null and b/public/img/faces/219.png differ diff --git a/public/img/faces/22.png b/public/img/faces/22.png new file mode 100644 index 0000000..dbc7d94 Binary files /dev/null and b/public/img/faces/22.png differ diff --git a/public/img/faces/220.png b/public/img/faces/220.png new file mode 100644 index 0000000..309cca2 Binary files /dev/null and b/public/img/faces/220.png differ diff --git a/public/img/faces/221.png b/public/img/faces/221.png new file mode 100644 index 0000000..1115283 Binary files /dev/null and b/public/img/faces/221.png differ diff --git a/public/img/faces/222.png b/public/img/faces/222.png new file mode 100644 index 0000000..9d29b92 Binary files /dev/null and b/public/img/faces/222.png differ diff --git a/public/img/faces/223.png b/public/img/faces/223.png new file mode 100644 index 0000000..fdcb7da Binary files /dev/null and b/public/img/faces/223.png differ diff --git a/public/img/faces/224.png b/public/img/faces/224.png new file mode 100644 index 0000000..1549bc1 Binary files /dev/null and b/public/img/faces/224.png differ diff --git a/public/img/faces/225.png b/public/img/faces/225.png new file mode 100644 index 0000000..175e840 Binary files /dev/null and b/public/img/faces/225.png differ diff --git a/public/img/faces/23.png b/public/img/faces/23.png new file mode 100644 index 0000000..0e56933 Binary files /dev/null and b/public/img/faces/23.png differ diff --git a/public/img/faces/232.png b/public/img/faces/232.png new file mode 100644 index 0000000..7af986e Binary files /dev/null and b/public/img/faces/232.png differ diff --git a/public/img/faces/233.png b/public/img/faces/233.png new file mode 100644 index 0000000..30bf366 Binary files /dev/null and b/public/img/faces/233.png differ diff --git a/public/img/faces/234.png b/public/img/faces/234.png new file mode 100644 index 0000000..f9dfdd2 Binary files /dev/null and b/public/img/faces/234.png differ diff --git a/public/img/faces/235.png b/public/img/faces/235.png new file mode 100644 index 0000000..63e0396 Binary files /dev/null and b/public/img/faces/235.png differ diff --git a/public/img/faces/236.png b/public/img/faces/236.png new file mode 100644 index 0000000..5bdd778 Binary files /dev/null and b/public/img/faces/236.png differ diff --git a/public/img/faces/237.png b/public/img/faces/237.png new file mode 100644 index 0000000..a30bf89 Binary files /dev/null and b/public/img/faces/237.png differ diff --git a/public/img/faces/238.png b/public/img/faces/238.png new file mode 100644 index 0000000..8af7c8b Binary files /dev/null and b/public/img/faces/238.png differ diff --git a/public/img/faces/239.png b/public/img/faces/239.png new file mode 100644 index 0000000..b61552f Binary files /dev/null and b/public/img/faces/239.png differ diff --git a/public/img/faces/24.png b/public/img/faces/24.png new file mode 100644 index 0000000..5882df2 Binary files /dev/null and b/public/img/faces/24.png differ diff --git a/public/img/faces/240.png b/public/img/faces/240.png new file mode 100644 index 0000000..adeefc2 Binary files /dev/null and b/public/img/faces/240.png differ diff --git a/public/img/faces/241.png b/public/img/faces/241.png new file mode 100644 index 0000000..350fd2e Binary files /dev/null and b/public/img/faces/241.png differ diff --git a/public/img/faces/248.png b/public/img/faces/248.png new file mode 100644 index 0000000..53a4db1 Binary files /dev/null and b/public/img/faces/248.png differ diff --git a/public/img/faces/249.png b/public/img/faces/249.png new file mode 100644 index 0000000..e57adeb Binary files /dev/null and b/public/img/faces/249.png differ diff --git a/public/img/faces/25.png b/public/img/faces/25.png new file mode 100644 index 0000000..5d35dfb Binary files /dev/null and b/public/img/faces/25.png differ diff --git a/public/img/faces/250.png b/public/img/faces/250.png new file mode 100644 index 0000000..63fe531 Binary files /dev/null and b/public/img/faces/250.png differ diff --git a/public/img/faces/251.png b/public/img/faces/251.png new file mode 100644 index 0000000..fc62218 Binary files /dev/null and b/public/img/faces/251.png differ diff --git a/public/img/faces/252.png b/public/img/faces/252.png new file mode 100644 index 0000000..682ec14 Binary files /dev/null and b/public/img/faces/252.png differ diff --git a/public/img/faces/253.png b/public/img/faces/253.png new file mode 100644 index 0000000..cb3e24e Binary files /dev/null and b/public/img/faces/253.png differ diff --git a/public/img/faces/254.png b/public/img/faces/254.png new file mode 100644 index 0000000..36f1f4a Binary files /dev/null and b/public/img/faces/254.png differ diff --git a/public/img/faces/255.png b/public/img/faces/255.png new file mode 100644 index 0000000..fc20f85 Binary files /dev/null and b/public/img/faces/255.png differ diff --git a/public/img/faces/256.png b/public/img/faces/256.png new file mode 100644 index 0000000..6bae391 Binary files /dev/null and b/public/img/faces/256.png differ diff --git a/public/img/faces/257.png b/public/img/faces/257.png new file mode 100644 index 0000000..bc52da5 Binary files /dev/null and b/public/img/faces/257.png differ diff --git a/public/img/faces/26.png b/public/img/faces/26.png new file mode 100644 index 0000000..ed3a641 Binary files /dev/null and b/public/img/faces/26.png differ diff --git a/public/img/faces/264.png b/public/img/faces/264.png new file mode 100644 index 0000000..ba82d02 Binary files /dev/null and b/public/img/faces/264.png differ diff --git a/public/img/faces/265.png b/public/img/faces/265.png new file mode 100644 index 0000000..f511ee0 Binary files /dev/null and b/public/img/faces/265.png differ diff --git a/public/img/faces/266.png b/public/img/faces/266.png new file mode 100644 index 0000000..06a9556 Binary files /dev/null and b/public/img/faces/266.png differ diff --git a/public/img/faces/267.png b/public/img/faces/267.png new file mode 100644 index 0000000..5218c01 Binary files /dev/null and b/public/img/faces/267.png differ diff --git a/public/img/faces/268.png b/public/img/faces/268.png new file mode 100644 index 0000000..40b9e41 Binary files /dev/null and b/public/img/faces/268.png differ diff --git a/public/img/faces/269.png b/public/img/faces/269.png new file mode 100644 index 0000000..2af6cb0 Binary files /dev/null and b/public/img/faces/269.png differ diff --git a/public/img/faces/27.png b/public/img/faces/27.png new file mode 100644 index 0000000..d3c453d Binary files /dev/null and b/public/img/faces/27.png differ diff --git a/public/img/faces/270.png b/public/img/faces/270.png new file mode 100644 index 0000000..64d91dc Binary files /dev/null and b/public/img/faces/270.png differ diff --git a/public/img/faces/271.png b/public/img/faces/271.png new file mode 100644 index 0000000..ee4609f Binary files /dev/null and b/public/img/faces/271.png differ diff --git a/public/img/faces/272.png b/public/img/faces/272.png new file mode 100644 index 0000000..7090a38 Binary files /dev/null and b/public/img/faces/272.png differ diff --git a/public/img/faces/273.png b/public/img/faces/273.png new file mode 100644 index 0000000..a305e71 Binary files /dev/null and b/public/img/faces/273.png differ diff --git a/public/img/faces/28.png b/public/img/faces/28.png new file mode 100644 index 0000000..f3c16b8 Binary files /dev/null and b/public/img/faces/28.png differ diff --git a/public/img/faces/29.png b/public/img/faces/29.png new file mode 100644 index 0000000..f8f52bc Binary files /dev/null and b/public/img/faces/29.png differ