# Methodology: veterinary chain profiles

**Source classes:** 23 chains from public location finders (including 1 from a host retailer's store locator) and 4 chains from careers/office listings (1,857 of 7,894 rows). Each chain's class and exact URL are in `source-classes.json`; a class is derived from the URL the rows were read from. These careers/office listings list practices with recent postings; coverage of practices without postings is unknown.

**Base:** The crawl has 7,965 rows; 71 are excluded (5 duplicate GoodVets rows, 10 office or remote-role rows in careers feeds, 56 rows labelled closed by the chain), leaving 7,894 listed chain locations; the veterinary chain locations report counts 7,961, removing 4 GoodVets repeats only. Shares are chain listed locations ÷ 7,894 × 100.

**Excluded rows:** A row that repeats an earlier row of the same chain with the same normalized name, street and five-digit ZIP is a duplicate; empty city or phone values of the kept row are filled from the repeat. In a careers/office listing, a row named only with a state code (optionally ' - region'), a row whose name contains 'Corporate', and a row whose name ends in 'Remote' are offices or remote-role listings, not practices. A row whose location name ends with the chain's own 'CLOSED' label is a closed location. Excluded rows are left out of every count, share, directory and download, and are listed in excluded-rows.csv and each chain's provenance.json.

**Overlap:** City key: Unicode-fold to ASCII and lower-case; read '&' as 'and'; treat a word 'st', 'st.' or 'saint' as 'saint', 'ft'/'ft.' as 'fort' and 'mt'/'mt.' as 'mount'; then drop every character that is not a letter or digit. Two rows share a city when their city keys and two-letter states are equal; rows without a city are left out.

**Cleaning:** Doubled apostrophes carried over from SQL-style escaping ('') become one apostrophe. A city value that begins with a street fragment ending in Rd, Road, Ave, Avenue, Blvd, Dr, Drive, Hwy, Pkwy or Ln moves that fragment to the street field. A street value that ends with ', <city>, <state> <ZIP>' (the row's own city, state and ZIP) drops that repeated suffix. Cells changed: 4.

**Change log:** Crawl of 2 Oct 2026: 20 chains compared, with 6 added and 2 removed locations since 28 Sep 2026. The 4 chains from careers/office listings are not comparable (careers-feed footprint). For 3 chains, the site was not reachable to the automated crawl on 2 Oct 2026. Per-chain blocks are read from the v2b→v2c source-fact ledger (crawl 1 2026-09-28, crawl 2 2026-10-02). Careers-feed chains are not compared, because their additions and removals follow job postings; chains whose locator refused or blocked the polite crawler are not compared.

**Indexing:** the hub and the 27 national pages are indexed; a state page is indexed when it has at least 5 street-addressed rows and its chain is not a careers/office listing; other pages are noindex,follow and are not in the sitemap.

**Owner and review:** Owner: Rome (Vettica). Review trigger: the next quarterly recrawl (due by 2026-12-28) or a correction report; figures are re-derived from the new crawl.
