migration to new feed source
@@ -176,10 +176,13 @@ export default function Fixtures({
|
||||
</div>
|
||||
</div>
|
||||
<div className="fx-meta">
|
||||
{m.venue && <span className="fx-venue">📍 {m.venue}</span>}
|
||||
{m.attendance != null && (
|
||||
<span className="fx-att">👥 {m.attendance.toLocaleString(intlLocale)}</span>
|
||||
)}
|
||||
{(() => {
|
||||
const stadium = [m.stadiumName, m.stadiumCity].filter(Boolean).join(", ");
|
||||
const crowd = m.attendance != null ? m.attendance.toLocaleString(intlLocale) : "";
|
||||
const sep = stadium && crowd ? " · " : "";
|
||||
const text = stadium + sep + crowd;
|
||||
return text ? <span className="fx-venue">{text}</span> : null;
|
||||
})()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,32 +1,27 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { Team } from "@/lib/types";
|
||||
import { TLA_TO_ISO2 } from "@/lib/flags";
|
||||
|
||||
// Zeigt die Flagge/das Wappen eines Teams. Fällt auf ein neutrales Rund
|
||||
// zurück, wenn keine crest-URL vorliegt oder das Bild nicht geladen werden kann.
|
||||
// Zeigt die Flagge eines Teams aus lokalem circle-flags-Bestand.
|
||||
// Fallback: kein Rendering bei fehlendem Team/Code (kein Broken-Image).
|
||||
export default function Flag({
|
||||
team, size = 22,
|
||||
}: { team?: Team; size?: number }) {
|
||||
const [imgFailed, setImgFailed] = useState(false);
|
||||
const style = { width: size, height: size } as const;
|
||||
|
||||
if (team?.crest && !imgFailed) {
|
||||
const iso2 = team?.code ? TLA_TO_ISO2[team.code.toUpperCase()] : undefined;
|
||||
if (iso2) {
|
||||
return (
|
||||
<img
|
||||
src={team.crest}
|
||||
alt={team.code || team.localisedName || team.name}
|
||||
src={`/flags/${iso2}.svg`}
|
||||
alt={team!.code || team!.localisedName || team!.name}
|
||||
className="flag"
|
||||
style={style}
|
||||
loading="lazy"
|
||||
onError={() => setImgFailed(true)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
// Fallback: Kreis mit Ländercode
|
||||
return (
|
||||
<span className="flag flag-fallback" style={style} aria-hidden>
|
||||
{team?.code?.slice(0, 2) || "··"}
|
||||
</span>
|
||||
);
|
||||
// Kein Team / kein Code: nichts rendern (kein Broken-Image)
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import type { NextRequest } from "next/server";
|
||||
import { fetchMatchesAndTeams, fetchOdds, attachOdds, attachKOOdds, fetchFifaScores, applyFifaScores, assignKONumbersBySlots, attachFifaGoals } from "@/lib/feeds";
|
||||
import { fetchMatchesAndTeamsFifa, fetchOdds, attachOdds, attachKOOdds, fetchFifaScores, applyFifaScores, attachFifaGoals } from "@/lib/feeds";
|
||||
import { computeGroupTables, computeThirdPlaceTable } from "@/lib/standings";
|
||||
import { qualifiedThirdGroups, resolveAnnexC } from "@/lib/bracket";
|
||||
import { securelyQualifiedThirdTeams } from "@/lib/third-place-security";
|
||||
|
||||
// Diese Route wird vom Frontend gepollt. Sie ist der einzige Ort, der die
|
||||
// Upstream-Feeds berührt — gecacht, damit Rate Limits eingehalten werden.
|
||||
// Diese Route wird vom Frontend gepollt. FIFA-API als Primärquelle.
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
const locale = request.nextUrl.searchParams.get("locale") || "de";
|
||||
try {
|
||||
const { matches: rawMatches, teams } = await fetchMatchesAndTeams();
|
||||
const { matches: rawMatches, teams } = await fetchMatchesAndTeamsFifa(locale);
|
||||
|
||||
// Odds sind optional: fällt der Polymarket-Call aus, liefern wir trotzdem.
|
||||
let matches = rawMatches;
|
||||
@@ -24,13 +23,11 @@ export async function GET(request: NextRequest) {
|
||||
console.error("[polymarket] fetchOdds fehlgeschlagen:", err);
|
||||
}
|
||||
|
||||
// FIFA-Live-Scores (additiv, Fallback auf football-data)
|
||||
assignKONumbersBySlots(matches, teams);
|
||||
|
||||
if (odds) {
|
||||
matches = attachKOOdds(matches, teams, odds);
|
||||
}
|
||||
|
||||
// FIFA-Live-Scores als häufiger gecachtes Overlay
|
||||
try {
|
||||
const fifaData = await fetchFifaScores(locale);
|
||||
matches = applyFifaScores(matches, teams, fifaData);
|
||||
|
||||
142
lib/feeds.ts
@@ -1,8 +1,9 @@
|
||||
import { GroupId, GoalEvent, Match, MatchStatus, Team } from "./types";
|
||||
import { venueFor } from "./venues";
|
||||
import { localisedTeamName } from "./team-mappings";
|
||||
import { localisedTeamName, TEAM_LOCALIZATION } from "./team-mappings";
|
||||
import { R32, LATER_ROUNDS, resolveAnnexC, qualifiedThirdGroups } from "./bracket";
|
||||
import { computeGroupTables, computeThirdPlaceTable } from "./standings";
|
||||
import { FIFA_GROUP_MAP, FIFA_STAGE_MAP } from "./fifa-constants";
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Caching: einfacher In-Memory-Cache mit TTL. Verhindert, dass jede Browser-
|
||||
@@ -609,6 +610,122 @@ interface FifaScores {
|
||||
idStage: string | null;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// FIFA-API Calendar-Endpoint: Spiele + Teams parallel zur football-data-Quelle
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
interface FifaCalendarTeamBlock {
|
||||
IdTeam: string;
|
||||
Abbreviation: string;
|
||||
TeamName: Array<{ Locale: string; Description: string }>;
|
||||
}
|
||||
|
||||
interface FifaCalendarMatch {
|
||||
IdMatch: string;
|
||||
IdStage: string;
|
||||
IdGroup: string | null;
|
||||
MatchNumber: number;
|
||||
Date: string;
|
||||
Home: FifaCalendarTeamBlock | null;
|
||||
Away: FifaCalendarTeamBlock | null;
|
||||
HomeTeamScore: number | null;
|
||||
AwayTeamScore: number | null;
|
||||
HomeTeamPenaltyScore: number | null;
|
||||
AwayTeamPenaltyScore: number | null;
|
||||
MatchStatus: number;
|
||||
MatchTime: string | null;
|
||||
ResultType: number | null;
|
||||
Winner?: string | null;
|
||||
Attendance: string | null;
|
||||
Stadium?: {
|
||||
Name: Array<{ Locale: string; Description: string }>;
|
||||
CityName: Array<{ Locale: string; Description: string }>;
|
||||
} | null;
|
||||
}
|
||||
|
||||
// Holt alle Spiele + Teams von der FIFA-API (parallele Quelle, noch nicht aktiv).
|
||||
export async function fetchMatchesAndTeamsFifa(locale: string = "de"): Promise<{ matches: Match[]; teams: Team[] }> {
|
||||
return cached(`fifa:matches:${locale}`, 60_000, async () => {
|
||||
const lang = locale === "en" ? "en" : "de";
|
||||
const url = `${FIFA_BASE}/calendar/matches?language=${lang}&count=500&idSeason=${FIFA_SEASON}`;
|
||||
const res = await fetch(url, {
|
||||
cache: "no-store",
|
||||
headers: { "User-Agent": "wm2026-board/1.0" },
|
||||
});
|
||||
if (!res.ok) throw new Error(`fifa-calendar ${res.status}`);
|
||||
const data = (await res.json()) as { Results: FifaCalendarMatch[] };
|
||||
|
||||
const teamMap = new Map<string, Team>();
|
||||
|
||||
function teamFromBlock(tb: FifaCalendarTeamBlock, idGroup: string | null): Team | null {
|
||||
const id = tb.IdTeam;
|
||||
if (teamMap.has(id)) return teamMap.get(id)!;
|
||||
const code = fifaCodeToAppCode(tb.Abbreviation);
|
||||
const group = idGroup ? FIFA_GROUP_MAP[idGroup] : null;
|
||||
if (!group) return null;
|
||||
const loc = TEAM_LOCALIZATION[code.toUpperCase()];
|
||||
const name = tb.TeamName?.[0]?.Description ?? "";
|
||||
const t: Team = {
|
||||
id,
|
||||
name,
|
||||
code,
|
||||
group,
|
||||
localisedName: loc ? loc[lang === "en" ? "en" : "de"] : name,
|
||||
localisedNames: loc ? { de: loc.de, en: loc.en } : { de: name, en: name },
|
||||
};
|
||||
teamMap.set(id, t);
|
||||
return t;
|
||||
}
|
||||
|
||||
function mapFifaStatus(ms: number): MatchStatus {
|
||||
switch (ms) {
|
||||
case 0: return "FINISHED";
|
||||
case 1: return "SCHEDULED";
|
||||
case 10: return "POSTPONED";
|
||||
default: return "LIVE";
|
||||
}
|
||||
}
|
||||
|
||||
const matches: Match[] = (data.Results ?? []).map((fm) => {
|
||||
const group = fm.IdGroup ? FIFA_GROUP_MAP[fm.IdGroup] ?? null : null;
|
||||
let homeTeam: Team | null = null;
|
||||
let awayTeam: Team | null = null;
|
||||
if (fm.Home) homeTeam = teamFromBlock(fm.Home, fm.IdGroup);
|
||||
if (fm.Away) awayTeam = teamFromBlock(fm.Away, fm.IdGroup);
|
||||
const attendance = fm.Attendance ? parseInt(fm.Attendance, 10) || null : null;
|
||||
const minute = fm.MatchTime ? parseInt(fm.MatchTime, 10) || null : null;
|
||||
const pref = lang === "en" ? "en-GB" : "de-DE";
|
||||
const stadiumName = fm.Stadium?.Name?.find(n => n.Locale === pref)?.Description
|
||||
?? fm.Stadium?.Name?.[0]?.Description ?? null;
|
||||
const stadiumCity = fm.Stadium?.CityName?.find(n => n.Locale === pref)?.Description
|
||||
?? fm.Stadium?.CityName?.[0]?.Description ?? null;
|
||||
return {
|
||||
id: fm.IdMatch,
|
||||
group,
|
||||
stage: FIFA_STAGE_MAP[fm.IdStage] ?? "GROUP",
|
||||
matchNumber: fm.MatchNumber,
|
||||
utcDate: fm.Date,
|
||||
status: mapFifaStatus(fm.MatchStatus),
|
||||
minute,
|
||||
homeTeamId: fm.Home?.IdTeam ?? null,
|
||||
awayTeamId: fm.Away?.IdTeam ?? null,
|
||||
homeScore: fm.HomeTeamScore,
|
||||
awayScore: fm.AwayTeamScore,
|
||||
homePenalty: fm.HomeTeamPenaltyScore,
|
||||
awayPenalty: fm.AwayTeamPenaltyScore,
|
||||
winnerTeamId: fm.Winner ?? null,
|
||||
venue: null,
|
||||
stadiumName,
|
||||
stadiumCity,
|
||||
attendance,
|
||||
};
|
||||
});
|
||||
|
||||
const teams = [...teamMap.values()];
|
||||
return { matches, teams };
|
||||
});
|
||||
}
|
||||
|
||||
// Holt Live-Scores von der FIFA-API. Gibt Map MatchNumber → Scores + FIFA-ID→App-Code-Map zurück.
|
||||
export async function fetchFifaScores(locale: string = "de"): Promise<{
|
||||
scores: Map<number, FifaScores>;
|
||||
@@ -660,17 +777,13 @@ export async function fetchFifaScores(locale: string = "de"): Promise<{
|
||||
}
|
||||
|
||||
// Wendet FIFA-Live-Scores auf Matches an (MatchNumber als exakter Schlüssel).
|
||||
// Team-IDs sind jetzt FIFA-IDs → winnerTeamId kann direkt gesetzt werden.
|
||||
export function applyFifaScores(
|
||||
matches: Match[], teams: Team[],
|
||||
fifaData: { scores: Map<number, FifaScores>; fifaIdToAppCode: Map<string, string> },
|
||||
): Match[] {
|
||||
const { scores: fifaMap, fifaIdToAppCode } = fifaData;
|
||||
const { scores: fifaMap } = fifaData;
|
||||
if (fifaMap.size === 0) return matches;
|
||||
// Baue App-Code → App-Team-ID Map
|
||||
const appCodeToId = new Map<string, string>();
|
||||
for (const t of teams) {
|
||||
if (t.code) appCodeToId.set(t.code.toLowerCase(), t.id);
|
||||
}
|
||||
let applied = 0;
|
||||
const result = matches.map((m) => {
|
||||
const fs = fifaMap.get(m.matchNumber);
|
||||
@@ -680,20 +793,7 @@ export function applyFifaScores(
|
||||
if (fs.awayScore != null) r.awayScore = fs.awayScore;
|
||||
if (fs.homePenalty != null) r.homePenalty = fs.homePenalty;
|
||||
if (fs.awayPenalty != null) r.awayPenalty = fs.awayPenalty;
|
||||
// FIFA-ID → App-Team-ID auflösen
|
||||
if (fs.winnerTeamId) {
|
||||
const appCode = fifaIdToAppCode.get(fs.winnerTeamId);
|
||||
if (appCode) {
|
||||
const appTeamId = appCodeToId.get(appCode.toLowerCase());
|
||||
if (appTeamId) {
|
||||
r.winnerTeamId = appTeamId;
|
||||
} else {
|
||||
console.warn("[fifa] Winner-Team-Code nicht in App-Teams:", appCode, "| matchNumber:", m.matchNumber);
|
||||
}
|
||||
} else {
|
||||
console.warn("[fifa] FIFA-Winner-ID nicht in Team-Map:", fs.winnerTeamId, "| matchNumber:", m.matchNumber);
|
||||
}
|
||||
}
|
||||
if (fs.winnerTeamId) r.winnerTeamId = fs.winnerTeamId;
|
||||
if (fs.matchTime) {
|
||||
const min = parseInt(fs.matchTime, 10);
|
||||
if (!isNaN(min)) r.minute = min;
|
||||
|
||||
14
lib/fifa-constants.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { GroupId, Match } from "./types";
|
||||
|
||||
// FIFA IdGroup → App-GroupId (verifiziert, fortlaufend 289275-289286)
|
||||
export const FIFA_GROUP_MAP: Record<string, GroupId> = {
|
||||
"289275": "A", "289276": "B", "289277": "C", "289278": "D",
|
||||
"289279": "E", "289280": "F", "289281": "G", "289282": "H",
|
||||
"289283": "I", "289284": "J", "289285": "K", "289286": "L",
|
||||
};
|
||||
|
||||
// FIFA IdStage → App-Stage (verifiziert)
|
||||
export const FIFA_STAGE_MAP: Record<string, Match["stage"]> = {
|
||||
"289273": "GROUP", "289287": "R32", "289288": "R16",
|
||||
"289289": "QF", "289290": "SF", "289291": "3RD", "289292": "FINAL",
|
||||
};
|
||||
52
lib/flags.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
// TLA (3-Buchstaben, wie in TEAM_LOCALIZATION) → circle-flags ISO-2-Dateiname.
|
||||
// Vollständig für alle Teams aus TEAM_LOCALIZATION.
|
||||
export const TLA_TO_ISO2: Record<string, string> = {
|
||||
ALG: "dz",
|
||||
ARG: "ar",
|
||||
AUS: "au",
|
||||
AUT: "at",
|
||||
BEL: "be",
|
||||
BIH: "ba",
|
||||
BRA: "br",
|
||||
CAN: "ca",
|
||||
CHE: "ch",
|
||||
CIV: "ci",
|
||||
COD: "cd",
|
||||
COL: "co",
|
||||
CPV: "cv",
|
||||
CZE: "cz",
|
||||
ECU: "ec",
|
||||
EGY: "eg",
|
||||
ENG: "gb-eng",
|
||||
ESP: "es",
|
||||
FRA: "fr",
|
||||
GER: "de",
|
||||
GHA: "gh",
|
||||
HAI: "ht",
|
||||
HRV: "hr",
|
||||
IRN: "ir",
|
||||
IRQ: "iq",
|
||||
JOR: "jo",
|
||||
JPN: "jp",
|
||||
KOR: "kr",
|
||||
KSA: "sa",
|
||||
MAR: "ma",
|
||||
MEX: "mx",
|
||||
NED: "nl",
|
||||
NOR: "no",
|
||||
NZL: "nz",
|
||||
PAN: "pa",
|
||||
PAR: "py",
|
||||
PRT: "pt",
|
||||
QAT: "qa",
|
||||
RSA: "za",
|
||||
SCO: "gb-sct",
|
||||
SEN: "sn",
|
||||
SWE: "se",
|
||||
TUN: "tn",
|
||||
TUR: "tr",
|
||||
URU: "uy",
|
||||
USA: "us",
|
||||
UZB: "uz",
|
||||
CUW: "cw",
|
||||
};
|
||||
@@ -51,8 +51,10 @@ export interface Match {
|
||||
winnerTeamId?: string | null; // FIFA-Winner (auch bei Elfmeterschießen)
|
||||
// Wahrscheinlichkeiten 0..1 (Polymarket), falls vorhanden
|
||||
prob?: { home: number; draw: number; away: number } | null;
|
||||
venue?: string | null; // Austragungsort
|
||||
attendance?: number | null; // Zuschauerzahl, falls verfügbar
|
||||
venue?: string | null; // Austragungsort (alt: football-data)
|
||||
stadiumName?: string | null; // FIFA-Stadionname
|
||||
stadiumCity?: string | null; // FIFA-Stadt
|
||||
attendance?: number | null; // Zuschauerzahl
|
||||
goals?: GoalEvent[] | null; // Torereignisse
|
||||
}
|
||||
|
||||
|
||||
16
public/flags/9460.svg
Normal file
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 54 36">
|
||||
<rect width="54" height="36" fill="#002b7f"/>
|
||||
<path d="M0,22.5H54V27H0z" fill="#f9e814"/>
|
||||
<g fill="#fff" id="s">
|
||||
<g id="f">
|
||||
<g id="t">
|
||||
<path d="m12,8v4h2z" transform="rotate(18,12,8)" id="o"/>
|
||||
<use xlink:href="#o" x="-24" transform="scale(-1,1)"/>
|
||||
</g>
|
||||
<use xlink:href="#t" transform="rotate(72,12,12)"/>
|
||||
</g>
|
||||
<use xlink:href="#t" transform="rotate(-72,12,12)"/>
|
||||
<use xlink:href="#f" transform="rotate(144,12,12)"/>
|
||||
</g>
|
||||
<use xlink:href="#s" x="-4" y="-4" transform="scale(0.75)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 593 B |
1
public/flags/ar.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#338af3" d="M0 0h512v144.7L488 256l24 111.3V512H0V367.3L26 256 0 144.7z"/><path fill="#eee" d="M0 144.7h512v222.6H0z"/><path fill="#ffda44" d="m332.4 256-31.2 14.7 16.7 30.3-34-6.5-4.2 34.3-23.7-25.2-23.6 25.2-4.3-34.3-34 6.5 16.6-30.3-31.2-14.7 31.3-14.7L194 211l34 6.5 4.3-34.3 23.6 25.2 23.6-25.2 4.4 34.3 34-6.5-16.7 30.3z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 523 B |
1
public/flags/at.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#d80027" d="M0 0h512v167l-23.2 89.7L512 345v167H0V345l29.4-89L0 167z"/><path fill="#eee" d="M0 167h512v178H0z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 306 B |
1
public/flags/au.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#0052b4" d="M0 0h512v512H0z"/><path fill="#eee" d="m154 300 14 30 32-8-14 30 25 20-32 7 1 33-26-21-26 21 1-33-33-7 26-20-14-30 32 8zm222-27h47l-38 27 15-44 14 44zm7-162 7 15 16-4-7 15 12 10-15 3v17l-13-11-13 11v-17l-15-3 12-10-7-15 16 4zm57 67 7 15 16-4-7 15 12 10-15 3v16l-13-10-13 11v-17l-15-3 12-10-7-15 16 4zm-122 22 7 15 16-4-7 15 12 10-15 3v16l-13-10-13 11v-17l-15-3 12-10-7-15 16 4zm65 156 7 15 16-4-7 15 12 10-15 3v17l-13-11-13 11v-17l-15-3 12-10-7-15 16 4zM0 0v32l32 32L0 96v160h32l32-32 32 32h32v-83l83 83h45l-8-16 8-15v-14l-83-83h83V96l-32-32 32-32V0H96L64 32 32 0Z"/><path fill="#d80027" d="M32 0v32H0v64h32v160h64V96h160V32H96V0Zm96 128 128 128v-31l-97-97z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 866 B |
1
public/flags/ba.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#ffda44" d="M0 0h445.3l33.9 255-33.9 257-323.7-134.3L0 66.8z"/><path fill="#0052b4" d="M0 66.8V512h445.4z"/><path fill="#0052b4" d="M445.3 0H512v512h-66.7z"/><path fill="#eee" d="m354.6 456-8.3 25.6h-26.8l21.7 15.8-8.3 25.5 21.7-15.8 21.7 15.8-8.3-25.5 21.7-15.8h-26.8zm-55-55.4-8.3 25.5h-26.8l21.7 15.8-8.3 25.5 21.7-15.8 21.7 15.8-8.3-25.5 21.7-15.8h-26.8zM244.4 345l-8.3 25.5h-26.8l21.7 15.8-8.3 25.5 21.7-15.8 21.7 15.8-8.3-25.5 21.7-15.8h-26.8zm-55.1-55.7-8.3 25.5h-26.8l21.7 15.8-8.3 25.5 21.7-15.8L211 356l-8.3-25.5 21.7-15.8h-26.8zm-55.4-55.7-8.3 25.5H98.8l21.7 15.8-8.3 25.5 21.7-15.8 21.7 15.8-8.3-25.5L169 259h-26.8zM78.7 178l-8.3 25.5H43.6l21.7 15.8-8.3 25.5L78.7 229l21.7 15.8-8.3-25.5 21.7-15.8H87zm-55.2-55.7-8.3 25.5h-26.8l21.7 15.8L1.8 189l21.7-15.8L45.2 189l-8.3-25.5 21.7-15.8H31.8z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 998 B |
1
public/flags/be.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#333" d="M0 0h167l38.2 252.6L167 512H0z"/><path fill="#d80027" d="M345 0h167v512H345l-36.7-256z"/><path fill="#ffda44" d="M167 0h178v512H167z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 338 B |
1
public/flags/br.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#6da544" d="M0 0h512v512H0z"/><path fill="#ffda44" d="M256 100.2 467.5 256 256 411.8 44.5 256z"/><path fill="#eee" d="M174.2 221a87 87 0 0 0-7.2 36.3l162 49.8a88.5 88.5 0 0 0 14.4-34c-40.6-65.3-119.7-80.3-169.1-52z"/><path fill="#0052b4" d="M255.7 167a89 89 0 0 0-41.9 10.6 89 89 0 0 0-39.6 43.4 181.7 181.7 0 0 1 169.1 52.2 89 89 0 0 0-9-59.4 89 89 0 0 0-78.6-46.8zM212 250.5a149 149 0 0 0-45 6.8 89 89 0 0 0 10.5 40.9 89 89 0 0 0 120.6 36.2 89 89 0 0 0 30.7-27.3A151 151 0 0 0 212 250.5z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 686 B |
1
public/flags/ca.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#d80027" d="M0 0v512h144l112-64 112 64h144V0H368L256 64 144 0Z"/><path fill="#eee" d="M144 0h224v512H144Z"/><path fill="#d80027" d="m301 289 44-22-22-11v-22l-45 22 23-44h-23l-22-34-22 33h-23l23 45-45-22v22l-22 11 45 22-12 23h45v33h22v-33h45z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 438 B |
1
public/flags/cd.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#338af3" d="M0 0h401.9L512 110.3V512H110.3L0 401.9z"/><path fill="#ffda44" d="M401.9 0 0 401.9V449l63 63h47.3L512 110.3V63L449 0z"/><path fill="#d80027" d="M449 0 0 449v63h63L512 63V0h-63z"/><path fill="#ffda44" d="m136.4 78 13.8 42.4H195l-36 26.3 13.7 42.5-36.2-26.3-36 26.3 13.7-42.5L78 120.4h44.7z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 497 B |
1
public/flags/ch.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#d80027" d="M0 0h512v512H0z"/><path fill="#eee" d="M389.6 211.5h-89v-89h-89.1v89h-89v89h89v89h89v-89h89z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 301 B |
1
public/flags/ci.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#eee" d="M167 0h178l31 253.2L345 512H167l-33.4-257.4z"/><path fill="#ff9811" d="M0 0h167v512H0z"/><path fill="#6da544" d="M345 0h167v512H345z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 338 B |
1
public/flags/co.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#d80027" d="m0 384 255.8-29.7L512 384v128H0z"/><path fill="#0052b4" d="m0 256 259.5-31L512 256v128H0z"/><path fill="#ffda44" d="M0 0h512v256H0z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 340 B |
1
public/flags/cv.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#0052b4" d="M0 0h512v256.2l-41.9 64.3 41.9 63.7V512H0V384.2L41.3 320 0 256.2z"/><path fill="#eee" d="M0 256.2h512v42.9l-15.7 21.6 15.7 21v42.5H0v-42.5l15.1-21.5L0 299z"/><path fill="#d80027" d="M0 299.1h512v42.6H0z"/><path fill="#ffda44" d="m182.8 190.4 5.2 16.4h17.1l-13.8 10 5.3 16.3-13.8-10-14 10 5.4-16.3-13.9-10h17.1zm0 213.3L188 420h17.1l-13.8 10 5.3 16.2-13.8-10-14 10L174 430l-14-10h17.2zm-99.2-72.1 5.2 16.2h17.1L92.1 358l5.2 16.2-13.7-10-14 10L75 358l-14-10.1h17.2zm37.9-119.8 5 16h17.2l-13.8 10.3 5.2 16.2-13.7-10-14 10 5.4-16.3-14-10.1H116zm-60.4 67h17l5.5-16.2 5.2 16.2h17.1L92.1 289l5.2 16.4L83.6 295l-14 10.3 5.4-16.4zm46.5 143 5.3-16.2L99 395.4h17.1l5.4-16.2 5.2 16.3h17.1L130 405.6l5.3 16.2-13.8-10zM282 331.6l-5.4 16.2h-17l13.8 10.2-5.3 16.2 13.9-10 13.8 10-5.2-16.3 13.7-10.1h-17zm-38-119.8-5.3 16.2h-17.1l14 10.2-5.4 16.2 13.9-10 13.8 10-5.3-16.3 13.8-10.1h-17zm60.3 67h-17l-5.3-16.2-5.4 16.2h-17l13.8 10.1-5.3 16.4L282 295l13.8 10.3-5.2-16.4zm-46.4 143-5.3-16.2 13.8-10.2h-17l-5.3-16.2-5.4 16.3h-17.1l14 10.1-5.4 16.2 13.9-10z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
1
public/flags/cw.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#0052b4" d="M0 0h512v342.3l-22 34.2 22 32.5v103H0V409l25.4-31L0 342.2z"/><path fill="#eee" d="m175.2 164.2 13.8 42.5h44.7L197.6 233l13.8 42.5-36.2-26.3-36.1 26.3 13.8-42.5-36.2-26.3h44.7zm-76.7-44.5 8.2 25.5h26.9L111.9 161l8.3 25.5-21.7-15.7-21.7 15.7L85 161l-21.7-15.7h26.9z"/><path fill="#ffda44" d="M0 342.3h512V409H0z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 518 B |
1
public/flags/cz.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#eee" d="M0 0h512v256l-265 45.2z"/><path fill="#d80027" d="M210 256h302v256H0z"/><path fill="#0052b4" d="M0 0v512l256-256L0 0z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 323 B |
1
public/flags/de.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#ffda44" d="m0 345 256.7-25.5L512 345v167H0z"/><path fill="#d80027" d="m0 167 255-23 257 23v178H0z"/><path fill="#333" d="M0 0h512v167H0z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 334 B |
1
public/flags/dz.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#496e2d" d="M0 0h256l32 256-32 256H0Z"/><path fill="#eee" d="M256 0h256v512H256z"/><path fill="#d80027" d="M245 167a89 89 0 1 0 67 153 72 72 0 0 1-35 8 72 72 0 1 1 35-136 89 89 0 0 0-67-25m66 40-21 29-34-11 21 29-21 29 34-11 21 29v-36l34-11-34-11z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 444 B |
1
public/flags/ec.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#d80027" d="m0 384 254.7-32.7L512 383.9V512H0z"/><path fill="#0052b4" d="m0 256 255-27 257 27v128H0z"/><path fill="#ffda44" d="M0 0h512v256H0z"/><circle cx="256" cy="256" r="89" fill="#ffda44"/><path fill="#338af3" d="M256 311.6c-30.7 0-55.7-25-55.7-55.6v-33.4a55.7 55.7 0 0 1 111.4 0V256c0 30.6-25 55.6-55.7 55.6z"/><path fill="#333" d="M345 122.4h-66.7a22.3 22.3 0 0 0-44.6 0H167a23 23 0 0 0 23 22.3h-.8c0 12.3 10 22.3 22.3 22.3 0 12.3 10 22.2 22.2 22.2h44.6c12.3 0 22.2-10 22.2-22.2 12.3 0 22.3-10 22.3-22.3h-.8a23 23 0 0 0 23-22.3z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 732 B |
1
public/flags/eg.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#eee" d="m0 144 256-32 256 32v224l-256 32L0 368Z"/><path fill="#d80027" d="M0 0h512v144H0Z"/><path fill="#333" d="M0 368h512v144H0Z"/><path fill="#ff9811" d="M250 191c-8 0-17 4-22 14 5-3 16-1 16 13 0 4-2 8-5 10-8 0-14-14-29-14-10 0-19 7-19 17v69l46-7-14 27h66l-14-27 46 7v-69c0-10-9-17-19-17-15 0-21 14-29 14 8-23-7-37-23-37z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 522 B |
1
public/flags/es.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#ffda44" d="m0 128 256-32 256 32v256l-256 32L0 384Z"/><path fill="#eee" d="M196 168q-11 1-15 11l-5-1q-15 1-16 16c-1 15 7 16 16 16q11 0 15-11a16 16 0 0 0 17-4 16 16 0 0 0 17 4 16 16 0 1 0 10-20 16 16 0 0 0-27-5q-4-6-12-6m0 8q8 1 8 8 0 8-8 8-7 0-8-8 1-7 8-8m24 0q8 1 8 8 0 8-8 8-7 0-8-8 1-7 8-8m-44 10 4 1 4 8q-1 7-8 7-9 0-8-8 1-7 8-8m64 0q8 1 8 8 0 8-8 8-7 0-8-7l4-8zm-112 38v80h16v-80zm80 0v40c-26 0-48 14-48 32s22 32 48 32 48-14 48-32v-72zm64 0v80h16v-80z"/><path fill="#ff9811" d="M200 160h16v32h-16z"/><path fill="#d80027" d="M0 0v128h512V0zm208 184c-22 0-40 11-40 24l8 8h64l8-8c0-13-18-24-40-24m-72 8a8 8 0 0 0-8 8v8a8 8 0 1 0 16 0v-8a8 8 0 0 0-8-8m144 0a8 8 0 0 0-8 8v8a8 8 0 1 0 16 0v-8a8 8 0 0 0-8-8m-120 32v24h-38a4 4 0 0 0-4 4 4 4 0 0 0 4 4h38v40a24 24 0 0 0 24 24 24 24 0 0 0 24-24 24 24 0 0 0 24 24 24 24 0 0 0 24-24v-24h-48v-48zm72 8a10 10 0 0 0-10 10v12a10 10 0 1 0 20 0v-12a10 10 0 0 0-10-10m24 16v8h38a4 4 0 0 0 4-4 4 4 0 0 0-4-4zm-134 24a4 4 0 0 0-4 4 4 4 0 0 0 4 4h28a4 4 0 0 0 4-4 4 4 0 0 0-4-4zm144 0a4 4 0 0 0-4 4 4 4 0 0 0 4 4h28a4 4 0 0 0 4-4 4 4 0 0 0-4-4zM0 384v128h512V384z"/><path fill="#ffda44" d="M186 196a6 6 0 0 0-6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0-6-6m22 0a6 6 0 0 0-6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0-6-6m22 0a6 6 0 0 0-6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0-6-6"/><path fill="#ff9811" d="M128 208a8 8 0 1 0 0 16h16a8 8 0 1 0 0-16zm144 0a8 8 0 1 0 0 16h16a8 8 0 1 0 0-16zm-96 8v8h64v-8zm-8 16v8h8v16h-8v8h32v-8h-8v-16h8v-8zm-8 40v24q1 12 9 19v-43zm19 0v47h10v-47zm20 0v43q9-7 9-19v-24zm-71 32a8 8 0 1 0 0 16h16a8 8 0 1 0 0-16zm144 0a8 8 0 1 0 0 16h16a8 8 0 1 0 0-16z"/><path fill="#338af3" d="M208 256a16 16 0 0 0-16 16 16 16 0 0 0 16 16 16 16 0 0 0 16-16 16 16 0 0 0-16-16m-80 64a8 8 0 1 0 0 16h16a8 8 0 1 0 0-16zm144 0a8 8 0 1 0 0 16h16a8 8 0 1 0 0-16z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
1
public/flags/fr.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#eee" d="M167 0h178l25.9 252.3L345 512H167l-29.8-253.4z"/><path fill="#0052b4" d="M0 0h167v512H0z"/><path fill="#d80027" d="M345 0h167v512H345z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 340 B |
1
public/flags/gb-eng.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#eee" d="M0 0h208l48 32 48-32h208v208l-32 48 32 48v208H304l-48-32-48 32H0V304l32-48-32-48Z"/><path fill="#d80027" d="M208 0v208H0v96h208v208h96V304h208v-96H304V0h-96z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 363 B |
1
public/flags/gb-sct.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#0052b4" d="M0 68 68 0h376l68 68v376l-68 68H68L0 444Z"/><path fill="#eee" d="M0 0v68l188 188L0 444v68h68l188-188 188 188h68v-68L324 256 512 68V0h-68L256 188 68 0H0z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 361 B |
1
public/flags/gh.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#ffda44" d="m0 167 256-32 256 32v178l-256 32L0 345Z"/><path fill="#d80027" d="M0 0h512v167H0Z"/><path fill="#496e2d" d="M0 345h512v167H0Z"/><path fill="#333" d="m198 345 151-109H163l151 109-58-178Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 394 B |
1
public/flags/hr.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#eee" d="m0 167 253.8-19.3L512 167v178l-254.9 32.3L0 345z"/><path fill="#d80027" d="M0 0h512v167H0z"/><path fill="#0052b4" d="M0 345h512v167H0z"/><path fill="#338af3" d="M322.8 178h-44.5l7.4-55.7 29.7-22.2 29.6 22.2V167zm-133.6 0h44.5l-7.4-55.7-29.7-22.2-29.6 22.2V167z"/><path fill="#0052b4" d="M285.7 178h-59.4v-55.7l29.7-22.2 29.7 22.2z"/><path fill="#eee" d="M167 167v122.3a89 89 0 0 0 35.8 71.3l15.5-3.9 19.7 19.8a89.1 89.1 0 0 0 18 1.8 89 89 0 0 0 17.9-1.8l22.4-18.7 13 2.8a89 89 0 0 0 35.7-71.3V167z"/><path fill="#d80027" d="M167 167h35.6v35.5H167zm71.2 0h35.6v35.5h-35.6zm71.2 0H345v35.5h-35.6zm-106.8 35.5h35.6v35.6h-35.6zm71.2 0h35.6v35.6h-35.6zM167 238.1h35.6v35.6H167zm35.6 35.6h35.6v35.6h-35.6zm35.6-35.6h35.6v35.6h-35.6zm71.2 0H345v35.6h-35.6zm-35.6 35.6h35.6v35.6h-35.6zm-35.6 35.6h35.6V345h-35.6zm-35.6 0h-33.3c3 13.3 9 25.4 17.3 35.6h16zM309.4 345h16a88.8 88.8 0 0 0 17.3-35.6h-33.3zm-106.8 0v15.6a88.7 88.7 0 0 0 35.6 16V345zm71.2 0v31.6a88.7 88.7 0 0 0 35.6-16V345z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
1
public/flags/ht.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#a2001d" d="m0 256 254.8-41.8L512 256v256H0z"/><path fill="#0052b4" d="M0 0h512v256H0z"/><path fill="#eee" d="m345 322.8-89-11.1-89 11V189.3h178z"/><circle cx="256" cy="267.1" r="44.5" fill="#0052b4"/><circle cx="256" cy="267.1" r="22.3" fill="#a2001d"/><path fill="#6da544" d="M222.6 211.5h66.8L256 244.9z"/><path fill="#ffda44" d="M244.9 233.7H267v66.8h-22z"/><path fill="#6da544" d="M291.6 293.8h-71.2l-53.4 29h178z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 615 B |
1
public/flags/iq.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#eee" d="m0 167 256-32 256 32v178l-256 32L0 345Z"/><path fill="#a2001d" d="M0 0h512v167H0Z"/><path fill="#333" d="M0 345h512v167H0Z"/><path fill="#496e2d" d="m186.4 223.4-7.5 12.2-4.8 9 8.5 12.1h18.9q2.3 0 3.8 1a6 6 0 0 1 2.4 3.5q.8 2.4.8 6.7v5.5h-47.1v-30.5h-14.7v8.6H129v-8.6h-14.7V287q0 4.4-1.7 6.8a5 5 0 0 1-4.5 2.4l-2-.1h-2.8l-.2 12.2 5.2.3q6.2 0 10.8-2.8 4.8-2.7 7.3-7.7 2.6-5 2.6-11V264h17.7v21.8h76.5V268q0-5-1.4-9.3-1.5-4.3-4-7.6a17 17 0 0 0-6.8-5 23 23 0 0 0-9.5-1.7h-11.1l1.4-2.7 1.6-3a104 104 0 0 1 5.3-8.5zM236 226v59.7h14.6V226zm132 0v47.3h-15.2v-38.6h-14.6v38.6h-15.3v-30.5h-20.4q-7.2 0-12.3 2.6a17 17 0 0 0-7.7 7.3 25 25 0 0 0-2.6 12q0 7 2.6 11.7a16 16 0 0 0 7.7 7q5.1 2.4 12.3 2.3h80.2V226zm26.3 0v59.7H409V226zm-91.8 29.3h5.7v18h-5.7q-2.7 0-4.5-.5a4 4 0 0 1-2.6-2.3q-.8-2-.8-5.8 0-4.2 1-6.2a5 5 0 0 1 2.7-2.6q1.8-.6 4.2-.6m-155.8 39.4v11.2h14.7v-11.2z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
1
public/flags/ir.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#eee" d="M0 144.7 258.8 39.6 512 144.7v222.6L257 493 0 367.3z"/><path fill="#6da544" d="M0 0v144.7h105.6v-22.2h33.6v22.2h33.3v-22.2h33.6v22.2h33.3v-22.2H273v22.2h33v-22.2h33.6v22.2h33.2v-22.2h33.6v22.2H512V0z"/><path fill="#d80027" d="M0 367.3V512h512V367.3H406.4v22.4h-33.6v-22.4h-33.2v22.4H306v-22.4h-33v22.4h-33.6v-22.4h-33.3v22.4h-33.6v-22.4h-33.3v22.4h-33.6v-22.4zm339.1-178h-33.4c.2 3.7.4 7.4.4 11.1 0 24.8-6.2 48.8-17 66-3.3 5.2-9 12.6-16.4 17.6v-94.7h-33.4v94.8c-7.5-5-13-12.4-16.4-17.7-10.8-17-17-41-17-65.9 0-3.7.2-7.4.4-11H173a190 190 0 0 0-.4 11c0 68.7 36.7 122.5 83.5 122.5s83.5-53.8 83.5-122.5c0-3.7-.1-7.4-.4-11z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 824 B |
1
public/flags/jo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#eee" d="m126 158 127.8-10.3L512 167v178l-254.9 32.3L126 335.9z"/><path fill="#333" d="M0 0h512v167H107z"/><path fill="#6da544" d="M107 345h405v167H0z"/><path fill="#d80027" d="M0 0v512l256-256z"/><path fill="#eee" d="m101.6 200.3 14 29.4 31.8-7.3-14.2 29.3 25.5 20.2-31.8 7.2.1 32.6-25.4-20.4-25.4 20.4V279l-31.7-7.2 25.5-20-14.2-29.4 31.8 7.3z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 542 B |
1
public/flags/jp.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#eee" d="M0 0h512v512H0z"/><circle cx="256" cy="256" r="111.3" fill="#d80027"/></g></svg>
|
||||
|
After Width: | Height: | Size: 273 B |
1
public/flags/kr.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#eee" d="M0 0h512v512H0Z"/><path fill="#333" d="m350 335 24-24 16 16-24 23zm-39 39 24-24 15 16-23 24zm87 8 23-24 16 16-24 24zm-40 39 24-23 16 15-24 24Zm16-63 24-23 15 15-23 24zm-39 40 23-24 16 16-24 23zm63-221-63-63 15-15 64 63zm-63-15-24-24 16-16 23 24zm39 39-24-24 16-15 24 23zm8-87-24-23 16-16 24 24Zm39 40-23-24 15-16 24 24ZM91 358l63 63-16 16-63-63zm63 16 23 24-15 15-24-23zm-40-39 24 23-16 16-23-24zm24-24 63 63-16 16-63-63zm16-220-63 63-16-16 63-63zm23 23-63 63-15-16 63-63zm24 24-63 63-16-16 63-63z"/><path fill="#d80027" d="M319 319 193 193a89 89 0 1 1 126 126z"/><path fill="#0052b4" d="M319 319a89 89 0 1 1-126-126z"/><circle cx="224.5" cy="224.5" r="44.5" fill="#d80027"/><circle cx="287.5" cy="287.5" r="44.5" fill="#0052b4"/></g></svg>
|
||||
|
After Width: | Height: | Size: 933 B |
1
public/flags/ma.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#d80027" d="M0 0h512v512H0z"/><path fill="#496e2d" d="M407.3 210H291.7L256 100.3 220.3 210H104.7l93.5 68-35.7 109.8L256 320l93.5 68-35.7-110zm-183 59.5 12.2-37.1h39l12.1 37.1-31.6 23-31.6-23zm44-59.4h-24.6l12.3-37.9zm38.3 45.7-7.7-23.4h39.9zM213 232.4l-7.7 23.4-32.2-23.4zm-8.3 97.3 12.3-38 20 14.5zm70.1-23.4 20-14.5 12.3 37.9z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 525 B |
1
public/flags/mx.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#eee" d="M144 0h223l33 256-33 256H144l-32-256z"/><path fill="#d80027" d="M368 0h144v512H368z"/><path fill="#751a46" d="M256 174c22 11 12 33 11 34l-2-4c-4-15-13-33-31-18v11q10 1 11 11-11 12-4 26l4 8-13 23 29-7 18 18v-11l11 11 23-11-35-21-2-13c22-2 34 4 51 29 9-83-45-86-64-86Z"/><path fill="#6da544" d="M209 183q-5 4-4 12 1 11 10 15c3 2 8 0 10 3 3 3-2 5-4 6q-8 5-9 14 3 10 12 15c2 2 7 4 5 7q-4 2-9-2-12-6-19-19c-2-3-1-10-7-10-7 2-4 10-2 14q8 14 21 23 9 8 20 3 10-6 4-17c-3-6-11-8-14-14-2-3 2-4 4-6q8-4 9-11-2-13-14-15-6 1-7-6c-1-3 3-7 0-11q-2-3-6-1"/><path fill="#496e2d" d="M0 0v512h144V0zm164 235a5 5 0 0 0-5 5 97 97 0 0 0 194 0 5 5 0 0 0-5-5 5 5 0 0 0-5 5 87 87 0 1 1-174 0 5 5 0 0 0-5-5m35 25-4 1q-3 4 1 8 23 21 54 24v17h12v-17q31-3 54-24 4-4 1-8-4-3-8 0a78 78 0 0 1-106 0z"/><path fill="#338af3" d="M256 316q-21 0-40-13l6-9c20 13 48 13 68 0l7 9q-18 13-41 13"/><rect width="34" height="22" x="239" y="299" fill="#ff9811" rx="11" ry="11"/><path fill="#ffda44" d="m234 186-12 11v11l18-9q4-3 1-7zm-62 79a10 10 0 0 0-10 10 10 10 0 0 0 10 10 10 10 0 0 0 10-10 10 10 0 0 0-10-10m169 0a10 10 0 0 0-10 10 10 10 0 0 0 10 10 10 10 0 0 0 10-10 10 10 0 0 0-10-10m-69 4-16 8v5l15-1 4-9zm-83 23a10 10 0 0 0-10 10 10 10 0 0 0 10 10 10 10 0 0 0 10-10 10 10 0 0 0-10-10m135 0a10 10 0 0 0-10 10 10 10 0 0 0 10 10 10 10 0 0 0 10-10 10 10 0 0 0-10-10m-108 21a10 10 0 0 0-10 10 10 10 0 0 0 10 10 10 10 0 0 0 10-10 10 10 0 0 0-10-10m81 0a10 10 0 0 0-10 10 10 10 0 0 0 10 10 10 10 0 0 0 10-10 10 10 0 0 0-10-10"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
1
public/flags/nl.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#eee" d="m0 167 253.8-19.3L512 167v178l-254.9 32.3L0 345z"/><path fill="#a2001d" d="M0 0h512v167H0z"/><path fill="#0052b4" d="M0 345h512v167H0z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 340 B |
1
public/flags/no.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#d80027" d="M0 0h100.2l66.1 53.5L233.7 0H512v189.3L466.3 257l45.7 65.8V512H233.7l-68-50.7-65.5 50.7H0V322.8l51.4-68.5-51.4-65z"/><path fill="#eee" d="M100.2 0v189.3H0v33.4l24.6 33L0 289.5v33.4h100.2V512h33.4l30.6-26.3 36.1 26.3h33.4V322.8H512v-33.4l-24.6-33.7 24.6-33v-33.4H233.7V0h-33.4l-33.8 25.3L133.6 0z"/><path fill="#0052b4" d="M133.6 0v222.7H0v66.7h133.6V512h66.7V289.4H512v-66.7H200.3V0z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 592 B |
1
public/flags/nz.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#0052b4" d="M256 0h256v512H0V256Z"/><path fill="#eee" d="M0 0v32l32 32L0 96v160h32l32-32 32 32h32v-83l83 83h45l-8-16 8-15v-14l-83-83h83V96l-32-32 32-32V0H96L64 32 32 0Zm382 92-11 35h-37l30 21-12 35 30-22 30 22-12-35 30-21h-37l-11-35Zm61 72-11 35h-37l30 21-11 35 29-21 30 21-12-35 30-21h-37Zm-123 10-11 35h-37l30 22-11 35 29-22 30 22-11-35 29-22h-36zm59 130-11 35h-37l30 21-11 35 29-21 30 21-11-35 29-21h-36z"/><path fill="#d80027" d="M32 0v32H0v64h32v160h64V96h160V32H96V0Zm96 128 128 128v-31l-97-97zm251 201-5 18h-19l15 10-6 18 15-11 15 11-5-18 14-10h-18Zm-59-129-5 17h-19l15 11-6 17 15-11 15 11-6-17 15-11h-18l-6-17zm123-11-6 18h-18l15 11-6 17 15-11 15 11-6-17 15-11h-18l-6-18zm-61-72-6 17h-18l15 11-6 17 15-10 15 10-6-17 15-11h-18z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 931 B |
1
public/flags/pa.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#eee" d="M0 0h256l256 256v256H256L0 256z"/><path fill="#0052b4" d="M0 256v256h256V256z"/><path fill="#d80027" d="M256 0h256v256H256z"/><path fill="#0052b4" d="m152.4 89 16.6 51h53.6l-43.4 31.6 16.6 51-43.4-31.5-43.4 31.5 16.6-51L82.2 140h53.6z"/><path fill="#d80027" d="m359.6 289.4 16.6 51h53.6L386.4 372l16.6 51-43.4-31.5-43.4 31.6 16.6-51-43.4-31.6H343z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 553 B |
1
public/flags/pt.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#6da544" d="M0 512h167l37.9-260.3L167 0H0z"/><path fill="#d80027" d="M512 0H167v512h345z"/><circle cx="167" cy="256" r="89" fill="#ffda44"/><path fill="#d80027" d="M116.9 211.5V267a50 50 0 1 0 100.1 0v-55.6H117z"/><path fill="#eee" d="M167 283.8c-9.2 0-16.7-7.5-16.7-16.7V245h33.4v22c0 9.2-7.5 16.7-16.7 16.7z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 506 B |
1
public/flags/py.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#eee" d="m0 144.7 255.3-36.5L512 144.7v222.6L250.5 407 0 367.3z"/><path fill="#d80027" d="M0 0h512v144.7H0z"/><path fill="#0052b4" d="M0 367.3h512V512H0z"/><path fill="#6da544" d="m319 182-23.6 23.5a55.5 55.5 0 0 1-39.4 95 55.7 55.7 0 0 1-39.3-95L193 182a89 89 0 1 0 126 0z"/><path fill="#ffda44" d="m256 211.5 8.3 25.5H291l-21.7 15.8 8.3 25.5-21.7-15.8-21.7 15.8 8.3-25.5-21.7-15.8h26.8z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 585 B |
1
public/flags/qa.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#eee" d="M0 0h173l61 255.8L173.4 512H0z"/><path fill="#751a46" d="m173 0-72.7 30.8L176 63l-75.7 32.2 75.7 32.1-75.7 32.2 75.7 32.1-75.7 32.1 75.7 32.2-75.7 32.2 75.7 32.1-75.7 32.2 75.7 32.1-75.7 32.2 75.7 32.1-75.7 32.2 73.1 31H512V0z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 432 B |
1
public/flags/sa.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#496e2d" d="M0 0h512v512H0Z"/><path fill="#eee" d="M336 356v16H128l24 24h184v16h16v-16h32v-24h-32v-16zM131.4 174v41.4h-15.8v-26.7H97.8q-6.3 0-10.8 2.3a15 15 0 0 0-6.7 6.4 22 22 0 0 0-2.3 10.5q0 6 2.3 10.3 2.3 4 6.7 6 4.5 2.1 10.8 2.1H173V174h-13v41.4h-15.8V174zm52.9 0v52.3h12.8V174zm55.3 0v41.4h-11v-31h-12.8v31h-9.3v10.9h45.9V174zm24.3 0v52.3h12.8V174zm77.8 0v41.4H326v-26.7h-17.8q-6.3 0-10.8 2.3a15 15 0 0 0-6.7 6.4 22 22 0 0 0-2.3 10.5q0 6 2.3 10.3 2.3 4 6.7 6 4.5 2.1 10.8 2.1h46.5V174zm24.2 0v52.3h12.8V174zm55.3 0v41.4h-11v-31h-12.8v31h-9.3v10.9h46V174ZM97.8 199.6h5v15.8h-5q-2.4 0-4-.4-1.5-.5-2.2-2a13 13 0 0 1-.8-5.1q0-3.7.8-5.4 1-1.8 2.5-2.3 1.5-.6 3.7-.6m210.3 0h5v15.8h-5q-2.4 0-4-.4-1.5-.5-2.2-2a13 13 0 0 1-.8-5.1q0-3.7.8-5.4 1-1.8 2.5-2.3 1.6-.6 3.7-.6M114.8 247v28.5h-10.9V257H91.6q-4.4 0-7.4 1.6-3 1.4-4.6 4.4t-1.6 7.2q0 4.3 1.6 7 1.5 2.9 4.6 4.3t7.4 1.4h51.7v-36h-8.8v28.5h-10.9V247Zm36.3 0v36h8.8v-36Zm39.7 0v35.8q0 1.5-.6 2.7t-2 2q-1.5.6-4 .7t-4.2-.7-2.4-2q-.9-1.3-.9-3.1l.2-2.8 1.5-10.8-8.7-1.1-1.2 8.4-.6 6.4q0 3.7 2 6.7a14 14 0 0 0 5.9 4.8q3.6 1.7 8.3 1.7 4.5 0 8-1.6 3.6-1.6 5.5-4.6 2-2.8 2-6.7V247Zm159.5 10a36 36 0 0 0-10 1.4 40 40 0 0 0-1.3 7.4 57 57 0 0 0 0 9.6h-11v-2a20 20 0 0 0-1.9-9.2q-1.8-3.6-5.4-5.3a20 20 0 0 0-8.7-1.8h-4.2v7.5h4.2q2.7 0 4.3.8 1.5.7 2.2 2.6.6 1.8.7 5.4v2h-12.7v7.6H434v-12.8q0-5-1.6-7.8-1.5-3-4.7-4.1-3.2-1.4-8-1.3a36 36 0 0 0-10 1.4 40 40 0 0 0-1.4 7.4 57 57 0 0 0 0 9.6h-10.9v-4.8q0-4.2-2-7.2t-5.5-4.6a18 18 0 0 0-7.9-1.7q-2.1 0-4.2.4l-4.3.8.7 7a48 48 0 0 1 6.7-.6q4 0 6 1.5 1.7 1.5 1.7 4.4v4.9h-23.9v-5.3q0-5-1.6-7.8-1.6-3-4.8-4.1-3-1.4-8-1.3m-131.7.1q-4.3 0-7.4 1.6-3 1.4-4.6 4.4t-1.6 7.2q0 4.3 1.6 7 1.6 2.9 4.6 4.3t7.4 1.4h3.5v1.6q0 2.3-1.5 3.4-1.4 1.2-4.7 1.2l-3-.2q-1.8 0-4.3-.4l-1.2 7a59 59 0 0 0 8.5 1q4.5 0 7.8-1.4 3.4-1.5 5.3-4.2a11 11 0 0 0 1.9-6.4V283h22.9a15 15 0 0 0 7.9-2q1 .6 2.2 1 2.3 1 4.7 1h13.9v-14l-.3-3.3-1.3-8.6-8.7 1.3a118 118 0 0 1 1.4 10.5v6.6h-5l-1.9-.4-.9-.5q.7-2.7.7-6.2v-8.6h-8.8v8.6q0 3-.4 4.6-.3 1.5-1 2a5 5 0 0 1-2.5.5h-3v-13h-9v13H231V257zm73.8 0v26.6q0 2.7-1 4-1 1.5-2.8 1.5h-2.8l-.2 7.3 3.1.2q3.8 0 6.6-1.7t4.3-4.6 1.6-6.7V257zm58 7.4q2.1 0 3.3.5t1.7 1.7q.4 1.3.4 3.4v5.4h-8a71 71 0 0 1 0-8.6l.2-2.3zm69.3 0q2.2 0 3.4.5t1.6 1.7q.5 1.3.5 3.4v5.4h-8a71 71 0 0 1-.1-8.6l.2-2.3zm-328.1.1H95v10.9h-3.4q-1.7 0-2.7-.3-1-.4-1.6-1.4a9 9 0 0 1-.5-3.5q0-2.6.6-3.7A3 3 0 0 1 89 265a8 8 0 0 1 2.5-.4m127 0h3.5v10.9h-3.5q-1.6 0-2.7-.3-1-.4-1.6-1.4a9 9 0 0 1-.5-3.5q0-2.6.6-3.7a3 3 0 0 1 1.7-1.6 8 8 0 0 1 2.5-.4"/></g></svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
1
public/flags/se.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#0052b4" d="M0 0h133.6l35.3 16.7L200.3 0H512v222.6l-22.6 31.7 22.6 35.1V512H200.3l-32-19.8-34.7 19.8H0V289.4l22.1-33.3L0 222.6z"/><path fill="#ffda44" d="M133.6 0v222.6H0v66.8h133.6V512h66.7V289.4H512v-66.8H200.3V0z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 412 B |
1
public/flags/sn.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#ffda44" d="M144.8 0h222.4l32 260-32 252H144.8l-32.1-256z"/><path fill="#496e2d" d="M0 0h144.8v512H0z"/><path fill="#d80027" d="M367.2 0H512v512H367.2z"/><path fill="#496e2d" d="m256.1 167 22.1 68h71.5L292 277l22 68-57.8-42-57.9 42 22.1-68-57.8-42H234z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 449 B |
1
public/flags/tn.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#d80027" d="M0 0h512v512H0z"/><circle cx="256" cy="256" r="123" fill="#eee"/><path fill="#d80027" d="M251 167a89 89 0 1 0 67 153 72 72 0 0 1-34 8 72 72 0 1 1 34-136 89 89 0 0 0-67-25m20 42v36l-34 11 34 11v36l21-29 34 11-21-29 21-29-34 11z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 435 B |
1
public/flags/tr.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#d80027" d="M0 0h512v512H0z"/><path fill="#eee" d="M208 115a141 141 0 1 0 106 242q-25 13-54 13a114 114 0 1 1 54-215 141 141 0 0 0-106-40m142 67v56l-54 18 54 17v57l33-46 54 18-33-46 33-46-54 18z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 390 B |
1
public/flags/us.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#eee" d="M256 0h256v64l-32 32 32 32v64l-32 32 32 32v64l-32 32 32 32v64l-256 32L0 448v-64l32-32-32-32v-64z"/><path fill="#d80027" d="M224 64h288v64H224Zm0 128h288v64H256ZM0 320h512v64H0Zm0 128h512v64H0Z"/><path fill="#0052b4" d="M0 0h256v256H0Z"/><path fill="#eee" d="m187 243 57-41h-70l57 41-22-67zm-81 0 57-41H93l57 41-22-67zm-81 0 57-41H12l57 41-22-67zm162-81 57-41h-70l57 41-22-67zm-81 0 57-41H93l57 41-22-67zm-81 0 57-41H12l57 41-22-67Zm162-82 57-41h-70l57 41-22-67Zm-81 0 57-41H93l57 41-22-67zm-81 0 57-41H12l57 41-22-67Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 723 B |
1
public/flags/uy.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#338af3" d="M0 256 256 0h256v55.7l-20.7 34.5 20.7 32.2v66.8l-21.2 32.7L512 256v66.8l-24 31.7 24 35.1v66.7l-259.1 28.3L0 456.3v-66.7l27.1-33.3L0 322.8z"/><path fill="#eee" d="M256 256h256v-66.8H236.9zm-19.1-133.6H512V55.7H236.9zM512 512v-55.7H0V512zM0 389.6h512v-66.8H0z"/><path fill="#eee" d="M0 0h256v256H0z"/><path fill="#ffda44" d="m222.6 149.8-31.3 14.7 16.7 30.3-34-6.5-4.3 34.3-23.6-25.2-23.7 25.2-4.3-34.3-33.9 6.5 16.6-30.3-31.2-14.7 31.2-14.7-16.6-30.3 34 6.5 4.2-34.3 23.7 25.3L169.7 77l4.3 34.3 34-6.5-16.7 30.3z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 720 B |
1
public/flags/uz.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#d80027" d="m0 178 254.2-22L512 178v22.3l-40.2 54.1 40.2 57.3V334l-254 23.4L0 334v-22.3l36.7-59.4-36.7-52z"/><path fill="#338af3" d="M0 0h512v178H0z"/><path fill="#eee" d="M0 200.3h512v111.4H0z"/><path fill="#6da544" d="M0 334h512v178H0z"/><path fill="#eee" d="M117.2 105.7a50 50 0 0 1 39.3-48.9 50.2 50.2 0 0 0-10.7-1.1 50 50 0 1 0 10.7 99c-22.5-5-39.3-25-39.3-49zm69 22.8 3.3 10.4h11l-9 6.5 3.5 10.4-9-6.4-8.7 6.4 3.4-10.4-9-6.5h11zm35 0 3.4 10.4h11l-9 6.5 3.4 10.4-8.8-6.4-9 6.4 3.5-10.4-9-6.5h11zm35 0 3.4 10.4h11l-9 6.5 3.5 10.4-9-6.4-8.8 6.4 3.4-10.4-9-6.5h11zm35 0 3.4 10.4h11l-9 6.5 3.5 10.4-9-6.4-8.8 6.4 3.4-10.4-9-6.5h11zm35 0 3.4 10.4h11l-9 6.5 3.5 10.4-9-6.4-8.8 6.4 3.4-10.4-8.8-6.5h11zm-105-36.4 3.4 10.4h11l-9 6.5 3.4 10.4-8.8-6.5-9 6.5 3.5-10.4-9-6.5h11zm35 0 3.4 10.4h11l-9 6.5 3.5 10.4-9-6.5-8.8 6.5 3.4-10.4-9-6.5h11zm35 0 3.4 10.4h11l-9 6.5 3.5 10.4-9-6.5-8.8 6.5 3.4-10.4-9-6.5h11zm35 0 3.4 10.4h11l-9 6.5 3.5 10.4-9-6.5-8.8 6.5 3.4-10.4-8.8-6.5h11zm-70-36.4 3.4 10.4h11l-9 6.4 3.6 10.5-9-6.5-8.8 6.5 3.4-10.5-9-6.4h11zm35 0 3.4 10.4h11l-9 6.4 3.6 10.5-9-6.5-8.8 6.5 3.4-10.5-9-6.4h11zm35 0 3.4 10.4h11l-9 6.4 3.6 10.5-9-6.5-8.8 6.5 3.4-10.5-8.8-6.4h11z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
1
public/flags/za.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><mask id="a"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#a)"><path fill="#eee" d="m0 0 192 256L0 512h47l465-189v-34l-32-33 32-33v-34L47 0Z"/><path fill="#333" d="M0 142v228l140-114z"/><path fill="#ffda44" d="M192 256 0 95v47l114 114L0 370v47z"/><path fill="#6da544" d="M512 223H223L0 0v94l161 162L0 418v94l223-223h289z"/><path fill="#d80027" d="M512 0H47l189 189h276z"/><path fill="#0052b4" d="M512 512H47l189-189h276z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 542 B |
50
scripts/download-flags.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
// download-flags.ts — Lädt circle-flags SVGs für alle Teams aus TLA_TO_ISO2.
|
||||
// Ausführung: npx tsx scripts/download-flags.ts
|
||||
|
||||
import { TLA_TO_ISO2 } from "../lib/flags";
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
const BASE = "https://hatscripts.github.io/circle-flags/flags";
|
||||
const OUT = path.join(__dirname, "..", "public", "flags");
|
||||
|
||||
async function main() {
|
||||
const codes = Object.values(TLA_TO_ISO2);
|
||||
const unique = [...new Set(codes)];
|
||||
console.log(`Lade ${unique.length} Flaggen (${codes.length} Team-Codes)...`);
|
||||
|
||||
if (!fs.existsSync(OUT)) fs.mkdirSync(OUT, { recursive: true });
|
||||
|
||||
let ok = 0;
|
||||
let failed = 0;
|
||||
for (const iso2 of unique) {
|
||||
const url = `${BASE}/${iso2}.svg`;
|
||||
try {
|
||||
const res = await fetch(url, {
|
||||
headers: { "User-Agent": "circle-flags-download/1.0" },
|
||||
});
|
||||
if (!res.ok) {
|
||||
console.warn(` ❌ ${iso2}: HTTP ${res.status}`);
|
||||
failed++;
|
||||
continue;
|
||||
}
|
||||
const svg = await res.text();
|
||||
// Prüfen: keine leere/Fehler-SVG (<10 Bytes = kaputt)
|
||||
if (svg.trim().length < 10) {
|
||||
console.warn(` ❌ ${iso2}: leere SVG (${svg.length} Bytes)`);
|
||||
failed++;
|
||||
continue;
|
||||
}
|
||||
fs.writeFileSync(path.join(OUT, `${iso2}.svg`), svg);
|
||||
ok++;
|
||||
} catch (err) {
|
||||
console.warn(` ❌ ${iso2}: ${err instanceof Error ? err.message : err}`);
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\n✅ ${ok} OK, ❌ ${failed} fehlgeschlagen`);
|
||||
if (failed > 0) process.exit(1);
|
||||
}
|
||||
|
||||
main();
|
||||
119
scripts/fifa-eval.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
// fifa-eval.ts — Analyse-Skript: IdGroup, MatchNumber, Attendance, MatchStatus
|
||||
// Ausführung: npx ts-node --compiler-options '{"module":"commonjs","target":"es2020"}' scripts/fifa-eval.ts
|
||||
// Oder mit Deno, Bun: bun run scripts/fifa-eval.ts
|
||||
|
||||
const FIFA_BASE = "https://api.fifa.com/api/v3";
|
||||
const FIFA_SEASON = "285023";
|
||||
|
||||
interface RawMatch {
|
||||
MatchNumber: number;
|
||||
MatchStatus: number;
|
||||
IdGroup: string | null;
|
||||
IdStage: string;
|
||||
StageName: Array<{ Locale: string; Description: string }>;
|
||||
GroupName?: Array<{ Locale: string; Description: string }>;
|
||||
Home: { IdTeam: string; Abbreviation: string; TeamName?: Array<{ Locale: string; Description: string }> } | null;
|
||||
Away: { IdTeam: string; Abbreviation: string; TeamName?: Array<{ Locale: string; Description: string }> } | null;
|
||||
HomeTeamScore: number | null;
|
||||
AwayTeamScore: number | null;
|
||||
Attendance: string | null;
|
||||
Date: string;
|
||||
LocalDate: string;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log("📡 Rufe FIFA Calendar-Endpoint ab...");
|
||||
const res = await fetch(
|
||||
`${FIFA_BASE}/calendar/matches?language=de&count=500&idSeason=${FIFA_SEASON}`,
|
||||
{ headers: { "User-Agent": "fifa-eval/1.0" } },
|
||||
);
|
||||
if (!res.ok) { console.error("Fehler:", res.status, res.statusText); process.exit(1); }
|
||||
const data = (await res.json()) as { Results: RawMatch[] };
|
||||
const matches = data.Results ?? [];
|
||||
console.log(`✅ ${matches.length} Matches geladen\n`);
|
||||
|
||||
// ── A) IdGroup → GroupName Mapping ──
|
||||
console.log("═══ A) IdGroup → Gruppe (A-L) ═══");
|
||||
const groupMap = new Map<string, string>();
|
||||
for (const m of matches) {
|
||||
if (!m.IdGroup || !m.GroupName) continue;
|
||||
const desc = m.GroupName.find(g => g.Locale === "de-DE")?.Description
|
||||
?? m.GroupName[0]?.Description
|
||||
?? `ID:${m.IdGroup}`;
|
||||
if (!groupMap.has(m.IdGroup)) groupMap.set(m.IdGroup, desc);
|
||||
}
|
||||
console.log(`Anzahl distinct IdGroup-Werte: ${groupMap.size}`);
|
||||
const sorted = [...groupMap.entries()].sort((a, b) => parseInt(a[0]) - parseInt(b[0]));
|
||||
for (const [id, name] of sorted) {
|
||||
console.log(` ${id} → "${name}"`);
|
||||
}
|
||||
// Als kopierbare Konstante
|
||||
console.log("\n// Kopierbare Konstante:");
|
||||
console.log("const FIFA_IDGROUP_TO_GROUP: Record<string, string> = {");
|
||||
for (const [id, name] of sorted) {
|
||||
const letter = name.replace(/^Gruppe\s+/, "");
|
||||
console.log(` "${id}": "${letter}", // ${name}`);
|
||||
}
|
||||
console.log("};");
|
||||
|
||||
// ── B) MatchNumber-Konsistenz ──
|
||||
console.log("\n═══ B) MatchNumber-Konsistenz ═══");
|
||||
const groupMatches = matches.filter(m => m.IdGroup != null).sort((a, b) => a.MatchNumber - b.MatchNumber);
|
||||
const koMatches = matches.filter(m => m.IdGroup == null).sort((a, b) => a.MatchNumber - b.MatchNumber);
|
||||
console.log(`Gruppenspiele: ${groupMatches.length} (MatchNumber ${groupMatches[0]?.MatchNumber}–${groupMatches[groupMatches.length-1]?.MatchNumber})`);
|
||||
console.log(`K.o.-Spiele: ${koMatches.length} (MatchNumber ${koMatches[0]?.MatchNumber}–${koMatches[koMatches.length-1]?.MatchNumber})`);
|
||||
|
||||
// Stichproben für K.o.-Slots
|
||||
const checkNums = [73, 74, 76, 89, 104];
|
||||
for (const n of checkNums) {
|
||||
const m = matches.find(x => x.MatchNumber === n);
|
||||
if (m) {
|
||||
const home = m.Home?.Abbreviation ?? "?";
|
||||
const away = m.Away?.Abbreviation ?? "?";
|
||||
console.log(` #${n}: ${home} vs ${away} | Stage=${m.StageName?.[0]?.Description ?? "?"} | Status=${m.MatchStatus}`);
|
||||
} else {
|
||||
console.log(` #${n}: NICHT GEFUNDEN`);
|
||||
}
|
||||
}
|
||||
|
||||
// ── C) Attendance + Scheduled ──
|
||||
console.log("\n═══ C) Attendance + Scheduled-Matches ═══");
|
||||
const withAttendance = matches.filter(m => m.Attendance != null);
|
||||
console.log(`Matches mit Attendance: ${withAttendance.length}`);
|
||||
if (withAttendance.length > 0) {
|
||||
const ex = withAttendance[0];
|
||||
console.log(` Beispiel: #${ex.MatchNumber} → ${ex.Attendance}`);
|
||||
}
|
||||
const scheduled = matches.filter(m => m.MatchStatus === 1);
|
||||
console.log(`Scheduled-Matches (Status=1): ${scheduled.length}`);
|
||||
if (scheduled.length > 0) {
|
||||
const ex = scheduled[0];
|
||||
console.log(` Beispiel: #${ex.MatchNumber} ${ex.Home?.Abbreviation ?? "?"} vs ${ex.Away?.Abbreviation ?? "?"} | Date=${ex.Date}`);
|
||||
}
|
||||
|
||||
// ── D) MatchStatus-Werte ──
|
||||
console.log("\n═══ D) Distinct MatchStatus-Werte ═══");
|
||||
const statuses = new Map<number, number>();
|
||||
for (const m of matches) {
|
||||
statuses.set(m.MatchStatus, (statuses.get(m.MatchStatus) ?? 0) + 1);
|
||||
}
|
||||
const statusLabels: Record<number, string> = { 0: "finished", 1: "scheduled", 10: "postponed", 3: "live?" };
|
||||
for (const [s, c] of [...statuses.entries()].sort((a, b) => a[0] - b[0])) {
|
||||
console.log(` MatchStatus ${s}: ${c} Matches ${statusLabels[s] ? `(${statusLabels[s]})` : ""}`);
|
||||
}
|
||||
|
||||
// ── E) Stage-Werte ──
|
||||
console.log("\n═══ E) Distinct Stages ═══");
|
||||
const stages = new Map<string, number>();
|
||||
for (const m of matches) {
|
||||
const sn = m.StageName?.[0]?.Description ?? String(m.IdStage);
|
||||
stages.set(sn, (stages.get(sn) ?? 0) + 1);
|
||||
}
|
||||
for (const [s, c] of stages.entries()) {
|
||||
console.log(` "${s}" (IdStage=${matches.find(m => (m.StageName?.[0]?.Description ?? "") === s)?.IdStage}): ${c}`);
|
||||
}
|
||||
|
||||
console.log("\n✅ Analyse abgeschlossen.");
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||