import i18n from 'i18next'; /** * Feature description translations, keyed by feature name. * * English descriptions are NOT here — the server is the single source of truth * for English. Fix a typo in features.rs and it propagates automatically. * * Non-English translations are keyed by the stable feature name, so they're * independent of the English description text. If a translation is missing, * tsDesc() falls back to the server's English description. */ const descriptions: Record> = { fr: { 'Listing status': 'Indique si le bien provient de ventes historiques, est en vente ou en location', 'Property type': 'Type de bien : individuel, jumelé, mitoyen, appartement ou autre', 'Leasehold/Freehold': 'Indique si le bien est en bail ou en pleine propriété', 'Last known price': 'Dernier prix de vente enregistré au Land Registry', 'Estimated current price': 'Estimation du prix actuel ajusté à l’inflation', 'Asking price': 'Prix demandé pour les biens actuellement en vente', 'Price per sqm': 'Prix de vente divisé par la surface totale', 'Est. price per sqm': 'Prix actuel estimé divisé par la surface totale', 'Asking price per sqm': 'Prix demandé divisé par la surface totale', 'Estimated monthly rent': 'Loyer mensuel privé médian pour le secteur', 'Asking rent (monthly)': 'Loyer mensuel affiché pour les biens en location', 'Total floor area (sqm)': 'Surface intérieure issue du diagnostic EPC', 'Number of bedrooms & living rooms': 'Nombre de pièces habitables selon le diagnostic EPC', 'Bedrooms': 'Nombre de chambres selon l’annonce en ligne', 'Bathrooms': 'Nombre de salles de bain selon l’annonce en ligne', 'Construction year': 'Année de construction estimée selon l’EPC', 'Date of last transaction': 'Date de la dernière vente enregistrée au Land Registry', 'Listing date': 'Date de première mise en ligne du bien', 'Former council house': 'Indique si le bien a été répertorié comme logement social', 'Current energy rating': 'Classement énergétique EPC actuel (A = meilleur, G = pire)', 'Potential energy rating': 'Classement EPC potentiel si toutes les améliorations recommandées étaient réalisées', 'Interior height (m)': 'Hauteur moyenne d’étage selon le diagnostic EPC', 'Distance to nearest train or tube station (km)': 'Distance à la gare ou station de métro la plus proche', 'Good+ primary schools within 2km': 'Écoles primaires notées Bien ou Excellent par Ofsted dans un rayon de 2 km', 'Good+ secondary schools within 2km': 'Collèges/lycées notés Bien ou Excellent par Ofsted dans un rayon de 2 km', 'Good+ primary schools within 5km': 'Écoles primaires notées Bien ou Excellent par Ofsted dans un rayon de 5 km', 'Good+ secondary schools within 5km': 'Collèges/lycées notés Bien ou Excellent par Ofsted dans un rayon de 5 km', 'Education, Skills and Training Score': 'Score de qualité éducative du secteur (plus élevé = meilleur)', 'Income Score (rate)': 'Taux de précarité de revenu, inversé (plus élevé = moins précaire)', 'Employment Score (rate)': 'Taux de précarité d’emploi, inversé (plus élevé = moins précaire)', 'Health Deprivation and Disability Score': 'Score de santé et handicap (plus élevé = meilleurs résultats)', 'Living Environment Score': 'Qualité de l’environnement intérieur et extérieur (plus élevé = meilleur)', 'Indoors Sub-domain Score': 'Qualité et état du logement (plus élevé = meilleur)', 'Outdoors Sub-domain Score': 'Qualité de l’air et sécurité routière (plus élevé = meilleur)', 'Serious crime per 1k residents (avg/yr)': 'Taux de crimes graves pour 1 000 habitants par an', 'Minor crime per 1k residents (avg/yr)': 'Taux de délits mineurs pour 1 000 habitants par an', 'Serious crime (avg/yr)': 'Agrégat des catégories de crimes graves par an', 'Minor crime (avg/yr)': 'Agrégat des catégories de délits mineurs par an', 'Violence and sexual offences (avg/yr)': 'Moyenne annuelle des violences et infractions sexuelles dans le secteur', 'Burglary (avg/yr)': 'Moyenne annuelle des cambriolages dans le secteur', 'Robbery (avg/yr)': 'Moyenne annuelle des vols avec violence dans le secteur', 'Vehicle crime (avg/yr)': 'Moyenne annuelle des crimes liés aux véhicules dans le secteur', 'Anti-social behaviour (avg/yr)': 'Moyenne annuelle des comportements antisociaux dans le secteur', 'Criminal damage and arson (avg/yr)': 'Moyenne annuelle des dégradations et incendies criminels dans le secteur', 'Other theft (avg/yr)': 'Moyenne annuelle des autres vols dans le secteur', 'Theft from the person (avg/yr)': 'Moyenne annuelle des vols à la personne dans le secteur', 'Shoplifting (avg/yr)': 'Moyenne annuelle des vols à l’étalage dans le secteur', 'Bicycle theft (avg/yr)': 'Moyenne annuelle des vols de vélos dans le secteur', 'Drugs (avg/yr)': 'Moyenne annuelle des infractions liées aux stupéfiants dans le secteur', 'Possession of weapons (avg/yr)': 'Moyenne annuelle des infractions de possession d’armes dans le secteur', 'Public order (avg/yr)': 'Moyenne annuelle des troubles à l’ordre public dans le secteur', 'Other crime (avg/yr)': 'Moyenne annuelle des autres crimes dans le secteur', 'Median age': 'Âge médian de la population locale', '% White': 'Pourcentage de la population se déclarant Blanche', '% South Asian': 'Pourcentage de la population se déclarant Sud-Asiatique', '% Black': 'Pourcentage de la population se déclarant Noire', '% East Asian': 'Pourcentage de la population se déclarant Est-Asiatique', '% Mixed': 'Pourcentage de la population se déclarant Métisse ou de plusieurs groupes ethniques', '% Other': 'Pourcentage de la population se déclarant d’un autre groupe ethnique', 'Distance to nearest park (km)': 'Distance au parc ou espace vert le plus proche', 'Number of parks within 2km': 'Nombre de parcs et espaces verts à moins de 2 km', 'Number of restaurants within 2km': 'Nombre de restaurants et cafés à moins de 2 km', 'Number of grocery shops and supermarkets within 2km': 'Nombre d’épiceries et supermarchés à moins de 2 km', 'Noise (dB)': 'Niveau de bruit routier au code postal en décibels (Lden)', 'Max available download speed (Mbps)': 'Débit descendant maximal disponible au code postal', }, de: { 'Listing status': 'Ob die Immobilie aus historischen Verkäufen stammt, aktuell zum Verkauf oder zur Miete steht', 'Property type': 'Immobilientyp: freistehend, Doppelhaushälfte, Reihenhaus, Wohnung oder sonstige', 'Leasehold/Freehold': 'Ob die Immobilie Erbbaurecht oder Volleigentum ist', 'Last known price': 'Letzter Verkaufspreis laut Land Registry', 'Estimated current price': 'Inflationsbereinigter Schätzwert der Immobilie', 'Asking price': 'Angebotspreis für aktuell zum Verkauf stehende Immobilien', 'Price per sqm': 'Verkaufspreis geteilt durch die Gesamtfläche', 'Est. price per sqm': 'Geschätzter aktueller Preis geteilt durch die Gesamtfläche', 'Asking price per sqm': 'Angebotspreis geteilt durch die Gesamtfläche', 'Estimated monthly rent': 'Mittlere monatliche Privatmiete in der Gegend', 'Asking rent (monthly)': 'Angebotene Monatsmiete für Mietimmobilien', 'Total floor area (sqm)': 'Wohnfläche laut EPC-Gutachten', 'Number of bedrooms & living rooms': 'Anzahl bewohnbarer Räume laut EPC-Gutachten', 'Bedrooms': 'Anzahl Schlafzimmer laut Online-Inserat', 'Bathrooms': 'Anzahl Badezimmer laut Online-Inserat', 'Construction year': 'Geschätztes Baujahr laut EPC', 'Date of last transaction': 'Datum des letzten Verkaufs laut Land Registry', 'Listing date': 'Datum der Erstveröffentlichung des Inserats', 'Former council house': 'Ob die Immobilie jemals als Sozialbau erfasst wurde', 'Current energy rating': 'Aktuelle EPC-Energieeffizienzklasse (A = beste, G = schlechteste)', 'Potential energy rating': 'Potenzielle EPC-Klasse bei Umsetzung aller empfohlenen Maßnahmen', 'Interior height (m)': 'Durchschnittliche Geschosshöhe laut EPC-Gutachten', 'Distance to nearest train or tube station (km)': 'Entfernung zum nächsten Bahn- oder U-Bahnhof', 'Good+ primary schools within 2km': 'Von Ofsted mit Gut oder Hervorragend bewertete Grundschulen im Umkreis von 2 km', 'Good+ secondary schools within 2km': 'Von Ofsted mit Gut oder Hervorragend bewertete weiterführende Schulen im Umkreis von 2 km', 'Good+ primary schools within 5km': 'Von Ofsted mit Gut oder Hervorragend bewertete Grundschulen im Umkreis von 5 km', 'Good+ secondary schools within 5km': 'Von Ofsted mit Gut oder Hervorragend bewertete weiterführende Schulen im Umkreis von 5 km', 'Education, Skills and Training Score': 'Bildungsqualitätsscore der Gegend (höher = besser)', 'Income Score (rate)': 'Einkommensbenachteiligungsrate, invertiert (höher = weniger benachteiligt)', 'Employment Score (rate)': 'Beschäftigungsbenachteiligungsrate, invertiert (höher = weniger benachteiligt)', 'Health Deprivation and Disability Score': 'Gesundheits- und Behinderungsscore (höher = bessere Ergebnisse)', 'Living Environment Score': 'Qualität der Innen- und Außenumgebung (höher = besser)', 'Indoors Sub-domain Score': 'Wohnqualität und -zustand (höher = besser)', 'Outdoors Sub-domain Score': 'Luftqualität und Verkehrssicherheit (höher = besser)', 'Serious crime per 1k residents (avg/yr)': 'Rate schwerer Straftaten pro 1.000 Einwohner pro Jahr', 'Minor crime per 1k residents (avg/yr)': 'Rate leichter Straftaten pro 1.000 Einwohner pro Jahr', 'Serious crime (avg/yr)': 'Summe der schweren Straftaten-Kategorien pro Jahr', 'Minor crime (avg/yr)': 'Summe der leichten Straftaten-Kategorien pro Jahr', 'Violence and sexual offences (avg/yr)': 'Jährlicher Durchschnitt der Gewalt- und Sexualdelikte in der Gegend', 'Burglary (avg/yr)': 'Jährlicher Durchschnitt der Einbrüche in der Gegend', 'Robbery (avg/yr)': 'Jährlicher Durchschnitt der Raubüberfälle in der Gegend', 'Vehicle crime (avg/yr)': 'Jährlicher Durchschnitt der Fahrzeugkriminalität in der Gegend', 'Anti-social behaviour (avg/yr)': 'Jährlicher Durchschnitt des antisozialen Verhaltens in der Gegend', 'Criminal damage and arson (avg/yr)': 'Jährlicher Durchschnitt der Sachbeschädigungen und Brandstiftungen in der Gegend', 'Other theft (avg/yr)': 'Jährlicher Durchschnitt des sonstigen Diebstahls in der Gegend', 'Theft from the person (avg/yr)': 'Jährlicher Durchschnitt des Taschendiebstahls in der Gegend', 'Shoplifting (avg/yr)': 'Jährlicher Durchschnitt des Ladendiebstahls in der Gegend', 'Bicycle theft (avg/yr)': 'Jährlicher Durchschnitt des Fahrraddiebstahls in der Gegend', 'Drugs (avg/yr)': 'Jährlicher Durchschnitt der Drogendelikte in der Gegend', 'Possession of weapons (avg/yr)': 'Jährlicher Durchschnitt der Waffenbesitzdelikte in der Gegend', 'Public order (avg/yr)': 'Jährlicher Durchschnitt der Störungen der öffentlichen Ordnung in der Gegend', 'Other crime (avg/yr)': 'Jährlicher Durchschnitt sonstiger Straftaten in der Gegend', 'Median age': 'Medianalter der lokalen Bevölkerung', '% White': 'Anteil der Bevölkerung, der sich als Weiß identifiziert', '% South Asian': 'Anteil der Bevölkerung, der sich als Südasiatisch identifiziert', '% Black': 'Anteil der Bevölkerung, der sich als Schwarz identifiziert', '% East Asian': 'Anteil der Bevölkerung, der sich als Ostasiatisch identifiziert', '% Mixed': 'Anteil der Bevölkerung, der sich als gemischt oder mehreren ethnischen Gruppen zugehörig identifiziert', '% Other': 'Anteil der Bevölkerung, der sich einer anderen ethnischen Gruppe zuordnet', 'Distance to nearest park (km)': 'Entfernung zum nächsten Park oder Grünfläche', 'Number of parks within 2km': 'Anzahl Parks und Grünflächen im Umkreis von 2 km', 'Number of restaurants within 2km': 'Anzahl Restaurants und Cafés im Umkreis von 2 km', 'Number of grocery shops and supermarkets within 2km': 'Anzahl Lebensmittelgeschäfte und Supermärkte im Umkreis von 2 km', 'Noise (dB)': 'Straßenlärmpegel an der Postleitzahl in Dezibel (Lden)', 'Max available download speed (Mbps)': 'Maximal verfügbare Breitband-Downloadgeschwindigkeit an der Postleitzahl', }, zh: { 'Listing status': '该房产是历史销售、当前在售还是出租', 'Property type': '房产类型:独立式、半独立式、联排、公寓或其他', 'Leasehold/Freehold': '该房产是租赁产权还是永久产权', 'Last known price': 'Land Registry记录的最近一次售价', 'Estimated current price': '经通胀调整后的当前估计价值', 'Asking price': '当前在售房产的挂牌价', 'Price per sqm': '售价除以总建筑面积', 'Est. price per sqm': '估计当前价格除以总建筑面积', 'Asking price per sqm': '挂牌价除以总建筑面积', 'Estimated monthly rent': '当地私人租赁的中位月租', 'Asking rent (monthly)': '当前出租房产的挂牌月租', 'Total floor area (sqm)': 'EPC评估的室内建筑面积', 'Number of bedrooms & living rooms': 'EPC评估的宜居房间数', 'Bedrooms': '在线房源中的卧室数量', 'Bathrooms': '在线房源中的浴室数量', 'Construction year': 'EPC评估的建造年份', 'Date of last transaction': 'Land Registry记录的最近一次销售日期', 'Listing date': '房产首次在线上市的日期', 'Former council house': '该房产是否曾被记录为公共住房', 'Current energy rating': '当前EPC能效评级(A = 最佳,G = 最差)', 'Potential energy rating': '实施所有建议改进后的潜在EPC评级', 'Interior height (m)': 'EPC评估的平均层高', 'Distance to nearest train or tube station (km)': '到最近火车或地铁站的距离', 'Good+ primary schools within 2km': 'Ofsted评为良好或优秀的2公里内小学', 'Good+ secondary schools within 2km': 'Ofsted评为良好或优秀的2公里内中学', 'Good+ primary schools within 5km': 'Ofsted评为良好或优秀的5公里内小学', 'Good+ secondary schools within 5km': 'Ofsted评为良好或优秀的5公里内中学', 'Education, Skills and Training Score': '当地教育质量得分(越高越好)', 'Income Score (rate)': '收入贫困率,反向指标(越高越不贫困)', 'Employment Score (rate)': '就业贫困率,反向指标(越高越不贫困)', 'Health Deprivation and Disability Score': '健康与残障得分(越高健康状况越好)', 'Living Environment Score': '室内外环境质量(越高越好)', 'Indoors Sub-domain Score': '住房质量和状况(越高越好)', 'Outdoors Sub-domain Score': '空气质量和道路安全(越高越好)', 'Serious crime per 1k residents (avg/yr)': '每千人每年严重犯罪率', 'Minor crime per 1k residents (avg/yr)': '每千人每年轻微犯罪率', 'Serious crime (avg/yr)': '严重犯罪类别年度总计', 'Minor crime (avg/yr)': '轻微犯罪类别年度总计', 'Violence and sexual offences (avg/yr)': '该地区年均暴力和性犯罪数', 'Burglary (avg/yr)': '该地区年均入室盗窃数', 'Robbery (avg/yr)': '该地区年均抢劫数', 'Vehicle crime (avg/yr)': '该地区年均车辆犯罪数', 'Anti-social behaviour (avg/yr)': '该地区年均反社会行为数', 'Criminal damage and arson (avg/yr)': '该地区年均刑事毁坏和纵火数', 'Other theft (avg/yr)': '该地区年均其他盗窃数', 'Theft from the person (avg/yr)': '该地区年均人身盗窃数', 'Shoplifting (avg/yr)': '该地区年均商店盗窃数', 'Bicycle theft (avg/yr)': '该地区年均自行车盗窃数', 'Drugs (avg/yr)': '该地区年均毒品犯罪数', 'Possession of weapons (avg/yr)': '该地区年均非法持有武器数', 'Public order (avg/yr)': '该地区年均扰乱公共秩序数', 'Other crime (avg/yr)': '该地区年均其他犯罪数', 'Median age': '当地人口的中位年龄', '% White': '白人人口比例', '% South Asian': '南亚裔人口比例', '% Black': '黑人人口比例', '% East Asian': '东亚裔人口比例', '% Mixed': '混血或多族裔人口比例', '% Other': '其他族裔人口比例', 'Distance to nearest park (km)': '到最近公园或绿地的距离', 'Number of parks within 2km': '2公里内公园和绿地数量', 'Number of restaurants within 2km': '2公里内餐厅和咖啡馆数量', 'Number of grocery shops and supermarkets within 2km': '2公里内食品店和超市数量', 'Noise (dB)': '该邮编的道路噪音水平(分贝,Lden)', 'Max available download speed (Mbps)': '该邮编可用的最大宽带下载速度', }, hu: { 'Listing status': 'Az ingatlan korábbi eladásból származik, jelenleg eladó vagy kiadó', 'Property type': 'Ingatlantípus: különálló, ikerház, sorház, lakás vagy egyéb', 'Leasehold/Freehold': 'Az ingatlan bérleti jogú vagy teljes tulajdonú', 'Last known price': 'A Land Registry-ben rögzített utolsó eladási ár', 'Estimated current price': 'Inflációval korrigált becsült jelenlegi érték', 'Asking price': 'A jelenleg eladásra kínált ingatlanok irányára', 'Price per sqm': 'Eladási ár osztva az összes alapterülettel', 'Est. price per sqm': 'Becsült jelenlegi ár osztva az összes alapterülettel', 'Asking price per sqm': 'Irányár osztva az összes alapterülettel', 'Estimated monthly rent': 'A környék medián havi magánbérleti díja', 'Asking rent (monthly)': 'A kiadó ingatlanok hirdetett havi bérleti díja', 'Total floor area (sqm)': 'Az EPC felmérésből származó belső alapterület', 'Number of bedrooms & living rooms': 'Lakószobák száma az EPC felmérés alapján', 'Bedrooms': 'Hálószobák száma az online hirdetés szerint', 'Bathrooms': 'Fürdőszobák száma az online hirdetés szerint', 'Construction year': 'Becsült építési év az EPC alapján', 'Date of last transaction': 'Az utolsó eladás dátuma a Land Registry szerint', 'Listing date': 'Az ingatlan első online megjelenésének dátuma', 'Former council house': 'Az ingatlan szerepelt-e valaha önkormányzati lakásként', 'Current energy rating': 'Jelenlegi EPC energiabesorolás (A = legjobb, G = legrosszabb)', 'Potential energy rating': 'Potenciális EPC besorolás az összes javasolt fejlesztés elvégzése után', 'Interior height (m)': 'Átlagos belmagasság az EPC felmérés alapján', 'Distance to nearest train or tube station (km)': 'Távolság a legközelebbi vasút- vagy metróállomásig', 'Good+ primary schools within 2km': 'Ofsted által Jó vagy Kiváló minősítésű általános iskolák 2 km-en belül', 'Good+ secondary schools within 2km': 'Ofsted által Jó vagy Kiváló minősítésű középiskolák 2 km-en belül', 'Good+ primary schools within 5km': 'Ofsted által Jó vagy Kiváló minősítésű általános iskolák 5 km-en belül', 'Good+ secondary schools within 5km': 'Ofsted által Jó vagy Kiváló minősítésű középiskolák 5 km-en belül', 'Education, Skills and Training Score': 'A környék oktatási minőségi pontszáma (magasabb = jobb)', 'Income Score (rate)': 'Jövedelmi deprivációs ráta, invertálva (magasabb = kevésbé hátrányos)', 'Employment Score (rate)': 'Foglalkoztatási deprivációs ráta, invertálva (magasabb = kevésbé hátrányos)', 'Health Deprivation and Disability Score': 'Egészségügyi és fogyatékossági pontszám (magasabb = jobb eredmények)', 'Living Environment Score': 'Belső és külső környezet minősége (magasabb = jobb)', 'Indoors Sub-domain Score': 'Lakásminőség és állapot (magasabb = jobb)', 'Outdoors Sub-domain Score': 'Levegőminőség és közlekedésbiztonság (magasabb = jobb)', 'Serious crime per 1k residents (avg/yr)': 'Súlyos bűncselekmények aránya 1000 lakosra évente', 'Minor crime per 1k residents (avg/yr)': 'Kisebb bűncselekmények aránya 1000 lakosra évente', 'Serious crime (avg/yr)': 'Súlyos bűncselekményi kategóriák éves összesítése', 'Minor crime (avg/yr)': 'Kisebb bűncselekményi kategóriák éves összesítése', 'Violence and sexual offences (avg/yr)': 'Erőszakos és szexuális bűncselekmények éves átlaga a környéken', 'Burglary (avg/yr)': 'Betörések éves átlaga a környéken', 'Robbery (avg/yr)': 'Rablások éves átlaga a környéken', 'Vehicle crime (avg/yr)': 'Gépjárművel kapcsolatos bűncselekmények éves átlaga a környéken', 'Anti-social behaviour (avg/yr)': 'Közösségellenes magatartás éves átlaga a környéken', 'Criminal damage and arson (avg/yr)': 'Rongálás és gyújtogatás éves átlaga a környéken', 'Other theft (avg/yr)': 'Egyéb lopások éves átlaga a környéken', 'Theft from the person (avg/yr)': 'Személyek elleni lopások éves átlaga a környéken', 'Shoplifting (avg/yr)': 'Bolti lopások éves átlaga a környéken', 'Bicycle theft (avg/yr)': 'Kerékpárlopások éves átlaga a környéken', 'Drugs (avg/yr)': 'Kábítószerrel kapcsolatos bűncselekmények éves átlaga a környéken', 'Possession of weapons (avg/yr)': 'Fegyvertartással kapcsolatos bűncselekmények éves átlaga a környéken', 'Public order (avg/yr)': 'Közrend elleni bűncselekmények éves átlaga a környéken', 'Other crime (avg/yr)': 'Egyéb bűncselekmények éves átlaga a környéken', 'Median age': 'A helyi lakosság medián életkora', '% White': 'A fehérként azonosított lakosság aránya', '% South Asian': 'A dél-ázsiaiként azonosított lakosság aránya', '% Black': 'A feketeként azonosított lakosság aránya', '% East Asian': 'A kelet-ázsiaiként azonosított lakosság aránya', '% Mixed': 'A vegyes vagy több etnikai csoporthoz tartozóként azonosított lakosság aránya', '% Other': 'Az egyéb etnikai csoportba tartozóként azonosított lakosság aránya', 'Distance to nearest park (km)': 'Távolság a legközelebbi parkig vagy zöldterületig', 'Number of parks within 2km': 'Parkok és zöldterületek száma 2 km-en belül', 'Number of restaurants within 2km': 'Éttermek és kávézók száma 2 km-en belül', 'Number of grocery shops and supermarkets within 2km': 'Élelmiszerboltok és szupermarketek száma 2 km-en belül', 'Noise (dB)': 'Közúti zajszint az irányítószámnál decibelben (Lden)', 'Max available download speed (Mbps)': 'Az irányítószámnál elérhető maximális szélessávú letöltési sebesség', }, }; /** * Translate a feature description. * - English: returns the server-provided description (single source of truth) * - Other languages: looks up by feature name, falls back to English if missing */ export function tsDesc(featureName: string, englishFromServer: string): string { const lang = i18n.language; if (lang === 'en') return englishFromServer; return descriptions[lang]?.[featureName] ?? englishFromServer; } /** * Translate a feature detail (the longer explanatory paragraph in the info card). * Same pattern as tsDesc: English from server, other languages from this file. */ export function tsDetail(featureName: string, englishFromServer: string): string { const lang = i18n.language; if (lang === 'en') return englishFromServer; return details[lang]?.[featureName] ?? englishFromServer; }