import json

IN = "/var/www/html/peta/storage/app/propertylab-catalogue-match/review/v_hr_01_in.jsonl"
OUT = "/var/www/html/peta/storage/app/propertylab-catalogue-match/review/v_hr_01_out.jsonl"

S, P, D, U = "SAME", "PART_OF", "DIFFERENT", "UNSURE"
RC, CR = "R_in_C", "C_in_R"

# case: (verdict, cand, confidence, relation, reason, web)
V = {
    "v0001": (P, 0, 82, RC, "Bandar Sunway PJS 8 condos sit inside the PJS 8 locality row; no price or district to verify.", False),
    "v0005": (S, 0, 82, None, "Flats in SS13 Subang Jaya match the 'SS 13 Flat' row; R geocoded by name, no price.", False),
    "v0009": (P, 0, 88, RC, "Sunway Court apartment lies in PJS 7, Bandar Sunway; C row is the PJS 7 locality, 34 m.", False),
    "v0013": (S, 0, 95, None, "Exact name, KL Sentral, about 200 m; k1 is a duplicate row of the same building.", False),
    "v0017": (S, 0, 93, None, "Exact name; psf and price agree within 5%; k1 duplicates it; distance is a geocode offset.", False),
    "v0021": (S, 1, 78, None, "Block 422 condo is a separate 1,000 sqft JPPH scheme (web); R size and price fit the flat row.", True),
    "v0025": (U, 2, 45, None, "Road-name scheme; '1 Persiaran Gurney' is its own JPPH scheme (web); other Gurney Drive condos possible.", True),
    "v0029": (P, 0, 72, RC, "Condos inside Bandar Puteri Bangi township; C row is the landed township row, points 26 km apart.", False),
    "v0033": (S, 1, 65, None, "Unnumbered Sri Langkawi; price fits phase 1 (0.91), phase 2 far cheaper; could span both.", False),
    "v0037": (S, 0, 90, None, "Distinctive Mutiara Ville, Cyberjaya in Dengkil mukim; psf 27% higher, likely launch-era sales.", False),
    "v0041": (P, 0, 70, RC, "Apartments inside the Kampung Dato Sulaiman Menteri village locality, 117 m; C row is landed.", False),
    "v0045": (P, 0, 90, RC, "Phase II flats of Taman Bukit Angkasa; estate row price matches exactly, 44 m.", False),
    "v0049": (S, 0, 72, None, "Flats of mixed Taman Seri Merdeka estate, Ampang, 76 m; estate price reflects houses.", False),
    "v0053": (S, 0, 92, None, "Web: Paradigm Residence is the serviced apartment above Paradigm Mall JB; 65 m, psf 0.85.", True),
    "v0057": (S, 2, 75, None, "Unnumbered Prima Tiara likely phase 1; its psf and unit size fit best, 80 m.", False),
    "v0061": (S, 0, 82, None, "Flat on Jalan Merlimau, Pudu, 55 m; price fits (0.86); C psf looks erroneous.", False),
    "v0065": (S, 1, 85, None, "Web: Villa Mutiara, Mutiara Complex Jalan Ipoh is the serviced residence; Bukit Bintang namesake is a condo.", True),
    "v0069": (S, 0, 92, None, "Exact name, Georgetown, 3 m apart; C has no price to compare.", False),
    "v0073": (S, 0, 80, None, "Exact name, 14 m, identical psf; R strata category versus landed estate row.", False),
    "v0077": (S, 1, 92, None, "Web: this scheme is Taman Merbau Jaya Flat, Raja Uda Butterworth; price matches (1.01).", True),
    "v0081": (P, 2, 60, RC, "Flats of Taman Dedap; several blocks, pangsapuri row price far off; estate-level link only.", False),
    "v0085": (S, 0, 78, None, "Flats of mixed Taman Sri Lembayung estate; Klang district consistent, 407 m; price reflects houses.", False),
    "v0089": (S, 0, 85, None, "Name and Puchong Jaya location match, 57 m; C price looks mixed with Dutamas namesake.", False),
    "v0093": (S, 0, 70, None, "Selangor Taman Impian Indah (Cheras) estate with high-rise; Penang namesake excluded by state.", False),
    "v0097": (S, 0, 82, None, "Prima Damansara flats, Damansara Damai; price roughly fits (0.85); KL condo namesake excluded.", False),
    "v0101": (S, 0, 88, None, "Web: RUMAWIP Residensi Suria Pantai (810 sqft) is EdgeProp's Suria Pantai Residency; C price data odd.", True),
    "v0105": (S, 2, 90, None, "Taman Balik Pulau Flat; psf and price agree (1.04/1.10).", False),
    "v0109": (S, 0, 92, None, "Exact distinctive name, Petaling Jaya; psf agrees (0.97); unit mix differs.", False),
    "v0113": (S, 0, 85, None, "Exact name, Bandar Country Homes, 20 m; R's odd high psf suggests bulk or mixed sales.", False),
    "v0117": (S, 0, 92, None, "Bangi Gateway serviced apartments; psf and price agree (0.93/1.10).", False),
    "v0121": (S, 0, 88, None, "Exact name, Kapar/Meru; no C price and R located by name only.", False),
    "v0125": (S, 0, 90, None, "Exact name, Bandar Sungai Long, 13 m; price matches (1.03), psf lower.", False),
    "v0129": (D, None, 65, None, "Web: Seksyen 32 Akasia is at Berjaya Park; candidates are the Setia Alam namesake.", True),
    "v0133": (P, 0, 85, RC, "Flats within the Bandar Seberang Jaya township row; Seberang Perai Tengah consistent.", False),
    "v0137": (S, 0, 90, None, "Condo units of Serai Saujana are The View; price agrees within 10%, 142 m.", False),
    "v0141": (S, 0, 75, None, "Flats of Taman Orchard Heights, Batu Pahat, 281 m; estate row landed so price differs.", False),
    "v0145": (D, None, 80, None, "Web: Suria Residence (2018) and Suria Jelutong (2014) are separate Sunsuria projects in Bukit Jelutong.", True),
    "v0149": (S, 0, 75, None, "Taman Kajang Indah flats, 113 m; psf close (1.16) but price 73% higher.", False),
    "v0153": (P, 0, 88, RC, "Aman Heights condo lies in Taman Bukit Serdang Seksyen 5 locality; Petaling mukim consistent.", False),
    "v0157": (S, 0, 93, None, "Name, Puchong area and price all match (1.00); 21 km gap is a geocode error.", False),
    "v0161": (S, 0, 75, None, "Only Penang Pangsapuri Sentral (Butterworth); C price looks inflated; R located by name only.", False),
    "v0165": (S, 2, 70, None, "R median matches the estate's houses; estate-level link; pangsapuri row price differs (1.57).", False),
    "v0169": (S, 1, 75, None, "Condo of Taman Sepakat Indah, Kajang matches the apartment row; no price to verify.", False),
    "v0173": (S, 0, 88, None, "Exact name incl. phase 2, KL, 84 m; phase 1 row is pricier market units.", False),
    "v0177": (S, 0, 85, None, "Exact name, Penang, 15 m; C labels it condo; no price to confirm.", False),
    "v0181": (S, 1, 93, None, "Taman Free School Flat; psf and price agree (0.92/0.92), 177 m.", False),
    "v0185": (P, 2, 68, RC, "Apartments inside Pandan Perdana township; several duplicate township rows, no specific building row.", False),
    "v0189": (P, 0, 82, RC, "Taipan low-cost flats inside Bandar Armada Putra township, Pulau Indah; township row mixed.", False),
    "v0193": (S, 1, 90, None, "Taman Pekaka Apartment matches psf and price (1.03/1.00), 124 m.", False),
    "v0197": (S, 0, 78, None, "Exact estate incl. 'Indah'; Taman Bukit Panchor is a different estate despite closer price.", False),
    "v0201": (S, 1, 95, None, "Exact name, Bangsar, 7 m; psf and price agree (0.99/1.03).", False),
    "v0205": (S, 0, 92, None, "Exact name, Tanjung Tokong, 39 m; other candidates are elsewhere.", False),
    "v0209": (S, 1, 88, None, "Desa Jelita Apartment matches psf and price exactly, Batu Maung; k0 may be same block.", False),
    "v0213": (S, 0, 95, None, "Exact name, Tanjung Bungah; psf and price agree (1.09).", False),
    "v0217": (S, 2, 88, None, "Exact estate name, price matches (1.01/1.02); Sri Angsana differs; mixed estate row.", False),
    "v0221": (D, None, 62, None, "R is RM42k low-cost flats; Pinggiran Machang Bubok pangsapuri rows are RM363k or new-launch projects.", True),
    "v0225": (P, 0, 85, RC, "Flats in Seksyen 16 Bandar Baru Bangi; C row is that section locality.", False),
    "v0229": (S, 0, 78, None, "Medium-cost flats of Taman Sungai Besi; estate row price close (1.05), 71 m.", False),
    "v0233": (S, 1, 90, None, "Exact name, Puchong Jaya, 56 m; 'Koi Kinrara Suites' row likely duplicate, price fits.", False),
    "v0237": (S, 0, 88, None, "Exact estate name, Kajang; psf and price agree (1.02/1.11).", False),
    "v0241": (S, 2, 88, None, "Web: original SkyAwani Residence is SkyAwani 1, Sentul (mukim Batu); 800 sqft units fit.", True),
    "v0245": (S, 1, 95, None, "Ara Greens Residences; psf and price agree (1.00/0.98).", False),
    "v0249": (P, 0, 60, RC, "Taman Sutera Kajang holds several high-rises (Mawar, Sutera 7, web); block unclear, estate-level only.", True),
    "v0253": (S, 1, 93, None, "Exact name; psf and price match (1.00/0.98), 16 m.", False),
    "v0257": (P, 1, 78, RC, "Web: Marina Residence (Pangsapuri Bayu Permai) lies in Taman Bayu Puteri; Bayu Marina is a separate resort.", True),
    "v0261": (S, 0, 90, None, "KL Plaza Suites is KL Plaza's residential tower; price agrees (1.08/1.05).", False),
    "v0265": (S, 0, 90, None, "The Seed by Sutera, Skudai/Pulai; exact name; later 'By Sutera' launch is a new project.", False),
    "v0269": (S, 0, 65, None, "Taman Perak Flat name match; but R's point sits by Taman Seri Perak, 1.5 km away.", False),
    "v0273": (S, 1, 90, None, "Exact name, Eco Sanctuary, Kuala Langat; psf 1.33 likely includes launch-era sales.", False),
    "v0277": (S, 1, 85, None, "Taman Emas Flat, Butterworth, 32 m; common name but district and mukim fit.", False),
    "v0281": (S, 0, 90, None, "Exact name, Bayan Lepas, 64 m; Venti is a block of the same project.", False),
    "v0285": (S, 1, 82, None, "Exact name, KL, 52 m; redevelopment of Razak Mansion; R price below k0's market units.", False),
    "v0289": (S, 0, 92, None, "Villa Sentosa, Klang; psf and price agree (1.09/1.04).", False),
    "v0293": (S, 0, 78, None, "Flats of mixed Taman Harmoni 1 estate, Skudai, 189 m; estate row pricier.", False),
    "v0297": (S, 0, 88, None, "Distinctive exact name, George Town, Penang; no C price, R located by name.", False),
    "v0301": (S, 0, 90, None, "Web: single Hap Seng project on Jalan Tun Razak (2015); R includes launch-era prices.", True),
    "v0305": (P, 0, 70, RC, "Web: Tanjung Permai De Centro apartments (1,200 sqft), Butterworth; C row is Taman Tanjung Permai estate.", True),
    "v0309": (S, 1, 93, None, "Pangsapuri Andorra, Taman Sri Muda; psf and price agree (1.03/0.93).", False),
    "v0313": (S, 0, 78, None, "Taman Desa Ukay equals 'Desa Ukay' row, Ukay Heights; other rows are differently named condos.", False),
    "v0317": (S, 0, 95, None, "Lot 15 @ SJCC; psf and price agree (1.01).", False),
    "v0321": (P, 0, 88, RC, "Block C of Halaman Damai, 24 m; cheaper block explains lower price.", False),
    "v0325": (S, 0, 93, None, "Prima 16 (Prima Sixteen), PJ Section 16, 77 m.", False),
    "v0329": (S, 0, 92, None, "Taman Kajang Villa; psf and price agree (1.04/1.06).", False),
    "v0333": (S, 1, 92, None, "Seri Jaya Condominium, Bukit Mertajam; psf and price agree (1.02/1.04).", False),
    "v0337": (S, 0, 92, None, "Exact name incl. phase 2; psf and price identical.", False),
    "v0341": (S, 0, 75, None, "Low-cost flats of Taman Segamat Jaya, Segamat, 26 m; estate row landed.", False),
    "v0345": (S, 0, 80, None, "Flats of mixed Taman Semenyih Ria estate, 50 m; price reflects houses.", False),
    "v0349": (S, 0, 94, None, "228 Selayang Condominium; psf and price agree (1.01/1.02).", False),
    "v0353": (D, None, 65, None, "Web: Seksyen 32 Akasia is at Berjaya Park; candidates are the Setia Alam namesake.", True),
    "v0357": (S, 0, 68, None, "Web: two Penang Desa Pinangs; R's ~950 sqft fits Bukit Gelugor block (925 sqft); no state.", True),
    "v0361": (S, 0, 85, None, "Exact name, Kuchai Lama, mukim Petaling; ~800 m; no C price.", False),
    "v0365": (U, None, 30, None, "No state; Desa Aman estates in Cheras KL and Relau Penang; neither price clearly matches.", False),
    "v0369": (S, 0, 80, None, "Tampin Court in Taman Tampin area, Sungai Pinang; price agrees (0.95/0.96).", False),
    "v0373": (S, 2, 90, None, "Trifolia 1, Sungai Jati Klang; psf and price identical.", False),
    "v0377": (S, 0, 95, None, "Goodyear Court 3, Subang Perdana; psf and price agree.", False),
    "v0381": (S, 1, 95, None, "D'Putra Suites, Bandar Putra Kulai; psf agrees (1.00), 15 m.", False),
    "v0385": (P, 2, 88, CR, "R covers Simfoni 1 and 2 towers; C row is Simfoni 1 only, Semenyih.", False),
    "v0389": (S, 1, 92, None, "Seri Nibung, Bukit Jambul; psf and price agree (1.08/1.09).", False),
    "v0393": (S, 0, 88, None, "Exact PPR name, 26 m; RM35k median fits PPR pricing.", False),
    "v0397": (S, 0, 95, None, "Prima Ria, Dutamas; psf and price identical.", False),
    "v0401": (S, 1, 95, None, "Setia Alam Seri Kasturi matches name and price exactly; Puchong namesake only near via geocode.", False),
    "v0405": (S, 0, 95, None, "D'Rimba, Kota Damansara; psf and price identical; distance is geocode error.", False),
    "v0409": (S, 0, 94, None, "Apartment Cuepacs (Wisma Cuepacs); psf and price agree (1.04).", False),
    "v0413": (S, 0, 92, None, "Exact address-name, Ampang Hilir, mukim Ampang consistent.", False),
    "v0417": (S, 0, 92, None, "Platinum Arena, Old Klang Road; psf identical, larger units in R.", False),
    "v0421": (S, 2, 85, None, "Exact distinctive name, Semenyih; psf 29% higher than C, R located by name.", False),
    "v0425": (U, 0, 45, None, "No state; Pangsapuri Cantik (Butterworth) and Cantik Apartment (Cheras) share the name; prices split.", False),
    "v0429": (S, 0, 94, None, "Desa Pelangi Condominium, Kajang; psf and price identical.", False),
    "v0433": (S, 1, 90, None, "Taman Hui Aun, Ayer Itam; psf and price agree (1.10), 54 m.", False),
    "v0437": (P, 0, 62, RC, "Generic apartments of Taman Impian Ehsan; several block rows, none matches psf; estate-level only.", False),
    "v0441": (S, 1, 80, None, "Section 28 Alam Megah flats match 'Flat Taman Alam Megah', 481 m; no C price.", False),
    "v0445": (P, 2, 65, RC, "Generic Mount Austin serviced apartments inside the township; 1990 flat row is a different product.", False),
    "v0449": (S, 0, 78, None, "Kajang Prima estate; psf close (1.10); flats of a mostly landed estate row.", False),
    "v0453": (P, 0, 85, RC, "Flats in Seksyen 1 Bandar Baru Bangi; C row is that section locality.", False),
    "v0457": (S, 1, 94, None, "Cascades Residences, Kota Damansara; psf and price identical.", False),
    "v0461": (S, 0, 70, None, "Condo of mixed Taman Sri Kenari, Kajang estate, 207 m; out-of-state namesakes excluded.", False),
    "v0465": (S, 1, 65, None, "Name matches Taman Sutera Residences, Cheras (96 m); C lists landed, R serviced apartments.", False),
    "v0469": (P, 0, 75, RC, "Serviced apartments in PJ Section 13; C row is that section locality.", False),
    "v0473": (P, 0, 85, RC, "Flats on Jalan BP 1/2 lie in Bandar Bukit Puchong BP 1 precinct, 202 m.", False),
    "v0477": (D, None, 90, None, "Web: Kayu Ara PJU 6 Sri Ara (650 sqft low-cost) differs from Ara Damansara's Apartment Sri Ara.", True),
    "v0481": (S, 0, 93, None, "Impian Seri Setia; psf and price agree (1.04/1.01).", False),
    "v0485": (S, 0, 85, None, "Utropolis Batu Kawan serviced-apartment row, psf matches (1.01), 297 m; other phases are condos.", False),
    "v0489": (S, 1, 93, None, "CloudTree Residence; k0/k1 duplicates at same point; price agrees (0.99/0.92).", False),
    "v0493": (S, 1, 92, None, "Desa Mentari 2 flats, PJS 2; psf and price agree (1.05).", False),
    "v0497": (S, 0, 88, None, "Exact distinctive name; no C price, R located by name only.", False),
    "v0501": (S, 1, 93, None, "D'Pulze Residence, Cyberjaya; psf and price agree (1.00/1.02).", False),
    "v0505": (S, 0, 88, None, "Menara Rajawali SS15 Subang Jaya, 19 m; psf 1.39 suggests mixed office/SOHO C row.", False),
    "v0509": (S, 0, 88, None, "Exact name, Cyberjaya, 102 m; price agrees (1.09); likely strata landed labelled condo.", False),
    "v0513": (S, 0, 93, None, "Univ 360 Place, Seri Kembangan/Serdang, 57 m.", False),
    "v0517": (P, 2, 70, RC, "Generic condos of Taman Pandan Indah township; estate row price close (0.90/0.88).", False),
    "v0521": (S, 0, 88, None, "Exact distinctive name; Perla is Ara Sentral's residential tower; psf fits Perla.", False),
    "v0525": (S, 0, 78, None, "Price matches Nova II exactly, 47 m; unnumbered name could also cover Nova I.", False),
    "v0529": (S, 0, 90, None, "Meldrum Heights Residence, JB, 6 m; name and location match.", False),
    "v0533": (S, 1, 95, None, "The Marin, Batu Ferringhi; psf and price agree (1.02/1.01).", False),
    "v0537": (P, 0, 65, RC, "Generic condos in Sungai Sering locality; R price above named condos; block unclear.", False),
    "v0541": (S, 2, 95, None, "Alias 79 Residences; psf and price identical.", False),
    "v0545": (S, 0, 90, None, "UBN Apartment, KL city, 9 m; psf 1.34 but unique name and location.", False),
    "v0549": (D, None, 60, None, "No 'Puncak Ara Damansara' in Ara Damansara; likely Puncak Damansara, Kayu Ara (sizes fit).", True),
    "v0553": (S, 0, 88, None, "Distinctive Datum Jelatek, 49 m; tower rows are parts; price 1.5x, R located by name.", False),
    "v0557": (S, 0, 96, None, "Perla @ Ara Sentral; psf and price agree (1.03/0.99).", False),
    "v0561": (S, 0, 72, None, "Apartments in Taman Junid, Muar, 601 m; estate row landed; Junid Indah etc differ.", False),
    "v0565": (S, 0, 85, None, "Exact distinctive name, Penang, 39 m; C price likely asking for larger units.", False),
    "v0569": (S, 0, 90, None, "Pangsapuri Taman Desa Batu Caves; psf and price agree (1.09/1.12).", False),
    "v0573": (S, 0, 78, None, "Apartments of mixed Wangsa Permai estate, Kepong, 75 m; estate price reflects houses.", False),
    "v0577": (S, 0, 90, None, "Distinctive name, 38 m, Petaling district; C's 'Semenyih' area label looks wrong.", False),
    "v0581": (S, 0, 72, None, "Low-cost flats of Taman Permata Impian, Johor; estate row landed; namesakes elsewhere.", False),
    "v0585": (S, 0, 93, None, "PV3 Platinum Hill, Setapak; psf and price agree (1.11).", False),
    "v0589": (P, 2, 80, RC, "Seri Mutiara lies in Setia Alam township row; Seri Intan is a sibling block; Johor namesake.", False),
    "v0593": (S, 0, 93, None, "Dwi Galaksi equals Twin Galaxy, JB, 117 m.", False),
    "v0597": (S, 0, 85, None, "Exact name, Cheras, 7 m; C price (RM900k) looks off for this apartment.", False),
    "v0601": (S, 1, 95, None, "3 Residen, Taman Melawati; price identical, psf 1.07.", False),
    "v0605": (S, 0, 72, None, "Flats of mixed Desa Bukit Cahaya estate; R has no state, located by name.", False),
    "v0609": (S, 0, 92, None, "Web: G Residence Desa Pandan is KL's only one; psf and price agree (1.01/1.06).", True),
    "v0613": (P, 1, 75, CR, "R covers Desa Mentari blocks; C rows are single blocks (7, 8, 9-10).", False),
    "v0617": (S, 0, 90, None, "Ixora Apartments, KL town centre, 21 m; other Ixoras are elsewhere.", False),
    "v0621": (P, 0, 82, RC, "Flats within Bandar Baru Air Itam township row; mukim 13 consistent.", False),
    "v0625": (S, 0, 85, None, "Taman Tampoi Utama Flat, JB; name exact, 704 m; no C price.", False),
    "v0629": (S, 1, 88, None, "Kampung Warisan condominium, Keramat, 59 m; low-cost price fits resettlement condo.", False),
    "v0633": (S, 1, 93, None, "La Vista, Puchong Jaya; psf and price agree (1.08/1.04).", False),
    "v0637": (S, 0, 75, None, "Flats of Taman Cahaya, Ampang, 197 m; Taman Cahaya Indah is a different estate.", False),
    "v0641": (S, 3, 93, None, "Scot Pine in Evergreen Park, Sungai Long; psf and price agree (1.02).", False),
    "v0645": (S, 0, 93, None, "Saville @ Kajang, 53 m; other Savilles are Cheras and Melawati.", False),
    "v0649": (U, 0, 40, None, "R's state is Kelantan but price matches Batu Caves Taman Gemilang Flat; no Kelantan namesake found.", True),
    "v0653": (S, 0, 75, None, "Exact name, price agrees (1.10/1.08); R mukim Batu vs Pudu row, 6.9 km.", True),
    "v0657": (S, 2, 88, None, "Taman Megah Cheras Apartment; psf and price agree (0.96/1.05), 212 m.", False),
    "v0661": (S, 0, 85, None, "Sri Harmonis Apartment, 38 m; other rows are Villa/Pangsapuri Harmonis.", False),
    "v0665": (S, 1, 85, None, "Pangsapuri Mutiara in Taman Balakong Jaya, 209 m; price 0.81.", False),
    "v0669": (U, 0, 35, None, "Generic Puncak Alam apartments lump; Tropika Puncak Alam type unknown, maybe one component or landed.", False),
    "v0673": (S, 0, 90, None, "Aliff Avenue (Dwi Alif) alias exact, JB; Aliff Residences is Alif Utama, different.", False),
    "v0677": (S, 1, 92, None, "Green Acre Park, Bandar Sungai Long; price agrees (1.09), psf 1.15.", False),
    "v0681": (S, 1, 93, None, "Green Villa Apartment; psf and price identical; distance is geocode offset.", False),
    "v0685": (S, 0, 78, None, "Flats of Taman Bukit Segar Jaya; Taman Bukit Segar is a different estate.", False),
    "v0689": (S, 0, 95, None, "KiPark Selayang; psf and price agree (1.00/0.96).", False),
    "v0693": (S, 1, 93, None, "Residensi Bistaria, Ukay Bistari; psf and price agree (1.04/1.03).", False),
    "v0697": (P, 3, 70, CR, "R lumps You City serviced apartments; You Residences is one phase; psf agrees (1.03).", False),
    "v0701": (S, 1, 97, None, "Ritz-Carlton Residences KL; psf and price identical.", False),
    "v0705": (P, 0, 85, RC, "Web: Apartment Harmoni (650 sqft walk-ups) is its own Damansara Damai block, not Vista Apartment.", True),
    "v0709": (S, 1, 94, None, "Kondo Rakyat (Desa Pantai Flat) alias; psf and price agree (0.95).", False),
    "v0713": (P, 0, 92, CR, "R covers Goodyear Court 7 and 8; C row is Court 7; price matches.", False),
    "v0717": (S, 1, 92, None, "E Park Residences, Sungai Buloh; psf and price agree; C type label wrong.", False),
    "v0721": (S, 0, 92, None, "Pangsapuri Maharani, Muar; psf and price agree (1.10/1.09).", False),
    "v0725": (S, 1, 93, None, "D'Secret Garden phase 1, Kempas; psf and price agree; phase 2 rows separate.", False),
    "v0729": (S, 1, 88, None, "Zennith Suites alias Pangsapuri Kebun Teh, JB, 893 m; small units fit.", False),
    "v0733": (P, 0, 60, RC, "Taman Sutera Kajang holds several high-rises (Mawar, Sutera 7, web); block unclear, estate-level only.", True),
    "v0737": (S, 2, 85, None, "Mentari Apartment; psf and price match (0.98/0.99); Subang Damai inside Pinggiran Subang area.", False),
    "v0741": (S, 0, 85, None, "Puteri Indah, Bayan Baru; psf and price agree (1.04/1.10); R located by name.", False),
    "v0745": (S, 0, 90, None, "Residensi Laman Sari RUMAWIP, mukim Batu, 97 m; RM300k RUMAWIP price.", False),
    "v0749": (S, 0, 80, None, "Flats of mixed Taman Pendamar Indah 2 estate, Port Klang, 342 m.", False),
    "v0753": (S, 1, 92, None, "Taman Han Chiang, George Town; psf and price agree (1.06), 96 m.", False),
    "v0757": (S, 0, 93, None, "Residensi Sentral is The Sentral Residences; psf and price agree (1.05/1.01).", False),
    "v0761": (S, 1, 94, None, "Tribeca Bukit Bintang; psf and price agree (1.05/1.01).", False),
    "v0765": (S, 1, 88, None, "Taman Seruling Emas Flat, Sungai Jawi; price agrees (1.03), 341 m.", False),
    "v0769": (S, 0, 60, None, "Price identical to Sri Nipah, Sungai Nibong; but web places it in Taman Lip Sin.", True),
    "v0773": (S, 1, 90, None, "Web: Pangsapuri Kinrara Mas (Jalan Mas 1, Bukit Jalil) is 'Kinrara Mas Condominium'; C row mixes terraces.", True),
}

cases = []
with open(IN) as f:
    for line in f:
        d = json.loads(line)
        cases.append((d["case"], {c["k"] for c in d["catalogue_candidates"]}))

assert len(cases) == len(V), (len(cases), len(V))
problems = []
out_lines = []
for cid, ks in cases:
    verdict, cand, conf, rel, reason, web = V[cid]
    if verdict in (S, P) and cand not in ks:
        problems.append((cid, "cand not in candidates", cand, ks))
    if verdict == D and cand is not None:
        problems.append((cid, "DIFFERENT with cand"))
    if cand is not None and cand not in ks:
        problems.append((cid, "cand missing", cand, ks))
    if verdict == P and rel not in (RC, CR):
        problems.append((cid, "PART_OF without relation"))
    if verdict != P and rel is not None:
        problems.append((cid, "relation on non PART_OF"))
    if len(reason.split()) > 20:
        problems.append((cid, "reason too long", len(reason.split())))
    if verdict == U and conf >= 90:
        problems.append((cid, "UNSURE >= 90"))
    out_lines.append(json.dumps({
        "case": cid, "verdict": verdict, "cand": cand, "confidence_pct": conf,
        "relation": rel, "reason": reason, "web": web,
    }, ensure_ascii=False))

if problems:
    for p in problems:
        print("PROBLEM", p)
    raise SystemExit(1)

with open(OUT, "w") as f:
    f.write("\n".join(out_lines) + "\n")

from collections import Counter
print("written", len(out_lines))
print(Counter(V[c][0] for c, _ in cases))
print("conf>=90:", sum(1 for c, _ in cases if V[c][2] >= 90))
print("web cases:", sum(1 for c, _ in cases if V[c][5]))
print("PART_OF relations:", Counter(V[c][3] for c, _ in cases if V[c][0] == P))
