diff --git a/.github/demo/stage-profile.gif b/.github/demo/stage-profile.gif new file mode 100644 index 0000000..c2a4664 Binary files /dev/null and b/.github/demo/stage-profile.gif differ diff --git a/.github/demo/url-audit.gif b/.github/demo/url-audit.gif new file mode 100644 index 0000000..0e8119a Binary files /dev/null and b/.github/demo/url-audit.gif differ diff --git a/README.md b/README.md index 239b23d..0deef1e 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,21 @@ Built with Astro + React islands + Tailwind CSS v4, deployed on Vercel. > 🔗 **Live demo:** [tiglet.vercel.app](https://tiglet.vercel.app) Almost everything runs entirely in your browser. No accounts, no cookies, no ads — -your input never leaves your device. (The exceptions: the currency converter fetches -public exchange rates, and anonymous page views are counted; see [Privacy](#privacy).) +your input never leaves your device. (The exceptions: a few tools fetch public data +like exchange rates or official lottery numbers, and anonymous page views are counted; +see [Privacy](#privacy).) + +## See it in ten seconds + +**Stage Profile** — drop in a GPX and get a Tour-style stage chart: hover readout, +auto-categorized climbs, and switchable export themes (including midnight dark): + +![Stage Profile demo](.github/demo/stage-profile.gif) + +**URL Audit** — paste a URL and get an SEO / social-card / AI-readiness score with a +simulated share preview (here it is auditing one of its own pages — 100/100): + +![URL Audit demo](.github/demo/url-audit.gif) ## Features @@ -21,8 +34,8 @@ public exchange rates, and anonymous page views are counted; see [Privacy](#priv - **Shareable deep links** — tool state lives in the URL (e.g. the wheel's options) - **Playful, accessible animations** — dice tumble in 3D, the wheel decelerates, the timer ring drains, the raffle reels, 2048 tiles pop; all respect `prefers-reduced-motion` -- **SEO-ready** — canonical URLs, Open Graph / Twitter cards, JSON-LD, and an auto-generated sitemap -- **Installable PWA** — add to your home screen and use it offline +- **SEO-ready** — canonical URLs, per-tool bilingual Open Graph share cards (66+ pre-rendered PNGs), JSON-LD, and an auto-generated sitemap +- **Installable PWA** — add to your home screen, use it offline, and share / open route files straight into Stage Profile ## Tools @@ -31,7 +44,7 @@ public exchange rates, and anonymous page views are counted; see [Privacy](#priv | Calculators | **Calculator** | Four-function calculator with keyboard input | | Calculators | **Text Calculator** | Type an expression, get the result (safe parser — no `eval`) | | Calculators | **Converter** | Unit conversion (length, mass, temperature, area incl. _ping_, volume, speed, data) plus live currency conversion | -| Calculators | **Everyday Calc** | BMI (Taiwan HPA bands), percentage helpers, discounts, and tip-splitting — in tabs | +| Calculators | **Everyday Calc** | BMI (Taiwan HPA bands), percentage helpers, discounts, tip-splitting, and Chinese uppercase amounts — in tabs | | Calculators | **World Clock** | Live multi-city clocks with DST-aware offsets, time differences, and a from-zone → to-zone time projection | | Calculators | **Date Calculator** | Date differences, date projection (with month-end clamping), shareable countdowns, and workday counting | | Games | **Tic-Tac-Toe** | Two-player or vs. an unbeatable computer (minimax) | @@ -40,20 +53,24 @@ public exchange rates, and anonymous page views are counted; see [Privacy](#priv | Games | **Snake** | The classic — eat to grow, avoid the walls and yourself; keyboard or on-screen D-pad | | Random | **Decision Wheel** | Spin a wheel of options; share the options via the URL | | Random | **Name Raffle** | Draw winners from a list or an imported **Excel / CSV** file, with per-prize rounds | -| Utilities | **Timer** | Countdown (with presets) and stopwatch, with a progress ring and a beep on finish | +| Utilities | **Timer** | Countdown (with presets), stopwatch, and interval training mode, with a progress ring and a beep on finish | | Utilities | **Dice** | Roll any number of 3D d4–d20 dice (real pip faces for d6), total them, keep a roll history | -| Utilities | **QR Code** | Turn text or a URL into a downloadable QR code | +| Utilities | **QR Code** | Turn text, URLs, WiFi credentials, or a vCard business card into a downloadable QR code | +| Utilities | **QR Scanner** | Scan QR codes from your camera or an image (click / drag / paste) — URLs, WiFi and vCards parsed into structured fields; decoded entirely in your browser | | Utilities | **Password Generator** | Customizable, ambiguity-free random passwords (Web Crypto CSPRNG) with a strength meter | | Utilities | **Color Converter** | Convert between HEX / RGB / HSL live, with a picker and one-tap copy | | Utilities | **Color Extractor** | Upload an image and pull out its dominant colors (median cut), copyable as HEX/RGB | -| Utilities | **Image Studio** | Compress, resize, and convert (JPEG / PNG / WebP) with a before/after comparison | +| Utilities | **Image Studio** | Compress, resize, convert (JPEG / PNG / WebP), and inspect / strip EXIF metadata, with a before/after comparison | | Utilities | **Taiwan ID Validator** | Checksum validation for Taiwan national IDs and business numbers (2023 rule), with test-number generators | | Utilities | **URL Audit** | Paste a URL to score its SEO, Open Graph social cards and GEO (AI-engine) readiness, with a simulated FB/X/LINE share-card preview and concrete fixes; the page HTML is fetched through a stateless proxy, then analyzed in your browser | +| Utilities | **Invoice Lottery** | Check Taiwan uniform-invoice numbers against the latest official draw — type the last 3 digits for an instant verdict, keep typing to confirm the prize tier; numbers are matched locally | +| Utilities | **Fuel Prices (TW)** | Today's CPC Taiwan pump prices (92/95/98, diesel, LPG) with this week's adjustment and a liters ⇄ amount fill-up calculator | +| Utilities | **PDF Studio** | Merge (with reordering), split by page ranges, and rotate PDFs — files never leave your browser | | Cycling | **Gear Calculator** | Road-bike drivetrain math — gear ratio matrix, cadence→speed tables, A/B setup comparison, and derailleur capacity check, all shareable via URL | | Cycling | **Ride Fuel** | Convert your bike computer's kJ into kcal burned and food equivalents, with carbs-per-hour fueling and sweat-rate hydration guidance | | Cycling | **FTP Zones** | Coggan 7-zone power table with sweet spot, W/kg level reference, and heart-rate zones (LTHR or max-HR method) | | Cycling | **Tire Pressure** | Front/rear pressure suggestion (psi + bar) from weight, tire width, tubeless and surface, with a hookless-limit warning | -| Cycling | **Stage Profile** | Upload a GPX / FIT / TCX (or drag-drop) and get a Tour-style stage profile — climbs auto-detected and categorized (HC–Cat 4), gradient stats, downloadable as PNG; parsed entirely in your browser | +| Cycling | **Stage Profile** | Upload a GPX / FIT / TCX (or drag-drop) and get a Tour-style stage profile — climbs auto-detected and categorized (HC–Cat 4), waypoints, per-km climb detail, five export themes (incl. midnight dark), shareable links, PNG / IG-story export; parsed entirely in your browser | | Text | **Word Count** | Live character / CJK / word / line / paragraph counts with reading-time estimate, Chinese and English counted separately | | Text | **Encoder** | Two-way Base64 (UTF-8 safe), URL percent-encoding, and HTML entities conversion with one-tap copy | | Text | **Text Diff** | Line-level LCS diff with inline character highlighting — zero dependencies | @@ -66,13 +83,13 @@ public exchange rates, and anonymous page views are counted; see [Privacy](#priv - **[Astro](https://astro.build)** — static output, near-zero JS on the home page - **React** — one interactive island per tool, hydrated lazily (`client:visible` / `client:idle`) - **Tailwind CSS v4** — design tokens via `@tailwindcss/vite` -- **Vitest** — unit tests for every tool's core logic (230+ specs) -- **Playwright** — E2E smoke tests for key flows (deep links, Excel/CSV import, ⌘K palette), run in CI +- **Vitest** — unit tests for every tool's core logic (550+ specs) +- **Playwright** — 65 E2E specs for key flows (deep links, file uploads, ⌘K palette, i18n, serverless-backed tools with stubbed APIs), run in CI - **[@astrojs/sitemap](https://docs.astro.build/en/guides/integrations-guide/sitemap/)** — sitemap generated at build time - **[@vite-pwa/astro](https://vite-pwa-org.netlify.app)** — manifest + service worker - **Web platform APIs** — Canvas for the image/color tools, Web Crypto for password generation, `Intl` for time zones -- Client-side **SheetJS** (`xlsx`), **`qrcode`**, and **`marked` + `DOMPurify`** (Markdown preview), all dynamically imported +- Client-side **SheetJS** (`xlsx`), **`qrcode`** / **`jsqr`**, **`pdf-lib`**, and **`marked` + `DOMPurify`** (Markdown preview), all loaded per tool ## Getting started @@ -134,15 +151,18 @@ command and output directory, and `.npmrc` keeps installs reproducible. Every page is prerendered; there is no SSR adapter. The one exception is `api/`, a directory of standalone Vercel serverless functions that Vercel picks up -alongside the static output. Today it holds a single function, `fetch-meta`, -which URL Audit uses to fetch a page's HTML (the browser can't, because of CORS). -Functions here must stay stateless — no database, no logging of user input. +alongside the static output. Today it holds three functions: `fetch-meta` +(URL Audit's HTML fetcher, with an SSRF guard), `invoice-numbers` (relays the +Ministry of Finance's official uniform-invoice draw), and `fuel-price` (relays +CPC's public price feed). Functions here must stay stateless — no database, +no logging of user input — and every change to `api/` is verified against the +real deployment before it ships. ## Privacy Tiglet is almost entirely client-side — no login, no cookies, no ads. The raffle's Excel -import, the QR generator, the image compressor/resizer, the color extractor, and every -other tool process your data locally in the browser and upload nothing. +import, the QR generator and scanner, the image and PDF tools, the color extractor, and +every other tool process your data locally in the browser and upload nothing. The few exceptions are all stateless — nothing you send is stored: @@ -153,6 +173,9 @@ The few exceptions are all stateless — nothing you send is stored: (`/api/fetch-meta`) that fetches the page's HTML and returns it for in-browser analysis. The function stores nothing and keeps no logs of the URL; it also refuses internal/reserved addresses (SSRF guard). +- **Invoice Lottery** and **Fuel Prices** fetch official public data (the Ministry of + Finance's winning numbers, CPC's price feed) through stateless relay functions. + Your invoice digits are matched locally — they are never sent anywhere. - **Vercel Web Analytics** collects anonymous, cookie-less page-view counts (no personal data, no cross-site tracking, nothing you type is ever sent). diff --git a/README.zh-TW.md b/README.zh-TW.md index 1664fe5..88d9af4 100644 --- a/README.zh-TW.md +++ b/README.zh-TW.md @@ -8,8 +8,20 @@ > 🔗 **線上展示:** [tiglet.vercel.app](https://tiglet.vercel.app) 幾乎所有功能都完全在你的瀏覽器裡執行。沒有帳號、沒有 cookie、沒有廣告—— -你的輸入不會離開你的裝置。(例外:匯率換算會抓取公開匯率,以及匿名的 -頁面瀏覽統計;詳見[隱私](#隱私)。) +你的輸入不會離開你的裝置。(例外:少數工具會抓取匯率、發票開獎號碼等公開資料, +以及匿名的頁面瀏覽統計;詳見[隱私](#隱私)。) + +## 十秒鐘看懂 + +**賽段剖面圖**——丟進 GPX 就生成環法風賽段圖:游標讀數、爬坡自動分級、 +可切換出圖主題(含午夜黑深色): + +![賽段剖面圖示範](.github/demo/stage-profile.gif) + +**網址健檢**——貼上網址,評 SEO/社群分享卡/AI 引擎就緒度並模擬分享預覽 +(示範裡掃的是它自己的工具頁——100 分滿分): + +![網址健檢示範](.github/demo/url-audit.gif) ## 特色 @@ -21,8 +33,8 @@ - **可分享的深連結**——工具狀態存在網址裡(例如輪盤的選項) - **有趣且無障礙的動畫**——骰子 3D 翻滾、輪盤減速、計時環倒數、 抽獎跑馬燈、2048 方塊彈出;全部尊重 `prefers-reduced-motion` -- **SEO 就緒**——canonical 網址、Open Graph / Twitter 卡片、JSON-LD、自動生成 sitemap -- **可安裝的 PWA**——加到主畫面,離線也能用 +- **SEO 就緒**——canonical 網址、每個工具中英各一張的 Open Graph 分享卡(66+ 張預先生成的 PNG)、JSON-LD、自動生成 sitemap +- **可安裝的 PWA**——加到主畫面、離線也能用,還能把路線檔直接「分享到」賽段剖面圖開啟 ## 工具 @@ -31,7 +43,7 @@ | 計算 | **計算機** | 支援鍵盤輸入的四則運算計算機 | | 計算 | **文字計算機** | 輸入算式文字,立即得到結果(安全解析器——不用 `eval`) | | 計算 | **換算器** | 單位換算(長度、質量、溫度、含「坪」的面積、體積、速度、資料量)加上即時匯率換算 | -| 計算 | **生活計算** | BMI(衛福部國健署標準)、百分比、折扣、小費分帳——分頁整合 | +| 計算 | **生活計算** | BMI(衛福部國健署標準)、百分比、折扣、小費分帳、中文大寫金額——分頁整合 | | 計算 | **世界時鐘** | 各地即時時間(含日光節約)、時差對照、跨時區時間推算 | | 計算 | **日期計算器** | 日期差、日期推算(含月底夾住)、可分享的倒數日、工作天計算 | | 遊戲 | **井字遊戲** | 雙人對戰,或挑戰不會輸的電腦(minimax) | @@ -40,20 +52,24 @@ | 遊戲 | **貪食蛇** | 經典款——吃食物變長,別撞牆或咬到自己;鍵盤或螢幕方向鍵 | | 隨機決定 | **決定輪盤** | 輸入選項轉一下,讓命運決定;選項可透過網址分享 | | 隨機決定 | **名單抽獎** | 從清單或匯入的 **Excel / CSV** 檔抽出中獎者,支援多輪多獎項 | -| 實用工具 | **計時器** | 倒數計時(含預設值)與碼錶,附進度環與結束提示音 | +| 實用工具 | **計時器** | 倒數計時(含預設值)、碼錶與間歇訓練模式,附進度環與結束提示音 | | 實用工具 | **擲骰子** | 擲任意數量的 3D d4–d20 骰子(d6 有真實點數面),加總並保留歷史 | -| 實用工具 | **QR 產生器** | 把文字或網址轉成可下載的 QR 碼 | +| 實用工具 | **QR 產生器** | 把文字、網址、WiFi 或名片(vCard)轉成可下載的 QR 碼 | +| 實用工具 | **QR 掃描** | 相機或圖片(點選/拖放/貼上)掃描 QR 碼——網址、WiFi、名片解析成結構化欄位;完全在瀏覽器本機解碼 | | 實用工具 | **密碼產生器** | 可自訂、排除易混淆字元的隨機密碼(Web Crypto CSPRNG),附強度計 | | 實用工具 | **色彩轉換器** | HEX / RGB / HSL 即時互轉,附取色器與一鍵複製 | | 實用工具 | **圖片取色** | 上傳圖片,取出主要色彩(中位切分法),可複製 HEX/RGB | -| 實用工具 | **圖片工具** | 壓縮、縮放、格式轉換(JPEG / PNG / WebP),附前後對比 | +| 實用工具 | **圖片工具** | 壓縮、縮放、格式轉換(JPEG / PNG / WebP)與 EXIF 檢視/清除,附前後對比 | | 實用工具 | **台灣證號** | 身分證字號與統一編號檢查碼驗證(統編採 112 年新制),附開發測試用號碼產生器 | | 實用工具 | **網址健檢** | 貼上網址,評分它的 SEO、Open Graph 社群分享卡與 GEO(AI 引擎)設定,附 FB/X/LINE 分享卡模擬預覽與具體優化建議;網頁 HTML 經無狀態代理抓取後在你的瀏覽器分析 | +| 實用工具 | **發票對獎** | 對照財政部最新開獎號碼——輸入末 3 碼立刻知道有沒有中,續輸到 8 碼確認獎級;號碼比對在本機進行 | +| 實用工具 | **中油油價** | 中油今日牌價(92/95/98、超級柴油、液化石油氣)與本週調價,附公升 ⇄ 金額加油試算 | +| 實用工具 | **PDF 工具** | 合併(可排序)、依頁碼範圍拆分、旋轉 PDF——檔案不離開瀏覽器 | | 單車 | **齒比計算器** | 公路車傳動計算——齒比表、迴轉速時速對照、A/B 設定比較、變速器容量檢查,設定可透過網址分享 | | 單車 | **騎乘熱量** | 把碼錶的 kJ 換算成消耗大卡與等值食物,附每小時碳水補給與排汗率補水建議 | | 單車 | **FTP 訓練區間** | Coggan 功率七區與 Sweet Spot、W/kg 推力比等級參考、心率五區(LTHR 或最大心率法) | | 單車 | **胎壓建議** | 依體重、胎寬、內胎/無內胎與路面條件計算前後輪建議胎壓(psi+bar),附 hookless 上限提醒 | -| 單車 | **賽段剖面圖** | 上傳 GPX/FIT/TCX(或直接拖曳)生成環法風格賽段剖面圖——自動偵測爬坡並分級(HC~四級)、坡度分布與最陡路段,一鍵下載 PNG;完全在瀏覽器本機解析 | +| 單車 | **賽段剖面圖** | 上傳 GPX/FIT/TCX(或直接拖曳)生成環法風格賽段剖面圖——爬坡自動分級(HC~四級)、地標航點、每 km 爬坡細部圖、五種出圖主題(含午夜黑)、可分享連結、PNG/IG 限動輸出;完全在瀏覽器本機解析 | | 文字 | **字數統計** | 字元、中文字數、英文單字、行數、段落與預估閱讀時間即時統計,中英文分開計算 | | 文字 | **編解碼工具** | Base64(UTF-8 安全)、URL 百分比編碼、HTML entities 雙向轉換,一鍵複製 | | 文字 | **文字比對** | 行級 LCS 差異比對加行內字元級高亮——零依賴 | @@ -66,12 +82,12 @@ - **[Astro](https://astro.build)**——靜態輸出,首頁近乎零 JS - **React**——每個工具一個互動島嶼,延遲 hydrate(`client:visible` / `client:idle`) - **Tailwind CSS v4**——透過 `@tailwindcss/vite` 管理設計 token -- **Vitest**——每個工具的核心邏輯都有單元測試(230+ 條) -- **Playwright**——關鍵流程的 E2E 冒煙測試(深連結、Excel/CSV 匯入、⌘K 面板),在 CI 執行 +- **Vitest**——每個工具的核心邏輯都有單元測試(550+ 條) +- **Playwright**——65 條 E2E 測試(深連結、檔案上傳、⌘K 面板、雙語、雲端函式工具的 stub 測試),在 CI 執行 - **[@astrojs/sitemap](https://docs.astro.build/en/guides/integrations-guide/sitemap/)**——建置時生成 sitemap - **[@vite-pwa/astro](https://vite-pwa-org.netlify.app)**——manifest + service worker - **Web 平台 API**——圖片/色彩工具用 Canvas、密碼生成用 Web Crypto、時區用 `Intl` -- 前端 **SheetJS**(`xlsx`)、**`qrcode`** 與 **`marked` + `DOMPurify`**(Markdown 預覽),皆為動態載入 +- 前端 **SheetJS**(`xlsx`)、**`qrcode`**/**`jsqr`**、**`pdf-lib`** 與 **`marked` + `DOMPurify`**(Markdown 預覽),皆按工具載入 ## 開始使用 @@ -132,13 +148,15 @@ Vercel 自動偵測 Astro。`vercel.json` 固定建置指令與輸出目錄, 所有頁面皆為預先渲染,沒有 SSR adapter。唯一的例外是 `api/`—— 一個獨立的 Vercel 雲端函式目錄,Vercel 會在靜態輸出之外一併編譯它。 -目前只有一支 `fetch-meta`,供網址健檢抓取目標頁的 HTML(瀏覽器因 CORS 無法直接抓)。 -這裡的函式必須維持無狀態——不接資料庫、不記錄使用者輸入。 +目前有三支:`fetch-meta`(網址健檢的 HTML 抓取代理,含 SSRF 防護)、 +`invoice-numbers`(轉發財政部統一發票開獎號碼)、`fuel-price`(轉發中油公開牌價)。 +這裡的函式必須維持無狀態——不接資料庫、不記錄使用者輸入——而且每次動到 +`api/` 都會在真實部署上驗證過才算完成。 ## 隱私 Tiglet 幾乎完全在前端運作——無登入、無 cookie、無廣告。抽獎的 Excel 匯入、 -QR 產生器、圖片壓縮/縮放、圖片取色,以及其他所有工具,都在你的瀏覽器本機 +QR 產生與掃描、圖片與 PDF 工具、圖片取色,以及其他所有工具,都在你的瀏覽器本機 處理資料,不會上傳任何東西。 少數例外都是「無狀態」的——你送出的內容一律不儲存: @@ -148,6 +166,8 @@ QR 產生器、圖片壓縮/縮放、圖片取色,以及其他所有工具 - **網址健檢**會把你輸入的網址送到一支無狀態的雲端函式(`/api/fetch-meta`), 由它抓取該頁 HTML 回傳給瀏覽器分析。函式不儲存任何資料、不記錄網址, 並會拒絕內網/保留位址(SSRF 防護)。 +- **發票對獎**與**中油油價**透過無狀態轉發函式抓取官方公開資料 + (財政部開獎號碼、中油牌價)。你的發票號碼在本機比對,不會送到任何地方。 - **Vercel Web Analytics** 匿名、無 cookie 的頁面瀏覽統計 (無個資、無跨站追蹤,你輸入的任何內容都不會被送出)。