# scouting.gateway-gamers.net **BCP Roster Scout**: paste a Best Coast Pairings (BCP) event link and get instant roster stats for that event. For team events, it can also generate a pre-filled Google Sheets matchup matrix for each opposing team. ## What it serves A single page (`index.html`). Enter an event URL or ID (it's also read from `?event=`, so scouted events can be linked) and the page shows: - **Summary**: event name and dates, player and team counts, checked-in rate, lists submitted. - **Insights and faction distribution**: faction spread, with each faction's most-used dispositions (Purge the Foe, Take and Hold and so on). - **Roster**, with ITC rank (Warhammer Global Rankings 2026) and career win % for every player: - team events: grouped by team, with a search box - singles events: a flat player table - **Generate Matrix** (team events): pick your team and the page: 1. copies the team's Google Sheets matchup-matrix template once per opposing team 2. fills in each opponent's name, faction and career win %, plus their army list cleaned up by the vendored 40k Compactor 3. links you to the new spreadsheet ## Data sources | Data | Source | | --- | --- | | Event, roster, team players | BCP `events/{id}` and related endpoints | | ITC rank | BCP `placings` for the ITC league and region | | Career W–L–T | BCP `placings?userId=…` for each player | | Army lists | BCP `armylists/{id}` (needs a subscriber token) | | Matrix | Google Drive and Sheets APIs, as the signed-in viewer | All requests come from the viewer's browser. There's no backend and nothing is stored on the server. ### Optional BCP token BCP often leaves faction or disposition blank on the roster. A viewer with a BCP subscription can paste their BCP auth token; the page then fetches each submitted list and pulls the missing faction and disposition out of it. Disposition names are fuzzy-matched so typos don't create duplicate entries. The same token is used to fetch lists for the matrix. The token is kept only in that browser's `localStorage` (`bcp_auth_token`) and only sent to BCP's own API. The page includes step-by-step instructions for finding it. BCP tokens expire after about an hour. ### Google sign-in (matrix only) Google Identity Services opens an OAuth popup and the viewer signs in with their own account. It requests these scopes: - `drive.readonly`: read the template so it can be copied - `drive.file`: create the copies - `spreadsheets`: write into the copies The OAuth client ID and template file ID are constants at the top of `src/matrix.js`. ## Files - `index.html`, `src/main.js`, `src/style.css`: the page, BCP data loading, stats and rendering - `src/matrix.js`: Google sign-in, template copying and list cleaning for **Generate Matrix** - `src/vendor/40k-compactor/`: vendored copy of Desjani's 40k Compactor (MIT), used to reformat army lists. It isn't on npm. See its `NOTICE.md` for where it came from, the license and how to update it. - `nav.html`: this site's header nav entries (see the root README) - `scouting.gateway-gamers.net.conf`: reference nginx config for the live server block. Its Content-Security-Policy allows BCP's API and Google's auth, Drive and Sheets hosts. Calling a new external host from the page means adding it there too. ## Deploy `.gitea/workflows/deploy-scouting.yml` builds the site and rsyncs `dist/` to `/var/www/domains/gateway-gamers.net/scouting/` on every push to `main` that touches `sites/scouting/` or `shared/`. See the root README for local dev commands and the shared header, footer and images.