Boring changes

This commit is contained in:
Andras Schmelczer 2026-07-12 15:10:26 +01:00
parent cfaf58dfba
commit 920119ff48
32 changed files with 912 additions and 88 deletions

View file

@ -4,7 +4,7 @@ import { details } from './details';
/**
* Feature description translations, keyed by feature name.
*
* English descriptions are NOT here the server is the single source of truth
* 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 theyre
@ -95,6 +95,9 @@ const descriptions: Record<string, Record<string, string>> = {
'% Social rent':
"Part des ménages locataires auprès d'une collectivité locale ou d'un bailleur social",
'% Private rent': 'Part des ménages locataires dans le privé ou logés à titre gratuit',
'% Council housing':
'Part des logements du code postal déjà enregistrés comme logement municipal ou social',
'% Ex-council': 'Part des logements du code postal autrefois municipaux mais qui ne le sont plus',
'% White': 'Part de la population sidentifiant comme blanche',
'% South Asian': 'Part de la population sidentifiant comme sud-asiatique',
'% Black': 'Part de la population sidentifiant comme noire',
@ -204,6 +207,10 @@ const descriptions: Record<string, Record<string, string>> = {
'% Social rent':
'Anteil der Haushalte, die von einer Kommune oder Wohnungsbaugesellschaft mieten',
'% Private rent': 'Anteil der Haushalte, die privat mieten oder mietfrei wohnen',
'% Council housing':
'Anteil der Wohnungen im Postcode, die jemals als Kommunal- oder Sozialwohnung erfasst wurden',
'% Ex-council':
'Anteil der Wohnungen im Postcode, die früher Kommunalwohnungen waren, es aber nicht mehr sind',
'% White': 'Anteil der Personen, die sich als weiß identifizieren',
'% South Asian': 'Anteil der Personen, die sich als südasiatisch identifizieren',
'% Black': 'Anteil der Personen, die sich als schwarz identifizieren',
@ -289,6 +296,8 @@ const descriptions: Record<string, Record<string, string>> = {
'% Owner occupied': '拥有自住房(全款或按揭)的家庭比例',
'% Social rent': '向地方政府或住房协会租房的家庭比例',
'% Private rent': '私人租房或免租居住的家庭比例',
'% Council housing': '邮编内曾被记录为公共住房或社会住房的房屋比例',
'% Ex-council': '邮编内曾是公共住房但现在不再是的房屋比例',
'% White': '白人人口比例',
'% South Asian': '南亚裔人口比例',
'% Black': '黑人人口比例',
@ -380,6 +389,9 @@ const descriptions: Record<string, Record<string, string>> = {
'% Owner occupied': 'अपने घर के स्वामी परिवारों का हिस्सा, चाहे पूर्ण रूप से या बंधक के साथ',
'% Social rent': 'काउंसिल या हाउसिंग एसोसिएशन से किराए पर रहने वाले परिवारों का हिस्सा',
'% Private rent': 'निजी रूप से किराए पर या बिना किराए के रहने वाले परिवारों का हिस्सा',
'% Council housing':
'पोस्टकोड के उन घरों का हिस्सा जिन्हें कभी न कभी काउंसिल या सामाजिक आवास के रूप में दर्ज किया गया',
'% Ex-council': 'पोस्टकोड के उन घरों का हिस्सा जो पहले काउंसिल आवास थे लेकिन अब नहीं हैं',
'% White': 'श्वेत के रूप में पहचान करने वाली आबादी का प्रतिशत',
'% South Asian': 'दक्षिण एशियाई के रूप में पहचान करने वाली आबादी का प्रतिशत',
'% Black': 'अश्वेत के रूप में पहचान करने वाली आबादी का प्रतिशत',
@ -481,6 +493,10 @@ const descriptions: Record<string, Record<string, string>> = {
'Azon háztartások aránya, amelyek önkormányzattól vagy lakásszövetkezettől bérelnek',
'% Private rent':
'Azon háztartások aránya, amelyek magánbérleményben élnek vagy lakbér nélkül laknak',
'% Council housing':
'Az irányítószámon belüli lakások aránya, amelyeket valaha önkormányzati vagy szociális lakásként rögzítettek',
'% Ex-council':
'Az irányítószámon belüli lakások aránya, amelyek korábban önkormányzati lakások voltak, de már nem azok',
'% 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',
@ -514,7 +530,7 @@ const descriptions: Record<string, Record<string, string>> = {
/**
* The crime features carry a window suffix ("Burglary (/yr, 7y)"), but the
* per-locale description/detail/icon maps are keyed by the bare type's legacy
* "(avg/yr)" name and the text is the same for both windows. Map a crime
* "(avg/yr)" name, and the text is the same for both windows. Map a crime
* feature name back to that legacy key so the existing translations resolve
* without duplicating every entry per window.
*/

View file

@ -1,7 +1,7 @@
/**
* Feature detail translations (the longer explanatory paragraph in the info card).
* Same structure as descriptions: keyed by language, then by feature name.
* English details come from the server NOT duplicated here.
* English details come from the server (not duplicated here).
*/
export const details: Record<string, Record<string, string>> = {
fr: {
@ -104,17 +104,21 @@ export const details: Record<string, Record<string, string>> = {
'% Apprenticeship':
"D'après le recensement de 2021 (TS067). Le diplôme le plus élevé est un apprentissage.",
'% A-levels':
"D'après le recensement de 2021 (TS067). Le diplôme le plus élevé est le A-levels, AS-levels, T-levels, un apprentissage avancé ou équivalent généralement étudié après 16 ans et avant un diplôme universitaire.",
"D'après le recensement de 2021 (TS067). Le diplôme le plus élevé est le A-levels, AS-levels, T-levels, un apprentissage avancé ou équivalent, généralement étudié après 16 ans et avant un diplôme universitaire.",
'% Degree or higher':
"D'après le recensement de 2021 (TS067). Le diplôme le plus élevé est de niveau universitaire ou supérieur licence, master ou doctorat, foundation degree, HNC/HND, NVQ 45 ou qualification professionnelle supérieure. Le recensement ne distingue pas les diplômes de premier cycle de ceux de troisième cycle.",
"D'après le recensement de 2021 (TS067). Le diplôme le plus élevé est de niveau universitaire ou supérieur : licence, master ou doctorat, foundation degree, HNC/HND, NVQ 45 ou qualification professionnelle supérieure. Le recensement ne distingue pas les diplômes de premier cycle de ceux de troisième cycle.",
'% Other qualifications':
"D'après le recensement de 2021 (TS067). Le diplôme le plus élevé est classé « autre » qualifications professionnelles ou techniques non rattachées à un niveau britannique, et diplômes obtenus hors du Royaume-Uni.",
"D'après le recensement de 2021 (TS067). Le diplôme le plus élevé est classé « autre » : qualifications professionnelles ou techniques non rattachées à un niveau britannique, et diplômes obtenus hors du Royaume-Uni.",
'% Owner occupied':
"D'après le recensement de 2021 (TS054). Pourcentage des ménages du quartier (LSOA) qui possèdent leur logement sans crédit, le possèdent avec un emprunt ou un crédit, ou le détiennent en propriété partagée.",
'% Social rent':
"D'après le recensement de 2021 (TS054). Pourcentage des ménages du quartier (LSOA) locataires auprès d'une collectivité ou d'une autorité locale, ou d'un bailleur social ou autre bailleur à vocation sociale.",
'% Private rent':
"D'après le recensement de 2021 (TS054). Pourcentage des ménages du quartier (LSOA) locataires auprès d'un propriétaire privé ou d'une agence de location, plus la faible part logée à titre gratuit.",
'% Council housing':
"Estimé à partir des données d'occupation EPC au sein du code postal : la part de ses logements dont l'historique du certificat de performance énergétique indique que le bien a été à un moment un logement municipal ou social, qu'il soit encore un logement social aujourd'hui ou qu'il ait depuis été vendu (par exemple dans le cadre du Right to Buy). Les logements sans EPC sont comptés comme non municipaux, et un code postal compte peu de logements ; il s'agit donc d'une borne inférieure approximative qui reflète la couverture EPC et n'est pas directement comparable à la part de logements sociaux du recensement.",
'% Ex-council':
"Estimé à partir des données d'occupation EPC au sein du code postal : la part de ses logements autrefois enregistrés comme logement municipal ou social dont le certificat de performance énergétique le plus récent indique une autre forme d'occupation, généralement des logements vendus dans le cadre du Right to Buy. Les logements sans EPC sont comptés comme non municipaux, et un code postal compte peu de logements ; il s'agit donc d'une borne inférieure approximative qui reflète la couverture EPC et n'est pas directement comparable à la part de logements sociaux du recensement.",
'% White':
"Provient du Census 2021. Pourcentage de la population du quartier (LSOA) s'identifiant comme Blanc (anglais, gallois, écossais, nord-irlandais, britannique, irlandais, Gitan ou Voyageur irlandais, Rom, ou tout autre origine blanche).",
'% South Asian':
@ -263,17 +267,21 @@ export const details: Record<string, Record<string, string>> = {
'Aus dem Census 2021 (TS067). Der höchste Abschluss entspricht etwa 5 oder mehr GCSEs mit den Noten 94 (A*C), einer mittleren Ausbildung oder Gleichwertigem.',
'% Apprenticeship': 'Aus dem Census 2021 (TS067). Der höchste Abschluss ist eine Ausbildung.',
'% A-levels':
'Aus dem Census 2021 (TS067). Der höchste Abschluss sind A-levels, AS-levels, T-levels, eine weiterführende Ausbildung oder Gleichwertiges meist nach dem 16. Lebensjahr und vor einem Studienabschluss erworben.',
'Aus dem Census 2021 (TS067). Der höchste Abschluss sind A-levels, AS-levels, T-levels, eine weiterführende Ausbildung oder Gleichwertiges, meist nach dem 16. Lebensjahr und vor einem Studienabschluss erworben.',
'% Degree or higher':
'Aus dem Census 2021 (TS067). Der höchste Abschluss liegt auf Hochschulniveau oder darüber Bachelor, Master oder Doktortitel, Foundation Degree, HNC/HND, NVQ 45 oder höhere berufliche Qualifikation. Der Census unterscheidet nicht zwischen Bachelor- und Masterabschlüssen.',
'Aus dem Census 2021 (TS067). Der höchste Abschluss liegt auf Hochschulniveau oder darüber: Bachelor, Master oder Doktortitel, Foundation Degree, HNC/HND, NVQ 45 oder höhere berufliche Qualifikation. Der Census unterscheidet nicht zwischen Bachelor- und Masterabschlüssen.',
'% Other qualifications':
'Aus dem Census 2021 (TS067). Der höchste Abschluss wird als „sonstiger“ eingestuft berufliche oder fachliche Qualifikationen, die keinem britischen Niveau zugeordnet sind, sowie außerhalb des Vereinigten Königreichs erworbene Abschlüsse.',
'Aus dem Census 2021 (TS067). Der höchste Abschluss wird als „sonstiger“ eingestuft: berufliche oder fachliche Qualifikationen, die keinem britischen Niveau zugeordnet sind, sowie außerhalb des Vereinigten Königreichs erworbene Abschlüsse.',
'% Owner occupied':
'Aus dem Census 2021 (TS054). Prozentsatz der Haushalte in der Nachbarschaft (LSOA), die ihre Wohnung schuldenfrei besitzen, sie mit Hypothek oder Darlehen besitzen oder sie über gemeinschaftliches Eigentum (Shared Ownership) halten.',
'% Social rent':
'Aus dem Census 2021 (TS054). Prozentsatz der Haushalte in der Nachbarschaft (LSOA), die von einer Kommune oder Gemeindeverwaltung oder von einer Wohnungsbaugesellschaft oder einem anderen sozialen Vermieter mieten.',
'% Private rent':
'Aus dem Census 2021 (TS054). Prozentsatz der Haushalte in der Nachbarschaft (LSOA), die von einem privaten Vermieter oder einer Vermittlungsagentur mieten, zuzüglich des kleinen Anteils, der mietfrei wohnt.',
'% Council housing':
'Geschätzt aus EPC-Mietverhältnisdaten innerhalb der Postleitzahl: der Prozentsatz ihrer Wohnungen, deren Energieausweis-Verlauf zeigt, dass die Wohnung irgendwann eine Kommunal- oder Sozialwohnung war, unabhängig davon, ob sie heute noch eine Sozialwohnung ist oder inzwischen verkauft wurde (zum Beispiel über Right to Buy). Wohnungen ohne EPC werden als nicht kommunal gezählt, und eine Postleitzahl umfasst nur wenige Wohnungen, daher ist dies eine grobe Untergrenze, die die EPC-Abdeckung widerspiegelt und nicht direkt mit dem Sozialmietanteil aus dem Census vergleichbar ist.',
'% Ex-council':
'Geschätzt aus EPC-Mietverhältnisdaten innerhalb der Postleitzahl: der Prozentsatz ihrer Wohnungen, die einst als Kommunal- oder Sozialwohnung erfasst wurden und deren neuester Energieausweis eine andere Wohnform ausweist, typischerweise über Right to Buy verkaufte Wohnungen. Wohnungen ohne EPC werden als nicht kommunal gezählt, und eine Postleitzahl umfasst nur wenige Wohnungen, daher ist dies eine grobe Untergrenze, die die EPC-Abdeckung widerspiegelt und nicht direkt mit dem Sozialmietanteil aus dem Census vergleichbar ist.',
'% White':
'Aus dem Census 2021. Prozentsatz der Bevölkerung der Nachbarschaft (LSOA), die sich als Weiß identifiziert (Englisch, Walisisch, Schottisch, Nordirisch, Britisch, Irisch, Sinti und Roma, Roma oder sonstiger weißer Hintergrund).',
'% South Asian':
@ -420,17 +428,21 @@ export const details: Record<string, Record<string, string>> = {
'数据来自 2021 年 CensusTS067。最高学历约为 5 门或以上成绩为 94A*C的 GCSE、中级学徒制或同等资格。',
'% Apprenticeship': '数据来自 2021 年 CensusTS067。最高学历为学徒制。',
'% A-levels':
'数据来自 2021 年 CensusTS067。最高学历为 A-levels、AS-levels、T-levels、高级学徒制或同等资格——通常在 16 岁之后、获得学位之前修读。',
'数据来自 2021 年 CensusTS067。最高学历为 A-levels、AS-levels、T-levels、高级学徒制或同等资格通常在 16 岁之后、获得学位之前修读。',
'% Degree or higher':
'数据来自 2021 年 CensusTS067。最高学历为学位及以上——学士、硕士或博士、预科学位、HNC/HND、NVQ 45或更高级别的职业资格。该 Census 不区分本科与研究生学位。',
'数据来自 2021 年 CensusTS067。最高学历为学位及以上学士、硕士或博士、预科学位、HNC/HND、NVQ 45或更高级别的职业资格。该 Census 不区分本科与研究生学位。',
'% Other qualifications':
'数据来自 2021 年 CensusTS067。最高学历被归为“其他”——未对应到英国级别的职业或专业资格,以及在英国境外取得的学历。',
'数据来自 2021 年 CensusTS067。最高学历被归为“其他”未对应到英国级别的职业或专业资格,以及在英国境外取得的学历。',
'% Owner occupied':
'数据来自 2021 年 CensusTS054。本地社区LSOA中全款拥有自住房、以按揭或贷款拥有自住房或通过共享产权持有住房的家庭百分比。',
'% Social rent':
'数据来自 2021 年 CensusTS054。本地社区LSOA中向地方议会或地方政府或向住房协会及其他社会房东租房的家庭百分比。',
'% Private rent':
'数据来自 2021 年 CensusTS054。本地社区LSOA中向私人房东或租赁中介租房的家庭百分比外加少量免租居住的家庭。',
'% Council housing':
'根据邮编内的 EPC 产权记录估算该邮编中其能源性能证书EPC历史显示该房屋曾经是公共住房或社会住房的房屋百分比无论它今天是否仍是社会住房还是此后已被售出例如通过 Right to Buy。没有 EPC 的房屋被视为非公共住房,且一个邮编包含的房屋很少,因此这是一个粗略的下限,反映的是 EPC 覆盖范围,无法与 Census 的社会租赁占比直接比较。',
'% Ex-council':
'根据邮编内的 EPC 产权记录估算该邮编中曾被记录为公共住房或社会住房、但其最新能源性能证书EPC显示为不同产权的房屋百分比通常是通过 Right to Buy 出售的房屋。没有 EPC 的房屋被视为非公共住房,且一个邮编包含的房屋很少,因此这是一个粗略的下限,反映的是 EPC 覆盖范围,无法与 Census 的社会租赁占比直接比较。',
'% White':
'来自2021年Census。本地社区LSOA人口中认同为白人英格兰人、威尔士人、苏格兰人、北爱尔兰人、英国人、爱尔兰人、吉普赛人或爱尔兰旅行者、罗姆人或其他白人背景的百分比。',
'% South Asian':
@ -574,17 +586,21 @@ export const details: Record<string, Record<string, string>> = {
'2021 की Census (TS067) से। सर्वोच्च योग्यता लगभग 5 या अधिक GCSE है जिनके ग्रेड 94 (A*C) हैं, एक इंटरमीडिएट अप्रेंटिसशिप, या समकक्ष।',
'% Apprenticeship': '2021 की Census (TS067) से। सर्वोच्च योग्यता एक अप्रेंटिसशिप है।',
'% A-levels':
'2021 की Census (TS067) से। सर्वोच्च योग्यता A-levels, AS-levels, T-levels, एक एडवांस्ड अप्रेंटिसशिप, या समकक्ष है आमतौर पर 16 वर्ष की उम्र के बाद और डिग्री से पहले पढ़ी जाती है।',
'2021 की Census (TS067) से। सर्वोच्च योग्यता A-levels, AS-levels, T-levels, एक एडवांस्ड अप्रेंटिसशिप, या समकक्ष है, आमतौर पर 16 वर्ष की उम्र के बाद और डिग्री से पहले पढ़ी जाती है।',
'% Degree or higher':
'2021 की Census (TS067) से। सर्वोच्च योग्यता डिग्री स्तर या उससे ऊपर है बैचलर, मास्टर या PhD, फाउंडेशन डिग्री, HNC/HND, NVQ 45, या उच्च व्यावसायिक योग्यता। Census स्नातक और स्नातकोत्तर डिग्री में अंतर नहीं करती।',
'2021 की Census (TS067) से। सर्वोच्च योग्यता डिग्री स्तर या उससे ऊपर है: बैचलर, मास्टर या PhD, फाउंडेशन डिग्री, HNC/HND, NVQ 45, या उच्च व्यावसायिक योग्यता। Census स्नातक और स्नातकोत्तर डिग्री में अंतर नहीं करती।',
'% Other qualifications':
"2021 की Census (TS067) से। सर्वोच्च योग्यता 'अन्य' श्रेणी में आती है ऐसी व्यावसायिक या पेशेवर योग्यताएं जो किसी UK स्तर से मेल नहीं खातीं, और UK के बाहर प्राप्त योग्यताएं।",
"2021 की Census (TS067) से। सर्वोच्च योग्यता 'अन्य' श्रेणी में आती है: ऐसी व्यावसायिक या पेशेवर योग्यताएं जो किसी UK स्तर से मेल नहीं खातीं, और UK के बाहर प्राप्त योग्यताएं।",
'% Owner occupied':
'2021 की Census (TS054) से। पड़ोस (LSOA) में उन परिवारों का प्रतिशत जो अपना घर पूर्ण रूप से अपने पास रखते हैं, बंधक या ऋण के साथ रखते हैं, या साझा स्वामित्व के माध्यम से रखते हैं।',
'% Social rent':
'2021 की Census (TS054) से। पड़ोस (LSOA) में उन परिवारों का प्रतिशत जो स्थानीय काउंसिल या स्थानीय प्राधिकरण से, या किसी हाउसिंग एसोसिएशन या अन्य सामाजिक मकान-मालिक से किराए पर रहते हैं।',
'% Private rent':
'2021 की Census (TS054) से। पड़ोस (LSOA) में उन परिवारों का प्रतिशत जो किसी निजी मकान-मालिक या किराया एजेंसी से किराए पर रहते हैं, साथ ही बिना किराए के रहने वाला छोटा हिस्सा।',
'% Council housing':
'पोस्टकोड के भीतर EPC स्वामित्व रिकॉर्ड से अनुमानित: उस पोस्टकोड के उन घरों का प्रतिशत जिनके ऊर्जा प्रदर्शन प्रमाणपत्र (EPC) के इतिहास से पता चलता है कि वह घर किसी समय काउंसिल या सामाजिक आवास था, चाहे वह आज भी सामाजिक आवास हो या तब से बेचा जा चुका हो (उदाहरण के लिए Right to Buy के तहत)। जिन घरों का कोई EPC नहीं है उन्हें गैर-काउंसिल माना जाता है, और एक पोस्टकोड में कुछ ही घर होते हैं, इसलिए यह एक मोटी निचली सीमा है जो EPC कवरेज को दर्शाती है और Census के सामाजिक-किराया हिस्से से सीधे तुलनीय नहीं है।',
'% Ex-council':
'पोस्टकोड के भीतर EPC स्वामित्व रिकॉर्ड से अनुमानित: उस पोस्टकोड के उन घरों का प्रतिशत जिन्हें कभी काउंसिल या सामाजिक आवास के रूप में दर्ज किया गया था, लेकिन जिनका सबसे हालिया ऊर्जा प्रदर्शन प्रमाणपत्र (EPC) एक अलग स्वामित्व दिखाता है, आमतौर पर Right to Buy के तहत बेचे गए घर। जिन घरों का कोई EPC नहीं है उन्हें गैर-काउंसिल माना जाता है, और एक पोस्टकोड में कुछ ही घर होते हैं, इसलिए यह एक मोटी निचली सीमा है जो EPC कवरेज को दर्शाती है और Census के सामाजिक-किराया हिस्से से सीधे तुलनीय नहीं है।',
'% White':
'Census 2021 से. स्थानीय पड़ोस (LSOA) की आबादी का प्रतिशत जो खुद को श्वेत (अंग्रेज़, वेल्श, स्कॉटिश, उत्तरी आयरिश, ब्रिटिश, आयरिश, जिप्सी या आयरिश ट्रैवलर, रोमा या किसी अन्य श्वेत पृष्ठभूमि) के रूप में पहचानता है.',
'% South Asian':
@ -733,17 +749,21 @@ export const details: Record<string, Record<string, string>> = {
'A 2021-es Census (TS067) alapján. A legmagasabb végzettség körülbelül 5 vagy több GCSE 94 (A*C) osztályzattal, középszintű tanoncképzés vagy ezzel egyenértékű.',
'% Apprenticeship': 'A 2021-es Census (TS067) alapján. A legmagasabb végzettség tanoncképzés.',
'% A-levels':
'A 2021-es Census (TS067) alapján. A legmagasabb végzettség A-levels, AS-levels, T-levels, emelt szintű tanoncképzés vagy ezzel egyenértékű jellemzően 16 éves kor után és a diploma előtt szerezhető meg.',
'A 2021-es Census (TS067) alapján. A legmagasabb végzettség A-levels, AS-levels, T-levels, emelt szintű tanoncképzés vagy ezzel egyenértékű, jellemzően 16 éves kor után és a diploma előtt szerezhető meg.',
'% Degree or higher':
'A 2021-es Census (TS067) alapján. A legmagasabb végzettség diploma szintű vagy afölötti alapdiploma, mesterdiploma vagy PhD, foundation degree, HNC/HND, NVQ 45, vagy magasabb szakmai képesítés. A Census nem különbözteti meg az alap- és mesterszintű diplomákat.',
'A 2021-es Census (TS067) alapján. A legmagasabb végzettség diploma szintű vagy afölötti: alapdiploma, mesterdiploma vagy PhD, foundation degree, HNC/HND, NVQ 45, vagy magasabb szakmai képesítés. A Census nem különbözteti meg az alap- és mesterszintű diplomákat.',
'% Other qualifications':
'A 2021-es Census (TS067) alapján. A legmagasabb végzettség „egyéb“ besorolású olyan szakmai vagy hivatásbeli képesítések, amelyek nem feleltethetők meg egy brit szintnek, valamint az Egyesült Királyságon kívül szerzett képesítések.',
'A 2021-es Census (TS067) alapján. A legmagasabb végzettség „egyéb“ besorolású: olyan szakmai vagy hivatásbeli képesítések, amelyek nem feleltethetők meg egy brit szintnek, valamint az Egyesült Királyságon kívül szerzett képesítések.',
'% Owner occupied':
'A 2021-es Census (TS054) alapján. A környéken (LSOA) azon háztartások százaléka, amelyek tehermentesen birtokolják lakásukat, jelzáloggal vagy kölcsönnel birtokolják, vagy résztulajdon (shared ownership) keretében tartják.',
'% Social rent':
'A 2021-es Census (TS054) alapján. A környéken (LSOA) azon háztartások százaléka, amelyek helyi önkormányzattól vagy hatóságtól, illetve lakásszövetkezettől vagy más szociális bérbeadótól bérelnek.',
'% Private rent':
'A 2021-es Census (TS054) alapján. A környéken (LSOA) azon háztartások százaléka, amelyek magán bérbeadótól vagy ingatlanügynökségtől bérelnek, kiegészülve a lakbér nélkül lakók kis arányával.',
'% Council housing':
'Az irányítószámon belüli EPC-bérlettörténeti adatokból becsülve: azon lakásainak százaléka, amelyek energiatanúsítványának (EPC) előzményei szerint a lakás valamikor önkormányzati vagy szociális lakás volt, függetlenül attól, hogy ma is szociális lakás-e vagy azóta eladták (például a Right to Buy keretében). Az EPC nélküli lakások nem önkormányzatinak számítanak, és egy irányítószám kevés lakást foglal magában, így ez egy durva alsó becslés, amely az EPC-lefedettséget tükrözi, és nem hasonlítható közvetlenül a Census szociális bérlakás-arányához.',
'% Ex-council':
'Az irányítószámon belüli EPC-bérlettörténeti adatokból becsülve: azon lakásainak százaléka, amelyeket egykor önkormányzati vagy szociális lakásként rögzítettek, de amelyek legutóbbi energiatanúsítványa (EPC) más lakhatási formát mutat, jellemzően a Right to Buy keretében eladott lakások. Az EPC nélküli lakások nem önkormányzatinak számítanak, és egy irányítószám kevés lakást foglal magában, így ez egy durva alsó becslés, amely az EPC-lefedettséget tükrözi, és nem hasonlítható közvetlenül a Census szociális bérlakás-arányához.',
'% White':
'A 2021-es Census alapján. A helyi környéken (LSOA) fehérként (angol, walesi, skót, észak-ír, brit, ír, cigány vagy ír vándor, roma, vagy bármely más fehér háttér) azonosított népesség százaléka.',
'% South Asian':

View file

@ -0,0 +1,37 @@
// @vitest-environment jsdom
import { describe, it, expect, beforeEach, vi } from 'vitest';
describe('language init from ?lang param', () => {
beforeEach(() => {
vi.resetModules();
localStorage.clear();
window.history.replaceState({}, '', '/');
});
it('applies, persists, and strips a ?lang param', async () => {
window.history.replaceState({}, '', '/?lang=de&foo=1');
const mod = await import('./index');
expect(mod.INITIAL_LANGUAGE).toBe('de');
expect(localStorage.getItem('language')).toBe('de');
expect(window.location.search).toBe('?foo=1');
});
it('lets a later stored choice win once ?lang has been stripped', async () => {
window.history.replaceState({}, '', '/?lang=de');
let mod = await import('./index');
expect(mod.INITIAL_LANGUAGE).toBe('de');
// user switches in-app -> dropdown writes localStorage
localStorage.setItem('language', 'en');
// reload (param was stripped, so URL has no lang)
vi.resetModules();
window.history.replaceState({}, '', '/');
mod = await import('./index');
expect(mod.INITIAL_LANGUAGE).toBe('en');
});
it('falls back to stored language when no ?lang is present', async () => {
localStorage.setItem('language', 'fr');
const mod = await import('./index');
expect(mod.INITIAL_LANGUAGE).toBe('fr');
});
});

View file

@ -44,15 +44,49 @@ function getUrlLanguage(): LanguageCode | null {
}
}
function setStoredLanguage(code: LanguageCode): void {
try {
localStorage.setItem('language', code);
} catch {
// Storage unavailable (private mode / disabled cookies); ignore.
}
}
// A ?lang= param is a one-time initializer (shared links, screenshot/OG image
// URLs). Strip it after consuming so a stale value can't override a later
// in-app language switch on reload.
function clearUrlLanguageParam(): void {
try {
if (typeof window === 'undefined' || !window.history?.replaceState) return;
const url = new URL(window.location.href);
if (!url.searchParams.has('lang')) return;
url.searchParams.delete('lang');
const search = url.searchParams.toString();
window.history.replaceState(
window.history.state,
'',
`${url.pathname}${search ? `?${search}` : ''}${url.hash}`
);
} catch {
// Malformed URL or unsupported history API; ignore.
}
}
function getBrowserLanguages(): readonly string[] {
if (typeof navigator === 'undefined') return [];
return navigator.languages?.length ? navigator.languages : [navigator.language];
}
function detectLanguage(): LanguageCode {
// 1. Explicit URL language, used by generated screenshot/OG image URLs.
// 1. Explicit URL language (shared links, screenshot/OG image URLs).
// Consume once: persist as the user's choice and strip from the URL so a
// stale ?lang can't override a later in-app language switch on reload.
const urlLanguage = getUrlLanguage();
if (urlLanguage) return urlLanguage;
if (urlLanguage) {
setStoredLanguage(urlLanguage);
clearUrlLanguageParam();
return urlLanguage;
}
// 2. Explicit user choice (persisted from the language dropdown)
const stored = getStoredLanguage();