TreeMap
무료 오픈소스 디스크 사용량 시각화 도구로, 사각형 트리맵·중복 파일 탐색·디스크 가득 예측·정리 시 파일을 휴지통으로만 이동한다
두 개를 비교해가며 순위를 매겨 자동으로 순위가 완성됩니다. 텍스트·이미지·색상 모두 가능, 무료이며 계정 필요 없음
Rank anything by pairwise comparison: pick the better of two, duel after duel, and the ranking builds itself. Text, images or colors. Free, no account.
생산성TypeScript · CSSGitHub @CostardRouge온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Rank anything by comparing two items at a time. Add text, images or colors, pick your favorite in each duel (buttons, keyboard or swipe), and let the ranking emerge. Live: https://versus.steevepommier.com/ (en français; the app itself is at /app/), also on https://costardrouge.github.io/versus/, without publishingREADME 전문 보기 ↗
Rank anything by comparing two items at a time. Add text, images or colors, pick your favorite in each duel (buttons, keyboard or swipe), and let the ranking emerge.
Live: https://versus.steevepommier.com/ (en français; the app itself is at /app/), also on https://costardrouge.github.io/versus/, without publishing
← A, → B, ↓ tie, S skip, ⌘/Ctrl+Z undo) or swipe.| Method | Algorithm | Best for |
|---|---|---|
| Balanced (default) | Bradley-Terry, fitted on all duels at once, with a ± margin per item | Photos, products, anything that doesn't change |
| Dynamic | Elo, duel by duel | Preferences that evolve over time |
| Simple | Smoothed win rate | Readability |
| Exact sort | Binary insertion sort | Settling a short list in the fewest duels |
llms.txt, all generated from one file (see docs/seo.md).docs/pwa.md).localStorage); only what you publish is sent. Visits are counted with a self-hosted, cookie-free Umami, never loaded for visitors who decline (a switch on the legal notice, Do Not Track, Global Privacy Control), and never with a ranking's content or id (see docs/analytics.md).docs/published-boards.md.docs/published-boards.md#notifications)./admin/ lists boards with their reports, hides or features them, removes items and takes boards down (see docs/published-boards.md#moderation)./t/<slug>/, /fr/t/<slug>/) listed in the sitemap once it has a crowd; the gallery's Popular section shows them with the boards the publisher put forward, to vote or start one's own ranking from.Requires Node.js 22 or newer; the project is developed and built on Node 26 (see .nvmrc).
npm install
npm run dev # local server with hot reload
npm run check # lint, typecheck, tests, build: what CI runs
| Script | What it does |
|---|---|
npm run dev | Vite dev server |
npm run build | Production build into dist/ |
npm run preview | Serve the production build |
npm test / npm run test:watch | Unit tests (Vitest) |
npm run coverage | Tests with coverage; the scoring engine must stay above 90% |
npm run e2e | End-to-end tests in Chromium (Playwright): duels by keyboard and swipe, the items list, the color editor, a published board voted to the end |
npm run lint / npm run format | Biome lint and format check / auto-fix |
npm run typecheck | TypeScript in strict mode (app and Worker) |
npm run worker:dev | The whole app and the published boards API on http://localhost:8787 (npm run dev proxies /api to it) |
npm run worker:deploy | Build, deploy to Cloudflare and apply the D1 migrations (needs a Cloudflare account) |
npm run icons | Redraw the favicons, app icons and social card into public/ from build/site.ts |
npm run screenshots | Take the install dialog's screenshots of the app into public/ (needs Playwright's Chromium: npx playwright install chromium, or CHROMIUM_PATH) |
npm run e2e | End-to-end tests: Playwright's Chromium against the app and the Worker run locally (npx playwright install chromium once, or CHROMIUM_PATH) |
npm run vapid | Print a key pair for notifications, to set as the Worker's secrets VAPID_PUBLIC_KEY and VAPID_PRIVATE_KEY |
src/
core/ pure, framework-free logic (fully unit tested)
scoring.ts Bradley-Terry, Elo, win rate, exact sort, pair selection
colors.ts hex/HSL conversions, gradients, harmonies
demos.ts demo data and deterministic simulation
board.ts published boards: votes, visibility, pair assignment
protocol.ts messages and views shared by the app and the Worker
i18n/ en.ts (source of keys), fr.ts (type-checked against en), helpers; landing-*.ts for the home page
landing/ the home page, rendered at build time in each language, then animated
admin/ the publisher's moderation page (/admin/), client of the Worker's admin routes
app/
ui.ts mount(): the entry point
gallery.ts, workspace.ts, items.ts, duel.ts, results.ts, color.ts one module per view
publish.ts, board.ts, remote.ts publishing, the published board page, the API client
rankings.ts navigation and actions on whole rankings
events.ts delegated event listeners
state.ts, dom.ts, header.ts, format.ts, storage.ts shared state, DOM helpers, header, formatting, localStorage
styles.css
build/ build-time SEO: site facts, head tags, JSON-LD, manifest, robots, sitemap, llms.txt (docs/seo.md)
scripts/ icons.ts: icons and social card
worker/ Cloudflare Worker: the site, the API, one Durable Object per published board
tests/ Vitest suites (core, jsdom views, the Worker in workerd) and Playwright end-to-end tests (tests/e2e)
worker/ serves the app and the API for shared boards: each published board is a Durable Object with its own SQLite storage and WebSockets, a D1 registry backs the admin API, and per-IP limits and Turnstile guard publishing. The rules live in src/core/board.ts, shared with the app. It runs locally (npm run worker:dev), in the tests, and live at versus.steevepommier.com; CI deploys it, see docs/online-architecture.md.
.github/workflows/ci.yml runs on every pull request and push to main: Biome, TypeScript, Vitest with coverage, a production build, and the Playwright end-to-end tests (the app with a faked API, and against the real Worker). On main, once both pass, the build is deployed to GitHub Pages, and the Worker (app + API) to Cloudflare once the repository has the CLOUDFLARE_ACCOUNT_ID variable and the CLOUDFLARE_API_TOKEN secret (setup). Dependabot keeps npm packages and actions up to date.
The Pages source must be set once to GitHub Actions in Settings → Pages.
CLAUDE.md: working memory for Claude Code (conventions, code map, domain rules).docs/decisions.md: decision log.docs/roadmap.md: done, next, later, open questions.docs/published-boards.md: agreed behavior of published (shared) boards.docs/online-architecture.md: backend for published boards on Cloudflare (worker/), and how to deploy it.The texts are typed against English, so TypeScript flags a missing key; the language lists are not, so each needs it:
src/i18n/fr.ts and translate it; register it in src/i18n/index.ts (LANGS, MESSAGES, PLURALS); add its button to the language switcher in app/index.html; add its labels to the demos (src/core/demos.ts).src/i18n/landing-*.ts and legal-*.ts, the page shells (copy fr/index.html and fr/mentions-legales/index.html), the language lists in src/landing/ (markup.ts, frame.ts, sections.ts) and src/legal/mount.ts.build/site.ts (LANGUAGES, the pages, titles, descriptions, social cards, LOCALES), then npm run icons for its social card.BoardLang in src/core/types.ts, its use in src/core/board.ts, the templates (src/core/templates.ts, TEMPLATE_LANGS), the Worker's texts (src/i18n/unfurl.ts) and routes (worker/src/index.ts, worker/src/templates.ts).src/i18n/admin.ts and src/admin/admin.ts.grep -rn "'fr'" src build worker/src lists the places that name a language.
MIT © 2026 Steeve Pommier