commit af6f7b1d091a0e8a7ef13cec85a8d38fab8ddd4a Author: Montia37 Date: Wed Aug 13 04:32:05 2025 +0800 init: 初始化 diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..628d4eb --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,126 @@ +name: Build and Release Assets + +on: + workflow_dispatch: + push: + tags: + - "v*" + release: + types: [created] + +jobs: + build-and-package: + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + + - name: Install Yarn + run: npm install -g yarn + + - name: Install dependencies + run: yarn + + - name: Build project + run: yarn build + + - name: Update theme configuration + run: | + # Get current date in YY.MM.DD format + VERSION_DATE=$(date +"%y.%m.%d") + # Get commit hash (short) + COMMIT_HASH=$(git rev-parse --short HEAD) + + echo "VERSION_DATE=${VERSION_DATE}" >> $GITHUB_ENV + echo "COMMIT_HASH=${COMMIT_HASH}" >> $GITHUB_ENV + + # Update komari-theme.json with new version and description + jq --arg version "$VERSION_DATE" \ + --arg desc "Theme for Komari Monitor (commit: $COMMIT_HASH)" \ + '.version = $version | .description = $desc' \ + komari-theme.json > komari-theme-updated.json + + mv komari-theme-updated.json komari-theme.json + + echo "Updated theme configuration:" + cat komari-theme.json + + - name: Verify required files exist + run: | + echo "Checking required files..." + ls -la preview.png || (echo "preview.png not found" && exit 1) + ls -la komari-theme.json || (echo "komari-theme.json not found" && exit 1) + ls -la dist/ || (echo "dist/ directory not found" && exit 1) + echo "All required files found!" + + - name: Create theme package + run: | + # Create a temporary directory for the package + mkdir -p theme-package + + # Copy required files + cp preview.png theme-package/ + cp komari-theme.json theme-package/ + cp -r dist/ theme-package/ + + # Create zip file with version and commit hash + ZIP_NAME="komari-theme-purcarte-v${VERSION_DATE}-${COMMIT_HASH}.zip" + + cd theme-package + zip -r ../${ZIP_NAME} . + cd .. + + echo "ZIP_NAME=${ZIP_NAME}" >> $GITHUB_ENV + echo "Created package: ${ZIP_NAME}" + ls -la ${ZIP_NAME} + + create-release: + needs: build-and-package + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') + permissions: + contents: write + + steps: + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: theme-package + path: . + + - name: Display structure of downloaded files + run: ls -R + + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref_name }} + body: | + New release based on commit ${{ env.COMMIT_HASH }} + draft: false + prerelease: false + + - name: Upload Release Asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./${{ env.ZIP_NAME }} + asset_name: ${{ env.ZIP_NAME }} + asset_content_type: application/zip diff --git a/.github/workflows/development.yaml b/.github/workflows/development.yaml new file mode 100644 index 0000000..a355f8e --- /dev/null +++ b/.github/workflows/development.yaml @@ -0,0 +1,60 @@ +name: Development Environment + +on: + # Temporarily disabled + # push: + # branches: [main] + # pull_request: + # branches: [main] + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: "22" + + - name: Install dependencies + run: npm install + + - name: Build project + run: npm run build + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: dist + path: dist + + deploy: + needs: build + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + + steps: + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: dist + path: dist + + - name: Setup SSH Key + uses: webfactory/ssh-agent@v0.8.0 + with: + ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }} + + - name: Add host to known hosts + run: | + mkdir -p ~/.ssh + ssh-keyscan -H ${{ vars.PRODUCTION_SERVER }} >> ~/.ssh/known_hosts + + - name: Deploy to production server + run: | + rsync -avz --delete dist/ root@${{ vars.PRODUCTION_SERVER }}:${{ vars.PRODUCTION_DIR }} diff --git a/.github/workflows/preview-theme.yaml b/.github/workflows/preview-theme.yaml new file mode 100644 index 0000000..0acb914 --- /dev/null +++ b/.github/workflows/preview-theme.yaml @@ -0,0 +1,89 @@ +name: Build Theme Package + +on: + push: + branches: + - dev + +jobs: + build-and-package: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + + - name: Install Yarn + run: npm install -g yarn + + - name: Install dependencies + run: yarn + + - name: Build project + run: yarn build + + - name: Update theme configuration + run: | + # Get current date in YY.MM.DD format + VERSION_DATE=$(date +"%y.%m.%d") + # Get commit hash (short) + COMMIT_HASH=$(git rev-parse --short HEAD) + + echo "VERSION_DATE=${VERSION_DATE}" >> $GITHUB_ENV + echo "COMMIT_HASH=${COMMIT_HASH}" >> $GITHUB_ENV + + # Update komari-theme.json with new version and description + jq --arg version "$VERSION_DATE" \ + --arg desc "Preview theme for Komari Monitor (commit: $COMMIT_HASH)" \ + '.version = $version | .description = $desc' \ + komari-theme.json > komari-theme-updated.json + + mv komari-theme-updated.json komari-theme.json + + echo "Updated theme configuration:" + cat komari-theme.json + + - name: Verify required files exist + run: | + echo "Checking required files..." + ls -la preview.png || (echo "preview.png not found" && exit 1) + ls -la komari-theme.json || (echo "komari-theme.json not found" && exit 1) + ls -la dist/ || (echo "dist/ directory not found" && exit 1) + echo "All required files found!" + + - name: Create theme package + run: | + # Create a temporary directory for the package + mkdir -p theme-package + + # Copy required files + cp preview.png theme-package/ + cp komari-theme.json theme-package/ + cp -r dist/ theme-package/ + + # Create zip file with version and commit hash + ZIP_NAME="komari-theme-purcarte-v${VERSION_DATE}-${COMMIT_HASH}.zip" + + cd theme-package + zip -r ../${ZIP_NAME} . + cd .. + + echo "ZIP_NAME=${ZIP_NAME}" >> $GITHUB_ENV + echo "Created package: ${ZIP_NAME}" + ls -la ${ZIP_NAME} + + - name: Upload theme as artifacts + uses: actions/upload-artifact@v4 + with: + name: komari-theme-purcarte-v${{ env.VERSION_DATE }}-${{ env.COMMIT_HASH }} + path: | + preview.png + komari-theme.json + dist/ + retention-days: 90 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..33aa564 --- /dev/null +++ b/.gitignore @@ -0,0 +1,70 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Dependency directories +node_modules/ +package-lock.json + +# Build output +dist/ +dist-ssr/ +*.local +bundle-analysis.html + +# Environment variables +.env +.env.local +.env.development +.env.development.local +.env.test.local +.env.production.local + +# Vite specific +.vite/ +vite.config.js.timestamp-* +vite.config.ts.timestamp-* + +# IDEs and editors +.idea/ +.vscode/ +!.vscode/extensions.json +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +# OS generated files +.DS_Store +Thumbs.db + +# Testing +coverage/ +*.lcov + +# Yarn +.yarn/* +!.yarn/patches +!.yarn/releases +!.yarn/plugins +!.yarn/sdks +!.yarn/versions +.pnp.* + + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +vite.config.dev.ts \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2239811 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Montia37 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..ba48f87 --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +
+ + + +## ✨ PurCarte ✨ + +一个为 [Komari](https://github.com/komari-monitor/komari) 设计的磨砂玻璃风格主题 + +
+ +--- + +> [!NOTE] +> 初学 React,部分借鉴官方主题在 Gemini 的帮助下完成,整体风格更偏向个人喜好 + +> [!WARNING] +> Instance 页面仍有较多缺陷,暂时参考官方样式小改 +> 延迟信息图表仅勉强可看,短时间无法完善,介意请先考虑其他主题 [社区维护的主题](https://komari-document.pages.dev/community/theme) + +## 开发 + +1. **克隆项目** + + ```bash + git clone https://github.com/Montia37/komari-theme-purcarte.git + cd Komari-theme-purcarte + ``` + +2. **安装依赖** + + ```bash + yarn install + ``` + +3. **运行开发服务器** + + ```bash + yarn dev + ``` + +4. 在浏览器中打开 `http://localhost:5173` (或 Vite 提示的其他端口)。 + +## 📄 许可证 + +[MIT License](LICENSE) diff --git a/components.json b/components.json new file mode 100644 index 0000000..73afbdb --- /dev/null +++ b/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "", + "css": "src/index.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "iconLibrary": "lucide" +} \ No newline at end of file diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..2434983 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,30 @@ +import js from "@eslint/js"; +import globals from "globals"; +import reactHooks from "eslint-plugin-react-hooks"; +import reactRefresh from "eslint-plugin-react-refresh"; +import tseslint from "typescript-eslint"; + +export default tseslint.config( + { ignores: ["dist"] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ["**/*.{ts,tsx}"], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + "react-hooks": reactHooks, + "react-refresh": reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + "react-refresh/only-export-components": [ + "warn", + { allowConstantExport: true }, + ], + "@typescript-eslint/no-explicit-any": "off", + "prefer-const": "off", + }, + } +); diff --git a/index.html b/index.html new file mode 100644 index 0000000..59f4696 --- /dev/null +++ b/index.html @@ -0,0 +1,14 @@ + + + + + + + Komari Monitor + + + +
+ + + diff --git a/komari-theme.json b/komari-theme.json new file mode 100644 index 0000000..8f9aea6 --- /dev/null +++ b/komari-theme.json @@ -0,0 +1,9 @@ +{ + "name": "Komari Theme PurCarte", + "short": "PurCarte", + "description": "A frosted glass theme for Komari", + "version": "0.1.0", + "author": "Montia & Gemini", + "url": "https://github.com/Montia37/Komari-theme-purcarte", + "preview": "preview.png" +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..7ae1c3b --- /dev/null +++ b/package.json @@ -0,0 +1,45 @@ +{ + "name": "komari-theme-purcarte", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "@radix-ui/react-avatar": "^1.1.10", + "@radix-ui/react-dropdown-menu": "^2.1.15", + "@radix-ui/react-icons": "^1.3.2", + "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-switch": "^1.2.5", + "@radix-ui/themes": "^3.2.1", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "lucide-react": "^0.537.0", + "react": "^19.1.1", + "react-dom": "^19.1.1", + "react-router-dom": "^7.8.0", + "recharts": "2.15.3", + "tailwind-merge": "^3.3.1", + "tw-animate-css": "^1.3.6" + }, + "devDependencies": { + "@eslint/js": "^9.32.0", + "@tailwindcss/vite": "^4.1.11", + "@types/node": "^24.2.0", + "@types/react": "^19.1.9", + "@types/react-dom": "^19.1.7", + "@vitejs/plugin-react": "^4.7.0", + "eslint": "^9.32.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.20", + "globals": "^16.3.0", + "tailwindcss": "^4.1.11", + "typescript": "~5.8.3", + "typescript-eslint": "^8.39.0", + "vite": "^7.1.0" + } +} diff --git a/preview.png b/preview.png new file mode 100644 index 0000000..9bae161 Binary files /dev/null and b/preview.png differ diff --git a/public/assets/TablerHelp.svg b/public/assets/TablerHelp.svg new file mode 100644 index 0000000..04e92a3 --- /dev/null +++ b/public/assets/TablerHelp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/edit_117847723_p0.png b/public/assets/edit_117847723_p0.png new file mode 100644 index 0000000..7c7071b Binary files /dev/null and b/public/assets/edit_117847723_p0.png differ diff --git a/public/assets/flags/AC.svg b/public/assets/flags/AC.svg new file mode 100644 index 0000000..53f90dc --- /dev/null +++ b/public/assets/flags/AC.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/AD.svg b/public/assets/flags/AD.svg new file mode 100644 index 0000000..be10594 --- /dev/null +++ b/public/assets/flags/AD.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/AE.svg b/public/assets/flags/AE.svg new file mode 100644 index 0000000..be8e114 --- /dev/null +++ b/public/assets/flags/AE.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/AF.svg b/public/assets/flags/AF.svg new file mode 100644 index 0000000..769efca --- /dev/null +++ b/public/assets/flags/AF.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/AG.svg b/public/assets/flags/AG.svg new file mode 100644 index 0000000..2716617 --- /dev/null +++ b/public/assets/flags/AG.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/AI.svg b/public/assets/flags/AI.svg new file mode 100644 index 0000000..6a91dd9 --- /dev/null +++ b/public/assets/flags/AI.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/AL.svg b/public/assets/flags/AL.svg new file mode 100644 index 0000000..2c8655d --- /dev/null +++ b/public/assets/flags/AL.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/AM.svg b/public/assets/flags/AM.svg new file mode 100644 index 0000000..0a966ab --- /dev/null +++ b/public/assets/flags/AM.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/AO.svg b/public/assets/flags/AO.svg new file mode 100644 index 0000000..65803b6 --- /dev/null +++ b/public/assets/flags/AO.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/AQ.svg b/public/assets/flags/AQ.svg new file mode 100644 index 0000000..fd29680 --- /dev/null +++ b/public/assets/flags/AQ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/AR.svg b/public/assets/flags/AR.svg new file mode 100644 index 0000000..e8e60ef --- /dev/null +++ b/public/assets/flags/AR.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/AS.svg b/public/assets/flags/AS.svg new file mode 100644 index 0000000..8b27532 --- /dev/null +++ b/public/assets/flags/AS.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/AT.svg b/public/assets/flags/AT.svg new file mode 100644 index 0000000..bfe1ec7 --- /dev/null +++ b/public/assets/flags/AT.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/AU.svg b/public/assets/flags/AU.svg new file mode 100644 index 0000000..989da76 --- /dev/null +++ b/public/assets/flags/AU.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/AW.svg b/public/assets/flags/AW.svg new file mode 100644 index 0000000..f383951 --- /dev/null +++ b/public/assets/flags/AW.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/AX.svg b/public/assets/flags/AX.svg new file mode 100644 index 0000000..03bc680 --- /dev/null +++ b/public/assets/flags/AX.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/AZ.svg b/public/assets/flags/AZ.svg new file mode 100644 index 0000000..b584854 --- /dev/null +++ b/public/assets/flags/AZ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BA.svg b/public/assets/flags/BA.svg new file mode 100644 index 0000000..bbcd3b5 --- /dev/null +++ b/public/assets/flags/BA.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BB.svg b/public/assets/flags/BB.svg new file mode 100644 index 0000000..7f9e8c9 --- /dev/null +++ b/public/assets/flags/BB.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BD.svg b/public/assets/flags/BD.svg new file mode 100644 index 0000000..6edc844 --- /dev/null +++ b/public/assets/flags/BD.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BE.svg b/public/assets/flags/BE.svg new file mode 100644 index 0000000..8670426 --- /dev/null +++ b/public/assets/flags/BE.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BF.svg b/public/assets/flags/BF.svg new file mode 100644 index 0000000..8bceec7 --- /dev/null +++ b/public/assets/flags/BF.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BG.svg b/public/assets/flags/BG.svg new file mode 100644 index 0000000..6e81fba --- /dev/null +++ b/public/assets/flags/BG.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BH.svg b/public/assets/flags/BH.svg new file mode 100644 index 0000000..73de582 --- /dev/null +++ b/public/assets/flags/BH.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BI.svg b/public/assets/flags/BI.svg new file mode 100644 index 0000000..e53644c --- /dev/null +++ b/public/assets/flags/BI.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BJ.svg b/public/assets/flags/BJ.svg new file mode 100644 index 0000000..133d711 --- /dev/null +++ b/public/assets/flags/BJ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BL.svg b/public/assets/flags/BL.svg new file mode 100644 index 0000000..9d4904d --- /dev/null +++ b/public/assets/flags/BL.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BM.svg b/public/assets/flags/BM.svg new file mode 100644 index 0000000..5e7b7f6 --- /dev/null +++ b/public/assets/flags/BM.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BN.svg b/public/assets/flags/BN.svg new file mode 100644 index 0000000..3c20edb --- /dev/null +++ b/public/assets/flags/BN.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BO.svg b/public/assets/flags/BO.svg new file mode 100644 index 0000000..ad0a8c9 --- /dev/null +++ b/public/assets/flags/BO.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BQ.svg b/public/assets/flags/BQ.svg new file mode 100644 index 0000000..bde4921 --- /dev/null +++ b/public/assets/flags/BQ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BR.svg b/public/assets/flags/BR.svg new file mode 100644 index 0000000..956e39d --- /dev/null +++ b/public/assets/flags/BR.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BS.svg b/public/assets/flags/BS.svg new file mode 100644 index 0000000..a75f68b --- /dev/null +++ b/public/assets/flags/BS.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BT.svg b/public/assets/flags/BT.svg new file mode 100644 index 0000000..e822f94 --- /dev/null +++ b/public/assets/flags/BT.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BV.svg b/public/assets/flags/BV.svg new file mode 100644 index 0000000..3d104a6 --- /dev/null +++ b/public/assets/flags/BV.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BW.svg b/public/assets/flags/BW.svg new file mode 100644 index 0000000..5edeb5d --- /dev/null +++ b/public/assets/flags/BW.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BY.svg b/public/assets/flags/BY.svg new file mode 100644 index 0000000..3fef573 --- /dev/null +++ b/public/assets/flags/BY.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/BZ.svg b/public/assets/flags/BZ.svg new file mode 100644 index 0000000..6f43e4a --- /dev/null +++ b/public/assets/flags/BZ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CA.svg b/public/assets/flags/CA.svg new file mode 100644 index 0000000..d9c386d --- /dev/null +++ b/public/assets/flags/CA.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CC.svg b/public/assets/flags/CC.svg new file mode 100644 index 0000000..ce130d7 --- /dev/null +++ b/public/assets/flags/CC.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CD.svg b/public/assets/flags/CD.svg new file mode 100644 index 0000000..d1b15c9 --- /dev/null +++ b/public/assets/flags/CD.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CF.svg b/public/assets/flags/CF.svg new file mode 100644 index 0000000..72166cb --- /dev/null +++ b/public/assets/flags/CF.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CG.svg b/public/assets/flags/CG.svg new file mode 100644 index 0000000..3d466e3 --- /dev/null +++ b/public/assets/flags/CG.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CH.svg b/public/assets/flags/CH.svg new file mode 100644 index 0000000..741b521 --- /dev/null +++ b/public/assets/flags/CH.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CI.svg b/public/assets/flags/CI.svg new file mode 100644 index 0000000..bd2c3e0 --- /dev/null +++ b/public/assets/flags/CI.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CK.svg b/public/assets/flags/CK.svg new file mode 100644 index 0000000..04e0344 --- /dev/null +++ b/public/assets/flags/CK.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CL.svg b/public/assets/flags/CL.svg new file mode 100644 index 0000000..52b3a00 --- /dev/null +++ b/public/assets/flags/CL.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CM.svg b/public/assets/flags/CM.svg new file mode 100644 index 0000000..7da7b66 --- /dev/null +++ b/public/assets/flags/CM.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CN.svg b/public/assets/flags/CN.svg new file mode 100644 index 0000000..c10116d --- /dev/null +++ b/public/assets/flags/CN.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CO.svg b/public/assets/flags/CO.svg new file mode 100644 index 0000000..dc825d2 --- /dev/null +++ b/public/assets/flags/CO.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CP.svg b/public/assets/flags/CP.svg new file mode 100644 index 0000000..4eafe7a --- /dev/null +++ b/public/assets/flags/CP.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CR.svg b/public/assets/flags/CR.svg new file mode 100644 index 0000000..acecc89 --- /dev/null +++ b/public/assets/flags/CR.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CU.svg b/public/assets/flags/CU.svg new file mode 100644 index 0000000..13b6370 --- /dev/null +++ b/public/assets/flags/CU.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CV.svg b/public/assets/flags/CV.svg new file mode 100644 index 0000000..9b2cc18 --- /dev/null +++ b/public/assets/flags/CV.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CW.svg b/public/assets/flags/CW.svg new file mode 100644 index 0000000..c53d09f --- /dev/null +++ b/public/assets/flags/CW.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CX.svg b/public/assets/flags/CX.svg new file mode 100644 index 0000000..6a322f5 --- /dev/null +++ b/public/assets/flags/CX.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CY.svg b/public/assets/flags/CY.svg new file mode 100644 index 0000000..19bead4 --- /dev/null +++ b/public/assets/flags/CY.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/CZ.svg b/public/assets/flags/CZ.svg new file mode 100644 index 0000000..fd3b470 --- /dev/null +++ b/public/assets/flags/CZ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/DE.svg b/public/assets/flags/DE.svg new file mode 100644 index 0000000..10a5399 --- /dev/null +++ b/public/assets/flags/DE.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/DG.svg b/public/assets/flags/DG.svg new file mode 100644 index 0000000..565a7aa --- /dev/null +++ b/public/assets/flags/DG.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/DJ.svg b/public/assets/flags/DJ.svg new file mode 100644 index 0000000..42cbb24 --- /dev/null +++ b/public/assets/flags/DJ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/DK.svg b/public/assets/flags/DK.svg new file mode 100644 index 0000000..5ab629b --- /dev/null +++ b/public/assets/flags/DK.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/DM.svg b/public/assets/flags/DM.svg new file mode 100644 index 0000000..750424f --- /dev/null +++ b/public/assets/flags/DM.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/DO.svg b/public/assets/flags/DO.svg new file mode 100644 index 0000000..c627c34 --- /dev/null +++ b/public/assets/flags/DO.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/DZ.svg b/public/assets/flags/DZ.svg new file mode 100644 index 0000000..c29a7e2 --- /dev/null +++ b/public/assets/flags/DZ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/EA.svg b/public/assets/flags/EA.svg new file mode 100644 index 0000000..d1fd565 --- /dev/null +++ b/public/assets/flags/EA.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/EC.svg b/public/assets/flags/EC.svg new file mode 100644 index 0000000..c035be7 --- /dev/null +++ b/public/assets/flags/EC.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/EE.svg b/public/assets/flags/EE.svg new file mode 100644 index 0000000..47a5589 --- /dev/null +++ b/public/assets/flags/EE.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/EG.svg b/public/assets/flags/EG.svg new file mode 100644 index 0000000..2034a3e --- /dev/null +++ b/public/assets/flags/EG.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/EH.svg b/public/assets/flags/EH.svg new file mode 100644 index 0000000..9b8dc5a --- /dev/null +++ b/public/assets/flags/EH.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/ER.svg b/public/assets/flags/ER.svg new file mode 100644 index 0000000..8e1e510 --- /dev/null +++ b/public/assets/flags/ER.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/ES.svg b/public/assets/flags/ES.svg new file mode 100644 index 0000000..d1fd565 --- /dev/null +++ b/public/assets/flags/ES.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/ET.svg b/public/assets/flags/ET.svg new file mode 100644 index 0000000..762cc1f --- /dev/null +++ b/public/assets/flags/ET.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/EU.svg b/public/assets/flags/EU.svg new file mode 100644 index 0000000..045024a --- /dev/null +++ b/public/assets/flags/EU.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/FI.svg b/public/assets/flags/FI.svg new file mode 100644 index 0000000..e07328e --- /dev/null +++ b/public/assets/flags/FI.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/FJ.svg b/public/assets/flags/FJ.svg new file mode 100644 index 0000000..190134b --- /dev/null +++ b/public/assets/flags/FJ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/FK.svg b/public/assets/flags/FK.svg new file mode 100644 index 0000000..0091bc7 --- /dev/null +++ b/public/assets/flags/FK.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/FM.svg b/public/assets/flags/FM.svg new file mode 100644 index 0000000..b49556b --- /dev/null +++ b/public/assets/flags/FM.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/FO.svg b/public/assets/flags/FO.svg new file mode 100644 index 0000000..93a1272 --- /dev/null +++ b/public/assets/flags/FO.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/FR.svg b/public/assets/flags/FR.svg new file mode 100644 index 0000000..4eafe7a --- /dev/null +++ b/public/assets/flags/FR.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/GA.svg b/public/assets/flags/GA.svg new file mode 100644 index 0000000..a8c6fa4 --- /dev/null +++ b/public/assets/flags/GA.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/GB.svg b/public/assets/flags/GB.svg new file mode 100644 index 0000000..21b97e9 --- /dev/null +++ b/public/assets/flags/GB.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/GD.svg b/public/assets/flags/GD.svg new file mode 100644 index 0000000..e4f37f9 --- /dev/null +++ b/public/assets/flags/GD.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/GE.svg b/public/assets/flags/GE.svg new file mode 100644 index 0000000..8c2bd5a --- /dev/null +++ b/public/assets/flags/GE.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/GF.svg b/public/assets/flags/GF.svg new file mode 100644 index 0000000..2f10cee --- /dev/null +++ b/public/assets/flags/GF.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/GG.svg b/public/assets/flags/GG.svg new file mode 100644 index 0000000..84f6043 --- /dev/null +++ b/public/assets/flags/GG.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/GH.svg b/public/assets/flags/GH.svg new file mode 100644 index 0000000..3330218 --- /dev/null +++ b/public/assets/flags/GH.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/GI.svg b/public/assets/flags/GI.svg new file mode 100644 index 0000000..432a727 --- /dev/null +++ b/public/assets/flags/GI.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/GL.svg b/public/assets/flags/GL.svg new file mode 100644 index 0000000..8a2ba3e --- /dev/null +++ b/public/assets/flags/GL.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/GM.svg b/public/assets/flags/GM.svg new file mode 100644 index 0000000..383cf9d --- /dev/null +++ b/public/assets/flags/GM.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/GN.svg b/public/assets/flags/GN.svg new file mode 100644 index 0000000..16f4a90 --- /dev/null +++ b/public/assets/flags/GN.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/GP.svg b/public/assets/flags/GP.svg new file mode 100644 index 0000000..ca9e4c6 --- /dev/null +++ b/public/assets/flags/GP.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/GQ.svg b/public/assets/flags/GQ.svg new file mode 100644 index 0000000..d4e7119 --- /dev/null +++ b/public/assets/flags/GQ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/GR.svg b/public/assets/flags/GR.svg new file mode 100644 index 0000000..74d842d --- /dev/null +++ b/public/assets/flags/GR.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/GS.svg b/public/assets/flags/GS.svg new file mode 100644 index 0000000..d8b1e5f --- /dev/null +++ b/public/assets/flags/GS.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/GT.svg b/public/assets/flags/GT.svg new file mode 100644 index 0000000..fea623c --- /dev/null +++ b/public/assets/flags/GT.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/GU.svg b/public/assets/flags/GU.svg new file mode 100644 index 0000000..2098ecc --- /dev/null +++ b/public/assets/flags/GU.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/GW.svg b/public/assets/flags/GW.svg new file mode 100644 index 0000000..6e01b9e --- /dev/null +++ b/public/assets/flags/GW.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/GY.svg b/public/assets/flags/GY.svg new file mode 100644 index 0000000..1edc6ef --- /dev/null +++ b/public/assets/flags/GY.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/HK.svg b/public/assets/flags/HK.svg new file mode 100644 index 0000000..ef5ca3b --- /dev/null +++ b/public/assets/flags/HK.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/HM.svg b/public/assets/flags/HM.svg new file mode 100644 index 0000000..989da76 --- /dev/null +++ b/public/assets/flags/HM.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/HN.svg b/public/assets/flags/HN.svg new file mode 100644 index 0000000..298ec95 --- /dev/null +++ b/public/assets/flags/HN.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/HR.svg b/public/assets/flags/HR.svg new file mode 100644 index 0000000..7b8740c --- /dev/null +++ b/public/assets/flags/HR.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/HT.svg b/public/assets/flags/HT.svg new file mode 100644 index 0000000..8ccca42 --- /dev/null +++ b/public/assets/flags/HT.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/HU.svg b/public/assets/flags/HU.svg new file mode 100644 index 0000000..206baa1 --- /dev/null +++ b/public/assets/flags/HU.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/IC.svg b/public/assets/flags/IC.svg new file mode 100644 index 0000000..46b0949 --- /dev/null +++ b/public/assets/flags/IC.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/ID.svg b/public/assets/flags/ID.svg new file mode 100644 index 0000000..de31273 --- /dev/null +++ b/public/assets/flags/ID.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/IE.svg b/public/assets/flags/IE.svg new file mode 100644 index 0000000..3c50257 --- /dev/null +++ b/public/assets/flags/IE.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/IL.svg b/public/assets/flags/IL.svg new file mode 100644 index 0000000..5cf3241 --- /dev/null +++ b/public/assets/flags/IL.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/IM.svg b/public/assets/flags/IM.svg new file mode 100644 index 0000000..7fc9d46 --- /dev/null +++ b/public/assets/flags/IM.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/IN.svg b/public/assets/flags/IN.svg new file mode 100644 index 0000000..55f97e6 --- /dev/null +++ b/public/assets/flags/IN.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/IO.svg b/public/assets/flags/IO.svg new file mode 100644 index 0000000..565a7aa --- /dev/null +++ b/public/assets/flags/IO.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/IQ.svg b/public/assets/flags/IQ.svg new file mode 100644 index 0000000..06cfe31 --- /dev/null +++ b/public/assets/flags/IQ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/IR.svg b/public/assets/flags/IR.svg new file mode 100644 index 0000000..e8ae7b1 --- /dev/null +++ b/public/assets/flags/IR.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/IS.svg b/public/assets/flags/IS.svg new file mode 100644 index 0000000..c8e918c --- /dev/null +++ b/public/assets/flags/IS.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/IT.svg b/public/assets/flags/IT.svg new file mode 100644 index 0000000..6c38017 --- /dev/null +++ b/public/assets/flags/IT.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/JE.svg b/public/assets/flags/JE.svg new file mode 100644 index 0000000..a17c379 --- /dev/null +++ b/public/assets/flags/JE.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/JM.svg b/public/assets/flags/JM.svg new file mode 100644 index 0000000..dd82d4f --- /dev/null +++ b/public/assets/flags/JM.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/JO.svg b/public/assets/flags/JO.svg new file mode 100644 index 0000000..40710a5 --- /dev/null +++ b/public/assets/flags/JO.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/JP.svg b/public/assets/flags/JP.svg new file mode 100644 index 0000000..3a724e9 --- /dev/null +++ b/public/assets/flags/JP.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/KE.svg b/public/assets/flags/KE.svg new file mode 100644 index 0000000..5bee37f --- /dev/null +++ b/public/assets/flags/KE.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/KG.svg b/public/assets/flags/KG.svg new file mode 100644 index 0000000..2616d9e --- /dev/null +++ b/public/assets/flags/KG.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/KH.svg b/public/assets/flags/KH.svg new file mode 100644 index 0000000..54f6e90 --- /dev/null +++ b/public/assets/flags/KH.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/KI.svg b/public/assets/flags/KI.svg new file mode 100644 index 0000000..233cce8 --- /dev/null +++ b/public/assets/flags/KI.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/KM.svg b/public/assets/flags/KM.svg new file mode 100644 index 0000000..91c12b8 --- /dev/null +++ b/public/assets/flags/KM.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/KN.svg b/public/assets/flags/KN.svg new file mode 100644 index 0000000..461e0f2 --- /dev/null +++ b/public/assets/flags/KN.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/KP.svg b/public/assets/flags/KP.svg new file mode 100644 index 0000000..d530523 --- /dev/null +++ b/public/assets/flags/KP.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/KR.svg b/public/assets/flags/KR.svg new file mode 100644 index 0000000..7b5ee23 --- /dev/null +++ b/public/assets/flags/KR.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/KW.svg b/public/assets/flags/KW.svg new file mode 100644 index 0000000..db949b2 --- /dev/null +++ b/public/assets/flags/KW.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/KY.svg b/public/assets/flags/KY.svg new file mode 100644 index 0000000..57323f8 --- /dev/null +++ b/public/assets/flags/KY.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/KZ.svg b/public/assets/flags/KZ.svg new file mode 100644 index 0000000..d2101ab --- /dev/null +++ b/public/assets/flags/KZ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/LA.svg b/public/assets/flags/LA.svg new file mode 100644 index 0000000..0ea005d --- /dev/null +++ b/public/assets/flags/LA.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/LB.svg b/public/assets/flags/LB.svg new file mode 100644 index 0000000..4271b73 --- /dev/null +++ b/public/assets/flags/LB.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/LC.svg b/public/assets/flags/LC.svg new file mode 100644 index 0000000..12b2237 --- /dev/null +++ b/public/assets/flags/LC.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/LI.svg b/public/assets/flags/LI.svg new file mode 100644 index 0000000..9e474bc --- /dev/null +++ b/public/assets/flags/LI.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/LK.svg b/public/assets/flags/LK.svg new file mode 100644 index 0000000..a2fe814 --- /dev/null +++ b/public/assets/flags/LK.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/LR.svg b/public/assets/flags/LR.svg new file mode 100644 index 0000000..dd4a1e4 --- /dev/null +++ b/public/assets/flags/LR.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/LS.svg b/public/assets/flags/LS.svg new file mode 100644 index 0000000..ec06e4f --- /dev/null +++ b/public/assets/flags/LS.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/LT.svg b/public/assets/flags/LT.svg new file mode 100644 index 0000000..5fcfd8b --- /dev/null +++ b/public/assets/flags/LT.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/LU.svg b/public/assets/flags/LU.svg new file mode 100644 index 0000000..e66c904 --- /dev/null +++ b/public/assets/flags/LU.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/LV.svg b/public/assets/flags/LV.svg new file mode 100644 index 0000000..f5f3922 --- /dev/null +++ b/public/assets/flags/LV.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/LY.svg b/public/assets/flags/LY.svg new file mode 100644 index 0000000..c6c12ed --- /dev/null +++ b/public/assets/flags/LY.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MA.svg b/public/assets/flags/MA.svg new file mode 100644 index 0000000..d6d689a --- /dev/null +++ b/public/assets/flags/MA.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MC.svg b/public/assets/flags/MC.svg new file mode 100644 index 0000000..8604a1c --- /dev/null +++ b/public/assets/flags/MC.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MD.svg b/public/assets/flags/MD.svg new file mode 100644 index 0000000..eb2d4a2 --- /dev/null +++ b/public/assets/flags/MD.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/ME.svg b/public/assets/flags/ME.svg new file mode 100644 index 0000000..47c5b2e --- /dev/null +++ b/public/assets/flags/ME.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MF.svg b/public/assets/flags/MF.svg new file mode 100644 index 0000000..4eafe7a --- /dev/null +++ b/public/assets/flags/MF.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MG.svg b/public/assets/flags/MG.svg new file mode 100644 index 0000000..becf2f4 --- /dev/null +++ b/public/assets/flags/MG.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MH.svg b/public/assets/flags/MH.svg new file mode 100644 index 0000000..6774f9b --- /dev/null +++ b/public/assets/flags/MH.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MK.svg b/public/assets/flags/MK.svg new file mode 100644 index 0000000..371b235 --- /dev/null +++ b/public/assets/flags/MK.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/ML.svg b/public/assets/flags/ML.svg new file mode 100644 index 0000000..3a522a0 --- /dev/null +++ b/public/assets/flags/ML.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MM.svg b/public/assets/flags/MM.svg new file mode 100644 index 0000000..69db533 --- /dev/null +++ b/public/assets/flags/MM.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MN.svg b/public/assets/flags/MN.svg new file mode 100644 index 0000000..b9635cf --- /dev/null +++ b/public/assets/flags/MN.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MO.svg b/public/assets/flags/MO.svg new file mode 100644 index 0000000..790900e --- /dev/null +++ b/public/assets/flags/MO.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MP.svg b/public/assets/flags/MP.svg new file mode 100644 index 0000000..f0a5fb4 --- /dev/null +++ b/public/assets/flags/MP.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MQ.svg b/public/assets/flags/MQ.svg new file mode 100644 index 0000000..f705309 --- /dev/null +++ b/public/assets/flags/MQ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MR.svg b/public/assets/flags/MR.svg new file mode 100644 index 0000000..8335c8b --- /dev/null +++ b/public/assets/flags/MR.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MS.svg b/public/assets/flags/MS.svg new file mode 100644 index 0000000..04a1cc1 --- /dev/null +++ b/public/assets/flags/MS.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MT.svg b/public/assets/flags/MT.svg new file mode 100644 index 0000000..5538102 --- /dev/null +++ b/public/assets/flags/MT.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MU.svg b/public/assets/flags/MU.svg new file mode 100644 index 0000000..6c24981 --- /dev/null +++ b/public/assets/flags/MU.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MV.svg b/public/assets/flags/MV.svg new file mode 100644 index 0000000..b57be9c --- /dev/null +++ b/public/assets/flags/MV.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MW.svg b/public/assets/flags/MW.svg new file mode 100644 index 0000000..9b8ddf5 --- /dev/null +++ b/public/assets/flags/MW.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MX.svg b/public/assets/flags/MX.svg new file mode 100644 index 0000000..93d54c4 --- /dev/null +++ b/public/assets/flags/MX.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MY.svg b/public/assets/flags/MY.svg new file mode 100644 index 0000000..0480330 --- /dev/null +++ b/public/assets/flags/MY.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/MZ.svg b/public/assets/flags/MZ.svg new file mode 100644 index 0000000..cfa9577 --- /dev/null +++ b/public/assets/flags/MZ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/NA.svg b/public/assets/flags/NA.svg new file mode 100644 index 0000000..d2a79fd --- /dev/null +++ b/public/assets/flags/NA.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/NC.svg b/public/assets/flags/NC.svg new file mode 100644 index 0000000..e5dff93 --- /dev/null +++ b/public/assets/flags/NC.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/NE.svg b/public/assets/flags/NE.svg new file mode 100644 index 0000000..53f25f5 --- /dev/null +++ b/public/assets/flags/NE.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/NF.svg b/public/assets/flags/NF.svg new file mode 100644 index 0000000..990687f --- /dev/null +++ b/public/assets/flags/NF.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/NG.svg b/public/assets/flags/NG.svg new file mode 100644 index 0000000..6c6e31c --- /dev/null +++ b/public/assets/flags/NG.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/NI.svg b/public/assets/flags/NI.svg new file mode 100644 index 0000000..990868a --- /dev/null +++ b/public/assets/flags/NI.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/NL.svg b/public/assets/flags/NL.svg new file mode 100644 index 0000000..65e8be9 --- /dev/null +++ b/public/assets/flags/NL.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/NO.svg b/public/assets/flags/NO.svg new file mode 100644 index 0000000..4f5260a --- /dev/null +++ b/public/assets/flags/NO.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/NP.svg b/public/assets/flags/NP.svg new file mode 100644 index 0000000..5e5faaf --- /dev/null +++ b/public/assets/flags/NP.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/NR.svg b/public/assets/flags/NR.svg new file mode 100644 index 0000000..72485e7 --- /dev/null +++ b/public/assets/flags/NR.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/NU.svg b/public/assets/flags/NU.svg new file mode 100644 index 0000000..dd50901 --- /dev/null +++ b/public/assets/flags/NU.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/NZ.svg b/public/assets/flags/NZ.svg new file mode 100644 index 0000000..956a9d2 --- /dev/null +++ b/public/assets/flags/NZ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/OM.svg b/public/assets/flags/OM.svg new file mode 100644 index 0000000..29af825 --- /dev/null +++ b/public/assets/flags/OM.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/PA.svg b/public/assets/flags/PA.svg new file mode 100644 index 0000000..4fc55f5 --- /dev/null +++ b/public/assets/flags/PA.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/PE.svg b/public/assets/flags/PE.svg new file mode 100644 index 0000000..fc93b29 --- /dev/null +++ b/public/assets/flags/PE.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/PF.svg b/public/assets/flags/PF.svg new file mode 100644 index 0000000..333c6d0 --- /dev/null +++ b/public/assets/flags/PF.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/PG.svg b/public/assets/flags/PG.svg new file mode 100644 index 0000000..2d20ed8 --- /dev/null +++ b/public/assets/flags/PG.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/PH.svg b/public/assets/flags/PH.svg new file mode 100644 index 0000000..e9f011d --- /dev/null +++ b/public/assets/flags/PH.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/PK.svg b/public/assets/flags/PK.svg new file mode 100644 index 0000000..a718df6 --- /dev/null +++ b/public/assets/flags/PK.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/PL.svg b/public/assets/flags/PL.svg new file mode 100644 index 0000000..8169875 --- /dev/null +++ b/public/assets/flags/PL.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/PM.svg b/public/assets/flags/PM.svg new file mode 100644 index 0000000..dc55c02 --- /dev/null +++ b/public/assets/flags/PM.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/PN.svg b/public/assets/flags/PN.svg new file mode 100644 index 0000000..234f53f --- /dev/null +++ b/public/assets/flags/PN.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/PR.svg b/public/assets/flags/PR.svg new file mode 100644 index 0000000..f4c2ace --- /dev/null +++ b/public/assets/flags/PR.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/PS.svg b/public/assets/flags/PS.svg new file mode 100644 index 0000000..6ce8ec7 --- /dev/null +++ b/public/assets/flags/PS.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/PT.svg b/public/assets/flags/PT.svg new file mode 100644 index 0000000..c1d4a84 --- /dev/null +++ b/public/assets/flags/PT.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/PW.svg b/public/assets/flags/PW.svg new file mode 100644 index 0000000..043f7a5 --- /dev/null +++ b/public/assets/flags/PW.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/PY.svg b/public/assets/flags/PY.svg new file mode 100644 index 0000000..c8e83dc --- /dev/null +++ b/public/assets/flags/PY.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/QA.svg b/public/assets/flags/QA.svg new file mode 100644 index 0000000..f3e91d0 --- /dev/null +++ b/public/assets/flags/QA.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/RE.svg b/public/assets/flags/RE.svg new file mode 100644 index 0000000..ab1399f --- /dev/null +++ b/public/assets/flags/RE.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/RO.svg b/public/assets/flags/RO.svg new file mode 100644 index 0000000..33ac6ed --- /dev/null +++ b/public/assets/flags/RO.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/RS.svg b/public/assets/flags/RS.svg new file mode 100644 index 0000000..5c6c69e --- /dev/null +++ b/public/assets/flags/RS.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/RU.svg b/public/assets/flags/RU.svg new file mode 100644 index 0000000..46f74d5 --- /dev/null +++ b/public/assets/flags/RU.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/RW.svg b/public/assets/flags/RW.svg new file mode 100644 index 0000000..6175c02 --- /dev/null +++ b/public/assets/flags/RW.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SA.svg b/public/assets/flags/SA.svg new file mode 100644 index 0000000..d0d9580 --- /dev/null +++ b/public/assets/flags/SA.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SB.svg b/public/assets/flags/SB.svg new file mode 100644 index 0000000..a55ff60 --- /dev/null +++ b/public/assets/flags/SB.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SC.svg b/public/assets/flags/SC.svg new file mode 100644 index 0000000..40e42ea --- /dev/null +++ b/public/assets/flags/SC.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SD.svg b/public/assets/flags/SD.svg new file mode 100644 index 0000000..ddb60ba --- /dev/null +++ b/public/assets/flags/SD.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SE.svg b/public/assets/flags/SE.svg new file mode 100644 index 0000000..a039dc2 --- /dev/null +++ b/public/assets/flags/SE.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SG.svg b/public/assets/flags/SG.svg new file mode 100644 index 0000000..199e54e --- /dev/null +++ b/public/assets/flags/SG.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SH.svg b/public/assets/flags/SH.svg new file mode 100644 index 0000000..57d004d --- /dev/null +++ b/public/assets/flags/SH.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SI.svg b/public/assets/flags/SI.svg new file mode 100644 index 0000000..e25c04c --- /dev/null +++ b/public/assets/flags/SI.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SJ.svg b/public/assets/flags/SJ.svg new file mode 100644 index 0000000..4f5260a --- /dev/null +++ b/public/assets/flags/SJ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SK.svg b/public/assets/flags/SK.svg new file mode 100644 index 0000000..c4f7caf --- /dev/null +++ b/public/assets/flags/SK.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SL.svg b/public/assets/flags/SL.svg new file mode 100644 index 0000000..b08dd1d --- /dev/null +++ b/public/assets/flags/SL.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SM.svg b/public/assets/flags/SM.svg new file mode 100644 index 0000000..b53d00d --- /dev/null +++ b/public/assets/flags/SM.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SN.svg b/public/assets/flags/SN.svg new file mode 100644 index 0000000..c233472 --- /dev/null +++ b/public/assets/flags/SN.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SO.svg b/public/assets/flags/SO.svg new file mode 100644 index 0000000..293dd34 --- /dev/null +++ b/public/assets/flags/SO.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SR.svg b/public/assets/flags/SR.svg new file mode 100644 index 0000000..c483fb9 --- /dev/null +++ b/public/assets/flags/SR.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SS.svg b/public/assets/flags/SS.svg new file mode 100644 index 0000000..0aa63d7 --- /dev/null +++ b/public/assets/flags/SS.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/ST.svg b/public/assets/flags/ST.svg new file mode 100644 index 0000000..f2bb52a --- /dev/null +++ b/public/assets/flags/ST.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SV.svg b/public/assets/flags/SV.svg new file mode 100644 index 0000000..873310c --- /dev/null +++ b/public/assets/flags/SV.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SX.svg b/public/assets/flags/SX.svg new file mode 100644 index 0000000..2047243 --- /dev/null +++ b/public/assets/flags/SX.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SY.svg b/public/assets/flags/SY.svg new file mode 100644 index 0000000..5e32d2c --- /dev/null +++ b/public/assets/flags/SY.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/SZ.svg b/public/assets/flags/SZ.svg new file mode 100644 index 0000000..cb7f84a --- /dev/null +++ b/public/assets/flags/SZ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/TA.svg b/public/assets/flags/TA.svg new file mode 100644 index 0000000..547fa05 --- /dev/null +++ b/public/assets/flags/TA.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/TC.svg b/public/assets/flags/TC.svg new file mode 100644 index 0000000..3c61bc7 --- /dev/null +++ b/public/assets/flags/TC.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/TD.svg b/public/assets/flags/TD.svg new file mode 100644 index 0000000..d106ba8 --- /dev/null +++ b/public/assets/flags/TD.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/TF.svg b/public/assets/flags/TF.svg new file mode 100644 index 0000000..cf4bfac --- /dev/null +++ b/public/assets/flags/TF.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/TG.svg b/public/assets/flags/TG.svg new file mode 100644 index 0000000..4a05a30 --- /dev/null +++ b/public/assets/flags/TG.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/TH.svg b/public/assets/flags/TH.svg new file mode 100644 index 0000000..0bd4165 --- /dev/null +++ b/public/assets/flags/TH.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/TJ.svg b/public/assets/flags/TJ.svg new file mode 100644 index 0000000..6045f46 --- /dev/null +++ b/public/assets/flags/TJ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/TK.svg b/public/assets/flags/TK.svg new file mode 100644 index 0000000..bfa9362 --- /dev/null +++ b/public/assets/flags/TK.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/TL.svg b/public/assets/flags/TL.svg new file mode 100644 index 0000000..6030072 --- /dev/null +++ b/public/assets/flags/TL.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/TM.svg b/public/assets/flags/TM.svg new file mode 100644 index 0000000..a57c35c --- /dev/null +++ b/public/assets/flags/TM.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/TN.svg b/public/assets/flags/TN.svg new file mode 100644 index 0000000..c13e730 --- /dev/null +++ b/public/assets/flags/TN.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/TO.svg b/public/assets/flags/TO.svg new file mode 100644 index 0000000..20a9555 --- /dev/null +++ b/public/assets/flags/TO.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/TR.svg b/public/assets/flags/TR.svg new file mode 100644 index 0000000..861da57 --- /dev/null +++ b/public/assets/flags/TR.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/TT.svg b/public/assets/flags/TT.svg new file mode 100644 index 0000000..578c8eb --- /dev/null +++ b/public/assets/flags/TT.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/TV.svg b/public/assets/flags/TV.svg new file mode 100644 index 0000000..6558df6 --- /dev/null +++ b/public/assets/flags/TV.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/TW.svg b/public/assets/flags/TW.svg new file mode 100644 index 0000000..4cd304e --- /dev/null +++ b/public/assets/flags/TW.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/TZ.svg b/public/assets/flags/TZ.svg new file mode 100644 index 0000000..a9ddb8e --- /dev/null +++ b/public/assets/flags/TZ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/UA.svg b/public/assets/flags/UA.svg new file mode 100644 index 0000000..989b5c2 --- /dev/null +++ b/public/assets/flags/UA.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/UG.svg b/public/assets/flags/UG.svg new file mode 100644 index 0000000..6602ca9 --- /dev/null +++ b/public/assets/flags/UG.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/UM.svg b/public/assets/flags/UM.svg new file mode 100644 index 0000000..d51f600 --- /dev/null +++ b/public/assets/flags/UM.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/UN.svg b/public/assets/flags/UN.svg new file mode 100644 index 0000000..a035a76 --- /dev/null +++ b/public/assets/flags/UN.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/US.svg b/public/assets/flags/US.svg new file mode 100644 index 0000000..d51f600 --- /dev/null +++ b/public/assets/flags/US.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/UY.svg b/public/assets/flags/UY.svg new file mode 100644 index 0000000..796244c --- /dev/null +++ b/public/assets/flags/UY.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/UZ.svg b/public/assets/flags/UZ.svg new file mode 100644 index 0000000..b913772 --- /dev/null +++ b/public/assets/flags/UZ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/VA.svg b/public/assets/flags/VA.svg new file mode 100644 index 0000000..7b2bffa --- /dev/null +++ b/public/assets/flags/VA.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/VC.svg b/public/assets/flags/VC.svg new file mode 100644 index 0000000..fb97611 --- /dev/null +++ b/public/assets/flags/VC.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/VE.svg b/public/assets/flags/VE.svg new file mode 100644 index 0000000..294b5c6 --- /dev/null +++ b/public/assets/flags/VE.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/VG.svg b/public/assets/flags/VG.svg new file mode 100644 index 0000000..d8194cd --- /dev/null +++ b/public/assets/flags/VG.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/VI.svg b/public/assets/flags/VI.svg new file mode 100644 index 0000000..d0602d2 --- /dev/null +++ b/public/assets/flags/VI.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/VN.svg b/public/assets/flags/VN.svg new file mode 100644 index 0000000..4e0e1b5 --- /dev/null +++ b/public/assets/flags/VN.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/VU.svg b/public/assets/flags/VU.svg new file mode 100644 index 0000000..151e7aa --- /dev/null +++ b/public/assets/flags/VU.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/WF.svg b/public/assets/flags/WF.svg new file mode 100644 index 0000000..9895422 --- /dev/null +++ b/public/assets/flags/WF.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/WS.svg b/public/assets/flags/WS.svg new file mode 100644 index 0000000..6b075cb --- /dev/null +++ b/public/assets/flags/WS.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/XK.svg b/public/assets/flags/XK.svg new file mode 100644 index 0000000..39890a9 --- /dev/null +++ b/public/assets/flags/XK.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/YE.svg b/public/assets/flags/YE.svg new file mode 100644 index 0000000..a82532c --- /dev/null +++ b/public/assets/flags/YE.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/YT.svg b/public/assets/flags/YT.svg new file mode 100644 index 0000000..76765b9 --- /dev/null +++ b/public/assets/flags/YT.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/ZA.svg b/public/assets/flags/ZA.svg new file mode 100644 index 0000000..275c136 --- /dev/null +++ b/public/assets/flags/ZA.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/ZM.svg b/public/assets/flags/ZM.svg new file mode 100644 index 0000000..d276896 --- /dev/null +++ b/public/assets/flags/ZM.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/flags/ZW.svg b/public/assets/flags/ZW.svg new file mode 100644 index 0000000..15a8464 --- /dev/null +++ b/public/assets/flags/ZW.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/logo.png b/public/assets/logo.png new file mode 100644 index 0000000..76ba95b Binary files /dev/null and b/public/assets/logo.png differ diff --git a/public/assets/os-alma.svg b/public/assets/os-alma.svg new file mode 100644 index 0000000..c0528fc --- /dev/null +++ b/public/assets/os-alma.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/public/assets/os-alpine.webp b/public/assets/os-alpine.webp new file mode 100644 index 0000000..6ad3e4f Binary files /dev/null and b/public/assets/os-alpine.webp differ diff --git a/public/assets/os-arch.svg b/public/assets/os-arch.svg new file mode 100644 index 0000000..debdd89 --- /dev/null +++ b/public/assets/os-arch.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/os-centos.svg b/public/assets/os-centos.svg new file mode 100644 index 0000000..1b7ef70 --- /dev/null +++ b/public/assets/os-centos.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/public/assets/os-debian.svg b/public/assets/os-debian.svg new file mode 100644 index 0000000..c9b7d60 --- /dev/null +++ b/public/assets/os-debian.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/public/assets/os-fedora.svg b/public/assets/os-fedora.svg new file mode 100644 index 0000000..e227311 --- /dev/null +++ b/public/assets/os-fedora.svg @@ -0,0 +1,16 @@ + + + + + + + diff --git a/public/assets/os-gentoo.svg b/public/assets/os-gentoo.svg new file mode 100644 index 0000000..31953c0 --- /dev/null +++ b/public/assets/os-gentoo.svg @@ -0,0 +1,24 @@ + + +Gentoo Linux logo (matte) + + + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/os-istore.png b/public/assets/os-istore.png new file mode 100644 index 0000000..eda0048 Binary files /dev/null and b/public/assets/os-istore.png differ diff --git a/public/assets/os-kail.svg b/public/assets/os-kail.svg new file mode 100644 index 0000000..3c2e0c3 --- /dev/null +++ b/public/assets/os-kail.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/os-macos.svg b/public/assets/os-macos.svg new file mode 100644 index 0000000..9f66fcc --- /dev/null +++ b/public/assets/os-macos.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/public/assets/os-manjaro-.svg b/public/assets/os-manjaro-.svg new file mode 100644 index 0000000..829cbaa --- /dev/null +++ b/public/assets/os-manjaro-.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/public/assets/os-mint.svg b/public/assets/os-mint.svg new file mode 100644 index 0000000..2256f4b --- /dev/null +++ b/public/assets/os-mint.svg @@ -0,0 +1,18 @@ + + + + + + + + + + diff --git a/public/assets/os-nix.svg b/public/assets/os-nix.svg new file mode 100644 index 0000000..1cceefe --- /dev/null +++ b/public/assets/os-nix.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/os-openSUSE.svg b/public/assets/os-openSUSE.svg new file mode 100644 index 0000000..f458fd9 --- /dev/null +++ b/public/assets/os-openSUSE.svg @@ -0,0 +1,44 @@ + + + + + + + + + diff --git a/public/assets/os-openwrt.svg b/public/assets/os-openwrt.svg new file mode 100644 index 0000000..71a93b5 --- /dev/null +++ b/public/assets/os-openwrt.svg @@ -0,0 +1 @@ +OpenWrt \ No newline at end of file diff --git a/public/assets/os-proxmox.ico b/public/assets/os-proxmox.ico new file mode 100644 index 0000000..ba0c9af Binary files /dev/null and b/public/assets/os-proxmox.ico differ diff --git a/public/assets/os-redhat.svg b/public/assets/os-redhat.svg new file mode 100644 index 0000000..078b338 --- /dev/null +++ b/public/assets/os-redhat.svg @@ -0,0 +1,69 @@ + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/public/assets/os-rocky.svg b/public/assets/os-rocky.svg new file mode 100644 index 0000000..8c3d766 --- /dev/null +++ b/public/assets/os-rocky.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/os-synology.ico b/public/assets/os-synology.ico new file mode 100644 index 0000000..154f6b4 Binary files /dev/null and b/public/assets/os-synology.ico differ diff --git a/public/assets/os-ubuntu.svg b/public/assets/os-ubuntu.svg new file mode 100644 index 0000000..77adbbc --- /dev/null +++ b/public/assets/os-ubuntu.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/assets/os-windows.svg b/public/assets/os-windows.svg new file mode 100644 index 0000000..d0332d4 --- /dev/null +++ b/public/assets/os-windows.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/pwa-icon.png b/public/assets/pwa-icon.png new file mode 100644 index 0000000..d2db8b4 Binary files /dev/null and b/public/assets/pwa-icon.png differ diff --git a/src/components/Loading.css b/src/components/Loading.css new file mode 100644 index 0000000..e8fbfae --- /dev/null +++ b/src/components/Loading.css @@ -0,0 +1,77 @@ +.loader { + position: relative; + margin: 0 auto; + width: 100px; + height: 100px; +} +.loader:before { + content: ""; + display: block; + padding-top: 100%; +} + +.circular { + -webkit-animation: rotate 2s linear infinite; + animation: rotate 2s linear infinite; + height: 100%; + -webkit-transform-origin: center center; + transform-origin: center center; + width: 100%; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; +} + +.path { + stroke-dasharray: 1, 200; + stroke-dashoffset: 0; + -webkit-animation: dash 1.5s ease-in-out infinite; + animation: dash 1.5s ease-in-out infinite; + stroke-linecap: round; + stroke: #3b82f6; +} + +@-webkit-keyframes rotate { + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +@keyframes rotate { + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@-webkit-keyframes dash { + 0% { + stroke-dasharray: 1, 200; + stroke-dashoffset: 0; + } + 50% { + stroke-dasharray: 89, 200; + stroke-dashoffset: -35px; + } + 100% { + stroke-dasharray: 89, 200; + stroke-dashoffset: -124px; + } +} +@keyframes dash { + 0% { + stroke-dasharray: 1, 200; + stroke-dashoffset: 0; + } + 50% { + stroke-dasharray: 89, 200; + stroke-dashoffset: -35px; + } + 100% { + stroke-dasharray: 89, 200; + stroke-dashoffset: -124px; + } +} diff --git a/src/components/loading.tsx b/src/components/loading.tsx new file mode 100644 index 0000000..0073836 --- /dev/null +++ b/src/components/loading.tsx @@ -0,0 +1,34 @@ +import "./Loading.css"; + +type LoadingProps = { + text?: string; + children?: React.ReactNode; + size?: number; +}; + +const Loading = ({ text, children, size }: LoadingProps) => { + return ( +
+
+
+ + + +
+
+

Loading...

+

{text}

+
{children}
+
+ ); +}; + +export default Loading; diff --git a/src/components/sections/Flag.tsx b/src/components/sections/Flag.tsx new file mode 100644 index 0000000..b6b7353 --- /dev/null +++ b/src/components/sections/Flag.tsx @@ -0,0 +1,104 @@ +import * as React from "react"; +import { Box } from "@radix-ui/themes"; + +interface FlagProps { + flag: string; // 地区代码 (例如 "SG", "US") 或旗帜 emoji (例如 "🇸🇬", "🇺🇳") + size?: string; // 可选的尺寸 prop,用于未来扩展 +} + +/** + * 算法:将由两个区域指示符符号组成的 emoji 转换为对应的两字母国家代码。 + * 例如:🇸🇬 (由两个区域指示符组成) -> SG + * @param emoji 输入的 emoji 字符串 + * @returns 转换后的两字母国家代码(例如 "SG"),如果不是有效的旗帜 emoji 则返回 null。 + */ +const getCountryCodeFromFlagEmoji = (emoji: string): string | null => { + // 使用 Array.from() 来正确处理 Unicode 代理对,将 emoji 字符串拆分为逻辑上的字符数组。 + // 对于一个国家旗帜 emoji,chars 数组的长度将是 2 (每个元素是一个区域指示符字符)。 + const chars = Array.from(emoji); + + // 国家旗帜 emoji 应该由且仅由两个区域指示符字符组成 + if (chars.length !== 2) { + return null; + } + + // 获取两个区域指示符字符的 Unicode 码点 + const codePoint1 = chars[0].codePointAt(0)!; + const codePoint2 = chars[1].codePointAt(0)!; + + // 区域指示符符号的 Unicode 范围是从 U+1F1E6 (🇦) 到 U+1F1FF (🇿) + const REGIONAL_INDICATOR_START = 0x1f1e6; // 🇦 的 Unicode 码点 + const ASCII_ALPHA_START = 0x41; // A 的 ASCII 码点 + + // 检查两个码点是否都在区域指示符范围内 + if ( + codePoint1 >= REGIONAL_INDICATOR_START && + codePoint1 <= 0x1f1ff && + codePoint2 >= REGIONAL_INDICATOR_START && + codePoint2 <= 0x1f1ff + ) { + // 算法转换:通过计算与 'A' 对应的区域指示符的偏移量,将区域指示符码点转换回对应的 ASCII 字母码点 + const letter1 = String.fromCodePoint( + codePoint1 - REGIONAL_INDICATOR_START + ASCII_ALPHA_START + ); + const letter2 = String.fromCodePoint( + codePoint2 - REGIONAL_INDICATOR_START + ASCII_ALPHA_START + ); + return `${letter1}${letter2}`; + } + + return null; +}; + +const Flag = React.memo(({ flag, size }: FlagProps) => { + let imgSrc: string; + let altText: string; + let resolvedFlagFileName: string; // 最终用于构建文件名的字符串 (例如 "SG", "UN") + + // 1. **算法处理:** 尝试将输入作为由区域指示符组成的旗帜 emoji 进行转换 + const countryCodeFromEmoji = getCountryCodeFromFlagEmoji(flag); + + if (countryCodeFromEmoji) { + resolvedFlagFileName = countryCodeFromEmoji; // 例如,如果输入是 "🇸🇬",则这里得到 "SG" + } + // 2. **直接识别:** 如果不是区域指示符 emoji,检查是否是两字母的字母组合(ISO 国家代码) + else if (flag && flag.length === 2 && /^[a-zA-Z]{2}$/.test(flag)) { + resolvedFlagFileName = flag.toUpperCase(); // 例如,如果输入是 "us",则这里得到 "US" + } + // 3. **硬编码处理特殊 Emoji:** 对于无法通过算法转换的特殊 emoji(例如 🇺🇳, 🌐), + // 因为它们不符合区域指示符模式,且不使用映射表,只能通过硬编码来识别。 + else if (flag === "🇺🇳" || flag === "🌐") { + resolvedFlagFileName = "UN"; // 例如,如果输入是 "🇺🇳",则这里得到 "UN" + } + // 4. **回退:** 对于任何其他无法识别的输入(包括不符合上述规则的 emoji 或非两字母代码), + // 使用默认的 "UN" 旗帜作为回退。 + else { + resolvedFlagFileName = "UN"; + } + + // 构建本地图片路径 + imgSrc = `/assets/flags/${resolvedFlagFileName}.svg`; + // 构建 alt 文本和 aria-label + altText = `地区旗帜: ${resolvedFlagFileName}`; + + return ( + + {altText} + + ); +}); + +// 确保 displayName 以便在 React DevTools 中识别 +Flag.displayName = "Flag"; + +export default Flag; diff --git a/src/components/sections/Footer.tsx b/src/components/sections/Footer.tsx new file mode 100644 index 0000000..4b0413b --- /dev/null +++ b/src/components/sections/Footer.tsx @@ -0,0 +1,29 @@ +import React from "react"; + +const Footer: React.FC = () => { + return ( + + ); +}; + +export default Footer; diff --git a/src/components/sections/Header.tsx b/src/components/sections/Header.tsx new file mode 100644 index 0000000..f56f95a --- /dev/null +++ b/src/components/sections/Header.tsx @@ -0,0 +1,120 @@ +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { + Search, + Grid3X3, + Table2, + Moon, + Sun, + CircleUserIcon, +} from "lucide-react"; +import { useState } from "react"; +import { useLocation } from "react-router-dom"; +import { useIsMobile } from "@/hooks/useMobile"; + +interface HeaderProps { + viewMode: "card" | "list"; + setViewMode: (mode: "card" | "list") => void; + theme: string; + toggleTheme: () => void; + sitename: string; + searchTerm: string; + setSearchTerm: (term: string) => void; +} + +export const Header = ({ + viewMode, + setViewMode, + theme, + toggleTheme, + sitename, + searchTerm, + setSearchTerm, +}: HeaderProps) => { + const [isSearchOpen, setIsSearchOpen] = useState(false); + const location = useLocation(); + const isInstancePage = location.pathname.startsWith("/instance"); + const isMobile = useIsMobile(); + + return ( +
+
+
+ + {sitename} + +
+
+ {!isInstancePage && ( + <> + {isMobile ? ( + <> + {isSearchOpen && ( +
+ ) => + setSearchTerm(e.target.value) + } + /> +
+ )} + + ) : ( +
+ ) => + setSearchTerm(e.target.value) + } + /> +
+ )} + + + + )} + + + + +
+
+
+ ); +}; diff --git a/src/components/sections/NodeCard.tsx b/src/components/sections/NodeCard.tsx new file mode 100644 index 0000000..6d10adb --- /dev/null +++ b/src/components/sections/NodeCard.tsx @@ -0,0 +1,188 @@ +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { formatBytes, formatUptime, getOSImage } from "@/utils"; +import type { NodeWithStatus } from "@/types/node"; +import { Link } from "react-router-dom"; +import { CpuIcon, MemoryStickIcon, HardDriveIcon } from "lucide-react"; +import Flag from "./Flag"; +import { Tag } from "../ui/tag"; +import { useNodeCommons } from "@/hooks/useNodeCommons"; + +interface NodeCardProps { + node: NodeWithStatus; +} + +const ProgressBar = ({ + value, + className, +}: { + value: number; + className?: string; +}) => ( +
+
+
+); + +export const NodeCard = ({ node }: NodeCardProps) => { + const { + stats, + isOnline, + tagList, + cpuUsage, + memUsage, + swapUsage, + diskUsage, + load, + daysLeft, + } = useNodeCommons(node); + + const getProgressBarClass = (percentage: number) => { + if (percentage > 90) return "bg-red-600"; + if (percentage > 50) return "bg-yellow-400"; + return "bg-green-500"; + }; + + return ( + + +
+ + {node.os} + + {node.name} + +
+
+ +
+ +
+
+
+
+ + + {node.cpu_cores} Cores + +
+
+ + + {formatBytes(node.mem_total)} + +
+
+ + + {formatBytes(node.disk_total)} + +
+
+
+ CPU +
+ + {cpuUsage.toFixed(0)}% +
+
+
+ 内存 +
+ + {memUsage.toFixed(0)}% +
+
+ {node.swap_total > 0 ? ( +
+ SWAP +
+ + {swapUsage.toFixed(0)}% +
+
+ ) : ( +
+ SWAP +
+ + OFF +
+
+ )} +
+ 硬盘 +
+ + {diskUsage.toFixed(0)}% +
+
+
+
+ 网络 +
+ ↑ {stats ? formatBytes(stats.network.up, true) : "N/A"} + + ↓ {stats ? formatBytes(stats.network.down, true) : "N/A"} + +
+
+
+ 流量 +
+ ↑ {stats ? formatBytes(stats.network.totalUp) : "N/A"} + + ↓ {stats ? formatBytes(stats.network.totalDown) : "N/A"} + +
+
+
+ 负载 + {load} +
+
+
+ 到期 +
+ {daysLeft !== null && daysLeft > 36500 + ? "长期" + : node.expired_at + ? new Date(node.expired_at).toLocaleDateString() + : "N/A"} +
+
+
+
+ 在线 + + {isOnline && stats ? formatUptime(stats.uptime) : "离线"} + +
+
+
+
+ ); +}; diff --git a/src/components/sections/NodeListHeader.tsx b/src/components/sections/NodeListHeader.tsx new file mode 100644 index 0000000..79f947a --- /dev/null +++ b/src/components/sections/NodeListHeader.tsx @@ -0,0 +1,14 @@ +export const NodeListHeader = () => { + return ( +
+
节点名称
+
CPU
+
内存
+
SWAP
+
硬盘
+
网络
+
流量
+
负载
+
+ ); +}; diff --git a/src/components/sections/NodeListItem.tsx b/src/components/sections/NodeListItem.tsx new file mode 100644 index 0000000..d5890e6 --- /dev/null +++ b/src/components/sections/NodeListItem.tsx @@ -0,0 +1,112 @@ +import { formatBytes, formatUptime } from "@/utils"; +import type { NodeWithStatus } from "@/types/node"; +import { Link } from "react-router-dom"; +import { CpuIcon, MemoryStickIcon, HardDriveIcon } from "lucide-react"; +import Flag from "./Flag"; +import { Tag } from "../ui/tag"; +import { useNodeCommons } from "@/hooks/useNodeCommons"; + +interface NodeListItemProps { + node: NodeWithStatus; +} + +export const NodeListItem = ({ node }: NodeListItemProps) => { + const { + stats, + isOnline, + tagList, + cpuUsage, + memUsage, + swapUsage, + diskUsage, + load, + daysLeft, + } = useNodeCommons(node); + + return ( +
+
+ +
+
+ {node.name} +
+ +
+
+ 到期: +
+ {daysLeft !== null && daysLeft > 36500 + ? "长期" + : node.expired_at + ? new Date(node.expired_at).toLocaleDateString() + : "N/A"} +
+
+
+
+ 在线: + + {isOnline && stats ? formatUptime(stats.uptime) : "离线"} + +
+
+
+
+
+
+ + {node.cpu_cores} Cores +
+
+ {isOnline ? `${cpuUsage.toFixed(1)}%` : "N/A"} +
+
+
+
+ + {formatBytes(node.mem_total)} +
+
+ {isOnline ? `${memUsage.toFixed(1)}%` : "N/A"} +
+
+ {node.swap_total > 0 ? ( +
+ {isOnline ? `${swapUsage.toFixed(1)}%` : "N/A"} +
+ ) : ( +
OFF
+ )} +
+
+ + {formatBytes(node.disk_total)} +
+
+ {isOnline ? `${diskUsage.toFixed(1)}%` : "N/A"} +
+
+
+ + ↑ {stats ? formatBytes(stats.network.up, true) : "N/A"}↓{" "} + {stats ? formatBytes(stats.network.down, true) : "N/A"} + +
+
+ + ↑ {stats ? formatBytes(stats.network.totalUp) : "N/A"}↓{" "} + {stats ? formatBytes(stats.network.totalDown) : "N/A"} + +
+
+ {load} +
+
+ ); +}; diff --git a/src/components/sections/StatsBar.tsx b/src/components/sections/StatsBar.tsx new file mode 100644 index 0000000..f707ad2 --- /dev/null +++ b/src/components/sections/StatsBar.tsx @@ -0,0 +1,186 @@ +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { Settings2 } from "lucide-react"; +import { Switch } from "@/components/ui/switch"; +import { Button } from "@/components/ui/button"; +import { formatBytes } from "@/utils"; + +interface StatsBarProps { + displayOptions: { + time: boolean; + online: boolean; + regions: boolean; + traffic: boolean; + speed: boolean; + }; + setDisplayOptions: (options: any) => void; + stats: { + onlineCount: number; + totalCount: number; + uniqueRegions: number; + totalTrafficUp: number; + totalTrafficDown: number; + currentSpeedUp: number; + currentSpeedDown: number; + }; + loading: boolean; + currentTime: Date; +} + +export const StatsBar = ({ + displayOptions, + setDisplayOptions, + stats, + loading, + currentTime, +}: StatsBarProps) => { + return ( +
+
+ + + + + + 状态显示设置 + + + 当前时间 + + setDisplayOptions({ ...displayOptions, time: checked }) + } + /> + + + 当前在线 + + setDisplayOptions({ ...displayOptions, online: checked }) + } + /> + + + 点亮地区 + + setDisplayOptions({ ...displayOptions, regions: checked }) + } + /> + + + 流量概览 + + setDisplayOptions({ ...displayOptions, traffic: checked }) + } + /> + + + 网络速率 + + setDisplayOptions({ ...displayOptions, speed: checked }) + } + /> + + + +
+
+ {displayOptions.time && ( +
+
+ + +
+
+ )} + {displayOptions.online && ( +
+
+ + +
+
+ )} + {displayOptions.regions && ( +
+
+ + +
+
+ )} + {displayOptions.traffic && ( +
+
+ +
+ {loading ? ( + "..." + ) : ( +
+ {`↑ ${formatBytes(stats.totalTrafficUp)}`} + {`↓ ${formatBytes(stats.totalTrafficDown)}`} +
+ )} +
+
+
+ )} + {displayOptions.speed && ( +
+
+ +
+ {loading ? ( + "..." + ) : ( +
+ {`↑ ${formatBytes(stats.currentSpeedUp)}/s`} + {`↓ ${formatBytes(stats.currentSpeedDown)}/s`} +
+ )} +
+
+
+ )} +
+
+ ); +}; diff --git a/src/components/ui/avatar.tsx b/src/components/ui/avatar.tsx new file mode 100644 index 0000000..52026ca --- /dev/null +++ b/src/components/ui/avatar.tsx @@ -0,0 +1,48 @@ +import * as React from "react"; +import * as AvatarPrimitive from "@radix-ui/react-avatar"; + +import { cn } from "@/utils"; + +const Avatar = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +Avatar.displayName = AvatarPrimitive.Root.displayName; + +const AvatarImage = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AvatarImage.displayName = AvatarPrimitive.Image.displayName; + +const AvatarFallback = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName; + +export { Avatar, AvatarImage, AvatarFallback }; diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx new file mode 100644 index 0000000..0d90cd5 --- /dev/null +++ b/src/components/ui/button.tsx @@ -0,0 +1,60 @@ +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { cva, type VariantProps } from "class-variance-authority"; + +import { cn } from "@/utils"; + +const buttonVariants = cva( + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", + { + variants: { + variant: { + default: + "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90", + destructive: + "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", + outline: + "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", + secondary: + "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80", + ghost: + "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-9 px-4 py-2 has-[>svg]:px-3", + sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5", + lg: "h-10 rounded-md px-6 has-[>svg]:px-4", + icon: "size-9", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +); + +function Button({ + className, + variant, + size, + asChild = false, + ...props +}: React.ComponentProps<"button"> & + VariantProps & { + asChild?: boolean; + }) { + const Comp = asChild ? Slot : "button"; + + return ( + + ); +} + +// eslint-disable-next-line react-refresh/only-export-components +export { Button, buttonVariants }; diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx new file mode 100644 index 0000000..ec7bb22 --- /dev/null +++ b/src/components/ui/card.tsx @@ -0,0 +1,83 @@ +import * as React from "react"; + +import { cn } from "@/utils"; + +const Card = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)); +Card.displayName = "Card"; + +const CardHeader = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)); +CardHeader.displayName = "CardHeader"; + +const CardTitle = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)); +CardTitle.displayName = "CardTitle"; + +const CardDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)); +CardDescription.displayName = "CardDescription"; + +const CardContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)); +CardContent.displayName = "CardContent"; + +const CardFooter = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)); +CardFooter.displayName = "CardFooter"; + +export { + Card, + CardHeader, + CardFooter, + CardTitle, + CardDescription, + CardContent, +}; diff --git a/src/components/ui/chart.tsx b/src/components/ui/chart.tsx new file mode 100644 index 0000000..d83b953 --- /dev/null +++ b/src/components/ui/chart.tsx @@ -0,0 +1,351 @@ +"use client"; + +import * as React from "react"; +import * as RechartsPrimitive from "recharts"; + +import { cn } from "@/utils"; + +// Format: { THEME_NAME: CSS_SELECTOR } +const THEMES = { light: "", dark: ".dark" } as const; + +export type ChartConfig = { + [k in string]: { + label?: React.ReactNode; + icon?: React.ComponentType; + } & ( + | { color?: string; theme?: never } + | { color?: never; theme: Record } + ); +}; + +type ChartContextProps = { + config: ChartConfig; +}; + +const ChartContext = React.createContext(null); + +function useChart() { + const context = React.useContext(ChartContext); + + if (!context) { + throw new Error("useChart must be used within a "); + } + + return context; +} + +function ChartContainer({ + id, + className, + children, + config, + ...props +}: React.ComponentProps<"div"> & { + config: ChartConfig; + children: React.ComponentProps< + typeof RechartsPrimitive.ResponsiveContainer + >["children"]; +}) { + const uniqueId = React.useId(); + const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`; + + return ( + +
+ + + {children} + +
+
+ ); +} + +const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => { + const colorConfig = Object.entries(config).filter( + ([, config]) => config.theme || config.color + ); + + if (!colorConfig.length) { + return null; + } + + return ( +