From e94617e9ff485adf5668487af9e2681604948fd1 Mon Sep 17 00:00:00 2001 From: Melo46 Date: Mon, 15 Apr 2024 15:22:42 +0000 Subject: [PATCH 01/69] Pontoon: Update Interlingua (ia) localization of Common Voice Co-authored-by: Melo46 --- web/locales/ia/messages.ftl | 1 + 1 file changed, 1 insertion(+) diff --git a/web/locales/ia/messages.ftl b/web/locales/ia/messages.ftl index 8c62355f5abf..25d57626ce47 100644 --- a/web/locales/ia/messages.ftl +++ b/web/locales/ia/messages.ftl @@ -684,6 +684,7 @@ about-playbook-how-project-governance-content-7 = Lege plus re c about-playbook-how-funded = Como es financiate Common Voice? about-playbook-how-funded-content-1 = Common Voice es un projecto del Mozilla Foundation, un organisation US 501c3. +about-playbook-how-funded-content-2 = Il costa tante moneta continuemente hospitar e publicar le collectiones de datos, meliorar le platteforma e exequer programmas de communitate. ## Glossary From 7273ed53b33d02bc83e9c7530e7da715102a5b66 Mon Sep 17 00:00:00 2001 From: Melo46 Date: Mon, 15 Apr 2024 15:32:45 +0000 Subject: [PATCH 02/69] Pontoon: Update Interlingua (ia) localization of Common Voice Co-authored-by: Melo46 --- web/locales/ia/messages.ftl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/locales/ia/messages.ftl b/web/locales/ia/messages.ftl index 25d57626ce47..aab1c823b4f4 100644 --- a/web/locales/ia/messages.ftl +++ b/web/locales/ia/messages.ftl @@ -685,6 +685,7 @@ about-playbook-how-project-governance-content-7 = Lege plus re c about-playbook-how-funded = Como es financiate Common Voice? about-playbook-how-funded-content-1 = Common Voice es un projecto del Mozilla Foundation, un organisation US 501c3. about-playbook-how-funded-content-2 = Il costa tante moneta continuemente hospitar e publicar le collectiones de datos, meliorar le platteforma e exequer programmas de communitate. +about-playbook-how-funded-content-3 = Si a vos o a vostre organisation placerea contribuer al projecto, vos pote facer un donation o contactar le equipa de nostre societates a commonvoice@mozilla.com. ## Glossary @@ -815,6 +816,7 @@ dataset-metadata-sex = Genere dataset-metadata-age = Etate donate-modal-message = Tu collection de datos es discargate! dataset-donate-modal-heading = Sape tu… +donate-modal-explanation-1 = Il costa quasi un million de dollars per anno le allogiamento del collectiones de datos e meliorar le platteforma pro le plus que 100 communitates linguistic que conta sur illo que nos face? # Text in will shown in bold donate-modal-explanation-2 = So tu apprecia le datos gratuite e inclusive - dona hodie! @@ -1735,6 +1737,7 @@ reviewing-sentences-explanation-1 = Si le phrase satisface le precedente criteri reviewing-sentences-explanation-2 = Si le phrase no satisface le precedente criterios, clicca le button "No". reviewing-sentences-explanation-3 = Si tu non es secur re le phrase, tu pote alsi saltar lo e mover al successive. reviewing-sentences-explanation-4 = Si tu exhauri le phrases a revider, per favor adjuta nos a colliger altere phrases! +domain-explanation = Le dominio se refere al materia del phrase. Actualmente, vos pote eliger inter: ## WRITE PAGE From f9877f5b59338850cdc179156f4407fe27637835 Mon Sep 17 00:00:00 2001 From: Melo46 Date: Mon, 15 Apr 2024 15:52:59 +0000 Subject: [PATCH 03/69] Pontoon: Update Interlingua (ia) localization of Common Voice Co-authored-by: Melo46 --- web/locales/ia/messages.ftl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/web/locales/ia/messages.ftl b/web/locales/ia/messages.ftl index aab1c823b4f4..425c46d04224 100644 --- a/web/locales/ia/messages.ftl +++ b/web/locales/ia/messages.ftl @@ -1847,3 +1847,8 @@ too-many-files = Troppo de files # Text wrapped in will have a white background. donate-banner-cta = Nos besonia
tu adjuta! +# Text wrapped in will be rendered on bold font +donate-banner-cta-explanation = Il costa quasi un million de dollars per anno le allogiamento del collectiones de datos e le melioration del platteforma pro le plus que 100 communitates linguistic que conta sur illo que nos face. Si vos apprecia le datos gratuite e inclusive: dona hodie! +# Text wrapped in will have a white background. +languages-donate-banner-cta = Usa vos CV pro
vostre recerca? +languages-donate-banner-cta-explanation = Common Voice es financiate per donationes e subventiones! Nos ama collaborar con academicos, recercatores de societate civil e industria. Le uso de Common Voice es gratuite, ma contribuer al platteforma e al costos de allogiamento proponente subventiones es realmente utile. From a1b969cbb9d784d28abee67a18dd009eb120028e Mon Sep 17 00:00:00 2001 From: lazerkatamara Date: Mon, 15 Apr 2024 17:33:05 +0000 Subject: [PATCH 04/69] Pontoon: Update Ukrainian (uk) localization of Common Voice Co-authored-by: lazerkatamara --- web/locales/uk/messages.ftl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/web/locales/uk/messages.ftl b/web/locales/uk/messages.ftl index 8f3d55ff371c..1b3833323ff6 100644 --- a/web/locales/uk/messages.ftl +++ b/web/locales/uk/messages.ftl @@ -697,6 +697,9 @@ about-playbook-how-project-governance-content-5 = Цінність і визна about-playbook-how-project-governance-content-6 = Взаємовідповідальність. about-playbook-how-project-governance-content-7 = Докладніше про керування +## How is Common Voice funded + + ## Glossary glossary = Глосарій @@ -796,6 +799,8 @@ subscribe = Підписатись get-started-speech = Початок роботи з розпізнаванням мови other-datasets = Інші набори голосових даних feedback-q = Залишити відгук +# This indicates that there is no data to display +no-information = Немає інформації resource-nemo-info = NVIDIA NeMo™ — це набір інструментів з відкритим кодом для дослідників, які розробляють найсучасніші розмовні моделі ШІ. resource-deepspeech-info = Рушій розпізнавання голосу з відкритим кодом Mozilla Deep Speech можна застосовувати для створення застосунків для розпізнавання мовлення. Прочитайте наш огляд на Github або приєднайтеся до DeepSpeech Discourse, щоб дізнатися, як розпочати роботу. resource-coqui-info = Coqui створено для технології відкритого мовлення. Їхні проєкти включають STT та TTS на основі глибокого навчання. @@ -1938,3 +1943,10 @@ file-invalid-type = Неприпустимий файл file-too-large = Файл завеликий file-too-small = Файл замалий too-many-files = Забагато файлів + +## Donate banner + +# Text wrapped in will have a white background. +donate-banner-cta = Нам потрібна
ваша допомога! +# Text wrapped in will have a white background. +languages-donate-banner-cta = Використовуєте резюме для
дослідження? From 208bc73b99696be24a53676d4c81161de0fb0479 Mon Sep 17 00:00:00 2001 From: Raivis Date: Tue, 16 Apr 2024 05:46:06 +0000 Subject: [PATCH 05/69] Pontoon: Update Latvian (lv) localization of Common Voice Co-authored-by: Raivis --- web/locales/lv/messages.ftl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/locales/lv/messages.ftl b/web/locales/lv/messages.ftl index ebd2006ffe2e..d4f06447a8df 100644 --- a/web/locales/lv/messages.ftl +++ b/web/locales/lv/messages.ftl @@ -800,6 +800,8 @@ subscribe = Pierakstīties get-started-speech = Darba sākšana ar runas atpazīšanu other-datasets = Citas balss datu kopas feedback-q = Vai jums ir atsauksmes? +# This indicates that there is no data to display +no-information = Informācija nav pieejama resource-nemo-info = NVIDIA NeMo™ ir atvērtā koda rīkkopa pētniekiem, kas izstrādā jaunākos sarunvalodas mākslīgā intelekta modeļus. resource-deepspeech-info = Common Voice datu kopa papildina Mozilla atvērtā koda balss atpazīšanas dzinēju Deep Speech, ko var izmantot, lai izveidotu runas atpazīšanas programmas. Izlasiet mūsu Github pārskatu vai pievienojieties DeepSpeech Discourse, lai uzzinātu, kā sākt darbu. resource-coqui-info = Coqui veltīta atvērtās runas tehnoloģijas attīstībai. Viņu projekti ietver dziļās mācīšanās metodēs balstītus STT un TTS dzinējus. @@ -1982,6 +1984,7 @@ single-sentence = Viens teikums bulk-sentences = Vairāki teikumi sentence-domain-select = .label = Teikuma joma +sentence-domain-select-placeholder = Izvēlieties līdz trim jomām # Sentence Domain dropdown option agriculture = Lauksaimniecība # Sentence Domain dropdown option From 70029cfdc192e636b22163f46518c34f963095df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Mesk=C3=B3?= Date: Tue, 16 Apr 2024 13:13:43 +0000 Subject: [PATCH 06/69] Pontoon: Update Hungarian (hu) localization of Common Voice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Balázs Meskó --- web/locales/hu/messages.ftl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/locales/hu/messages.ftl b/web/locales/hu/messages.ftl index 5fca4b6f8aad..2bfa9a9d4291 100644 --- a/web/locales/hu/messages.ftl +++ b/web/locales/hu/messages.ftl @@ -455,6 +455,7 @@ help-accent = Segítségre van szüksége az akcentussal kapcsolatban? help-accent-explanation = Az akcentusa az, ahogy a szavakat kiejti. Alakíthatja hogy hol élt, milyen más nyelveket beszél, és sok egyéb tényező. Itt megoszthat minden olyan információt, amelyet relevánsnak érez. help-variants = Segítségre van szüksége a változatokkal kapcsolatban? help-variants-explanation = A változatok egy nyelv sajátos formáját jelentik – például egy adott földrajzi területen vagy közösségben élők közös nyelvi formáját. Néha ezeket dialektusoknak nevezik. +help-sex-or-gender-changes = Segítségre van szüksége a nem vagy nemi identitás változásával kapcsolatban? help-sex-or-gender-changes-explanation = Több lehetőséget kínálunk, hogy az emberek nemükről vagy nemi identitásukról többféle választási lehetőség közül választhassanak. Írja le magát az Ön számára legtermészetesebb módon. Tudjon meg többet a biológiai és a társadalmi nemről alkotott megközelítésünkről. ## Profile - Email @@ -785,6 +786,8 @@ subscribe = Feliratkozás get-started-speech = Első lépések a beszédfelismeréssel other-datasets = Más hangadatkészletek feedback-q = Visszajelzése van? +# This indicates that there is no data to display +no-information = Nincs információ resource-nemo-info = Az NVIDIA NeMo™ egy nyílt forráskódú eszközkészlet a legmodernebb társalgási MI modelleket fejlesztő kutatók számára. resource-deepspeech-info = A Mozilla nyílt forráskódú hangfelismerő motorja, a Deep Speech, beszédfelismerő alkalmazások készítéséhez használható. Olvassa el a Github áttekintést, vagy az első lépésekhez csatlakozzon a DeepSpeech Discourse-hoz. resource-coqui-info = A Coqui elkötelezett a nyílt beszédtechnológia iránt. A projektjeik közé tartoznak a mély tanuláson alapuló STT (beszédfelismerés) és TTS (beszédszintézis) motorok. @@ -1771,6 +1774,7 @@ single-sentence = Egyetlen mondat bulk-sentences = Több mondat sentence-domain-select = .label = Mondatdomén +sentence-domain-select-placeholder = Válasszon legfeljebb három domént # Sentence Domain dropdown option agriculture = Mezőgazdaság # Sentence Domain dropdown option From 2cc91c64ec934fa6aac0cd30d72ac57caf7d1fc6 Mon Sep 17 00:00:00 2001 From: Waleghwa Date: Tue, 16 Apr 2024 16:43:06 +0000 Subject: [PATCH 07/69] Pontoon: Update Kidaw'ida (dav) localization of Common Voice Co-authored-by: mkawanyika62 Co-authored-by: Waleghwa --- web/locales/dav/messages.ftl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/web/locales/dav/messages.ftl b/web/locales/dav/messages.ftl index 89557a05fa6b..84ec239d55db 100644 --- a/web/locales/dav/messages.ftl +++ b/web/locales/dav/messages.ftl @@ -653,6 +653,11 @@ about-playbook-how-project-governance-content-5 = Nguma na kumanyika. about-playbook-how-project-governance-content-6 = W'uhachi kwa mipande rose. about-playbook-how-project-governance-content-7 = Shoma zaidi aighu ya w'utawali ghodu +## How is Common Voice funded + +about-playbook-how-funded = Pesa reagha Common Voice rafumagha hao? +about-playbook-how-funded-content-1 = Common Voice ni nmradi ghwa Mozilla Foundation, w'eko na 501c3 aja Amerika. Mradi ughu ghwagaramilwa putu ni mafunyo gha w'andu, na manosi gha w'andu andu kose w'urumwengunyi. + ## Glossary glossary = Kamusi @@ -1304,3 +1309,6 @@ bulk-sentence-submission = Kuchanga Msigo Ghwa Sentensi ## BULK SUBMISSION + +## Donate banner + From 28e2d132dbc73ed60018fed3bffb86e2df6de7db Mon Sep 17 00:00:00 2001 From: Jasmine Date: Wed, 17 Apr 2024 13:33:02 +0000 Subject: [PATCH 08/69] Pontoon: Update Punjabi (pa-IN) localization of Common Voice Co-authored-by: Jasmine --- web/locales/pa-IN/messages.ftl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/locales/pa-IN/messages.ftl b/web/locales/pa-IN/messages.ftl index b036d14d253e..fba6be1be531 100644 --- a/web/locales/pa-IN/messages.ftl +++ b/web/locales/pa-IN/messages.ftl @@ -260,7 +260,7 @@ no-clips-to-validate = ਇੰਜ ਜਾਪਦਾ ਹੈ ਕਿ ਇਸ ਭਾਸ vote-yes = ਹਾਂ vote-no = ਨਹੀਂ toggle-play-tooltip = ਪਲੇ ਮੋਡ ਵਿੱਚ ਟੌਗਲ ਕਰਨ ਲਈ { shortcut-play-toggle } ਦਬਾਓ -speak-subtitle = ਆਪਣੀ ਆਵਾਜ਼ ਪ੍ਰਦਾਨ ਕਰੋ +speak-subtitle = ਆਪਣੀ ਆਵਾਜ਼ ਦਾਨ ਕਰੋ speak-paragraph = ਵੌਇਸ ਕਲਿੱਪਾਂ ਨੂੰ ਰਿਕਾਰਡ ਕਰਨਾ ਸਾਡੇ ਖੁੱਲੇ ਡੇਟਾਸੇਟ ਨੂੰ ਬਣਾਉਣ ਦਾ ਇਕ ਅਨਿੱਖੜਵਾਂ ਅੰਗ ਹੈ; ਕੁਝ ਕਹਿੰਦੇ ਹਨ ਕਿ ਇਹ ਮਜ਼ੇਦਾਰ ਹਿੱਸਾ ਵੀ ਹੈ। speak-goal-text = ਰਿਕਾਰਡ ਕੀਤੇ ਕਲਿੱਪ listen-subtitle = ਆਵਾਜ਼ਾਂ ਪ੍ਰਮਾਣਿਤ ਕਰਨ ‘ਚ ਸਾਡੀ ਮਦਦ ਕਰੋ @@ -272,7 +272,7 @@ voices-online = ਹੁਣ ਆਵਾਜ਼ਾਂ ਆਨਲਾਈਨ todays-progress = ਅੱਜ ਦੀ ਤਰੱਕੀ help-reach-goal = { $goal } ਤੱਕ ਪਹੁੰਚਣ ਲਈ ਸਾਡੀ ਮਦਦ ਕਰੋ read-terms-q = ਕੀ ਤੁਸੀਂ ਸਾਡੀਆਂ ਸ਼ਰਤਾਂ ਪੜ੍ਹੀਆਂ ਹਨ? -ready-to-record = ਆਪਣੀ ਆਵਾਜ਼ ਪ੍ਰਦਾਨ ਕਰਨ ਲਈ ਤਿਆਰ ਹੋ? +ready-to-record = ਆਪਣੀ ਆਵਾਜ਼ ਦਾਨ ਕਰਨ ਲਈ ਤਿਆਰ ਹੋ? all-locales = ਸਭ today = ਅੱਜ x-weeks-short = From fb736b4b890278a93ac608371330eaacfa1867bc Mon Sep 17 00:00:00 2001 From: Mubasher Kaleem Date: Wed, 17 Apr 2024 13:53:32 +0000 Subject: [PATCH 09/69] Pontoon: Update Saraiki (skr) localization of Common Voice Co-authored-by: Parvez Qadir Co-authored-by: Mubasher Kaleem --- web/locales/skr/messages.ftl | 64 ++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/web/locales/skr/messages.ftl b/web/locales/skr/messages.ftl index 3d314df8b864..c340d91f53df 100644 --- a/web/locales/skr/messages.ftl +++ b/web/locales/skr/messages.ftl @@ -421,7 +421,9 @@ profile-form-submit-save = محفوظ profile-form-submit-saved = محفوظ تھیا male_masculine = مرد/مذکر female_feminine = تریمت/مؤنث +intersex = ٹرانسجینڈر transgender = ہیجڑا +non-binary = غیر-بائنری do_not_wish_to_say = کجھ کائنی ݙساوݨ چاہندا # Gender other = ٻیا @@ -460,6 +462,8 @@ help-accent = لہجے وچ کجھ مدد دی لوڑ ہے؟ help-accent-explanation = تہاݙا لہجہ او طریقہ ہے جیندے نال تساں لفظاں دا تلفظ کریندے ہو. تساں کتھاں راہندے ہو، تساں ٻیاں کہڑیاں زباناں الیندے ہو تے ٻئے ٻہوں سارے عوامل نال بݨدا ہے. تساں کوئی وی معلومات جنہاں کوں تساں اہم سمجھدے ہو، اتھ سان٘جھیاں کر سڳدے ہو. help-variants = لہجیاں وچ کجھ مدد دی لوڑ ہے؟ help-variants-explanation = متغیرات زبان دی ہک مخصوص شکل ہن ــ مثال دے طور تے ہک برادری یا جغرافیہ وچ راہوݨ آلیاں ولوں سانجھا۔ کہیں کہیں ویلے انہاں کوں لہجے آہدن۔ +help-sex-or-gender-changes = بھلا جنس یا صنفی تبدیلیاں وِچ مَدَت دی لوڑ ہِے؟ +help-sex-or-gender-changes-explanation = اَساں لوکاں کوں آپݨی جنس یا صنفی سُن٘ڄاݨ دے بارے وِچ جہڑا کُجھ ݙَسین٘دے ہِسے اُون٘دے وِچ اُنّھاں کوں چوݨ ݙیوݨ کِیتے ٻئے چوݨ پیش کرین٘دے پئے ہِسے۔ تھورائیت کرین٘ے ہوئے آپݨے آپ کوں اِیں انداز وِچ ݙَساؤ جہڑا تُہاکوں سچّی وِچ محسوس تِھین٘دا ہِٖ۔ جنس اَتے صنف دے بارے وِچ اَساݙے نقطۂ نظر دے بارے وِچ ٻِیا ڄاݨُو۔ ## Profile - Email @@ -691,6 +695,10 @@ about-playbook-how-project-governance-content-7 = اساں حک ## How is Common Voice funded +about-playbook-how-funded = کامن وائس دی مالی مَدَت کِین٘ویں کِیتی وین٘دی ہِے؟ +about-playbook-how-funded-content-1 = کامن وائس موزیلا فاؤنڈیشن دا ہِک منصوبہ ہِے، ہِک یو ایس 501 سی3۔ اِیہ منصوبہ اِیں ویلے مخیّر امداد ، اتے ساری دُنیاں دے لوکاں دے دان نال چلدا پئے۔ +about-playbook-how-funded-content-2 = ڈیٹا سیٹاں دی مسلسل میزبانی اَتے ریلیز کرݨ، پلیٹ فارم کوں چنڳاں کرݨ اَتے کمیونٹی پروگرامز کوں چلاوݨ وِچ ٻہوں وَدھ رقم خرچ تھین٘دی ہِے۔ +about-playbook-how-funded-content-3 = ڄیکر تُساں یا تُہاݙی تنظیم اِیں منصوبے وِچ وَلا حِصّہ پاوݨاں چاہن٘دے ہِیوے، تاں تُساں ہِک عطیہݙے سڳدے ہِیوے یا وَل commonvoice@mozilla.com اُتے اَساݙے بَھئیوال جَتّھے نال رابطہ کر سڳدے ہِیوے۔ ## Glossary @@ -769,10 +777,12 @@ validated-hr-total = کل تصدیق تھئے گھنٹے overall-hr-total = کُل مجموعی گھنٹے cv-license = لائسنس audio-format = آڈیو فارمیٹ +dataset-splits = ون٘ݙ (عمر اتے جنس) number-of-voices = اوازوں دی تعداد splits = ٹکڑے email-to-download = ڈاؤن لوڈ کرݨ کیتے ای میل درج کرو why-email = ہک ای میل کیوں؟ ڈیٹا سیٹ وچ تبدیلیاں بارے ساکوں مستقبل وچ تہاݙے نال رابطہ کرݨ دی لوڑ پئے سڳدی ہے، ہک ای میل ساکوں رابطے دا ہک موقع ݙیندے۔ +why-donate-datasets-page = موزیلا کامن وائس دُنیاں دا ساریاں کنوں متنوع کراؤڈ سورس اوپن سپیچ ڈیٹا سیٹ ہے - اَتے اَساں پوری طرحاں عطیاں نال چلدے ہِسے۔ ڈیٹا سیٹس دی میزبانی کرݨ اَتے 100+ ٻولیاں دی کمیونیٹیز کِیتے پلیٹ فارم کوں چَنڳا بݨاوݨ کِیتے تقریباً ہِک ملین ڈالر سالانہ خرچ تِھین٘دے ہِن جہڑے اَساݙے کِیتے اُتے بھرواسا کرین٘دے ہِن۔ ڄیکر تُساں کُھلّے، جامع ڈیٹا دی قدر کرین٘دے ہِیوے اَڄّو عطیہ کرو! confirm-size = تساں { $size } کوں ڈاؤن لوڈ شروع کرݨ کیتے تیار ہو size-gigabyte = جی بی size-megabyte = ایم بی @@ -821,6 +831,11 @@ no-information-available = کوئی معلومات دستیاب کائنی۔ dataset-metadata-sex = جنس # dataset metadata - age of contributor dataset-metadata-age = عمر +donate-modal-message = تُہاݙا ڈیٹا شیٹ ڈاؤن لوڈ تھین٘دی پئی ہِے! +dataset-donate-modal-heading = بَھلا تُہاکوں پَتہ ہِے… +donate-modal-explanation-1 = ڈیٹا سیٹس دی میزبانی کرݨ اَتے 100+ ٻولیاں دیاں بِیادریاں جِہڑیاں اَساݙے اُتے بھرواسہ کرین٘دیاں ہِن اُنّھاں کِیتے پلیٹ فارم کوں چَنڳا بݨاوݨ کِیتے تقریباً ہِک ملین ڈالر سالانہ خرچ تِھین٘دے ہِن؟ +# Text in will shown in bold +donate-modal-explanation-2 = ڄیکر تُساں اوپن، جامع ڈیٹا دی قدر کرین٘دے ہِیوے - اَڄّو عطیہ کرو! ## Download Modal @@ -1639,6 +1654,7 @@ create-profile-button = پروفائل بݨاؤ img-alt-success-checkmark = کامیابی دا نشان # GUIDELINES PAGE guidelines-header = ونگار دے رہنما اصول +guidelines-header-subtitle = کامن وائس ڈیٹا سیٹ وِچ جُملیاں اَتے آڈیو کلپس دے تعاون اَتے جواز ݙیؤݨ دا طریقہ سمجھو voice-collection = اوازاں دا مجموعہ sentence-collection = فقریاں دا مجموعہ varying-pronunciations = بدلدا ہویا تلفظ @@ -1655,6 +1671,8 @@ varying-pronunciations-explanation-2 = ݙوجھے پاسے، جے تہاکوں varying-pronunciations-example = رستہ واضح کائناں ہائی۔ varying-pronunciations-tip-1 = [کینیڈین انگریزی وچ "رُوٹ" دی آواز "rowt" وانگوں تھی سڳدی ہے] varying-pronunciations-tip-2 = [برطانوی انگریزی "ڄڑھ" بݨا سڳدی ہے] +offensive-content-explanation = جُملے دی پَرکھ کمیونٹی دے اعتدال دے عمل دے ذریعے کِیتی وین٘دی ہِے، تاں جو اِیہ عمل کامل کائے نِھیں، ڄیکر تُساں کُئی اِیہو جیہاں جُملہ ݙیہدے یا سُݨدے ہِیوے جیہڑا تُہاکوں اَوازار یا پریشان کرین٘دا ہِے - مثال دے طور تے کیوں جو اِیہ اَساݙی کمیونٹی بَھئیوالی دے رہنما خطوط دی خلاف ورزی کرین٘دا ہِے - تاں تھورائیت کرین٘دے ہوئے یو آئی وِچ جھنڈے آلے بٹݨ دا استعمال کرو۔ تُساں commonvoice@mozilla.com اُتے وِی اَساݙے نال رابطہ کر سڳدے ہِیوے۔ +misreadings-explanation-1 = پَنّے اُتے موجود سارے لوّظاں کوں صحیح طریقے نال پڑھݨ نال فرق پون٘دا ہِے۔ سُݨن ویلے، ٻہوں بھال پاؤ جو جِہڑا کُجھ ریکارڈ کِیتا ڳِیا ہِے اُوہ اَصلُوں اُوہو اِی ہِے جِہڑا کُجھ لِکّھیا ڳِیا ہِے۔ مسترد کرو ڄیکر اُنّھاں نے لوّظ رلائے ہِن، معاہدہ کِیتا ہِے یا چھوٹ ݙِتّی ہِے۔ misreadings-explanation-2 = عام غلطیاں وچ شامل ہن: misreadings-explanation-3 = ریکاڈنگ دے شروع وچ 'A' یا 'The' غائب ہے۔ misreadings-explanation-4 = لفظ دے چھیکڑ تے 'س' غائب ہے۔ @@ -1668,12 +1686,14 @@ misreadings-example-4 = بھون٘را تکھے تکھے اڳوں تے چلا ڳ misreadings-tip-1 = [ہووݨاں چاہیدا ہے "اساں ہیں"] misreadings-tip-2 = [اصل عبارت وچ کوئی ‘a’ کائنی] misreadings-tip-3 = [غیر مماثل مواد] +background-noise-explanation = تُہاکوں ریکارڈنگ دے ہر لوّظ کوں سُݨن دے قابل ہووݨ دی لوڑ ہِے۔ اَساں چاہن٘دے ہِسے کو مشین لرننگ الگورتھم اَن٘جو اَن٘ج ونکی دے پِچھوکڑ منظر دے شور کوں وَرتݨ دے قابل ہووِن، اَتے اِیہ تئیں جو نسبتاً اُچّی اَواز یا پُر سکون پِچھوکڑ منظر دی موسیقی کوں وی قبول کِیتا ون٘ڄ سڳین٘دا ہِے اِیں شرط تے جو اُوہ تُہاکوں پُورا مواد سُݨن کنوں نہ روکے۔ کریکلز یا 'بریک اپ' جہڑے تُہاکوں مواد سُݨن کنوں رُکین٘دے ہِن اِین٘دا مطلب ہِے جو تُہاکوں کلپ کوں مسترد کر ݙیوݨاں چاہِیدا ہِے۔ background-noise-example-1 = ٹریاسک دے دیوہیکل ڈایناسور۔ background-noise-example-2 = [نچھ] [کھنگھ] ٹریاسک دے دیوہیکل ڈایناسور. background-noise-example-3 = ٹریاسک دا دیوہیکل ڈاینا [کف]۔ background-noise-example-4 = [کریکل] ـ ریاسک دے [کریکل] دیوہیکل ڈایناسور۔ background-noise-tip-1 = [پس منظر دے شور کنوں روکیا ہویا] background-noise-tip-2 = [عبارت دا حصہ کائنی سُݨ سڳیندا] +background-voices-explanation = ذری جِتّی پس منظر دا شور چل ویسی، پَر ڄیکر تُساں کئیں ٻئے بندے کوں وَکّھو وَکھ لوّظ ٻُلین٘دے ہوئے سُݨ سڳدے ہِیوے، تاں کلپ کوں مسترد کر ݙیوݨاں چاہِیدا ہِے، عام طور تے اِین٘ویں تِھین٘دا ہِے جِتّھاں ٹی وی کوں چھوڑ ݙِتّا ڳِیا ہووے، یا جِتّھاں نیڑے اِی کُئی ڳالھ مُہاڑ تھین٘دی پئی ہووے۔ background-voices-example-1 = ٹریاسک دے دیوہیکل ڈایناسور، [ہک اواز نال پڑھو] background-voices-tip-1 = بھلا تساں آن٘دے پئے ہو؟ [ٻئے ولوں سݙا] volume-explanation = قارئین دے وِچال حجم وِچ قدرتی تغیرات ہوسن۔ صرف ایں صورت وِچ رد کرو جݙاں حجم اتنا زیادہ ہووے جو ریکارڈنگ ترٹ ویسے، یا (عام طور تے) جے ایہ اتنا گھٹ ہووے جو تساں تحریری متن دے حوالے دے بغیر جیڑھا کجھ آکھیا ویندا پیا ہووے اونکوں سݨ نہیں سڳدے۔ @@ -1685,6 +1705,14 @@ public-domain = عوامی ڈومین citing-sentences = جملے دا حوالہ ݙیوݨ adding-sentences = جملے شامل کرݨ reviewing-sentences = جملیاں دا جائزہ گھنݨ +sentence-domain = جملے دی ڈومین +public-domain-explanation-1 = اِیہ ٻہوں اہم ہِے جو سارے متنی جملے عوام ڈومین ( سی سی 0) ہووِن کیوں جو کامن وائس ڈیٹا سیٹ کوں سی سی 0 لائسنس دے تحت جاری کِیتا ڳِیا ہِے۔ صرف ہِک جملہ اَپ لوڈ کرو ڄیکر تُہاکوں یقین ہووے، اَتے نِت متعلقہ حوالہ رَلاؤ۔ +public-domain-explanation-2 = ہِک کار اآمد تقریر دی سُن٘ڄاݨ دے انجن دی اُساری کِیتے بہترین جملے ٻول چال، جدید ٻول چال ہِن۔ جملے بݨاوݨ وِچ تُہاݙی مَدَت کرݨ کِیتے کُجھ خیالات ہِن؛ +public-domain-explanation-3 = آپُوں کنوں یا آپݨے ٻیلیاں یا ٻولی دی بیادری دے نال جدید، ٻول چال دے جملے بݨاؤ - مثال دے طور تے 'رائٹ-اے-تھون' دے ذریعے +public-domain-explanation-4 = مصنفاں، ڈرامہ نگاراں یا سکرین لکھاریاں نال رابطہ کرو اَتے پُچّھو جو بَھلا اُوہ آپݨے کَماں دا ہِک نِکڑا جِیہاں حِصّہ عوامی ڈومین کِیتے وقف کرݨ کِیتے تیار تِھین٘دے ہِن +public-domain-explanation-5 = اِیہو جِیہاں مواد لبّھو جین٘دے اُتّے ہُݨ کاپی رائٹ لاگو کائے نِھیں تِھین٘دا - مثال دے طور تے زیادہ تر کتاباں جہڑیاں 1920 کنوں پہلاں چَھپّیاں ہَن +public-domain-explanation-6 = حکومتاں، غیر منافع بخش ادارے یا میڈیا اداریاں نال اِیہ پَتہ لاوݨ کِیتے رابطو کرو جو بَھلا اُنّھاں دا کُئی وی ویب مواد، رپورٹاں یا ٻئے مواد عوامی ڈومین کِیتے وقف کِیتا ون٘ڄ سڳین٘دا ہِے +citing-sentences-explanation-1 = حوالیاں کوں رَلاوݨ ضروری ہِے تاں جو اَساں ݙیکھ سڳّوں جو جملے عوامی ڈومین وِچ ہِن اَتے کاپی رائٹ دی کُئی پابندی لاڳو نئیں تِھین٘دے۔ citing-sentences-subheader-websites = ویب سائٹاں citing-sentences-subheader-websites-explanation = تساں ویب سائٹ شامل کر سڳدے ہو، مثال دے طور تے "کامن وائس"۔ https://commonvoice.mozilla.org/ citing-sentences-subheader-academic-reference = تعلیمی حوالہ @@ -1700,18 +1728,25 @@ adding-sentences-subheader-length-explanation = جملے وچ 15 کنوں گھٹ adding-sentences-subheader-spelling-punctuation = ہجے تے علامتی اکھر adding-sentences-subheader-spelling-punctuation-explanation = جملے دے ہجے درست ہووݨ ضروری ہن۔ adding-sentences-subheader-speakable = ٻولݨ دے قابل +adding-sentences-subheader-speakable-explanation = بہترین جملے فطری اَتے ڳالھ مُہاڑ دے ہون٘دے ہِن — اِنّھاں کوں پڑھݨ وِچ سَوکھ تِھیوݨی چاہِیدی ہِے، بھان٘ویں جو صوتی تنوع اَتے جملیاں وِچ ان٘جو ان٘ج لوّظ اہم ہِن، اَساں اِیہ وی کوشِت کرن٘دے پئے ہِسے جو ریکارڈنگ جملیاں کوں آپݨی رضاکار بِیادری کِیتے ہر ممکن حد توڑیں دِلچسپ اَتے تفریحی بݨاؤں۔ adding-sentences-subheader-numbers = اعداد adding-sentences-subheader-numbers-explanation = ماخذ متن وِچ مثالی طور تے کوئی ہندسہ نہیں ہووݨا چاہیدا کیوں جو او بلند آواز نال پڑھݨ تے مسائل پیدا کر سڳدے او۔ جیویں کہیں نمبر کوں پڑھیا ویندا ہے تے ڈیٹا سیٹ وِچ الجھن پیدا کر سڳدا ہے۔ مثال دے طور تے، نمبر “2409” کوں "چوویہ صفر نوں" تے "ݙو ہزار چار سو نوں" ݙوہیں دے طور تے درست طریقے نال پڑھیا ونڄ سڳدا ہے۔ adding-sentences-subheader-abbreviations = مخففات تے سرنامیے +adding-sentences-subheader-abbreviations-explanation = + ماخذ دے متن وِچ مخففات اَتے مخفف جین٘ویں "یو ایس اے" یا + "آئی سی ای" کنوں گریز کِیتا ون٘ڄݨاں چاہِیدا ہِے کیوں جو انّھاں کوں اِیں طرحاں پڑھیا ون٘ڄ سڳین٘دا ہِے جو اِنّھاں دے ہِجّے دے موافق نہ ہووے۔ ٻِیا اِیہ جو، ہِکّے اِی مخفف کِیتے اَݨ ڳِݨَت درست ریڈنگز تھی سڳدیاں ہِن۔ adding-sentences-subheader-punctuation = علامتی اکھر adding-sentences-subheader-punctuation-explanation = خصوصی علامات تے اوقاف صرف ایں وقت شامل کیتے ونڄن جݙاں بالکل ضروری ہوون۔ مثال دے طور تے، انگریزی الفاظ جیویں "dont" تے "we're" وِچ ہک apostrophe شامل ہے تے اینکوں ماخذ متن وِچ شامل کیتا ونڄݨا چاہیدا ہے، لیکن ایں ڳالھ دا امکان کائنی جو تہاکوں کݙاہیں وی "@" یا "# جیویں خصوصی علامت دی ضرورت پووے۔ " adding-sentences-subheader-special-characters = حاص حروف تے غیرملکی حروف adding-sentences-subheader-special-characters-explanation-1 = جیڑھی زبان وِچ ٻولی ویندی پئی ہے ایندے وِچ حروف درست ہووݨے چاہیدے ہن۔ مثال دے طور تے، “ж” روسی اکھر تختی وِچ ہک حرف ہے لیکن انگریزی وِچ کݙاہیں استعمال نہیں ہوندا تے ایں سانگے انگریزی دے کہیں ماخذ متن وِچ کݙاہیں ظاہر نہیں ہووݨا چاہیدا۔ +adding-sentences-subheader-special-characters-explanation-2 = ٻولیاں مقامی ہووݨ تے وادھو تقاضیاں دے نال اِنّھاں دے آپݨے توثیق دے اصول تھی سڳدے ہِن۔ ڄیکر کئیں ٻولی کِیتے کُئی مخصوص توثیق دی فائل کائے نِھیں، تاں انگریزی دے قاعدے شراکت داراں کِیتے ظاہر تِھیسِن۔ adding-sentences-subheader-offensive-content = جارحانہ مواد +adding-sentences-subheader-offensive-content-explanation = ڄیکر جملہ جارحانہ یا پریشان کرݨ آلا ہِے - مثال دے طور تے واضح مواد دی وجہ کنوں، یا اَساݙی کمیونٹی شرکت دے رہنما خطوط دی خلاف ورزی - تُہاکوں سزا کوں مسترد کر ݙیوݨاں چاہِیدا ہِے۔ تُساں مسئلے کوں وَدھاوݨ کِیتے commonvoice@mozilla.com اُتے وی اَساݙے نال رابطہ کر سڳدے ہِیوے۔ reviewing-sentences-explanation-1 = جے جملے اُتلے معیار تے پورے ہن تاں "جیا" بٹݨ کلک کرو۔ reviewing-sentences-explanation-2 = جے جملے اُتلے معیار تے پورے کائنی آندے تاں "کو" بٹݨ کلک کرو۔ reviewing-sentences-explanation-3 = جے تہاکوں جملے بارے پک کائنی تاں تساں ایں کوں چھوڑ تے اڳلے جملے تے ون٘ڄ سڳدے ہو۔ reviewing-sentences-explanation-4 = جے تہاݙے کول نظرثانی کیتے جملے کائنی تاں سوہݨا، ٻئے جملے کٹھے کرݨ وچ ساݙی مدد کرو! +domain-explanation = ڈومین جملے دے مضوع نال مراد ہِے۔ ایں ویلے، تُساں اِنّھاں وِچوں چوݨ کر سڳدے ہِیوے: ## WRITE PAGE @@ -1735,6 +1770,9 @@ new-sentence-rule-7 = مناسب حوالہ شامل کرو new-sentence-rule-8 = مثالی قدرتی تے ڳالھ مہاڑ آلے (ایہ پڑھݨ کیتے سوکھے ہووݨے چاہیدن) how-to-cite = میں حوالہ کین٘ویں ݙیواں؟ how-to-cite-explanation-bold = یوآرایل لنک یا کم دے پورے ناں نال حوالہ ݙیوو۔ +how-to-cite-explanation = + ڄیکر اِیہ تُہاݙے آپݨے لوّظ ہِن تاں صرف + "آپݨاں حوالہ" ٻولو۔ اَساکوں اِیہ ڄاݨن دی لوڑ ہِے جو تُہاکوں اِیہ مواد کِتّھوں لبّھیا ہِے تاں جو اَساں ݙیکھ سڳوں جو اِیہ عوامی ڈومین وِچ ہِے اَتے کاپی رائٹ دی کُئی پابندی لاڳو نِھیں تِھین٘دی۔ حوالہ جات دے بارے وِچ ٻئے معلومات کِیتے اَساݙا رہنمائی دا پَنّاں ݙیکھو۔ guidelines = ہدایات contact-us = ساݙے نال رابطہ کرو add-sentence-success = 1 جملہ کٹھا تھیا @@ -1757,6 +1795,20 @@ finance = فنانس food_service_retail = خوراک، خدمت تے پرچون # Sentence Domain dropdown option general = عمومی +# Sentence Domain dropdown option +healthcare = صحت دی ݙیکھ بھال +# Sentence Domain dropdown option +history_law_government = تاریخ، قنُون اَتے حکومت +# Sentence Domain dropdown option +language_fundamentals = ٻولی دے بنیادی اصول (مثلاً ہِنسے، اَکّھر، رقم) +# Sentence Domain dropdown option +media_entertainment = میڈیا اَتے تفریح +# Sentence Domain dropdown option +nature_environment = فطرت اَتے ماحولیات +# Sentence Domain dropdown option +news_current_affairs = خبراں اَتے موجودہ حالات +# Sentence Domain dropdown option +technology_robotics = ٹیکنالوجی اَتے روبوٹکس ## REVIEW PAGE @@ -1768,8 +1820,10 @@ report-sc-different-language = مختلف زبان report-sc-different-language-detail = ایہ میݙی نظرثانی آلی زبان کنوں مختلف زبان لکھا ڳیا ہے۔ sentences-fetch-error = ایں جملے دے واپس ولݨ وچ خرابی تھی ڳئی review-error = ایں جملے دی نظرثانی وچ خرابی تھی ڳئی +review-error-rate-limit-exceeded = تُساں ٻہوں جَلتی نال وین٘دے پئے ہِیوے۔ تھورائیت کرین٘دے ہوئے جملے دی پَرکھ کرݨ کِیتے ذری وخت کڈّھو تاں جو اِیہ یقینی بݨایا ون٘ڄ سڳیڄے جو اِیہ ٹھیک ہِے۔ # SENTENCE-COLLECTOR-REDIRECT PAGE sc-redirect-page-title = اساں کجھ وݙیاں تبدیلیاں کریندے پئے ہیں +sc-redirect-page-subtitle-1 = جملے کَٹّھے کرݨ آلا بنیادی کامن وائس پلیٹ فارم اُتے وین٘دا پِیا ہِے۔ ہُݨ تُساں کامن وائس اُتے ہِک جملہ لکھ سڳدے ہِیوے ہک جملہ یا پَرکھ کر کے ہِک جملہ کَٹھا کر سڳدے ہِیوے۔ sc-redirect-page-subtitle-2 = ساݙے کنوں میٹرکس، ڈسکورس یا ای میل بارے سوالات پُچھو۔ ## BULK SUBMISSION @@ -1778,6 +1832,8 @@ sc-redirect-page-subtitle-2 = ساݙے کنوں میٹرکس عوامی ڈومین جملے اپ لوڈ کرو sc-bulk-upload-instruction = آپݨی فائل اتھ گھیل آؤ یا اپ لوڈ کرݨ کیتے کلک کرو sc-bulk-upload-instruction-drop = اپ لوڈ کرݨ کیتے فائل اتھ سٹو +bulk-upload-additional-information = ڄیکر تُساں اِیں فائل دے بارے وِچ کُئی وادھو معلومات ݙیوݨاں چاہن٘دے ہِیوے تاں تھورائیت کرین٘دے ہوئے commonvoice@mozilla.com نال رابطہ کرو +template-file-additional-information = ڄیکر تُساں اِیں فائل دے بارے وِچ کُئی وادھو معلومات ݙیوݨاں چاہن٘دے ہِیوے جیہڑی جو سانچے وِچ شامل کائے نِھیں، تاں تھورائیت کرین٘دے ہوئے commonvoice@mozilla.com نال رابطہ کرو try-upload-again = آپݨی فائل اتھ گھیلݨ نال ولدا کوشش کرو try-upload-again-md = ولدا اپ لوڈ کرݨ دی کوشش کرو select-file = فائل چݨو @@ -1785,6 +1841,7 @@ select-file-mobile = اپ لوڈ کرݨ کیتے فائل چݨو accepted-files = قابل قبول فائل قسماں: .tsv صرف maximum-file-size = ودھ و ودھ فائل سائز: 25 ایم بی what-needs-to-be-in-file = میکوں آپݨی حیاتی وچ کہڑی شئے دی لوڑ ہے؟ +what-needs-to-be-in-file-explanation = تھورائیت کرین٘دے ہوئے اَساݙی سانچہ فائل ݙیکھو۔ تُہاݙے جُملے کاپی رائٹ کنوں اَزاد ہووݨے چاہِیدے ہِن (سی سی0 اَتے جمع کراوݨ آلے دی طرفوں اجازت یافتہ اصل کَم) اَتے واضح، گرامر دے لحاظ نال درست اَتے پڑھݨ وِچ سَوکھا ہووݨاں چاہِیدا ہِے۔ جمع کرائے ڳئے جملیاں کوں پڑھݨ وِچ تقریباً 10-15 سیکنڈ لڳݨے چاہِیدے ہِن اَتے اِنّھاں وِچ اعداد، مناسب اسم اَتے خصوصی اَکّھر رلاوݨ کنوں گریز کرݨاں چاہِیدا ہِے۔ upload-progress-text = اپ لوڈ تھیندا پئے۔۔۔ sc-bulk-submit-confirm = میں تصدیق کرینداں جو ایہ جملہ عوامی ڈومین دے ہِن تے میکوں انہاں دے اپ لوڈ کرݨ دی اجازت ہے۔ bulk-upload-success-toast = ڈھڳ جملے اپ لوڈ تھی ڳئے @@ -1799,3 +1856,10 @@ too-many-files = ٻہوں ساریاں فائلاں ## Donate banner +# Text wrapped in will have a white background. +donate-banner-cta = اَساکوں لوڑ ہِے
تُہاݙی مَدَت دی! +# Text wrapped in will be rendered on bold font +donate-banner-cta-explanation = ڈیٹا سیٹس دی میزبانی کرݨ اَتے 100+ ٻولیاں دیاں بیادریاں جہڑیاں اَساݙے اُتّے بھرواسہ کرین٘دیاں ہِن کِیتے پلیٹ فارم کوں چَنڳا بݨاوݨ کِیتے تقریباً ہِک ملین ڈالر سالانہ خرچ تھین٘دے۔ ڄیکر تُساں اوپن، جامع ڈیٹا دی قدر کرین٘دے ہِیوے تاں - اڄّو عطیہ کرو! +# Text wrapped in will have a white background. +languages-donate-banner-cta = سی وی استعمال کرین٘دا پئے
تُہاݙی پَرکھ کِیتے؟ +languages-donate-banner-cta-explanation = کامن وائس کوں عطیات اَتے گرانٹاں نال مالی معاوݨت ݙِتّی ون٘ڄ سڳین٘دی ہِے! اَساکوں تعلیم دے ماہراں، سول سوسائٹی اَتے صنعت دے محققاں دے نال تعاون کرݨ بھان٘دا ہِے۔ کامن وائس وَرتݨ کِیتے مُفت ہِے، پَر گرانٹ دیاں تجویزاں دے ذریعے پلیٹ فارم اَتے میزبانی دے خرچیاں وِچ حِصّہ پاوݨاں سچّی وِچ مددی ہِے۔ From 8c19ff977ca4f99999fc83d28f1bbe77b83d5663 Mon Sep 17 00:00:00 2001 From: Stev_En_Bee <98711733+Steven-EB@users.noreply.github.com> Date: Wed, 17 Apr 2024 11:15:49 -0300 Subject: [PATCH 10/69] Create documentation_request.md (#4445) New draft of documentation issue/request template --- .../ISSUE_TEMPLATE/documentation_request.md | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/documentation_request.md diff --git a/.github/ISSUE_TEMPLATE/documentation_request.md b/.github/ISSUE_TEMPLATE/documentation_request.md new file mode 100644 index 000000000000..4388d817dea2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/documentation_request.md @@ -0,0 +1,24 @@ +--- +name: Documentation Request +about: Request new, updates, or changes to documentation +title: '[DOCS]' +labels: 'Documentation' +assignees: '' +--- + +**Topic of request** +What **topic** does this documentation request concern? +
+ +**Kind of request** +Is this a request for **new documentation**? An **update**? Or a **change** to existing docs? +
+ +If this is a request to create **new** documentation, what do you think is important to include? +
+ +If this is a request to **update** existing documention, what needs to be updated? +
+ +If this is a request to **change** existing documentation, what needs to be changed? +
From 4f155748da3147618023104b46df31c5a53d19e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=86hor=20Hordiichuk?= Date: Wed, 17 Apr 2024 18:05:32 +0000 Subject: [PATCH 11/69] Pontoon: Update Ukrainian (uk) localization of Common Voice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Artem Polivanchuk Co-authored-by: Іhor Hordiichuk --- web/locales/uk/messages.ftl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/web/locales/uk/messages.ftl b/web/locales/uk/messages.ftl index 1b3833323ff6..fed1f7d33c69 100644 --- a/web/locales/uk/messages.ftl +++ b/web/locales/uk/messages.ftl @@ -699,6 +699,10 @@ about-playbook-how-project-governance-content-7 = Докладн ## How is Common Voice funded +about-playbook-how-funded = Як фінансується Common Voice? +about-playbook-how-funded-content-1 = Common Voice — це проєкт Mozilla Foundation, US 501c3. Зараз він повністю фінансується за рахунок благодійних грантів і допомоги людей з усього світу. +about-playbook-how-funded-content-2 = Постійне розміщення та випуск наборів даних, удосконалення платформи та виконання програм спільноти коштують чималих грошей. +about-playbook-how-funded-content-3 = Якщо ви або ваша організація бажаєте підтримати проєкт, ви можете зробити внесок або зв'язатися з нашою командою партнерства за адресою commonvoice@mozilla.com. ## Glossary @@ -1728,6 +1732,9 @@ continue-speaking-button = Ні, дякую, хочу продовжити го create-profile-text = Хочете зберегти свою інформацію? Створіть профіль thanks-for-voice-toast = Дякуємо за інформацію про голос thanks-for-voice-toast-error = Під час надсилання вашої інформації про голос сталася помилка +first-cta-gender-select-default-option = Вибрати опцію +first-cta-gender-select-help-text = + .label = Як би ви описали свою стать або гендерну приналежність? # SECOND POST SUBMISSION CTA second-cta-header-text = Дякуємо за внесок вашого голосу! second-cta-subtitle-text = За допомогою профілю ви можете відстежувати свою активність і зв’язуватися зі спільнотою мовців. @@ -1873,6 +1880,7 @@ single-sentence = Одне речення bulk-sentences = Масові речення sentence-domain-select = .label = Належність речення +sentence-domain-select-placeholder = Виберіть до трьох доменів # Sentence Domain dropdown option agriculture = Сільське господарство # Sentence Domain dropdown option @@ -1948,5 +1956,8 @@ too-many-files = Забагато файлів # Text wrapped in will have a white background. donate-banner-cta = Нам потрібна
ваша допомога! +# Text wrapped in will be rendered on bold font +donate-banner-cta-explanation = Розміщення наборів даних і вдосконалення платформи для понад 100 мовних спільнот, які покладаються на нашу роботу, коштує майже мільйон доларів на рік. Якщо ви цінуєте відкриті та доступні дані – зробіть внесок уже сьогодні! # Text wrapped in will have a white background. languages-donate-banner-cta = Використовуєте резюме для
дослідження? +languages-donate-banner-cta-explanation = Common Voice фінансується коштом внесків і грантів! Ми любимо співпрацювати з науковцями, громадянським суспільством і галузевими дослідниками. Common Voice безплатний для користування, але допомога покриття витрат на платформу та хостинг через грантову підтримку справді корисна. From dddcbfec5818c5d603fe3e8d65b0f37c60bc9bba Mon Sep 17 00:00:00 2001 From: Dmitrij Feller <119537889+moz-dfeller@users.noreply.github.com> Date: Thu, 18 Apr 2024 10:28:28 +0200 Subject: [PATCH 12/69] Oi 3005 update the add sentence endpoint to take in the variant (#4440) * feat: add possiblity to tag a sentence with a variant * test: add expected sentence submission * refactor: eta reduce saveSentence call * refactor: move variants to it's own repository * feat: add checks to the add sentence command handler and remove localeId dependency * chore: remove console log statement --- .../sentences/handler/add-sentence-handler.ts | 31 ++- .../validation/pending-sentences-requests.ts | 9 +- server/src/application/helper/error-helper.ts | 4 +- .../sentences/repository/locale-repository.ts | 24 +++ .../repository/sentences-repository.ts | 69 +++--- .../repository/variant-repository.ts | 44 ++++ .../add-sentence-command-handler.ts | 167 ++++++++++----- .../command/add-sentence-command.ts | 8 +- server/src/application/types/error.ts | 4 +- .../application/types/sentence-submission.ts | 14 +- server/src/core/sentences/types/sentence.ts | 2 + server/src/core/sentences/types/validators.ts | 12 +- .../core/sentences/validation/validation.ts | 21 +- server/src/core/types/variant.ts | 6 + .../add-sentence-command-handler.test.ts | 202 ++++++++++++++++++ 15 files changed, 504 insertions(+), 113 deletions(-) create mode 100644 server/src/application/sentences/repository/locale-repository.ts create mode 100644 server/src/application/sentences/repository/variant-repository.ts create mode 100644 server/src/core/types/variant.ts create mode 100644 server/src/test/application/sentences/use-case/command-handler/add-sentence-command-handler.test.ts diff --git a/server/src/api/sentences/handler/add-sentence-handler.ts b/server/src/api/sentences/handler/add-sentence-handler.ts index 7ab7e7c21693..291109e1aee8 100644 --- a/server/src/api/sentences/handler/add-sentence-handler.ts +++ b/server/src/api/sentences/handler/add-sentence-handler.ts @@ -1,35 +1,54 @@ import { Request, Response } from 'express' import * as TE from 'fp-ts/TaskEither' import * as T from 'fp-ts/Task' +import * as O from 'fp-ts/Option' +import * as I from 'fp-ts/Identity' import { pipe } from 'fp-ts/function' import { AddSentenceCommandHandler } from '../../../application/sentences/use-case/command-handler/add-sentence-command-handler' import { AddSentenceCommand } from '../../../application/sentences/use-case/command-handler/command/add-sentence-command' import { - SentencesRepositoryErrorKind, + SentenceRepositoryErrorKind, SentenceValidationErrorKind, } from '../../../application/types/error' import { createPresentableError } from '../../../application/helper/error-helper' import { StatusCodes } from 'http-status-codes' +import { validateSentence } from '../../../core/sentences' +import { + findDomainIdByNameInDb, + saveSentenceInDb, +} from '../../../application/sentences/repository/sentences-repository' +import { findVariantByTagInDb } from '../../../application/sentences/repository/variant-repository' +import { getAllLocales } from '../../../application/sentences/repository/locale-repository' export default async (req: Request, res: Response) => { - const { sentence, localeId, localeName, source, domains } = req.body + const { sentence, localeName, source, domains, variant } = req.body const command: AddSentenceCommand = { clientId: req.client_id, sentence: sentence, - localeId: localeId, localeName: localeName, source: source, - domains: domains + domains: domains, + variant: O.fromNullable(variant), } + const cmdHandler = pipe( + AddSentenceCommandHandler, + I.ap(validateSentence), + I.ap(findDomainIdByNameInDb), + I.ap(findVariantByTagInDb), + I.ap(getAllLocales), + I.ap(saveSentenceInDb) + ) + return pipe( - AddSentenceCommandHandler(command), + command, + cmdHandler, TE.mapLeft(createPresentableError), TE.match( err => { switch (err.kind) { - case SentencesRepositoryErrorKind: { + case SentenceRepositoryErrorKind: { return T.of(res.status(StatusCodes.INTERNAL_SERVER_ERROR).json(err)) } case SentenceValidationErrorKind: diff --git a/server/src/api/sentences/validation/pending-sentences-requests.ts b/server/src/api/sentences/validation/pending-sentences-requests.ts index efa9175b013b..29ebbc553708 100644 --- a/server/src/api/sentences/validation/pending-sentences-requests.ts +++ b/server/src/api/sentences/validation/pending-sentences-requests.ts @@ -3,7 +3,7 @@ import { sentenceDomains } from 'common' export const AddSentenceRequest: AllowedSchema = { type: 'object', - required: ['sentence', 'source', 'localeId', 'localeName', 'domains'], + required: ['sentence', 'source', 'localeName', 'domains'], properties: { sentence: { type: 'string', @@ -11,10 +11,6 @@ export const AddSentenceRequest: AllowedSchema = { source: { type: 'string', }, - localeId: { - type: 'integer', - minimum: 1, - }, localeName: { type: 'string', }, @@ -27,6 +23,9 @@ export const AddSentenceRequest: AllowedSchema = { }, uniqueItems: true, }, + variant: { + type: 'string', + }, }, } diff --git a/server/src/application/helper/error-helper.ts b/server/src/application/helper/error-helper.ts index a54f9d2da846..3708f2566ec0 100644 --- a/server/src/application/helper/error-helper.ts +++ b/server/src/application/helper/error-helper.ts @@ -29,8 +29,8 @@ export const createSentenceValidationError = ( } } -export const createPendingSentencesRepositoryError = createError( - 'SentencesRepository' +export const createSentenceRepositoryError = createError( + 'SentenceRepository' ) export const createDatabaseError = createError('DatabaseError') diff --git a/server/src/application/sentences/repository/locale-repository.ts b/server/src/application/sentences/repository/locale-repository.ts new file mode 100644 index 000000000000..6e225f42cc4e --- /dev/null +++ b/server/src/application/sentences/repository/locale-repository.ts @@ -0,0 +1,24 @@ +import * as TE from 'fp-ts/TaskEither' +import { ApplicationError } from '../../types/error' +import { createDatasetError } from '../../helper/error-helper' +import { pipe } from 'fp-ts/lib/function' +import { queryDb } from '../../../infrastructure/db/mysql' + +export type Locale = Readonly<{ + id: number + name: string +}> + +export type GetAllLocales = () => TE.TaskEither + +const getAllLocalesQuery = 'SELECT id, name FROM locales' + +export const getAllLocales: GetAllLocales = () => { + return pipe( + queryDb(getAllLocalesQuery)([]), + TE.map(([rows]: Array> | Array): Locale[] => { + return rows.map((row: Locale) => ({ id: row.id, name: row.name })) + }), + TE.mapLeft(err => createDatasetError('Error retrieving locales', err)) + ) +} diff --git a/server/src/application/sentences/repository/sentences-repository.ts b/server/src/application/sentences/repository/sentences-repository.ts index 9eb68cf60123..0f632022f434 100644 --- a/server/src/application/sentences/repository/sentences-repository.ts +++ b/server/src/application/sentences/repository/sentences-repository.ts @@ -1,11 +1,11 @@ -import { taskEither as TE, taskOption as TO } from 'fp-ts' +import { option as O, taskEither as TE, taskOption as TO } from 'fp-ts' import { pipe } from 'fp-ts/lib/function' import { MysqlError } from 'mysql2Types' import { UnvalidatedSentence } from '../../../core/sentences/types' import { SentencesForReviewRow } from '../../../infrastructure/db/types' import Mysql, { getMySQLInstance } from '../../../lib/model/db/mysql' import { createSentenceId } from '../../../lib/utility' -import { createPendingSentencesRepositoryError } from '../../helper/error-helper' +import { createSentenceRepositoryError } from '../../helper/error-helper' import { ApplicationError } from '../../types/error' import { SentenceSubmission } from '../../types/sentence-submission' @@ -16,12 +16,25 @@ const db = getMySQLInstance() const DUPLICATE_KEY_ERR = 1062 const BATCH_SIZE = 1000 +export type SaveSentence = ( + sentenceSubmission: SentenceSubmission +) => TE.TaskEither + +export type FindDomainIdByName = ( + domainName: string +) => TE.TaskEither> + const insertSentenceTransaction = async ( db: Mysql, sentence: SentenceSubmission ) => { const sentenceId = createSentenceId(sentence.sentence, sentence.locale_id) const conn = await mysql2.createConnection(db.getMysqlOptions()) + const variant_id = pipe( + sentence.variant, + O.map(variant => variant.id), + O.getOrElse(() => null) + ) try { await conn.beginTransaction() @@ -35,10 +48,10 @@ const insertSentenceTransaction = async ( await conn.query( ` - INSERT INTO sentence_metadata(sentence_id, client_id) - VALUES (?, ?); + INSERT INTO sentence_metadata(sentence_id, client_id, variant_id) + VALUES (?, ?, ?); `, - [sentenceId, sentence.client_id] + [sentenceId, sentence.client_id, variant_id] ) for (const domainId of sentence.domain_ids ?? []) { @@ -126,22 +139,22 @@ const insertBulkSentencesTransaction = async ( } } -const insertSentence = +const saveSentence = (db: Mysql) => ( sentenceSubmission: SentenceSubmission - ): TE.TaskEither => { + ): TE.TaskEither => { return TE.tryCatch( () => insertSentenceTransaction(db, sentenceSubmission), (err: MysqlError) => { if (err.errno && err.errno === DUPLICATE_KEY_ERR) { - return createPendingSentencesRepositoryError( + return createSentenceRepositoryError( `Duplicate entry '${sentenceSubmission.sentence}'`, err ) } - return createPendingSentencesRepositoryError( + return createSentenceRepositoryError( `Error inserting pending sentence '${sentenceSubmission.sentence}'`, err ) @@ -178,7 +191,7 @@ const insertSentenceVote = [vote.sentenceId, vote.vote, vote.clientId] ), (err: Error) => - createPendingSentencesRepositoryError( + createSentenceRepositoryError( `Error inserting vote for pending_sentence ${vote.sentenceId} with client_id ${vote.clientId}`, err ) @@ -214,8 +227,8 @@ const findSentencesForReview = COUNT(sentence_votes.vote) as number_of_votes FROM sentences LEFT JOIN sentence_votes ON (sentence_votes.sentence_id=sentences.id) - WHERE - sentences.is_validated = FALSE + WHERE + sentences.is_validated = FALSE AND sentences.locale_id = ? AND NOT EXISTS ( SELECT 1 FROM skipped_sentences ss WHERE sentences.id = ss.sentence_id AND ss.client_id = ? @@ -238,20 +251,26 @@ const findSentencesForReview = const findDomainIdByName = (db: Mysql) => - (domainName: string): TO.TaskOption => - TO.tryCatch(async () => { - const [[result]] = await db.query( - ` - SELECT id FROM domains WHERE domain = ? - `, - [domainName] - ) - - return result ? Promise.resolve(result.id) : Promise.reject() - }) + (domainName: string): TE.TaskEither> => + TE.tryCatch( + async () => { + const [[row]] = await db.query( + ` + SELECT id FROM domains WHERE domain = ? + `, + [domainName] + ) + return row ? O.some(row.id) : O.none + }, + (err: Error) => + createSentenceRepositoryError( + `Error retrieving domain id for domain "${domainName}"`, + err + ) + ) -export const insertSentenceIntoDb = insertSentence(db) +export const saveSentenceInDb: SaveSentence = saveSentence(db) export const insertBulkSentencesIntoDb = insertBulkSentences(db) export const insertSentenceVoteIntoDb = insertSentenceVote(db) export const findSentencesForReviewInDb = findSentencesForReview(db) -export const findDomainIdByNameInDb = findDomainIdByName(db) +export const findDomainIdByNameInDb: FindDomainIdByName = findDomainIdByName(db) diff --git a/server/src/application/sentences/repository/variant-repository.ts b/server/src/application/sentences/repository/variant-repository.ts new file mode 100644 index 000000000000..66e2ab151a17 --- /dev/null +++ b/server/src/application/sentences/repository/variant-repository.ts @@ -0,0 +1,44 @@ +import { getMySQLInstance } from '../../../lib/model/db/mysql' +import * as O from 'fp-ts/Option' +import * as TE from 'fp-ts/TaskEither' +import { ApplicationError } from '../../types/error' +import { createDatabaseError } from '../../helper/error-helper' +import { Variant } from '../../../core/types/variant' +import lazyCache from '../../../lib/lazy-cache' + +const db = getMySQLInstance() + +export type FindVariantByTag = ( + variantToken: string +) => TE.TaskEither> + +const lazyFindVariantByTag = lazyCache( + 'sentence-find-variant-by-id', + async (variantToken: string): Promise> => { + const [[row]] = await db.query( + ` + SELECT v.id, l.name as locale, variant_name as name, variant_token as tag FROM variants v + JOIN locales l + ON v.locale_id = l.id + WHERE variant_token = ? + `, + [variantToken] + ) + return row ? O.some(row) : O.none + }, + 24 * 60 * 60 * 1000 +) + +const findVariantByTag = ( + variantToken: string +): TE.TaskEither> => + TE.tryCatch( + () => lazyFindVariantByTag(variantToken), + (err: Error) => + createDatabaseError( + `Error retrieving variant information for token "${variantToken}"`, + err + ) + ) + +export const findVariantByTagInDb: FindVariantByTag = findVariantByTag diff --git a/server/src/application/sentences/use-case/command-handler/add-sentence-command-handler.ts b/server/src/application/sentences/use-case/command-handler/add-sentence-command-handler.ts index f826d6e40937..2d4537227818 100644 --- a/server/src/application/sentences/use-case/command-handler/add-sentence-command-handler.ts +++ b/server/src/application/sentences/use-case/command-handler/add-sentence-command-handler.ts @@ -1,67 +1,130 @@ +import * as O from 'fp-ts/Option' +import * as Id from 'fp-ts/Identity' +import * as A from 'fp-ts/Array' import { pipe } from 'fp-ts/lib/function' -import { validateSentence } from '../../../../core/sentences' +import { ValidateSentence, ValidatedSentence } from '../../../../core/sentences' import { - insertSentenceIntoDb, - findDomainIdByNameInDb, + FindDomainIdByName, + SaveSentence, } from '../../repository/sentences-repository' import { AddSentenceCommand } from './command/add-sentence-command' +import { either as E, taskEither as TE } from 'fp-ts' +import { ApplicationError } from '../../../types/error' import { - either as E, - task as T, - taskEither as TE, - taskOption as TO, -} from 'fp-ts' -import { ApplicationError, OtherErrorKind } from '../../../types/error' -import { - createError, createSentenceValidationError, + createValidationError, } from '../../../helper/error-helper' import { SentenceSubmission } from '../../../types/sentence-submission' +import { FindVariantByTag } from '../../repository/variant-repository' +import { + GetAllLocales, + Locale, + getAllLocales, +} from '../../repository/locale-repository' +import { Variant } from '../../../../core/types/variant' -const createSentenceSubmissionFromCommand = ( - command: AddSentenceCommand -): E.Either => - pipe( - command.sentence, - validateSentence(command.localeName), - E.mapLeft(createSentenceValidationError), - E.map(validatedSentence => ({ - client_id: command.clientId, - locale_id: command.localeId, - sentence: validatedSentence, - source: command.source, - })) - ) +const toValidatedSentence = + (validateSentence: ValidateSentence) => + (sentence: string) => + (localeName: string): TE.TaskEither => + pipe( + sentence, + validateSentence(localeName), + E.mapLeft(createSentenceValidationError), + TE.fromEither + ) -export const AddSentenceCommandHandler = ( - command: AddSentenceCommand -): TE.TaskEither => { - return pipe( - TE.Do, - TE.bind('sentenceSubmission', () => - TE.fromEither(createSentenceSubmissionFromCommand(command)) - ), - TE.bind('domainIds', () => { - const domains = command.domains ?? [] - const findDomainIds = domains.map(domain => - findDomainIdByNameInDb(domain) - ) +const toDomainIds = + (findDomainId: FindDomainIdByName) => + (domains: string[]): TE.TaskEither => { + const findDomainIds = domains.map(domain => findDomainId(domain)) return pipe( findDomainIds, - TO.sequenceArray, - TE.fromTaskOption(() => - createError(OtherErrorKind)( - `Could not find a matching domain in ${command.domains}` + TE.sequenceArray, + TE.map(domainIds => pipe(domainIds, O.sequenceArray)), + TE.map(domainIds => + pipe( + domainIds, + O.getOrElse(() => []) ) ) ) - }), - TE.map(({ sentenceSubmission, domainIds }): SentenceSubmission => { - return { - ...sentenceSubmission, - domain_ids: [...domainIds], - } - }), - TE.chain(sentenceSubmission => insertSentenceIntoDb(sentenceSubmission)) - ) -} + } + +const validateVariantWithLocale = + (localeName: string) => (variant: Variant) => { + return variant.locale === localeName + } + +export const AddSentenceCommandHandler = + (validateSentence: ValidateSentence) => + (findDomainIdByName: FindDomainIdByName) => + (findVariantByTag: FindVariantByTag) => + (getAllLocales: GetAllLocales) => + (saveSentence: SaveSentence) => + (command: AddSentenceCommand): TE.TaskEither => + pipe( + TE.Do, + TE.bind('validatedSentence', () => + pipe( + toValidatedSentence, + Id.ap(validateSentence), + Id.ap(command.sentence), + Id.ap(command.localeName) + ) + ), + TE.bind('domainIds', () => + toDomainIds(findDomainIdByName)(command.domains) + ), + TE.bind('variant', () => + pipe( + command.variant, + O.match(() => TE.of(O.none), findVariantByTag) + ) + ), + TE.bind('isLocaleMatching', ({ variant }) => { + const doesNotMatchErr = createValidationError( + 'Sentence variant does not match locale' + ) + + return pipe( + variant, + O.map(validateVariantWithLocale(command.localeName)), + O.map(res => (res ? TE.right(true) : TE.left(doesNotMatchErr))), + O.getOrElse(() => TE.left(doesNotMatchErr)) + ) + }), + TE.bind('localeId', () => + pipe( + getAllLocales(), + TE.chain(locales => + pipe( + locales, + A.findFirst(locale => locale.name === command.localeName), + O.map(({ id }) => id), + TE.fromOption(() => + createValidationError('Locale not found') + ) + ) + ) + ) + ), + TE.map( + ({ + validatedSentence, + localeId, + domainIds, + variant, + }): SentenceSubmission => { + return { + sentence: validatedSentence, + source: command.source, + locale_id: localeId, + client_id: command.clientId, + domain_ids: [...domainIds], + variant: variant, + } + } + ), + TE.chain(saveSentence) + ) diff --git a/server/src/application/sentences/use-case/command-handler/command/add-sentence-command.ts b/server/src/application/sentences/use-case/command-handler/command/add-sentence-command.ts index 7a2804963dab..4bf78b3ba7a5 100644 --- a/server/src/application/sentences/use-case/command-handler/command/add-sentence-command.ts +++ b/server/src/application/sentences/use-case/command-handler/command/add-sentence-command.ts @@ -1,10 +1,12 @@ -import { SentenceDomain } from "common" +import { Option } from 'fp-ts/Option' + +import { SentenceDomain } from 'common' export type AddSentenceCommand = { clientId: string sentence: string - localeId: number localeName: string - source: string, + source: string domains: SentenceDomain[] + variant: Option } diff --git a/server/src/application/types/error.ts b/server/src/application/types/error.ts index 07ade44550a6..3e44eff97f74 100644 --- a/server/src/application/types/error.ts +++ b/server/src/application/types/error.ts @@ -1,6 +1,6 @@ import { ValidatorRuleErrorType } from '../../core/sentences' -export const SentencesRepositoryErrorKind = 'SentencesRepository' +export const SentenceRepositoryErrorKind = 'SentenceRepository' export const SentenceValidationErrorKind = 'SentenceValidation' export const ValidationErrorKind = 'Validation' export const DatabaseErrorKind = 'DatabaseError' @@ -10,7 +10,7 @@ export const OtherErrorKind = 'Other' export const ApplicationErrorKinds = [ ValidationErrorKind, - SentencesRepositoryErrorKind, + SentenceRepositoryErrorKind, SentenceValidationErrorKind, DatabaseErrorKind, BulkSubmissionErrorKind, diff --git a/server/src/application/types/sentence-submission.ts b/server/src/application/types/sentence-submission.ts index a30b82e5bcd2..6f921b250cf9 100644 --- a/server/src/application/types/sentence-submission.ts +++ b/server/src/application/types/sentence-submission.ts @@ -1,7 +1,11 @@ +import { Option } from 'fp-ts/Option' +import { Variant } from '../../core/types/variant' + export type SentenceSubmission = { - sentence: string; - source: string; - locale_id: number; - client_id: string; + sentence: string + source: string + locale_id: number + client_id: string domain_ids?: number[] | null -}; + variant: Option +} diff --git a/server/src/core/sentences/types/sentence.ts b/server/src/core/sentences/types/sentence.ts index 72b75b7dfa69..5605cac153d0 100644 --- a/server/src/core/sentences/types/sentence.ts +++ b/server/src/core/sentences/types/sentence.ts @@ -4,3 +4,5 @@ export type UnvalidatedSentence = { source: string localeId: number } + +export type ValidatedSentence = string diff --git a/server/src/core/sentences/types/validators.ts b/server/src/core/sentences/types/validators.ts index 50795965205b..977cc24a4cf0 100644 --- a/server/src/core/sentences/types/validators.ts +++ b/server/src/core/sentences/types/validators.ts @@ -22,12 +22,12 @@ const ValidatorLocales = [ 'default_locale', ] as const -export const ERR_TOO_LONG = 'TOO_LONG' -export const ERR_NO_NUMBERS = 'NO_NUMBERS' -export const ERR_NO_SYMBOLS = 'NO_SYMBOLS' -export const ERR_NO_ABBREVIATIONS = 'NO_ABBREVIATIONS' -export const ERR_NO_FOREIGN_SCRIPT = 'NO_FOREIGN_SCRIPT' -export const ERR_OTHER = 'OTHER' +export const ERR_TOO_LONG = 'TOO_LONG' as const +export const ERR_NO_NUMBERS = 'NO_NUMBERS' as const +export const ERR_NO_SYMBOLS = 'NO_SYMBOLS' as const +export const ERR_NO_ABBREVIATIONS = 'NO_ABBREVIATIONS' as const +export const ERR_NO_FOREIGN_SCRIPT = 'NO_FOREIGN_SCRIPT' as const +export const ERR_OTHER = 'OTHER' as const export const ERROR_TYPES = [ ERR_TOO_LONG, diff --git a/server/src/core/sentences/validation/validation.ts b/server/src/core/sentences/validation/validation.ts index a13db0d78e92..02b803a1bc74 100644 --- a/server/src/core/sentences/validation/validation.ts +++ b/server/src/core/sentences/validation/validation.ts @@ -26,6 +26,7 @@ import { flow, pipe } from 'fp-ts/function' import { Validators } from '..' import { isValidatorLocale, + ValidatedSentence, ValidatorLocale, ValidatorRule, ValidatorRuleError, @@ -88,10 +89,16 @@ const normalizeForLocale = (locale: string) => (sentence: string) => const validateSentenceForLocale = flow(getValidatorFor, runValidatorOnSentence) -export const validateSentence = (locale: string) => (sentence: string) => { - return pipe( - sentence, - normalizeForLocale(locale), - validateSentenceForLocale(locale) - ) -} +export type ValidateSentence = ( + locale: string +) => (sentence: string) => E.Either + +export const validateSentence: ValidateSentence = + (locale: string) => + (sentence: string): E.Either => { + return pipe( + sentence, + normalizeForLocale(locale), + validateSentenceForLocale(locale) + ) + } diff --git a/server/src/core/types/variant.ts b/server/src/core/types/variant.ts new file mode 100644 index 000000000000..26216626a224 --- /dev/null +++ b/server/src/core/types/variant.ts @@ -0,0 +1,6 @@ +export type Variant = { + id: number + locale: string + name: string + tag: string +} diff --git a/server/src/test/application/sentences/use-case/command-handler/add-sentence-command-handler.test.ts b/server/src/test/application/sentences/use-case/command-handler/add-sentence-command-handler.test.ts new file mode 100644 index 000000000000..2a72753bb72c --- /dev/null +++ b/server/src/test/application/sentences/use-case/command-handler/add-sentence-command-handler.test.ts @@ -0,0 +1,202 @@ +import { either as E, taskEither as TE } from 'fp-ts' +import { constVoid, pipe } from 'fp-ts/lib/function' +import * as I from 'fp-ts/Identity' +import * as O from 'fp-ts/Option' +import { AddSentenceCommandHandler } from '../../../../../application/sentences/use-case/command-handler/add-sentence-command-handler' +import { ERR_TOO_LONG, ValidateSentence } from '../../../../../core/sentences' +import { + FindDomainIdByName, + SaveSentence, +} from '../../../../../application/sentences/repository/sentences-repository' +import { AddSentenceCommand } from '../../../../../application/sentences/use-case/command-handler/command/add-sentence-command' +import { SentenceSubmission } from '../../../../../application/types/sentence-submission' +import { FindVariantByTag } from '../../../../../application/sentences/repository/variant-repository' +import { GetAllLocales } from '../../../../../application/sentences/repository/locale-repository' + +describe('Add sentence command handler', () => { + it('should save the sentence in the repository', async () => { + const validateSentenceMock: ValidateSentence = jest.fn( + () => () => E.right('This is a sentence') + ) + const findDomainIdByNameMock: FindDomainIdByName = jest.fn(() => + TE.right(O.some(1)) + ) + const findVariantByTag: FindVariantByTag = jest.fn(() => + TE.right( + O.some({ id: 1, name: 'Central', locale: 'ca', tag: 'ca-central' }) + ) + ) + const getAllLocales: GetAllLocales = jest.fn(() => TE.right([{ id: 2, name: 'ca' }])) + const saveSentenceMock: SaveSentence = jest.fn(() => TE.right(constVoid())) + + const cmd: AddSentenceCommand = { + clientId: 'abc', + sentence: 'This is a sentence', + localeName: 'ca', + source: 'Myself', + domains: ['finance'], + variant: O.some('ca-central'), + } + + const expectedSentenceSubmission: SentenceSubmission = { + sentence: 'This is a sentence', + source: 'Myself', + locale_id: 2, + client_id: 'abc', + domain_ids: [1], + variant: O.some({ + id: 1, + name: 'Central', + locale: 'ca', + tag: 'ca-central', + }), + } + + const cmdHandler = pipe( + AddSentenceCommandHandler, + I.ap(validateSentenceMock), + I.ap(findDomainIdByNameMock), + I.ap(findVariantByTag), + I.ap(getAllLocales), + I.ap(saveSentenceMock) + ) + + const result = await pipe(cmd, cmdHandler)() + expect(saveSentenceMock).toBeCalledWith(expectedSentenceSubmission) + expect(E.isRight(result)).toBeTruthy() + }) + + it('should return validation error', async () => { + const validationError = { + error: 'Oops', + errorType: ERR_TOO_LONG, + } + const validateSentenceMock: ValidateSentence = jest.fn( + () => () => E.left(validationError) + ) + const findDomainIdByNameMock: FindDomainIdByName = jest.fn(() => + TE.right(O.some(1)) + ) + const findVariantByTag: FindVariantByTag = jest.fn(() => + TE.right( + O.some({ id: 1, name: 'Central', locale: 'ca', tag: 'ca-central' }) + ) + ) + const getAllLocales: GetAllLocales = jest.fn(() => TE.right([{ id: 1, name: 'ca' }])) + const saveSentenceMock: SaveSentence = jest.fn(() => TE.right(constVoid())) + + const cmd: AddSentenceCommand = { + clientId: 'abc', + sentence: 'This is a sentence', + localeName: 'en', + source: 'Myself', + domains: ['finance'], + variant: O.none, + } + + const cmdHandler = pipe( + AddSentenceCommandHandler, + I.ap(validateSentenceMock), + I.ap(findDomainIdByNameMock), + I.ap(findVariantByTag), + I.ap(getAllLocales), + I.ap(saveSentenceMock) + ) + + const result = await pipe(cmd, cmdHandler)() + expect(E.isLeft(result)).toBeTruthy() + expect(saveSentenceMock).toHaveBeenCalledTimes(0) + }) + + it('should return validation error when locale does not match variant', async () => { + const validateSentenceMock: ValidateSentence = jest.fn( + () => () => E.right('This is a sentence') + ) + const findDomainIdByNameMock: FindDomainIdByName = jest.fn(() => + TE.right(O.some(1)) + ) + const findVariantByTag: FindVariantByTag = jest.fn(() => + TE.right( + O.some({ id: 1, name: 'Central', locale: 'ca', tag: 'ca-central' }) + ) + ) + const getAllLocales: GetAllLocales = jest.fn(() => TE.right([{ id: 1, name: 'ca' }])) + const saveSentenceMock: SaveSentence = jest.fn(() => TE.right(constVoid())) + + const cmd: AddSentenceCommand = { + clientId: 'abc', + sentence: 'This is a sentence', + localeName: 'en', + source: 'Myself', + domains: ['finance'], + variant: O.some('ca-central'), + } + + const cmdHandler = pipe( + AddSentenceCommandHandler, + I.ap(validateSentenceMock), + I.ap(findDomainIdByNameMock), + I.ap(findVariantByTag), + I.ap(getAllLocales), + I.ap(saveSentenceMock) + ) + const result = await pipe(cmd, cmdHandler)() + const errMsg = pipe( + result, + E.fold( + err => err.message, + () => "Shouldn't be here" + ) + ) + + expect(E.isLeft(result)).toBeTruthy() + expect(errMsg).toBe('Sentence variant does not match locale') + expect(saveSentenceMock).toHaveBeenCalledTimes(0) + }) + + it('should return error when locale is not found', async () => { + const validateSentenceMock: ValidateSentence = jest.fn( + () => () => E.right('This is a sentence') + ) + const findDomainIdByNameMock: FindDomainIdByName = jest.fn(() => + TE.right(O.some(1)) + ) + const findVariantByTag: FindVariantByTag = jest.fn(() => + TE.right( + O.some({ id: 1, name: 'Central', locale: 'ca', tag: 'ca-central' }) + ) + ) + const getAllLocales: GetAllLocales = jest.fn(() => TE.right([{ id: 1, name: 'en' }])) + const saveSentenceMock: SaveSentence = jest.fn(() => TE.right(constVoid())) + + const cmd: AddSentenceCommand = { + clientId: 'abc', + sentence: 'This is a sentence', + localeName: 'ca', + source: 'Myself', + domains: ['finance'], + variant: O.some('ca-central'), + } + + const cmdHandler = pipe( + AddSentenceCommandHandler, + I.ap(validateSentenceMock), + I.ap(findDomainIdByNameMock), + I.ap(findVariantByTag), + I.ap(getAllLocales), + I.ap(saveSentenceMock) + ) + const result = await pipe(cmd, cmdHandler)() + const errMsg = pipe( + result, + E.fold( + err => err.message, + () => "Shouldn't be here" + ) + ) + + expect(E.isLeft(result)).toBeTruthy() + expect(errMsg).toBe('Locale not found') + expect(saveSentenceMock).toHaveBeenCalledTimes(0) + }) +}) From 6dbe5049f51f34fe36b7eef202f458b658045bf4 Mon Sep 17 00:00:00 2001 From: Dmitrij Feller <119537889+moz-dfeller@users.noreply.github.com> Date: Thu, 18 Apr 2024 11:05:08 +0200 Subject: [PATCH 13/69] feat: add the variant tag to the sentence review response (#4446) --- .../repository/sentences-repository.ts | 8 ++++-- .../sentences/types/unvalidatedSentenceDto.ts | 7 +++++ .../get-sentences-for-review-query-handler.ts | 27 ++++++++++++++----- server/src/core/sentences/types/sentence.ts | 3 +++ .../db/types/sentences-for-review-row.ts | 1 + 5 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 server/src/application/sentences/types/unvalidatedSentenceDto.ts diff --git a/server/src/application/sentences/repository/sentences-repository.ts b/server/src/application/sentences/repository/sentences-repository.ts index 0f632022f434..142cc3ca12b5 100644 --- a/server/src/application/sentences/repository/sentences-repository.ts +++ b/server/src/application/sentences/repository/sentences-repository.ts @@ -206,6 +206,7 @@ const toUnvalidatedSentence = ([unvalidatedSentenceRows]: [ sentenceId: row.id, source: row.source, localeId: row.locale_id, + variantTag: O.fromNullable(row.variant_token), })) const findSentencesForReview = @@ -223,12 +224,15 @@ const findSentencesForReview = sentences.text, sentences.source, sentences.locale_id, + variants.variant_token, SUM(sentence_votes.vote) as number_of_approving_votes, COUNT(sentence_votes.vote) as number_of_votes FROM sentences LEFT JOIN sentence_votes ON (sentence_votes.sentence_id=sentences.id) - WHERE - sentences.is_validated = FALSE + LEFT JOIN sentence_metadata ON (sentence_metadata.sentence_id=sentences.id) + LEFT JOIN variants ON (variants.id=sentence_metadata.variant_id) + WHERE + sentences.is_validated = FALSE AND sentences.locale_id = ? AND NOT EXISTS ( SELECT 1 FROM skipped_sentences ss WHERE sentences.id = ss.sentence_id AND ss.client_id = ? diff --git a/server/src/application/sentences/types/unvalidatedSentenceDto.ts b/server/src/application/sentences/types/unvalidatedSentenceDto.ts new file mode 100644 index 000000000000..b19b268d7a5b --- /dev/null +++ b/server/src/application/sentences/types/unvalidatedSentenceDto.ts @@ -0,0 +1,7 @@ +export type UnvalidatedSentenceDto = { + sentence: string + sentenceId: string + source: string + localeId: number + variantTag: string | null +} diff --git a/server/src/application/sentences/use-case/query-handler/get-sentences-for-review-query-handler.ts b/server/src/application/sentences/use-case/query-handler/get-sentences-for-review-query-handler.ts index b13d0ae507c3..7432e6275b6f 100644 --- a/server/src/application/sentences/use-case/query-handler/get-sentences-for-review-query-handler.ts +++ b/server/src/application/sentences/use-case/query-handler/get-sentences-for-review-query-handler.ts @@ -1,14 +1,29 @@ import { pipe } from 'fp-ts/lib/function' -import { task as T, taskOption as TO } from 'fp-ts' +import { option as O, task as T, taskOption as TO } from 'fp-ts' import { findSentencesForReviewInDb } from '../../repository/sentences-repository' import { GetSentencesForReviewQuery } from './query/get-sentences-for-review-query' -import { UnvalidatedSentence } from '../../../../core/sentences/types' +import { UnvalidatedSentenceDto } from '../../types/unvalidatedSentenceDto' export const GetSentencesForReviewQueryHandler = ( query: GetSentencesForReviewQuery -) => { - return pipe( +): T.Task => { + return pipe( findSentencesForReviewInDb(query), - TO.getOrElse(() => T.of([] as UnvalidatedSentence[])) - ) + TO.map((sentences): UnvalidatedSentenceDto[] => { + return sentences.map(sentence => { + const variantTag = pipe( + sentence.variantTag, + O.getOrElse(() => null) + ) + return { + sentence: sentence.sentence, + sentenceId: sentence.sentenceId, + source: sentence.source, + localeId: sentence.localeId, + variantTag: variantTag, + } + }) + }), + TO.getOrElse(() => T.of([] as UnvalidatedSentenceDto[])) + ) } diff --git a/server/src/core/sentences/types/sentence.ts b/server/src/core/sentences/types/sentence.ts index 5605cac153d0..08e62d78f0f6 100644 --- a/server/src/core/sentences/types/sentence.ts +++ b/server/src/core/sentences/types/sentence.ts @@ -1,8 +1,11 @@ +import { Option } from 'fp-ts/Option' + export type UnvalidatedSentence = { sentence: string sentenceId: string source: string localeId: number + variantTag: Option } export type ValidatedSentence = string diff --git a/server/src/infrastructure/db/types/sentences-for-review-row.ts b/server/src/infrastructure/db/types/sentences-for-review-row.ts index 41bf097108dc..c57cae220833 100644 --- a/server/src/infrastructure/db/types/sentences-for-review-row.ts +++ b/server/src/infrastructure/db/types/sentences-for-review-row.ts @@ -3,6 +3,7 @@ export type SentencesForReviewRow = { text: string source: string locale_id: number + variant_token: string number_of_approving_votes: number number_of_votes: number } From c898c462ac6d0785523746ab586c0e7e6683bcd6 Mon Sep 17 00:00:00 2001 From: Dmitrij Feller Date: Thu, 18 Apr 2024 14:54:55 +0200 Subject: [PATCH 14/69] This reverts breaking changes in OI-3005 Reverts: 771043bc3d5f6c4aba31919654e63cdf132c5032 7349355d270da9513d0212a7404c6be3d8f1e9a7 d10b79fe51c1ee8cde477d7631a6a4c9d3753058 --- .../sentences/handler/add-sentence-handler.ts | 9 +- .../validation/pending-sentences-requests.ts | 6 +- .../sentences/repository/locale-repository.ts | 24 --- .../repository/sentences-repository.ts | 43 +++-- .../repository/variant-repository.ts | 44 ----- .../add-sentence-command-handler.ts | 164 +++++++----------- .../command/add-sentence-command.ts | 7 +- .../application/types/sentence-submission.ts | 13 +- server/src/core/types/variant.ts | 6 - .../add-sentence-command-handler.test.ts | 130 ++------------ 10 files changed, 123 insertions(+), 323 deletions(-) delete mode 100644 server/src/application/sentences/repository/locale-repository.ts delete mode 100644 server/src/application/sentences/repository/variant-repository.ts delete mode 100644 server/src/core/types/variant.ts diff --git a/server/src/api/sentences/handler/add-sentence-handler.ts b/server/src/api/sentences/handler/add-sentence-handler.ts index 291109e1aee8..bb54d498a345 100644 --- a/server/src/api/sentences/handler/add-sentence-handler.ts +++ b/server/src/api/sentences/handler/add-sentence-handler.ts @@ -15,17 +15,17 @@ import { StatusCodes } from 'http-status-codes' import { validateSentence } from '../../../core/sentences' import { findDomainIdByNameInDb, + findVariantIdByTokenInDb, saveSentenceInDb, } from '../../../application/sentences/repository/sentences-repository' -import { findVariantByTagInDb } from '../../../application/sentences/repository/variant-repository' -import { getAllLocales } from '../../../application/sentences/repository/locale-repository' export default async (req: Request, res: Response) => { - const { sentence, localeName, source, domains, variant } = req.body + const { sentence, localeId, localeName, source, domains, variant } = req.body const command: AddSentenceCommand = { clientId: req.client_id, sentence: sentence, + localeId: localeId, localeName: localeName, source: source, domains: domains, @@ -36,8 +36,7 @@ export default async (req: Request, res: Response) => { AddSentenceCommandHandler, I.ap(validateSentence), I.ap(findDomainIdByNameInDb), - I.ap(findVariantByTagInDb), - I.ap(getAllLocales), + I.ap(findVariantIdByTokenInDb), I.ap(saveSentenceInDb) ) diff --git a/server/src/api/sentences/validation/pending-sentences-requests.ts b/server/src/api/sentences/validation/pending-sentences-requests.ts index 29ebbc553708..0a31bc28fecb 100644 --- a/server/src/api/sentences/validation/pending-sentences-requests.ts +++ b/server/src/api/sentences/validation/pending-sentences-requests.ts @@ -3,7 +3,7 @@ import { sentenceDomains } from 'common' export const AddSentenceRequest: AllowedSchema = { type: 'object', - required: ['sentence', 'source', 'localeName', 'domains'], + required: ['sentence', 'source', 'localeId', 'localeName', 'domains'], properties: { sentence: { type: 'string', @@ -11,6 +11,10 @@ export const AddSentenceRequest: AllowedSchema = { source: { type: 'string', }, + localeId: { + type: 'integer', + minimum: 1, + }, localeName: { type: 'string', }, diff --git a/server/src/application/sentences/repository/locale-repository.ts b/server/src/application/sentences/repository/locale-repository.ts deleted file mode 100644 index 6e225f42cc4e..000000000000 --- a/server/src/application/sentences/repository/locale-repository.ts +++ /dev/null @@ -1,24 +0,0 @@ -import * as TE from 'fp-ts/TaskEither' -import { ApplicationError } from '../../types/error' -import { createDatasetError } from '../../helper/error-helper' -import { pipe } from 'fp-ts/lib/function' -import { queryDb } from '../../../infrastructure/db/mysql' - -export type Locale = Readonly<{ - id: number - name: string -}> - -export type GetAllLocales = () => TE.TaskEither - -const getAllLocalesQuery = 'SELECT id, name FROM locales' - -export const getAllLocales: GetAllLocales = () => { - return pipe( - queryDb(getAllLocalesQuery)([]), - TE.map(([rows]: Array> | Array): Locale[] => { - return rows.map((row: Locale) => ({ id: row.id, name: row.name })) - }), - TE.mapLeft(err => createDatasetError('Error retrieving locales', err)) - ) -} diff --git a/server/src/application/sentences/repository/sentences-repository.ts b/server/src/application/sentences/repository/sentences-repository.ts index 142cc3ca12b5..240de8186540 100644 --- a/server/src/application/sentences/repository/sentences-repository.ts +++ b/server/src/application/sentences/repository/sentences-repository.ts @@ -16,13 +16,14 @@ const db = getMySQLInstance() const DUPLICATE_KEY_ERR = 1062 const BATCH_SIZE = 1000 -export type SaveSentence = ( - sentenceSubmission: SentenceSubmission -) => TE.TaskEither +export type SaveSentence = + (sentenceSubmission: SentenceSubmission) => TE.TaskEither -export type FindDomainIdByName = ( - domainName: string -) => TE.TaskEither> +export type FindDomainIdByName = + (domainName: string) => TE.TaskEither> + +export type FindVariantIdByToken = + (variantToken: string) => TE.TaskEither> const insertSentenceTransaction = async ( db: Mysql, @@ -31,8 +32,7 @@ const insertSentenceTransaction = async ( const sentenceId = createSentenceId(sentence.sentence, sentence.locale_id) const conn = await mysql2.createConnection(db.getMysqlOptions()) const variant_id = pipe( - sentence.variant, - O.map(variant => variant.id), + sentence.variant_id, O.getOrElse(() => null) ) @@ -260,8 +260,8 @@ const findDomainIdByName = async () => { const [[row]] = await db.query( ` - SELECT id FROM domains WHERE domain = ? - `, + SELECT id FROM domains WHERE domain = ? + `, [domainName] ) return row ? O.some(row.id) : O.none @@ -273,8 +273,31 @@ const findDomainIdByName = ) ) +const findVariantIdByToken = + (db: Mysql) => + (variantToken: string): TE.TaskEither> => + TE.tryCatch( + async () => { + const [[row]] = await db.query( + ` + SELECT id FROM variants WHERE variant_token = ? + `, + [variantToken] + ) + return row ? O.some(row.id) : O.none + }, + (err: Error) => + createSentenceRepositoryError( + `Error retrieving variant id for token "${variantToken}"`, + err + ) + ) + export const saveSentenceInDb: SaveSentence = saveSentence(db) export const insertBulkSentencesIntoDb = insertBulkSentences(db) export const insertSentenceVoteIntoDb = insertSentenceVote(db) export const findSentencesForReviewInDb = findSentencesForReview(db) + export const findDomainIdByNameInDb: FindDomainIdByName = findDomainIdByName(db) +export const findVariantIdByTokenInDb: FindVariantIdByToken = + findVariantIdByToken(db) diff --git a/server/src/application/sentences/repository/variant-repository.ts b/server/src/application/sentences/repository/variant-repository.ts deleted file mode 100644 index 66e2ab151a17..000000000000 --- a/server/src/application/sentences/repository/variant-repository.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { getMySQLInstance } from '../../../lib/model/db/mysql' -import * as O from 'fp-ts/Option' -import * as TE from 'fp-ts/TaskEither' -import { ApplicationError } from '../../types/error' -import { createDatabaseError } from '../../helper/error-helper' -import { Variant } from '../../../core/types/variant' -import lazyCache from '../../../lib/lazy-cache' - -const db = getMySQLInstance() - -export type FindVariantByTag = ( - variantToken: string -) => TE.TaskEither> - -const lazyFindVariantByTag = lazyCache( - 'sentence-find-variant-by-id', - async (variantToken: string): Promise> => { - const [[row]] = await db.query( - ` - SELECT v.id, l.name as locale, variant_name as name, variant_token as tag FROM variants v - JOIN locales l - ON v.locale_id = l.id - WHERE variant_token = ? - `, - [variantToken] - ) - return row ? O.some(row) : O.none - }, - 24 * 60 * 60 * 1000 -) - -const findVariantByTag = ( - variantToken: string -): TE.TaskEither> => - TE.tryCatch( - () => lazyFindVariantByTag(variantToken), - (err: Error) => - createDatabaseError( - `Error retrieving variant information for token "${variantToken}"`, - err - ) - ) - -export const findVariantByTagInDb: FindVariantByTag = findVariantByTag diff --git a/server/src/application/sentences/use-case/command-handler/add-sentence-command-handler.ts b/server/src/application/sentences/use-case/command-handler/add-sentence-command-handler.ts index 2d4537227818..2ebcb370ec6f 100644 --- a/server/src/application/sentences/use-case/command-handler/add-sentence-command-handler.ts +++ b/server/src/application/sentences/use-case/command-handler/add-sentence-command-handler.ts @@ -1,130 +1,82 @@ import * as O from 'fp-ts/Option' import * as Id from 'fp-ts/Identity' -import * as A from 'fp-ts/Array' import { pipe } from 'fp-ts/lib/function' import { ValidateSentence, ValidatedSentence } from '../../../../core/sentences' import { FindDomainIdByName, + FindVariantIdByToken, SaveSentence, } from '../../repository/sentences-repository' import { AddSentenceCommand } from './command/add-sentence-command' import { either as E, taskEither as TE } from 'fp-ts' import { ApplicationError } from '../../../types/error' -import { - createSentenceValidationError, - createValidationError, -} from '../../../helper/error-helper' +import { createSentenceValidationError } from '../../../helper/error-helper' import { SentenceSubmission } from '../../../types/sentence-submission' -import { FindVariantByTag } from '../../repository/variant-repository' -import { - GetAllLocales, - Locale, - getAllLocales, -} from '../../repository/locale-repository' -import { Variant } from '../../../../core/types/variant' const toValidatedSentence = (validateSentence: ValidateSentence) => - (sentence: string) => - (localeName: string): TE.TaskEither => - pipe( - sentence, - validateSentence(localeName), - E.mapLeft(createSentenceValidationError), - TE.fromEither - ) + (sentence: string) => + (localeName: string): TE.TaskEither => + pipe( + sentence, + validateSentence(localeName), + E.mapLeft(createSentenceValidationError), + TE.fromEither + ) const toDomainIds = (findDomainId: FindDomainIdByName) => - (domains: string[]): TE.TaskEither => { - const findDomainIds = domains.map(domain => findDomainId(domain)) - return pipe( - findDomainIds, - TE.sequenceArray, - TE.map(domainIds => pipe(domainIds, O.sequenceArray)), - TE.map(domainIds => - pipe( - domainIds, - O.getOrElse(() => []) - ) + (domains: string[]): TE.TaskEither => { + const findDomainIds = domains.map(domain => findDomainId(domain)) + return pipe( + findDomainIds, + TE.sequenceArray, + TE.map(domainIds => pipe(domainIds, O.sequenceArray)), + TE.map(domainIds => + pipe( + domainIds, + O.getOrElse(() => []) ) ) - } - -const validateVariantWithLocale = - (localeName: string) => (variant: Variant) => { - return variant.locale === localeName + ) } export const AddSentenceCommandHandler = (validateSentence: ValidateSentence) => - (findDomainIdByName: FindDomainIdByName) => - (findVariantByTag: FindVariantByTag) => - (getAllLocales: GetAllLocales) => - (saveSentence: SaveSentence) => - (command: AddSentenceCommand): TE.TaskEither => - pipe( - TE.Do, - TE.bind('validatedSentence', () => - pipe( - toValidatedSentence, - Id.ap(validateSentence), - Id.ap(command.sentence), - Id.ap(command.localeName) - ) - ), - TE.bind('domainIds', () => - toDomainIds(findDomainIdByName)(command.domains) - ), - TE.bind('variant', () => - pipe( - command.variant, - O.match(() => TE.of(O.none), findVariantByTag) - ) - ), - TE.bind('isLocaleMatching', ({ variant }) => { - const doesNotMatchErr = createValidationError( - 'Sentence variant does not match locale' - ) - - return pipe( - variant, - O.map(validateVariantWithLocale(command.localeName)), - O.map(res => (res ? TE.right(true) : TE.left(doesNotMatchErr))), - O.getOrElse(() => TE.left(doesNotMatchErr)) - ) - }), - TE.bind('localeId', () => - pipe( - getAllLocales(), - TE.chain(locales => - pipe( - locales, - A.findFirst(locale => locale.name === command.localeName), - O.map(({ id }) => id), - TE.fromOption(() => - createValidationError('Locale not found') - ) - ) - ) - ) - ), - TE.map( - ({ - validatedSentence, - localeId, - domainIds, - variant, - }): SentenceSubmission => { - return { - sentence: validatedSentence, - source: command.source, - locale_id: localeId, - client_id: command.clientId, - domain_ids: [...domainIds], - variant: variant, - } - } - ), - TE.chain(saveSentence) - ) + (findDomainIdByName: FindDomainIdByName) => + (findVariantIdByToken: FindVariantIdByToken) => + (saveSentence: SaveSentence) => + (command: AddSentenceCommand): TE.TaskEither => + pipe( + TE.Do, + TE.bind('validatedSentence', () => + pipe( + toValidatedSentence, + Id.ap(validateSentence), + Id.ap(command.sentence), + Id.ap(command.localeName) + ) + ), + TE.bind('domainIds', () => + toDomainIds(findDomainIdByName)(command.domains) + ), + TE.bind('variantId', () => + pipe( + command.variant, + O.match(() => TE.of(O.none), findVariantIdByToken) + ) + ), + TE.map( + ({ validatedSentence, domainIds, variantId }): SentenceSubmission => { + return { + sentence: validatedSentence, + source: command.source, + locale_id: command.localeId, + client_id: command.clientId, + domain_ids: [...domainIds], + variant_id: variantId, + } + } + ), + TE.chain(saveSentence) + ) diff --git a/server/src/application/sentences/use-case/command-handler/command/add-sentence-command.ts b/server/src/application/sentences/use-case/command-handler/command/add-sentence-command.ts index 4bf78b3ba7a5..b27769371678 100644 --- a/server/src/application/sentences/use-case/command-handler/command/add-sentence-command.ts +++ b/server/src/application/sentences/use-case/command-handler/command/add-sentence-command.ts @@ -1,12 +1,13 @@ import { Option } from 'fp-ts/Option' -import { SentenceDomain } from 'common' +import { SentenceDomain } from "common" export type AddSentenceCommand = { clientId: string sentence: string + localeId: number localeName: string - source: string + source: string, domains: SentenceDomain[] - variant: Option + variant: Option } diff --git a/server/src/application/types/sentence-submission.ts b/server/src/application/types/sentence-submission.ts index 6f921b250cf9..cf6c6e23ad42 100644 --- a/server/src/application/types/sentence-submission.ts +++ b/server/src/application/types/sentence-submission.ts @@ -1,11 +1,10 @@ import { Option } from 'fp-ts/Option' -import { Variant } from '../../core/types/variant' export type SentenceSubmission = { - sentence: string - source: string - locale_id: number - client_id: string + sentence: string; + source: string; + locale_id: number; + client_id: string; domain_ids?: number[] | null - variant: Option -} + variant_id: Option +}; diff --git a/server/src/core/types/variant.ts b/server/src/core/types/variant.ts deleted file mode 100644 index 26216626a224..000000000000 --- a/server/src/core/types/variant.ts +++ /dev/null @@ -1,6 +0,0 @@ -export type Variant = { - id: number - locale: string - name: string - tag: string -} diff --git a/server/src/test/application/sentences/use-case/command-handler/add-sentence-command-handler.test.ts b/server/src/test/application/sentences/use-case/command-handler/add-sentence-command-handler.test.ts index 2a72753bb72c..a587e419cd81 100644 --- a/server/src/test/application/sentences/use-case/command-handler/add-sentence-command-handler.test.ts +++ b/server/src/test/application/sentences/use-case/command-handler/add-sentence-command-handler.test.ts @@ -6,12 +6,11 @@ import { AddSentenceCommandHandler } from '../../../../../application/sentences/ import { ERR_TOO_LONG, ValidateSentence } from '../../../../../core/sentences' import { FindDomainIdByName, + FindVariantIdByToken, SaveSentence, } from '../../../../../application/sentences/repository/sentences-repository' import { AddSentenceCommand } from '../../../../../application/sentences/use-case/command-handler/command/add-sentence-command' import { SentenceSubmission } from '../../../../../application/types/sentence-submission' -import { FindVariantByTag } from '../../../../../application/sentences/repository/variant-repository' -import { GetAllLocales } from '../../../../../application/sentences/repository/locale-repository' describe('Add sentence command handler', () => { it('should save the sentence in the repository', async () => { @@ -21,43 +20,35 @@ describe('Add sentence command handler', () => { const findDomainIdByNameMock: FindDomainIdByName = jest.fn(() => TE.right(O.some(1)) ) - const findVariantByTag: FindVariantByTag = jest.fn(() => - TE.right( - O.some({ id: 1, name: 'Central', locale: 'ca', tag: 'ca-central' }) - ) + const findVariantIdByTokenMock: FindVariantIdByToken = jest.fn(() => + TE.right(O.some(1)) ) - const getAllLocales: GetAllLocales = jest.fn(() => TE.right([{ id: 2, name: 'ca' }])) const saveSentenceMock: SaveSentence = jest.fn(() => TE.right(constVoid())) const cmd: AddSentenceCommand = { clientId: 'abc', sentence: 'This is a sentence', - localeName: 'ca', + localeId: 1, + localeName: 'en', source: 'Myself', domains: ['finance'], - variant: O.some('ca-central'), + variant: O.none, } const expectedSentenceSubmission: SentenceSubmission = { sentence: 'This is a sentence', source: 'Myself', - locale_id: 2, + locale_id: 1, client_id: 'abc', domain_ids: [1], - variant: O.some({ - id: 1, - name: 'Central', - locale: 'ca', - tag: 'ca-central', - }), + variant_id: O.none, } const cmdHandler = pipe( AddSentenceCommandHandler, I.ap(validateSentenceMock), I.ap(findDomainIdByNameMock), - I.ap(findVariantByTag), - I.ap(getAllLocales), + I.ap(findVariantIdByTokenMock), I.ap(saveSentenceMock) ) @@ -77,126 +68,31 @@ describe('Add sentence command handler', () => { const findDomainIdByNameMock: FindDomainIdByName = jest.fn(() => TE.right(O.some(1)) ) - const findVariantByTag: FindVariantByTag = jest.fn(() => - TE.right( - O.some({ id: 1, name: 'Central', locale: 'ca', tag: 'ca-central' }) - ) - ) - const getAllLocales: GetAllLocales = jest.fn(() => TE.right([{ id: 1, name: 'ca' }])) - const saveSentenceMock: SaveSentence = jest.fn(() => TE.right(constVoid())) - - const cmd: AddSentenceCommand = { - clientId: 'abc', - sentence: 'This is a sentence', - localeName: 'en', - source: 'Myself', - domains: ['finance'], - variant: O.none, - } - - const cmdHandler = pipe( - AddSentenceCommandHandler, - I.ap(validateSentenceMock), - I.ap(findDomainIdByNameMock), - I.ap(findVariantByTag), - I.ap(getAllLocales), - I.ap(saveSentenceMock) - ) - - const result = await pipe(cmd, cmdHandler)() - expect(E.isLeft(result)).toBeTruthy() - expect(saveSentenceMock).toHaveBeenCalledTimes(0) - }) - - it('should return validation error when locale does not match variant', async () => { - const validateSentenceMock: ValidateSentence = jest.fn( - () => () => E.right('This is a sentence') - ) - const findDomainIdByNameMock: FindDomainIdByName = jest.fn(() => + const findVariantIdByTokenMock: FindVariantIdByToken = jest.fn(() => TE.right(O.some(1)) ) - const findVariantByTag: FindVariantByTag = jest.fn(() => - TE.right( - O.some({ id: 1, name: 'Central', locale: 'ca', tag: 'ca-central' }) - ) - ) - const getAllLocales: GetAllLocales = jest.fn(() => TE.right([{ id: 1, name: 'ca' }])) const saveSentenceMock: SaveSentence = jest.fn(() => TE.right(constVoid())) const cmd: AddSentenceCommand = { clientId: 'abc', sentence: 'This is a sentence', + localeId: 1, localeName: 'en', source: 'Myself', domains: ['finance'], - variant: O.some('ca-central'), + variant: O.none, } const cmdHandler = pipe( AddSentenceCommandHandler, I.ap(validateSentenceMock), I.ap(findDomainIdByNameMock), - I.ap(findVariantByTag), - I.ap(getAllLocales), + I.ap(findVariantIdByTokenMock), I.ap(saveSentenceMock) ) - const result = await pipe(cmd, cmdHandler)() - const errMsg = pipe( - result, - E.fold( - err => err.message, - () => "Shouldn't be here" - ) - ) - - expect(E.isLeft(result)).toBeTruthy() - expect(errMsg).toBe('Sentence variant does not match locale') - expect(saveSentenceMock).toHaveBeenCalledTimes(0) - }) - - it('should return error when locale is not found', async () => { - const validateSentenceMock: ValidateSentence = jest.fn( - () => () => E.right('This is a sentence') - ) - const findDomainIdByNameMock: FindDomainIdByName = jest.fn(() => - TE.right(O.some(1)) - ) - const findVariantByTag: FindVariantByTag = jest.fn(() => - TE.right( - O.some({ id: 1, name: 'Central', locale: 'ca', tag: 'ca-central' }) - ) - ) - const getAllLocales: GetAllLocales = jest.fn(() => TE.right([{ id: 1, name: 'en' }])) - const saveSentenceMock: SaveSentence = jest.fn(() => TE.right(constVoid())) - const cmd: AddSentenceCommand = { - clientId: 'abc', - sentence: 'This is a sentence', - localeName: 'ca', - source: 'Myself', - domains: ['finance'], - variant: O.some('ca-central'), - } - - const cmdHandler = pipe( - AddSentenceCommandHandler, - I.ap(validateSentenceMock), - I.ap(findDomainIdByNameMock), - I.ap(findVariantByTag), - I.ap(getAllLocales), - I.ap(saveSentenceMock) - ) const result = await pipe(cmd, cmdHandler)() - const errMsg = pipe( - result, - E.fold( - err => err.message, - () => "Shouldn't be here" - ) - ) - expect(E.isLeft(result)).toBeTruthy() - expect(errMsg).toBe('Locale not found') expect(saveSentenceMock).toHaveBeenCalledTimes(0) }) }) From 886a198df80a8ec54f0d68fd1ffd901c99c0c3af Mon Sep 17 00:00:00 2001 From: Joergen Date: Thu, 18 Apr 2024 13:12:35 +0000 Subject: [PATCH 15/69] Pontoon: Update Danish (da) localization of Common Voice Co-authored-by: Joergen Co-authored-by: Peter Leth --- web/locales/da/messages.ftl | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/web/locales/da/messages.ftl b/web/locales/da/messages.ftl index ae076630c627..d28a211174b7 100644 --- a/web/locales/da/messages.ftl +++ b/web/locales/da/messages.ftl @@ -52,6 +52,7 @@ cak = Kaqchikel ckb = Sorani cnh = Hakha Chin co = Korsikansk +crh = Krim-tatarisk cs = Tjekkisk cv = Tjuvasjisk cy = Walisisk @@ -144,6 +145,7 @@ nl = Nederlandsk nn-NO = Nynorsk nr = Sydndebele nso = Nordsotho +ny = Nyanja nyn = Nyankole oc = Occitansk om = Oromo @@ -165,6 +167,8 @@ sah = Yakut sat = Santali (Ol Chiki) sc = Sardisk scn = Siciliansk +sco = Skotsk +sd = Sindhi sdh = Sydkurdisk shi = Shilha si = Singalesisk @@ -206,6 +210,7 @@ ve = Venda vec = Venetiansk vi = Vietnamesisk vot = Votisk +wo = Wolof xh = Xhosa yi = Jiddisch yo = Yoruba @@ -391,8 +396,6 @@ native-language = profile-form-add-accent = Tilføj ny brugerdefineret accent "{ $inputValue }" profile-form-submit-save = Gem profile-form-submit-saved = Gemt -male = Mand -female = Kvinde # Gender other = Andet why-profile-title = Hvorfor oprette en profil? @@ -660,6 +663,9 @@ about-playbook-how-project-governance-content-5 = Værdi og anerkendelse. about-playbook-how-project-governance-content-6 = Gensidig ansvarlighed. about-playbook-how-project-governance-content-7 = Læs mere om, hvordan vi styres +## How is Common Voice funded + + ## Glossary glossary = Ordliste @@ -1538,8 +1544,12 @@ localization-select = .label = Vælg sprog/oversættelse # PARTNERSHIPS PAGE partnerships-header = Partnerskaber +add-information-button = Tilføj information sentence-collection = Indsamling af sætninger +## WRITE PAGE + + ## REVIEW PAGE @@ -1550,3 +1560,6 @@ file-invalid-type = Ugyldig fil file-too-large = Filen er for stor file-too-small = Filen er for lille too-many-files = For mange filer + +## Donate banner + From fed3b350290105cdc1a0ea49e1adb094ea4a006c Mon Sep 17 00:00:00 2001 From: Peter Leth Date: Thu, 18 Apr 2024 13:23:15 +0000 Subject: [PATCH 16/69] Pontoon: Update Danish (da) localization of Common Voice Co-authored-by: Joergen Co-authored-by: Peter Leth --- web/locales/da/messages.ftl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/web/locales/da/messages.ftl b/web/locales/da/messages.ftl index d28a211174b7..9418e35652cb 100644 --- a/web/locales/da/messages.ftl +++ b/web/locales/da/messages.ftl @@ -18,6 +18,8 @@ banner-error-slow-1 = Beklager, Common Voice arbejder langsomt. Tak for din inte banner-error-slow-2 = Vi modtager meget trafik og er i øjeblikket ved at undersøge sagerne. banner-error-slow-link = Statusside error-something-went-wrong = Noget gik galt +error-clip-upload = Upload af denne optagelse mislykkes fortsat. Vil du blive ved med at prøve? +error-clip-upload-server = Upload af denne optagelse mislykkes ved server. Genindlæs siden eller prøv igen senere. # Don't rename the following section, its contents are auto-inserted based on the name (see scripts/pontoon-languages-to-ftl.js) # [Languages] @@ -220,6 +222,7 @@ zh-CN = Kinesisk (Kina) zh-HK = Kinesisk (Hong Kong) zh-TW = Kinesisk (Taiwan) zu = Zulu +zza = Zaza # [/] @@ -396,6 +399,12 @@ native-language = profile-form-add-accent = Tilføj ny brugerdefineret accent "{ $inputValue }" profile-form-submit-save = Gem profile-form-submit-saved = Gemt +male_masculine = Mand / maskulin +female_feminine = Kvinde / feminin +intersex = Intersex +transgender = Transkønnet +non-binary = Ikke-binær +do_not_wish_to_say = Ønsker ikke at oplyse # Gender other = Andet why-profile-title = Hvorfor oprette en profil? @@ -414,6 +423,7 @@ why-demographic = Hvorfor er dette vigtigt? why-demographic-explanation-2 = Anonymiserede brugerdata som alder, køn og accent hjælper med at forbedre de lyddata, der bruges til at træne nøjagtigheden af talegenkendelses-motorer. Dit brugernavn og din mailadresse vil aldrig blive forbundet med dine indsendte data, og du kan vælge, om du vil gøre dit brugernavn offentligt eller anonymt. accept-privacy = Det er helt fint, at I håndterer disse oplysninger som beskrevet i Mozillas privatlivspolitik accept-privacy-title = Privatlivspolitik +accept-privacy-and-terms = Jeg accepterer Common Voices' vilkår og privatlivserklæring login-identity = Login-identitet login = Log ind login-signup = Log ind / Opret dig @@ -665,6 +675,7 @@ about-playbook-how-project-governance-content-7 = Læs mere om, ## How is Common Voice funded +about-playbook-how-funded = Hvordan er Common Voice finansieret? ## Glossary @@ -732,12 +743,14 @@ datasets-positioning = På denne side finder du en oversigt over andre open source-samlinger af stemme-datasæt, og - i takt med at Common Voice vokser - en oversigt over vores udgivelser og opdateringer. language = Sprog +download-dataset-header = Hent datasættet # File size in gigabytes size = Størrelse validated-hr-total = Validerede timer i alt overall-hr-total = Samlede timer i alt cv-license = Licens audio-format = Lydformat +dataset-splits = Fordeling (alder og køn) number-of-voices = Antal stemmer splits = Fordeling email-to-download = Indtast mailadresse for at hente @@ -759,6 +772,8 @@ subscribe = Abonnér get-started-speech = Kom godt i gang med talegenkendelse other-datasets = Andre stemme-datasæt feedback-q = Har du feedback? +# This indicates that there is no data to display +no-information = Ingen information resource-nemo-info = NVIDIA NeMo™ er et open source-værktøjssæt til forskere, der udvikler avancerede samtale-AI-modeller. resource-deepspeech-info = Datasættet fra Common Voice supplerer Deep Speech, en open source-tjeneste til stemmegenkendelse fra Mozilla, som du kan bruge til at bygge software, der gør brug af stemmegenkendelse. Få overblik over projektet på Github eller deltag i diskussionen om Deepspeech på Discourse for at komme godt i gang. resource-coqui-info = Coqui er dedikeret til åben taleteknologi. Deres projekter omfatter deep learning-baserede STT- og TTS-motorer. @@ -779,6 +794,7 @@ close = Luk download = Hent dataset-version = Version clipboard-not-supported = Udklipsholder er ikke understøttet +no-information-available = Ingen tilgængelig information ## Download Modal From 7264daf18076b03344b2ef3c761718ab2bc1739c Mon Sep 17 00:00:00 2001 From: Peter Leth Date: Thu, 18 Apr 2024 13:32:45 +0000 Subject: [PATCH 17/69] Pontoon: Update Danish (da) localization of Common Voice Co-authored-by: Joergen Co-authored-by: Peter Leth Co-authored-by: hennsoe --- web/locales/da/messages.ftl | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/web/locales/da/messages.ftl b/web/locales/da/messages.ftl index 9418e35652cb..e9592198086e 100644 --- a/web/locales/da/messages.ftl +++ b/web/locales/da/messages.ftl @@ -720,7 +720,7 @@ license = Licens: { $license } license-mixed = Blandet data-download-singleword-title = Hent målsegmentet med enkelte ord data-download-singleword-callout-v2 = Dette er et brugsmønster-drevet segment, der indeholder data til understøttelse af stemmeudtalt tal og detektering af ja / nej. -review-terms = Ved brug af Common Voice accepterer du vores Vilkår og Privatlivspolitik +review-terms = Ved brug af Common Voice accepterer du vores vilkår og privatlivserklæring terms-agree = Jeg accepterer terms-disagree = Jeg accepterer ikke review-aborted = Upload afbrudt. Vil du slette dine optagelser? @@ -795,6 +795,13 @@ download = Hent dataset-version = Version clipboard-not-supported = Udklipsholder er ikke understøttet no-information-available = Ingen tilgængelig information +dataset-metadata-sex = Køn +# dataset metadata - age of contributor +dataset-metadata-age = Alder +donate-modal-message = Dit datasæt downloades! +dataset-donate-modal-heading = Vidste du… +# Text in will shown in bold +donate-modal-explanation-2 = Hvis du værdsætter åbne, inkluderende data - så donér i dag! ## Download Modal @@ -892,6 +899,7 @@ action-click = Klik på action-tap = Tryk på contribute = Bidrag listen = Lyt +write = Skriv skip = Spring over shortcuts = Genveje clips-with-count-pluralized = @@ -937,6 +945,9 @@ listen-empty-state = Der er ikke flere stemmeoptagelser at validere på dette sp listen-loading-error = Vi kunne ikke finde nogen lydklip, som du kan lytte til. Prøv igen senere. +listen-abort-title = Er du færdig med at validere optagelser? +listen-abort-cancel = Fortsæt med at validere +listen-abort-confirm = Afslut valideringen speak-empty-state = Der er ikke flere sætninger at optage på dette sprog... speak-empty-state-cta = Bidrag med sætninger speak-loading-error = @@ -1560,6 +1571,7 @@ localization-select = .label = Vælg sprog/oversættelse # PARTNERSHIPS PAGE partnerships-header = Partnerskaber +partnerships-governments-header = Regeringer add-information-button = Tilføj information sentence-collection = Indsamling af sætninger From 394a9d8ddd8192e98c9880d7a34457dba82ebb3a Mon Sep 17 00:00:00 2001 From: hennsoe Date: Thu, 18 Apr 2024 13:42:43 +0000 Subject: [PATCH 18/69] Pontoon: Update Danish (da) localization of Common Voice Co-authored-by: Joergen Co-authored-by: Peter Leth Co-authored-by: hennsoe --- web/locales/da/messages.ftl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/web/locales/da/messages.ftl b/web/locales/da/messages.ftl index e9592198086e..8798fb4d2a92 100644 --- a/web/locales/da/messages.ftl +++ b/web/locales/da/messages.ftl @@ -1572,11 +1572,18 @@ localization-select = # PARTNERSHIPS PAGE partnerships-header = Partnerskaber partnerships-governments-header = Regeringer +partnerships-our-partners = Vores partnere +why-donate = Hvorfor spørger du? add-information-button = Tilføj information sentence-collection = Indsamling af sætninger ## WRITE PAGE +how-to-cite = Hvordan citerer jeg? +contact-us = Kontakt os +add-sentence-success = 1 sætning indsamlet +add-sentence-error = Fejl ved tilføjelse af sætning +required-field = Udfyld venligst dette felt. ## REVIEW PAGE @@ -1584,6 +1591,10 @@ sentence-collection = Indsamling af sætninger ## BULK SUBMISSION select-file = Vælg fil +select-file-mobile = Vælg fil, der skal uploades +accepted-files = Accepterede filtyper: Kun .tsv +maximum-file-size = Maksimal filstørrelse: 25 MB +what-needs-to-be-in-file = Hvad skal der være i min fil? file-invalid-type = Ugyldig fil file-too-large = Filen er for stor file-too-small = Filen er for lille From dd08c03c62901a56e892c403f193d14574f53642 Mon Sep 17 00:00:00 2001 From: Waleghwa Date: Thu, 18 Apr 2024 15:43:02 +0000 Subject: [PATCH 19/69] Pontoon: Update Kidaw'ida (dav) localization of Common Voice Co-authored-by: Waleghwa --- web/locales/dav/messages.ftl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/locales/dav/messages.ftl b/web/locales/dav/messages.ftl index 84ec239d55db..053ae8065660 100644 --- a/web/locales/dav/messages.ftl +++ b/web/locales/dav/messages.ftl @@ -407,7 +407,7 @@ native-language = .label = Kiteto Chevalwa profile-form-add-accent = Churia madedo maw'ishi "{ $inputValue }" profile-form-submit-save = Kira -profile-form-submit-saved = Ikirilo +profile-form-submit-saved = Yakirwa male_masculine = Mndu wa Kiw'omi female_feminine = Mndu wa Kiw'aka intersex = mundu uko kuw'i From 67a2af673a73b2dc9d855b652549e5c682705be8 Mon Sep 17 00:00:00 2001 From: TINAUNGLIN Date: Thu, 18 Apr 2024 17:03:44 +0000 Subject: [PATCH 20/69] Pontoon: Update Burmese (my) localization of Common Voice Co-authored-by: TINAUNGLIN --- web/locales/my/messages.ftl | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/web/locales/my/messages.ftl b/web/locales/my/messages.ftl index 311b279e9731..0c465b7a6174 100644 --- a/web/locales/my/messages.ftl +++ b/web/locales/my/messages.ftl @@ -197,21 +197,41 @@ ta = တမီးလ် te = တယ်လုဂု tg = တာဂျစ် th = ထိုင်း +ti = တီဂျရီယာ +tig = တီဂရီ +tk = တတ်ခမန် tl = တန်ဂလို +tn = ဆက်စွာနာ +tok = တိုကီ ပိုနာ tr = တူရကီ +ts = Xitsonga tt = တာတာ +tw = တွီ +ty = တဟီးတီယန်း +tyv = တူဗန် uby = အူဗိုက် udm = အမုဒ် +ug = ဝီဂါ uk = ယူကရိန်း ur = အူရဒူ uz = ဥဇဘက် +ve = ရှီဗင်ဒါ vec = ဗနီးရှင်း vi = ဗီယက်နမ် +vmw = Emakhuwa vot = ဗို့တစ် +wep = အနောက်ဖလီယန် +wo = ဝေါလောက် +xh = ဇော်ဆာ +yi = ရစ်ဒစ်ရှ် +yo = ယောရူဘာ yue = ကန်တုန်နိစ် +zgh = Tamazight zh-CN = တရုတ် (တရုတ်) zh-HK = တရုတ် (ဟောင်ကောင်) zh-TW = တရုတ် (တိုင်ဝမ်) +zu = ဇူးလူး +zza = ဇာဇာ # [/] @@ -223,6 +243,7 @@ speak-now = ယခု ပြောပါ datasets = ဒေတာအစုများ languages = ဘာသာစကားများ about = အကြောင်း +partner = ပူးပေါင်းဆောင်ရွက်သူ profile = ကိုယ်ရေးအကျဉ်း help = အကူအညီ contact = ဆက်သွယ်ရန် @@ -236,10 +257,12 @@ share-text = လူတွေ မည်သို့အသံထွက်သည် link-copied = လင့်ခ်ကို ကူယူပြီး back-top = အပေါ်သို့ ပြန်သွားရန် logout = ထွက်ရန် +donate = လှူဒါန်းပါ ## Home Page home-title = Common Voice သည် လူအများ မည်သို့ ပြောဆိုသည်ဆိုတာ စက်များကို သင်ပေးရာတွင် ကူညီရန် Mozilla ၏ စတင်ဆောင်ရွက်မှုတစ်ခု ဖြစ်သည်။ +default-tagline = Common Voice သည် လူအများ မည်သို့ ပြောဆိုသည်ဆိုတာ စက်များကို သင်ပေးရာတွင် ကူညီရန် Mozilla ၏ စတင်ဆောင်ရွက်မှုတစ်ခု ဖြစ်သည်။ home-cta = စကားပြောပါ၊ ဒီမှာ ပါဝင်ကူညီပါ။ wall-of-text-start = သဘာဝကျသော အသံဖြစ်ရမည်၊ လူသားအသံဖြစ်ရမည်။ ဒါကြောင့် ကျွန်တော်တို့က ကျွန်တော်တို့ရဲ့ စက်ပစ္စည်းတွေအတွက် နည်းပညာအသုံးချပြီး အသံဖန်တီးခြင်းကို စိတ်ဝင်စားလာရခြင်းပါ။ သို့ပေမဲ့ အသံဖန်တီးခြင်းစနစ်ကို ပြုလုပ်ဖို့အတွက် အလွန့်ကို များပြားတဲ့ အသံဖိုင်ဆိုင်ရာအချက်အလက်တွေ လိုအပ်ပါတယ်။ wall-of-text-more-mobile = @@ -332,6 +355,10 @@ shortcut-record-toggle = r shortcut-record-toggle-label = အသံသွင်း/ရပ် shortcut-rerecord-toggle = [1-5] shortcut-rerecord-toggle-label = အသံကလစ် ပြန်သွင်း +shortcut-discard-ongoing-recording = ထွက် +shortcut-discard-ongoing-recording-label = လက်ရှိအသံသွင်းခြင်းကို မလုပ်တော့ပါ +shortcut-submit = ပြန်လာ +shortcut-submit-label = အသံကလစ်များကို တွင်သွင်းပါ request-language-text = Common Voice မှာ သင့်ဘာသာစကား ကို ရှာမတွေ့ဘူးလား။ request-language-button = ဘာသာစကားတစ်ခု တောင်းဆိုရန် @@ -356,6 +383,8 @@ profile-form-native-language = .label = မိခင်ဘာသာစကား profile-form-additional-language = .label = ထပ်ဆောင်း ဘာသာစကား +profile-form-language = + .label = ဘာသာစကား profile-form-accent = .label = လေယူလေသိမ်း profile-form-age = From e39fe7bdf99d2312a809260bef363efcaaf0bb98 Mon Sep 17 00:00:00 2001 From: TINAUNGLIN Date: Thu, 18 Apr 2024 17:13:01 +0000 Subject: [PATCH 21/69] Pontoon: Update Burmese (my) localization of Common Voice Co-authored-by: TINAUNGLIN --- web/locales/my/messages.ftl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/web/locales/my/messages.ftl b/web/locales/my/messages.ftl index 0c465b7a6174..7b62d2db102e 100644 --- a/web/locales/my/messages.ftl +++ b/web/locales/my/messages.ftl @@ -385,8 +385,14 @@ profile-form-additional-language = .label = ထပ်ဆောင်း ဘာသာစကား profile-form-language = .label = ဘာသာစကား +profile-form-variant = + .label = { $language } ဘာသာ မှမည်သည့်ပုံဟန်ကို သင် သုံးသနည်း? +profile-form-variant-default-value = မူကွဲကို ရွေးထားခြင်းမရှိပါ။ profile-form-accent = .label = လေယူလေသိမ်း +profile-form-custom-accent-help-text = + .label = မင်းရဲ့ လေယူလေသိမ်းကို ဘယ်လိုဖော်ပြမလဲ။ +profile-form-custom-accent-placeholder-2 = သင့်လေယူလေသိမ်းကို ဖော်ပြရန်အတွက် စတင်ရိုက်ပါ။ profile-form-age = .label = အသက် profile-form-gender-2 = @@ -397,8 +403,15 @@ hidden = ဖျောက်ထား visible = ပြရန် native-language = .label = မိခင် ဘာသာစကား +profile-form-add-accent = စိတ်ကြိုက်လေယူလေသိမ်းအသစ် "{ $inputValue }" ကို ထည့်ပါ profile-form-submit-save = သိမ်း profile-form-submit-saved = သိမ်းပြီး +male_masculine = ယောက်ျား/ယောက်ျားလေး +female_feminine = အမျိုးသမီး/အမျိုးသမီး +intersex = လိင်နှစ်မျိုးသုံး +transgender = လိင်ပြောင်း +non-binary = ဒွိမဟုတ်သော +do_not_wish_to_say = မပြောချင်ဘူး။ # Gender other = အခြား why-profile-title = ပရိုဖိုင် က ဘာလိုလဲ? @@ -419,6 +432,7 @@ why-demographic = အဘယ်ကြောင့် ဤအရာသည် အရ why-demographic-explanation-2 = အသက်၊ လိင် (ကျား၊ မ) နှင့် လေယူလေသိမ်း သည် အသံ အချက်အလက် သုံးကာ စကားပြော နားလည်နိုင်မှု အင်ဂျင် ကို တိကျစွာ လေ့ကျင့်သင်ကြား နိုင်ရန် ကူညီ ထောက်ပံ့ သည်။ သင်၏ အသုံးပြုသူအမည် နှင့် အီးမေးလ်သည် သင် တင်သွင်းထားသော အချက်အလက်များ နှင့် မည်သည့်အခါမျှ (သင်၏ အသုံးပြုသူ အမည် ကို အများသိစေရန် ခွင့်ပြုထားစေကာသော်မျှ) ဆက်စပ်မှုမရှိပါ။ accept-privacy = Mozilla ၏ တကိုယ်ရေကာကွယ်ရေး မူဝါဒ တွင် သင် ရှင်းပြသည့်အတိုင်းဤ အချက်အလက် ကို သင်တို့ ကိုင်တွယ်မည်ဆိုလျှင် ကျွန်ုပ် အတွက် အဆင်ပြေပါသည်။ accept-privacy-title = ကိုယ်ရေးအချက်အလက်ကာကွယ်မှု မူဝါဒ +accept-privacy-and-terms = Common Voice ကိုအသုံးပြုခြင်းအားဖြင့်ကျွန်ုပ်တို့၏ Terms နှင့် Privacy Notice ကိုသဘောတူတယ်။ login-identity = ဝင်ရန် သက်သေခံ login = အဝင် login-signup = ဝင်ရန်/စာရင်းသွင်းရန် @@ -477,7 +491,9 @@ faq-why-important-a = faq-how-get-q = ကျွန်တော် Common Voice ရဲ့ ဒေတာကို ဘယ်လိုရနိုင်မလဲ။ faq-how-get-a = Common Voice ‌အချက်အလက်ဆက်လိုက် ကို CC0 လိုင်စင် ဖြင့် ကျွန်​တော်တို့ ၏ အချက်အလက်အစုဆက် စာမျက်နှာ ​အောက်တွင် ​ဒေါင်းလုပ် ရယူနိုင်သည်။ သင်သည် အများပြည်သူ အတွက် ရရှိနိုင်သည့် အခြား​သော အချက်အလက်အစုဆက်များ ကိုလဲ အဆိုပါ စာမျက်နှာတွင် ​ဒေါင်းလုပ် ရယူနိုင်သည်။ faq-when-release2-q = Common Voice အချက်အလက်များကိုအခြားဘာသာစကားများဖြင့်ဘယ်အချိန်တွင်ထုတ်ပြန်မလဲ။ +faq-when-release2-a = Common Voice ဒေတာအတွဲ၏ ဘာသာစကားပေါင်းစုံဗားရှင်းသည် လက်ရှိတွင် လူအများအတူတကွ အစုအဝေးနှင့် သန့်ရှင်းရေးကို လုပ်ဆောင်နေပါသည်။ ဘာသာစကားအသစ်များသို့ Common Voice များယူဆောင်လာစေရန် ကူညီလိုပါက၊ ဒေတာ သို့ စာကြောင်းအသစ်များထည့်ရန်အတွက် Sentence Collection Tool နှင့် Mozilla Pontoon ကိုသွား၍ ဝဘ်ဆိုဒ်ကို ဘာသာပြန်ဆိုရန် ကိုယ်တိုင် အတည်ပြုထားသော စာကြောင်း 5000 ကို စုဆောင်းပြီးသောအခါ အသံပံ့ပိုးမှုအတွက် Common Voice တွင် ဘာသာစကားအသစ်များကို ပေါင်းထည့်ပါသည်။ faq-why-mission-q = Common Voice သည် Mozilla မစ်ရှင် ၏ အစိတ်အပိုင်း တစ်ခု ဘာကြောင့် ဖြစ်သနည်း။ +faq-why-mission-a = Mozilla သည် ဝဘ်ကိုပွင့်လင်းစေပြီး လူတိုင်းအတွက် အသုံးပြုနိုင်စေရန် ရည်ရွယ်ပါသည်။ ထိုသို့လုပ်ဆောင်ရန် ကျွန်ုပ်တို့သည် Common Voice ကဲ့သို့သော ပရောဂျက်များမှတစ်ဆင့် ဝဘ်ဖန်တီးသူများကို ခွန်အားပေးရန် လိုအပ်ပါသည်။ အသံနည်းပညာများသည် နယ်ပယ်အသီးသီးမှ အက်ပ်ပလီကေးရှင်းများထက် ကျယ်ပြန့်လာသည်နှင့်အမျှ ၎င်းတို့သည် သုံးစွဲသူအားလုံးကို ညီတူညီမျှ ဝန်ဆောင်မှုပေးရမည် ဟု ကျွန်ုပ်တို့ ယုံကြည်ပါသည်။ ဆိုလိုသည်မှာ ဘာသာစကားများ ပိုမိုရင်းနှီးမြုပ်နှံပြီး အသံနည်းပညာများကို တည်ဆောက်ခြင်းနှင့် စမ်းသပ်သည့်အခါ ကွဲပြားသော လေယူလေသိမ်းနှင့် လူဦးရေစာရင်းကို လိုက်လျောညီထွေဖြစ်စေရန် ဆိုလိုသည်။ Common Voice သည် လူတိုင်းအတွက်ရရှိနိုင်သည့် အများသူငှာအရင်းအမြစ်တစ်ခုဖြစ်ပြီး ကမ္ဘာတစ်ဝှမ်းရှိ Mozilla အဖွဲ့များနှင့် developer များသည် ၎င်းကို ကျွန်ုပ်တို့၏ကိုယ်ပိုင်ပရောဂျက်များတွင်လည်း အသုံးပြုနေပြီဖြစ်သည်။ faq-what-cv-and-deepspeech-q = Common Voice နှင့် Deep Speech တို့ ၏ ကွာခြားချက်က ဘာလဲ? faq-is-goal-assistant-q = Common Voice ရဲ့ ပန်းတိုင်က အသံ လက်ထောက် ကို တည်ဆောက်ဖို့လား? faq-do-want-native-q = ကျွန်ုပ်သည်အသံ၀ဲပြီး Native Speaker တစ်ယောက်မဟုတ်ပါ။ ကျွန်ုပ်၏အသံကိုသင်လိုသေးလား? @@ -696,6 +712,7 @@ language-search-input = language-speakers = ပြောသူများ localized = ဒေသသုံးပြုရန် sentences = ဝါကျများ +language-validation-hours = နာရီများ ## Contribution From 1f697c96dc3b332d915f598c15a22d908bea7a3d Mon Sep 17 00:00:00 2001 From: Hanif Rahman Date: Thu, 18 Apr 2024 18:33:33 +0000 Subject: [PATCH 22/69] Pontoon: Update Pashto (ps) localization of Common Voice Co-authored-by: Hanif Rahman --- web/locales/ps/messages.ftl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/locales/ps/messages.ftl b/web/locales/ps/messages.ftl index f2b69a0c7152..a843cc0b1d32 100644 --- a/web/locales/ps/messages.ftl +++ b/web/locales/ps/messages.ftl @@ -1698,7 +1698,7 @@ public-domain = عامه ډومین citing-sentences = د جملې نقل کول adding-sentences = د جملو اضافه کول reviewing-sentences = د جملو بیاکتنه -sentence-domain = د جملې ډومین +sentence-domain = د جملې ټولۍ public-domain-explanation-1 = دا ډیره مهمه ده چې د متن ټولې جملې عامه ډومین (cc0) وي ځکه چې د عام غږ ډیټاسیټ د cc0 جواز لاندې خپور شوی. یوازې کله هم یوه جمله اپلوډ کړئ که تاسو ډاډه یاست، او تل اړونده حواله شامل کړئ. public-domain-explanation-2 = د ګټورې وینا پیژندنې انجن رامینځته کولو لپاره غوره جملې خبرې ، عصري خبرې دي. ځینې نظریات چې تاسو سره د جملو په جوړولو کې مرسته کوي؛ public-domain-explanation-3 = د خپل ځان او یا د خپلو ملګرو یا د ژبې ټولنې سره عصري، د خبرو اترو جملې جوړې کړئ - د مثال په توګه د "لیکوالۍ" له لارې From eb5736624f6951f73a76bc744efb236e297daf68 Mon Sep 17 00:00:00 2001 From: Hanif Rahman Date: Thu, 18 Apr 2024 18:43:28 +0000 Subject: [PATCH 23/69] Pontoon: Update Pashto (ps) localization of Common Voice Co-authored-by: Hanif Rahman --- web/locales/ps/messages.ftl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/locales/ps/messages.ftl b/web/locales/ps/messages.ftl index a843cc0b1d32..c800910b9a12 100644 --- a/web/locales/ps/messages.ftl +++ b/web/locales/ps/messages.ftl @@ -440,7 +440,7 @@ accept-privacy = زه ستاسو سره د دې مالوماتو په سمبال accept-privacy-title = د پټتیا تګلاره accept-privacy-and-terms = زه د عام غږ د شرائط او د محرمیت خبرتیا سره موافق یم login-identity = د ننوتنې پېژند -login = لاګ ان +login = ننوتل login-signup = ننوتنه/ نوملیکنه edit = سمون email-subscriptions = د برېښنالیک ګډونونه @@ -1783,7 +1783,7 @@ finance = مالیه # Sentence Domain dropdown option food_service_retail = خواړه، خدمت او پرچون # Sentence Domain dropdown option -general = جنرال +general = عمومي معلومات # Sentence Domain dropdown option healthcare = روغتیایی پاملرنه # Sentence Domain dropdown option From 53b550251839e2e954a61d20aa4ae042a053e745 Mon Sep 17 00:00:00 2001 From: hennsoe Date: Fri, 19 Apr 2024 15:33:04 +0000 Subject: [PATCH 24/69] Pontoon: Update Danish (da) localization of Common Voice Co-authored-by: hennsoe --- web/locales/da/messages.ftl | 1 + 1 file changed, 1 insertion(+) diff --git a/web/locales/da/messages.ftl b/web/locales/da/messages.ftl index 8798fb4d2a92..799bc00fec38 100644 --- a/web/locales/da/messages.ftl +++ b/web/locales/da/messages.ftl @@ -900,6 +900,7 @@ action-tap = Tryk på contribute = Bidrag listen = Lyt write = Skriv +review = Verificer skip = Spring over shortcuts = Genveje clips-with-count-pluralized = From 73b12ffbb3e9b5481f3b53948a6062810da660e0 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Sat, 20 Apr 2024 09:52:39 +0000 Subject: [PATCH 25/69] Pontoon: Update Danish (da) localization of Common Voice --- web/locales/da/messages.ftl | 1 - 1 file changed, 1 deletion(-) diff --git a/web/locales/da/messages.ftl b/web/locales/da/messages.ftl index 799bc00fec38..8798fb4d2a92 100644 --- a/web/locales/da/messages.ftl +++ b/web/locales/da/messages.ftl @@ -900,7 +900,6 @@ action-tap = Tryk på contribute = Bidrag listen = Lyt write = Skriv -review = Verificer skip = Spring over shortcuts = Genveje clips-with-count-pluralized = From d549335147929bb3875d5467b54874b1f15d776f Mon Sep 17 00:00:00 2001 From: Alvyn Abranches Date: Sat, 20 Apr 2024 11:22:41 +0000 Subject: [PATCH 26/69] Pontoon: Update Goan Konkani (gom) localization of Common Voice Co-authored-by: Alvyn Abranches --- web/locales/gom/cross-locale.ftl | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 web/locales/gom/cross-locale.ftl diff --git a/web/locales/gom/cross-locale.ftl b/web/locales/gom/cross-locale.ftl new file mode 100644 index 000000000000..038ff16d9a67 --- /dev/null +++ b/web/locales/gom/cross-locale.ftl @@ -0,0 +1,7 @@ +## Languages + +get-involved-stayintouch = Voice technology'cher ami ek community karma Mozilla'an. Ami chad khosi tumka update dovarpak, novo data duvpak and aikpak tumi koso ho data use karta toh. +get-involved-privacy-info = { "" } +get-involved-success-title = { "" } +get-involved-success-text = { "" } +get-involved-return-to-languages = { "" } From a6c18a861ffc3c9f3755aedfa177ac9cdb752913 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Sat, 20 Apr 2024 11:42:26 +0000 Subject: [PATCH 27/69] Pontoon: Update Goan Konkani (gom) localization of Common Voice --- web/locales/gom/cross-locale.ftl | 5 ----- 1 file changed, 5 deletions(-) diff --git a/web/locales/gom/cross-locale.ftl b/web/locales/gom/cross-locale.ftl index 038ff16d9a67..9001d5cd6de4 100644 --- a/web/locales/gom/cross-locale.ftl +++ b/web/locales/gom/cross-locale.ftl @@ -1,7 +1,2 @@ ## Languages -get-involved-stayintouch = Voice technology'cher ami ek community karma Mozilla'an. Ami chad khosi tumka update dovarpak, novo data duvpak and aikpak tumi koso ho data use karta toh. -get-involved-privacy-info = { "" } -get-involved-success-title = { "" } -get-involved-success-text = { "" } -get-involved-return-to-languages = { "" } From 6fdbc2c965531ddccfe6645a8c1b636c435f15ab Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sat, 20 Apr 2024 19:13:16 +0000 Subject: [PATCH 28/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index 0dbc9356c477..c9c4ad1a2201 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -7,6 +7,7 @@ return-to-cv = Comman Voiceşa Goikti. email-input = .label = Emaili submit-form-action = Mendancğoni +loading = Eyulun email-opt-in-info = Comman Voiceşi noğire goşinupe, ixenu dulyapeşi meoğanupe do anbaişi bultenepe steri e-postape eç̌opumu minon. email-opt-in-info-title = Comman Voiceşi maili listhes eǩomanthalit. email-opt-in-info-sub-with-challenge = Comman Voiceşi omondunu do noğire goşinupe, ixenu dulyapeşi meoğanupe do anbaişi bultenepe steri e-post̆ape eç̌opit. @@ -314,6 +315,7 @@ email-subscription-title-new = Comman Voiceşi xaberi bultenepes, gonoşinupes d benefits = Pelapape rich-data = Momincğonit datapeşi daha ǩai oxenu şeni bazi anonimi demografiǩuri datape momçit. Mteli demografiǩuri datape ǩamus p̌i gontzǩaşe noçinepe gotziğit. +improve-audio = Profilişi çkinapape, osinapu çinapa tzorinoba oslop̌us na ixmaren xomaşi datape oǩaimams. ## What's public @@ -438,6 +440,9 @@ about-playbook-how-validate = Nena doloç'areri geptzora vana mot geptzora muç' ## How are decisions made +## How is Common Voice funded + + ## Glossary @@ -589,3 +594,6 @@ shortcuts = Gzamk'ule ## BULK SUBMISSION + +## Donate banner + From 1bd02bf77e447fa0fd806dfbb1604a033e1f9618 Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sat, 20 Apr 2024 19:22:36 +0000 Subject: [PATCH 29/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 63 ++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index c9c4ad1a2201..48035ef8ab37 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -316,9 +316,19 @@ email-subscription-title-new = Comman Voiceşi xaberi bultenepes, gonoşinupes d benefits = Pelapape rich-data = Momincğonit datapeşi daha ǩai oxenu şeni bazi anonimi demografiǩuri datape momçit. Mteli demografiǩuri datape ǩamus p̌i gontzǩaşe noçinepe gotziğit. improve-audio = Profilişi çkinapape, osinapu çinapa tzorinoba oslop̌us na ixmaren xomaşi datape oǩaimams. +keep-track = Megzalu do mezuma-tkvani arişen dido nenaşen otzǩedirt +compare-progress = Megzalu-tkvani dunyaşi genelis majura memşvelupe-şkala muç̌o na oxitzonen dzirit. +view-goals = Personaluri do proje hedefepe-tkvani-şkala megzalu-tkvani dzirit. +join-newsletter = Ginonan-na proje-çkunişi oağanu do ağani çkinapape şeni e-postaşi list̆es eǩomant̆alit. ## What's public +whats-public = Umumi mu oren? +email-not-public = E-posta-tkvani xalǩik var dziraseren. +recordings-and-locale-public = Muǩu doloç̌ara do nam nenapes nuşvelit umimi iyasen (iris adzirasen). +username-optin-public = Oxmaru coxo-tkvani umimi vana anonimi gaxenenan. +demographic-deidentified-clarity-2 = Opsiyoneli na moncğonit demografiǩuri datape (tzana, cinsiyet̆i, nena do aksani) p̌ot̆e profili-tkvanis xalǩi şeni gontzǩeri var iyasen. Hantepe, data ǩumuli-şkala na oren xesabi-tkvani-ǩala var oǩimbinasen. Personaluri nenaşi ǩlibepe, daha tzori analizi şeni demografiǩuri datape-ǩala oǩimbinasen - Evuli, ar goǩitxaces ar slop̌ua modeli meçkineri ar demografiǩuri segmentis meğiru agoren. +username-email-not-demographic = Xmaroceşi Coxo do e-posta-tkvani gamişku datape-şkala var oǩimç̌ǩeşasen. ## Speak & Listen Shortcuts @@ -346,12 +356,25 @@ shortcut-record-toggle = d shortcut-record-toggle-label = Doloç̌ari/ Dodgiti shortcut-rerecord-toggle = [1-5] shortcut-rerecord-toggle-label = Nena gori +shortcut-discard-ongoing-recording = ESC +shortcut-discard-ongoing-recording-label = Hatzineri doloç̌ara ip̌t̆ali doyi shortcut-submit = Goikti shortcut-submit-label = K'ilibi mendancğoni +request-language-text = Common Voices daha nena-tkvani var dziremt-i? +request-language-button = Ar Nena Gori ## ProjectStatus +status-title = Projeşi geneluri xali: naǩu na igzalit dzirit. status-contribute = Nena-tkvanis numxacit. +status-hours = + { $hours -> + [one] Hamoraşani ar tane kontroli ixenu + *[other] Hamoraşani ar tane kontroli ixenu + } +# Variables: +# $goal - number of hours representing the next goal +status-goal = Uǩaçxeni hedefepe: { $goal } english = İngilizuri ## ProfileForm @@ -369,37 +392,77 @@ profile-form-variant = profile-form-variant-default-value = Aina varianti goşatsxuneri va oren. profile-form-accent = .label = Aksani +profile-form-custom-accent-help-text = + .label = Aksani tkvani muç̌o oçinapatet̆u? +profile-form-custom-accent-placeholder-2 = Aksani tkvani oçinapus komoǩiç̌it profile-form-age = .label = Tzana profile-form-gender-2 = .label = Cinsiyet'i +leaderboard-visibility = + .label = Leaderboard-işi tzirama hidden = T'k'obaşe +visible = Native Language +profile-form-add-accent = Ağani ar aksani "{ $inputValue }" keǩumtsxvi profile-form-submit-save = Şinaxi profile-form-submit-saved = Kodoliç'aru +male_masculine = Mamuli +female_feminine = Daduli +intersex = Majura # Gender other = Majura +why-profile-title = Muşeni ar profili? +why-profile-text = Ti-tkvani daha vorsi domoçinapat-na, Common Voices na oncğonit datapeşi tzorinoba gorapa motorepeşi oxotzonu şeni daha vorsi iyaseren. +dashboard = Tzirama Paneli +build-profile = Profili Getzopxi +avatar = Avatari +goals = Hedefepe settings = Getzopxi edit-profile = Profili getzopxi +profile-create-success = Dobeceri, profili diç̌ǩadu (kogeitzopxu) profile-close = Genk'oli +profile-explanation = Ar profilite gamayonu-tkvanis nontxozit do xomaşi datape daha tzori oyapus memişvelit. +thanks-for-account = Xesabi-tkvani na otzuranit şeni ntsaşa extit, hatzi (hus) profili-tkvani gep̌tzopxat. +why-demographic = Ham muşeni becit̆i oren? +why-demographic-explanation-2 = Tzana, cinsiyet̆i do aksani steri anonimi xeneri xmaraceşi datape, osinapu çinobua motorepeşi tzorinoba oslop̌u şeni na ixmaren xoma datapeşi oǩaimus nuşvelams. Xmarace coxo-tkvani do e-posta adresi-tkvani na moncğonit datape-ǩala p̌ot̆e var oǩimç̌ǩeşinasen. Xmarace coxo-tkvani ǩamus gontzǩeri vana ononimuri iyasen-i goşogatsxunanen. +accept-privacy = Mozillaşi t̆obaşoba Polotiǩas ignapinu steri ham dataşi tkvani oxmaru momarçilen. accept-privacy-title = T'obaşobaşi Polotik'a +accept-privacy-and-terms = Common Voiceşi Şart̆epe do t̆obaşoba Gognapa elemivelams. login-identity = Amaxtimui oçinoba login = Amaxti login-signup = Amaxti/ Doliç'ari edit = Sturesari email-subscriptions = E-mailişi abonobape download-profile = Datape-çkimi Kogeiği +contribution-experience = Meşveluşi Getsadu +skip-submission-feedback = Oncğonuşi ǩap̌ula Gnapas Moyuǩap̌i +skip-submission-description = Ment̆ala oncoğonuşi oras, "mencğoni"s not̆ank̆aşk̆ule, K̆ap̆ula Gnapa moyuk̆ap̆inasinon. Ment̆ala, na mulun 5 doloç̆ara var na otzuranuşi setiten naqonasinon. +skip-submission-note = Noti: Meşveluşi çeşit̆i gokturu şeni İsinapi do İşǩini (İuci/ İsimini)-şi doloxe goşuğaten. +off = Genǩoleri +on = Gontzǩumeri help-accent = Aksani şeni meşvelu gorum-i? +help-accent-explanation = Aksanitkvani zit̆ape muç̆o na tkumet iya tkvala ren. Na skidurt sva, na ğarğalapt majura nenape do çkva do çkva mutxanepeten gitzipxen.Hak, diç̆irs ya na isimadept mtelli mutxani gigadvenan. help-variants = Variantepe şeni meşvelu gorum-i? +help-variants-explanation = Variantepe nenaşi meçkineri ar k̆ata ren. Meçkineri ar svas var na ar ok̆obğalas na skidunanpek na uk̆uixmarnanpe steri...Yomi, antepes dialekti itkven. ## Profile - Email browse-file-title = Ar resimişi dosya kogedvit +browse-file = Dolotiri do dolodvi var na mendatzk̆edi connect-gravatar = Gravatarite Nik'ori gravatar_not_found = Emaili şeni Gravatari var İdziru file_too_large = Goşatsxuneri dosya opşa didi ren +avatar-uploaded = Avatari keiğu +max-file-size = { $kb }kb max +remove-avatar = Avatari moseli ## Profile - Email +manage-subscriptions = Abonobape okti +manage-email-subscriptions = E posta abonobape okti +email-already-used = Ham e-post̆a adresi zat̆i farǩli ar xesap̌is ixmaren. +add-language = Nena Ekumtsxvi +change-email-setings = Amolva Noçineşi tude "getzopxupe"şi doloxe e-posta-tkvani gokturit. ## FAQ From eccd8716d26313093f3584cb69f63ab25c2c5b6c Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sat, 20 Apr 2024 19:32:44 +0000 Subject: [PATCH 30/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 80 ++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index 48035ef8ab37..cf5001628b40 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -466,7 +466,87 @@ change-email-setings = Amolva Noçineşi tude "getzopxupe"şi doloxe e-posta-tkv ## FAQ +faq-title = Ordo ordo na iǩitxaman ǩitxalape +faq-what-cv-q = Common Voice mu oren? +faq-what-cv-a = Nena oxotzonuşi teknolojik, makena oxmaruşi k̆aidepe dido k̆ap̆et̆i oktiraps ala atzi na ren sistemepe paxali do mencubaleri renan.Common Voiceik, nena oxotzonuşi teknolojepes k̆ataik daha k̆ai do k̆olai nunç̆işas ya do Mozillak na k̆idu ar sistemi ren. Common Voicei na ixarsuven nenapeşi ar çkinaşt̆abu ren do k̆ata nenaten +faq-what-cv-a-2 = Nena oçinuşi teǩnoloji, makinepe-şkala oǩomç̌ǩeşu şeǩli-çkuni cicişen gokturams. Ana, hatzi na oren sistemepe paxali renan do doxmeli mulikiyet̆is renan. Mozilla Common Voice, nena oçinuşi teknolojipe iri şeni daha ǩai do daha ipelen xalişe moyonu na unon ar insiyatifi oren. Common Voice, ar nenas xomate na itsadebun aplikasyonepe manişa do ǩolai oslop̌u şeni iris furset̆i meçams do xarsuveri xomapeşi kianuri ar database oren. Dido na ixmaren nenape xvala var, mtsika ǩoçik na isinapams nenapeşen-ti xoma evulepe p̌ǩorobumt. Çeşit̆li xomaşi datamarç̌ape-ti gamaşkvinu, iris apelasen do ğanci meçasen. +faq-why-important-q = Ham muşeni becit̆i oren? +faq-why-important-a = Osinapu artiǩati ognapuşi eni vorsi gza oren. Xomaşi teknolojipek ham ǩolaoba okunepe do mobili t̆ilifonepe-çkunis momiyonaman. Ham dulyaşi matzupxepek xomate na içalişams dijitali asistanepe do tzori oras na içalişams tercumanepe getzopxas minonan. Ama hus na diç̌irs datate doxmeli mulkiyetis oren do dido paxali orenan. Common Voiceşi datamarç̌apete aşkva ağanoba ixenasen. ǩat̆ais muşi nenas xomaşi teknoloji oxmaru şeni na dvaç̌inan mutxa meçamu mepşunumt. Nena oçinu daha globaluri oxenu şeni dido na isinapinen nenape şuǩuri mtsika msinapu na uyonun ç̌ut̆a nenape şeni xomaşi evulepe p̌ǩorobumt. Tevuli tevuli datamarç̌a gamaşkvinu matzopxepes, girişimcipes do mtel xomaşi ǩatapes ham eksuği mutepek opşu şeni menç̌eli meçasen. +faq-how-get-q = Common Voice datamarç̌aşa muç̌o malasen? +faq-how-get-a = Common Voiceşi Datamarç̌a, CC0 lisansişi tude geiğmalinen do Datamarç̌a butka-çkunişen idziren. Ayni butkas jur-sum majura geneli geneliş odzirus gontzkeri datamarç̌a-ti gegağenan. +faq-when-release2-q = Majura nenapeşi Common Voice datamarç̌a mundes gamiğaten? +faq-why-mission-q = Common Voice, Mozilla misyonişi muşeni ar notzile ren? +faq-why-mission-a = + "Mozilla, mzesa k̆atai şeni gontzk̆imeri t̆as do k̆ataik + ixmaras ya do dik̆idu.Aya oxvenu şeni Common Voicei + steri projepeten mzesa magetzopxepe omencelu diç̆irs. + Xomaşi teknolojepe niche ap̆lik̆asyonepe mik̆ilan do + irdanşk̆ule, aya teknolojepe mtelli maxmarepes ar + uxezmat̆u diç̆irs ya visimadept. Aya, xomaşi teknolojepe + ikipt̆aşi do tsadup̆t̆aşi daha dido nenapes memxacu do + çkva do çkva dialektepe do demografiğepe osimadu + diç̆irs tkvala ren. Common Voicei k̆atta k̆oçis na axmarinen, + ar goncameri otişe ren do mtel kianas na ren Mozillaşi k̆atapek çkini projepes ixmanan." +faq-what-cv-and-deepspeech-q = Common Voice do Deep Speechşi oşkenas mu farki oren? +faq-what-cv-and-deepspeech-a = + "Common Voice datamarçak, Mozillaşi goncameri + xoma oxotzonuşi mat̆ori Deep Speechis mxuci meçaps. + Deep Speecişi maartani versiyoni 2017 Tzilvas gamaxtu + do emuşen akole p̆ant̆a imralen. Common Voice datamarç̆aten, + aya goncameri xoma oxotzonuşi teknolojişa k̆ataişi nuç̆işu beciti + ren ya do visimadept. (........) " +faq-is-goal-assistant-q = Common Voiceşi hedefi ar nenaşi asist̆ani otzopxu oren-i? +faq-is-goal-assistant-a = + "Common Voice datamarç̆a mot yeçkindu? Kianas sotxani ort̆as, + k̆atais xoma oxotzonu, mağarğale oxotzonu var na xoma + oxmarinu na diç̆irs ar ap̆likasyoni getzipxus nuşvelas ya do. + Ar xoma-memxace, datamarç̆a oxmaruten na gaxvenenanpeşi + xvala ari ren. + " +faq-do-want-native-q = Ma svaluri na va ren ar msinapu vore do aksanite visinapam, colo-ti xoma-çkimi ginonan-i? +faq-do-want-native-a = + "Ho, mtini tkvani xoma minonan! Common Voiceişi noğirepeşi + ari, xoma oxotzonuşi sistemepe k̆atai şeni k̆ai içalişas ya do, + na iqven k̆onari çkva do çkva aksanepe ok̆orobu ren. Aya, + nana-nenamutepeşi Lazuri na varen k̆oçepeşi xoma ok̆orobu dido + beciti ren tkvala ren." +faq-why-different-speakers-q = Muşeni k̆ata nena şeni ek̆o çkva do çkva mağarğale unon? +faq-why-my-lang-q = Muşeni nena-çkimi henuzǩi var eǩint̆alinu? +faq-why-my-lang-a = + "Common Voicei dido k̆oçoloni ar tzk̆artoli ren do mtelli + nenape memxacepeşi gedvala ren. Nenatkvani gedvit + dido minonan! Dilinizi eklemek için sorun." +faq-what-quality-q = Data setis na ixmaren ar xomaşi ǩlibi şeni na diç̌irs xomaşi ǩaliteşi seviye mu oren? +faq-why-10k-hours-q = Xomaşi oxotzonu şeni ǩat̆a nena şeni tzorineri 10,000 zit̆a hedefi geidu doren? +faq-why-10k-hours-a = + "Aya aşo xomaşen ç̆ara na ixvenen ar sistemi oxvenu şeni + na diç̆irs saat̆i ren." +faq-how-calc-hours-q = Common Voicek saatepe muç̌o xesap̌ums? +faq-how-calc-hours-a = + "Saat̆i oxesap̆u şeni k̆ata doloç̆areri xomaşi gindzenoba ptsadupt, + ok̆ule iya, mtelli nenapes na ixvenu mtelli doloç̆arapeşi k̆orotsxala k̆ala vomralapt." faq-where-src-from-2-q = Monduni ç'ara solen mulun? +faq-where-src-from-2-a = + "Tzk̆artoli ç̆araçkini, mtini na mixarsuvupanpeşen do It’s a Wonderful Life + steri goncameri filimi senaryopeşen na guşitsxunu ok̆oğarğalapeten dik̆idu." +faq-why-not-ask-read-q = Muşeni k̆oçepes çkva do çkva nenapeşi sup̆arape do vikipediaşi ç̆arape ik̆itxit ya varutzumet? +faq-why-not-ask-read-a = + "Common Voice datambağu na maxvenenan k̆onari, k̆olai + na ixmarinen ar mutxani gaxadu şeni, xvala Goncameri + (CCO) lisansişi doloxe na ren tzk̆ariştoli ç̆arapes nek̆na + gomtzk̆at ya ptkvit. CCO standarti oxmaru, tzk̆ariştoli ç̆arape + odziramu do ok̆orobu dido menceli gaxadeps, ala, na + gamulun xomaşi datape,oxmaruşi ugyok̆ordinu var na + Mozillaşi izini ugutzamalu, k̆atais axmarinen. E do, nenamarç̆a + magorepe, universitepe, ağani na ik̆iden şirketepe, hukyumetepe, acamepe do k̆atai şeni + , n maxvenena k̆onari pelaperi oxvenu minonan." +faq-why-account-q = Muşeni ar xesabis doloviç̌arare? +faq-is-account-public-q = Xesabişi çkinapape-çkimi iris gontzumeri oren-i? +faq-how-privacy-q = Xoma-nişi na uxarsuvu şurepeşi anonimoba do dompuloba muç̌o sturesarumt? +faq-what-determine-identity-q = Common Voiceşi datamarç̌as na oren msinapaceşi "noçine çinapa" mu itkven? +faq-what-is-cv = Common Voice mu oren? +faq-using-cv = Common Voiceşi Oxmaru +faq-description = Common Voicei, mtini ǩoçepeşi oğarğalu makenapes oguran ya do na Mozillak na ǩidu ar dulya ren. ## ABOUT US From 44bc5d3f78312718cfdaba4370f2c929c6430102 Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sat, 20 Apr 2024 19:42:44 +0000 Subject: [PATCH 31/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 46 ++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index cf5001628b40..4397cdc54ecb 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -547,16 +547,62 @@ faq-what-determine-identity-q = Common Voiceşi datamarç̌as na oren msinapace faq-what-is-cv = Common Voice mu oren? faq-using-cv = Common Voiceşi Oxmaru faq-description = Common Voicei, mtini ǩoçepeşi oğarğalu makenapes oguran ya do na Mozillak na ǩidu ar dulya ren. +faq-search-for-answers = + .label = Cuğap̌epe gori ## ABOUT US +about-title = Muşeni Common Voice? +how-does-it-work-title-v2 = Common Voice muç̌o itsadeburs/ içalişams? ## How does it work section +about-language-req-subtitle = A mitxak ar nena eǩomtsxvalu gorums. +about-localization-title = Website Sva meçamu +about-localization-subtitle = Web siteşi ç̌ara hem nenaşe golakti. +about-sentence-collection-title = Cumleşi ǩoleǩsiyoni +about-sentence-collection-subtitle = Cumlepe ǩoçepeşi mağali xomate oǩitxu şeni iǩoroben. +about-new-lang-title = Ağani Nenaşi Lansmani +about-new-lang-subtitle = Common Voiceşi site ham nenate oxmarus mevuçkinamt. +about-voice-contrib-title = Xoma Eǩont̆alu +about-voice-contrib-subtitle = ǩoçepe mulunan do xomape-nişite memaǩatenan. +about-voice-validation-title = Nena Otzuranu +about-voice-validation-subtitle = ǩoçepek ham nenaşi ǩlibepe tzorinuman. +about-dataset-release-title = Datamarç̌aşi gamaşkvinu +about-dataset-release-subtitle = Datamarç̌a sum tutaşe ar gamavoşkumt. +about-subscribe-text = Common Voice-ǩala ǩont̆aǩt̆i giğut̆an gorumt-i? +about-speak = İsinapi +about-speak-text = Memşvelupek, xarsuveri cumlepete pşeri ar bankaşen iǩitxaman do ǩlibepe doloç̌aruman. +about-listen-queue = Oşǩinuşi Sira +about-listen-queue-text = Xomaşi ǩlibepe, hentepe oşǩinu şeni na xadzirums ar nocğone ǩudelis amilven. +about-listen = İuci - İşkini - İsimini +about-listen-text = Maxmarepe, msinapuk cumle tzori iǩitxu-i ya do kontroli ikums do xarsuveri ǩlibepeşi tzorinoba tzorinums. +about-is-it-valid = ǩlibi oxmaroni oren-i? +about-is-it-valid-text = Maxmarek "Ho" ya do rei meçasi 'oxmaroni" ya do niğaren. +about-yes-votes = ≥ 2 Ho rei +about-yes-votes-text = Ar xoma ǩlibi Common Voice datamarç̌as dolocharu şeni, jur maxmareşi "ixmarinen" otku diç̌irs. +about-no-votes = ≥ 2 Var rei +about-no-votes-text = Maxmare ar ǩlibis "var" rei meçaşi, xoma Xoma ǩudelişa guikten. Jur fara "var" rei niçu na xomaşi ǩlibi Vasaglaxtişa ulun. +about-dataset-new = Common Voice Datamarç̌a +about-clip-graveyard = ǩilibişi Doxvume +about-clip-graveyard-text = Vasaglaxtis, Common Voice datamarç̌as na varen xomaşi ǩlibepe ren. Muç̌o datamarç̌a steri, Vasaglaxti-ti giğen. +about-get-involved = Eǩomant̆alit +about-get-involved-text-2 = + "Common Voicei dido ǩai gaxadus meşvelu ginonan-i? + Ntsaşa Yextat! E-posta var na Discourseiten koniǩirit, forumepes amaxtit, sites na ren problemepe Git̆ub iten kommemotsadapit var na Matrixişen ǩatas oğarğaluşa amaxtit." +about-stay-in-touch = Muç̌o oǩovimçinaten? +about-stay-in-touch-button = Uye iyi (Uye ivi/ iqvi) +about-nav-why-common-voice = Muşeni? +about-nav-how-it-works = Muç̌o? +about-nav-partners = Maǩatape +about-nav-get-involved = Eǩomant̆alit +about-nav-how-it-works-2 = Common Voice muç̌o itsadeburs/ içalişams? +about-nav-playbook = Muç̌o na eǩvant̆alaten digurit ## Community Playbook Content ## What is a language +about-playbook-what-is-language = Common Voices nena mu oren? ## How do I add a language From 62c925869aa5770a9b86a1b032e120fadfdf4ff9 Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sat, 20 Apr 2024 19:52:51 +0000 Subject: [PATCH 32/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index 4397cdc54ecb..9fd2373d2a20 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -606,18 +606,29 @@ about-playbook-what-is-language = Common Voices nena mu oren? ## How do I add a language +about-playbook-how-add-language = Nena muşho eǩevunt̆alare? +about-playbook-how-add-language-translating-heading = Siteşi tercume +about-playbook-how-add-language-collecting-sentences-heading = Cumlepe oǩorobu ## How does localization work +about-playbook-how-localize = Siteşi lokaloba muç̌ote içalişams? +about-playbook-how-localize-content-4 = %75 oranişa inç̌elasi siye gamaşkvinoni iyasen. +about-playbook-how-localize-content-5 = Meşvelu şeni video gamognaponi-çkunis otzǩedit. ## How to add sentences +about-playbook-how-add-sentences = Cumlepe muç̌o eǩevuç̌arare? ## How to record quality +about-playbook-how-record-quality = Mağali ǩalitete ar xoma ǩlibi muç̌o dolovoç̌arare? ## How to grow language +about-playbook-how-grow-language-content-2 = Vaǩape +about-playbook-how-grow-language-content-4 = Sosyaluri Medya +about-playbook-how-grow-language-content-6 = Ortağepe do Mosape ## How to validate @@ -628,28 +639,61 @@ about-playbook-how-validate = Nena doloç'areri geptzora vana mot geptzora muç' ## How are decisions made +about-playbook-how-project-governance = Projeşi ǩarari muç̌o eiç̌open? +about-playbook-how-project-governance-content-2 = Maktaloba-çkuni tudeni temelepeşi jin geidgu doren. +about-playbook-how-project-governance-content-3 = t̆obaşoba, oceroba, şefafoba +about-playbook-how-project-governance-content-4 = ǩomunitişi eǩont̆aloba do ǩarari meçamu. +about-playbook-how-project-governance-content-5 = Ğirapa do oçinapa +about-playbook-how-project-governance-content-6 = Artiǩatis xesap̌i meçamu. +about-playbook-how-project-governance-content-7 = Muç̌o na moktaman ognapu şeni dido-muşi iǩitxit ## How is Common Voice funded ## Glossary +glossary = Nenapuna +localization = Lokaloba +sst = Osinapu ç̌aras meonktu (STT) +de-identified = Oçinoba-muşi dimpulu/ var içinapu ## Error pages +error-code = Xeta { $code } ## Data +data-download-button = Common Voiceşi Datape kogeiğit +data-download-yes = Ho +data-download-deny = Var +data-download-license = Lisans: CC-0 +data-get-started = Osinapu Oçinobas Kogyoç̌ǩit +data-other-title = Majura xomaşi datamarç̌ape +data-other-goto = { $isname }'şe idi data-other-download = Meçama Geiği +data-bundle-button = Datamarç̌aşi Paket̆i kogeiğit +data-bundle-description = Comman Voicesi data març̌ape xvala var jindoleni majura xoma datapeti. release-version = Versioni dataset-date = Tarixi license = Lisansi: { $license } +license-mixed = Oǩont̆aleri +data-download-singleword-title = Ar Zit̆a Noğire Boligina Kogeiğit terms-agree = Ok'ovuvelut terms-disagree = Var Ok'ovuvelut +review-aborted = Eğmalu ip̌t̆ali dixenu. Doloç̌arupe-tkvani gejilu ginonan-i? +review-submit-title = Tsadi do Moncğoni +review-submit-msg = Doloç̌aritşeni ntsaşa extit! Hatzi klibepe tkvani tudendo otzedit do oncğonit. +review-recording = Meotzǩedi +review-rerecord = Meoç̌ari +review-cancel = Oncğonu ip̌t̆ali doyi +review-keep-recordings = Doloç̌arape şinaxit +review-delete-recordings = Doloç̌arape-çkimi gejilit (cejirit) ## Datasets Page +datasets-heading = Datamarç̌ape language = Nena +download-dataset-header = datamarç̌a Kogeiğit cv-license = Lisansi audio-format = Xomaşi Format'i From 579ff5fe52815f8521c353b5ea5935a27255900a Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 09:22:55 +0000 Subject: [PATCH 33/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index 9fd2373d2a20..8bb76cdc705f 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -403,6 +403,8 @@ leaderboard-visibility = .label = Leaderboard-işi tzirama hidden = T'k'obaşe visible = Native Language +native-language = + .label = Svaloni Nena profile-form-add-accent = Ağani ar aksani "{ $inputValue }" keǩumtsxvi profile-form-submit-save = Şinaxi profile-form-submit-saved = Kodoliç'aru From e5e94be457b55f9c14ad973252b6f8cccab7fb26 Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 09:33:03 +0000 Subject: [PATCH 34/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 1 + 1 file changed, 1 insertion(+) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index 8bb76cdc705f..528376b9b296 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -411,6 +411,7 @@ profile-form-submit-saved = Kodoliç'aru male_masculine = Mamuli female_feminine = Daduli intersex = Majura +transgender = { "" } # Gender other = Majura why-profile-title = Muşeni ar profili? From 90748ab929a7d223c9673bfa593ef8b4c0fe7cce Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 11:13:07 +0000 Subject: [PATCH 35/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 1 + 1 file changed, 1 insertion(+) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index 528376b9b296..7be5e3d9488d 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -711,6 +711,7 @@ audio-format = Xomaşi Format'i ## Request Language Pages +request-language-google-recaptcha-required = Meyonu ginonan-na reCAPTCHA diç̌irs ## Languages Overview From ceb4d17fa463c52b845bc9c4e475d22deeff2908 Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 11:22:48 +0000 Subject: [PATCH 36/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 72 ++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index 7be5e3d9488d..f603570a8e95 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -697,33 +697,105 @@ review-delete-recordings = Doloç̌arape-çkimi gejilit (cejirit) datasets-heading = Datamarç̌ape language = Nena download-dataset-header = datamarç̌a Kogeiğit +# File size in gigabytes +size = Boyut̆i +validated-hr-total = Tzuraneri saatişi ǩoroba +overall-hr-total = Geneluri saatişi ǩoroba cv-license = Lisansi audio-format = Xomaşi Format'i +number-of-voices = Xomaşi ǩoretsxa +splits = Boginape +size-gigabyte = Didi Biritanya +size-megabyte = MB +confirm-no-identify = Common Voiceşi datamarç̌as na ren msinapupeşi noçinepe odziru şeni var inç̌itatenǩebuli atna +download-language = { $language } doya geiğit +validated-hours = İtzuranu Saatepe +recorded-hours = Doliç̌aru Saatepe +whats-inside = Common Voice datamarç̌aşi doloxe mupe orenan? +subscribe = Abone iyi +get-started-speech = Osinapu Oçinus Kogyoç̌ǩit +other-datasets = Majura Xomaşi Datamarç̌ape +feedback-q = Uǩaçxeni gnapa giğunan-i? +community-playbook = Partiyaşi becit̆i kitabi +data-other-ted-name = TED-LIUM ǩoroba +clipboard-not-supported = Panok var numxacams +# dataset metadata - age of contributor +dataset-metadata-age = TzanaTzana ## Download Modal +download-title = Geğmalu kogegiç̌it. +download-back = Common Voive Dataset̆işe goiktit ## Contact Modal +contact-title = Memçinuşi Formi +contact-form-name = + .label = Coxo/ yoxo +contact-form-message = + .label = Mesaji +contact-required = *diç̌irs ## Request Language Modal +request-language-title = Nenaşi Talebi +request-language-form-language = + .label = NenaNena +request-language-success-title = Nenaşi talebi t̆işineri dolinç̌aru, ntsaşa exti. +request-language-success-content = Common Voice'işa ar nena dodvalu muç̌o iyen otku şeni na mulun ndğalepes giç̌araten. +select-language = Nena goşuğit… +other-language = Çkva nena ## Request Language Pages +request-language-heading = Ağani nena şeni iǩitxi +request-language-form-email = + .label = E-mail adresi-skani +request-language-form-info = + .label = Nena şeni çkinapa +request-language-form-info-explanation-list-1 = Nena-skanişi coxo/yoxo +request-language-form-info-explanation-list-2 = ISO Codes igiçkin-na +request-language-form-info-explanation-list-3 = Nena-tkvani daha ǩai ognapus meşvelu şeni websitepeşi linki request-language-google-recaptcha-required = Meyonu ginonan-na reCAPTCHA diç̌irs +request-language-google-recaptcha-error = reCAPTCHA's mutxape tersi idu. Xolo geitsadit. +# Success page +request-language-success-heading = Ntsaşa extit! Ağani ar nenaşi ǩitxapa moncğonit ## Languages Overview +language-section-in-progress = Nayonen +language-section-launched = Kogeiç̌ǩu +languages-show-more = Daha fazla dziri +languages-show-less = Daha mtsika dziri +language-meter-in-progress = Ogzalaman language-total-progress = Mteli +language-search-input = + .placeholder = Goiǩitxi language-speakers = Msinapu +localized = Dilokalizu +sentences = Cumlepe +language-validation-hours = Saat̆epe +language-validation-progress = Otzuranuşi elaxtima ## Contribution +action-click = Met̆aǩulu +action-tap = Ombolina listen = İuci - İşkini - İsimini write = Ç'ari skip = Moyok'ap'it shortcuts = Gzamk'ule +review-tooltip = Hakolen ulurt̆aşani ǩilibepes ar çkva otzǩedit do xolo doloç̌arit +share-clip = ǩilibi-tkvani gurtit +share-common-voice = Common Voive gurtit +review-instruction = Diç̌irs-na ǩlibepes otzǩedit do meoç̌arit +record-submit-tooltip = { $actionType } xadziri iyasis oncğoni +clips-uploaded = Eğmaleri ǩlibepe +record-abort-title = Maarani doloç̌aru oçodinu ginon-i? +record-abort-text = Hatzi kogamaxtit-na elaxtimu tkvani gondinateren. +record-abort-submit = K'ilibi mendancğoniǩilibi mendancğoni +record-abort-continue = Doloç̌aru doçodini +record-abort-delete = ǩlibepeşen Gamaxti § Gejili (Cejiri) ## Contribution Nav Items From eb37832536a4a87449c2aae8bdb3f1c303fdfe0a Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 11:32:39 +0000 Subject: [PATCH 37/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index f603570a8e95..5d21ee48b531 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -718,6 +718,16 @@ other-datasets = Majura Xomaşi Datamarç̌ape feedback-q = Uǩaçxeni gnapa giğunan-i? community-playbook = Partiyaşi becit̆i kitabi data-other-ted-name = TED-LIUM ǩoroba +go-discourse = Zit̆aşe İdi +missing-language = Nena-tkvani datamarç̌as var dziremt-i? Nena ogoru şeni Nenapeşi butkaşa idit. +go-languages-page = Nena but̆ǩaşe idi +ready-to-validate = Cumlepe getzuranus meşvelu şeni xadziri oret-i? +more = Çkva +close = Genk'oliGenǩoli +download = Kogeiği +dataset-version = VersioniVersioni +sha256-checksum-copied = SHA256 Checksum ǩop̌ya dixenu! +sha256-checksum-copied-error = SHA256 Checksum ǩop̌ya var ixenu! clipboard-not-supported = Panok var numxacams # dataset metadata - age of contributor dataset-metadata-age = TzanaTzana @@ -781,8 +791,10 @@ language-validation-progress = Otzuranuşi elaxtima action-click = Met̆aǩulu action-tap = Ombolina +contribute = MemaǩatitEǩoşvelu listen = İuci - İşkini - İsimini write = Ç'ari +review = MeotzǩediMeotzǩedi skip = Moyok'ap'it shortcuts = Gzamk'ule review-tooltip = Hakolen ulurt̆aşani ǩilibepes ar çkva otzǩedit do xolo doloç̌arit From c2606d72cce6af96d6e50b357230e7cc15aa3197 Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 11:42:38 +0000 Subject: [PATCH 38/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index 5d21ee48b531..5da8d2d78112 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -797,6 +797,19 @@ write = Ç'ari review = MeotzǩediMeotzǩedi skip = Moyok'ap'it shortcuts = Gzamk'ule +contribute-more = + { $count -> + [one] { $count } daha dido-muşi oxenus xadziri ore-i? + *[other] { $count } daha dido-muşi oxenus xadziri ore-i? + } +record-cta = Doloç̌arus kogyoç̌ǩi +record-platform-not-supported = Mixarsuvit, pilatformi çkunik hatzi var numxacams. +record-platform-not-supported-desktop = Masajin cihazepes geğmalute megaşvelenan... +record-platform-not-supported-ios-non-safari = iOS'sis doloç̌aru oaktifuşeni Safarite nayonit... +record-error-too-short = Doloç̌ara dido mǩule ren. +record-error-too-long = Doloç̌ara dido gundze ren. +record-error-too-quiet = Doloç̌ara dido misa ort̆u. +record-cancel = Meyo-doloç̌aru ip̌t̆aki doyi review-tooltip = Hakolen ulurt̆aşani ǩilibepes ar çkva otzǩedit do xolo doloç̌arit share-clip = ǩilibi-tkvani gurtit share-common-voice = Common Voive gurtit From 1f94c695adbfd939ce1751a48de3609c80780f64 Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 12:03:36 +0000 Subject: [PATCH 39/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index 5da8d2d78112..a49fe150f6e0 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -806,6 +806,8 @@ record-cta = Doloç̌arus kogyoç̌ǩi record-platform-not-supported = Mixarsuvit, pilatformi çkunik hatzi var numxacams. record-platform-not-supported-desktop = Masajin cihazepes geğmalute megaşvelenan... record-platform-not-supported-ios-non-safari = iOS'sis doloç̌aru oaktifuşeni Safarite nayonit... +record-must-allow-microphone = Miǩrofoni oxmarus izni momçit. +record-no-mic-found = Miǩrofoni var madzires. record-error-too-short = Doloç̌ara dido mǩule ren. record-error-too-long = Doloç̌ara dido gundze ren. record-error-too-quiet = Doloç̌ara dido misa ort̆u. From 09bbb67aa7910877fc0eaa5b073aa2a20968a8f9 Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 12:22:38 +0000 Subject: [PATCH 40/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index a49fe150f6e0..9d01e5140a71 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -812,6 +812,8 @@ record-error-too-short = Doloç̌ara dido mǩule ren. record-error-too-long = Doloç̌ara dido gundze ren. record-error-too-quiet = Doloç̌ara dido misa ort̆u. record-cancel = Meyo-doloç̌aru ip̌t̆aki doyi +record-instruction = { $actionType }> uǩaçxe cumle mağali xemate iǩitxit +record-stop-instruction = { $actionType }> eiçorasis review-tooltip = Hakolen ulurt̆aşani ǩilibepes ar çkva otzǩedit do xolo doloç̌arit share-clip = ǩilibi-tkvani gurtit share-common-voice = Common Voive gurtit From 841d3c15f60ca55f8ab717ca8b42f4cca108cabd Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 12:32:55 +0000 Subject: [PATCH 41/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 73 ++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index 9d01e5140a71..6198c07c564f 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -763,6 +763,7 @@ request-language-form-email = .label = E-mail adresi-skani request-language-form-info = .label = Nena şeni çkinapa +request-language-form-info-explanation = Giçkinan ǩonari (gişǩuran şuǩuri) nena şeni çkinapa eǩudvit. Hani (hantepe) eǩogadvenan: request-language-form-info-explanation-list-1 = Nena-skanişi coxo/yoxo request-language-form-info-explanation-list-2 = ISO Codes igiçkin-na request-language-form-info-explanation-list-3 = Nena-tkvani daha ǩai ognapus meşvelu şeni websitepeşi linki @@ -814,6 +815,10 @@ record-error-too-quiet = Doloç̌ara dido misa ort̆u. record-cancel = Meyo-doloç̌aru ip̌t̆aki doyi record-instruction = { $actionType }> uǩaçxe cumle mağali xemate iǩitxit record-stop-instruction = { $actionType }> eiçorasis +record-three-more-instruction = Sum tane dosǩidu +record-again-instruction = Great! Uǩaçxeni ǩilibi-tkvani doloç̌arit +record-again-instruction2 = Nayoni, xolo doloç̌ar +record-last-instruction = Eçouri! review-tooltip = Hakolen ulurt̆aşani ǩilibepes ar çkva otzǩedit do xolo doloç̌arit share-clip = ǩilibi-tkvani gurtit share-common-voice = Common Voive gurtit @@ -825,21 +830,89 @@ record-abort-text = Hatzi kogamaxtit-na elaxtimu tkvani gondinateren. record-abort-submit = K'ilibi mendancğoniǩilibi mendancğoni record-abort-continue = Doloç̌aru doçodini record-abort-delete = ǩlibepeşen Gamaxti § Gejili (Cejiri) +listen-instruction = { $actionType }> cumle tzori iǩitxesi? +listen-again-instruction = Dido ǩai dulya gamiğit ! Xadziri iyasi xolo geitsadit. +listen-3rd-time-instruction = 2 melu, nayoni! +listen-empty-state = ǩlibepe-çkuni diçonu doren, butka meoğanit vana uǩaçxeşe xolo geitsadit. +speak-empty-state = Ham nenas doliç̌arasen cumle var madzires. +speak-empty-state-cta = Cumlepe şeni eǩuşvelit +record-button-label = Nena-skani doloç̌ari +share-title-new = Daha dido xoma odzirus memişvelit +keep-track-profile = Ar profilite ogzalu-tkvani nayonit +login-to-get-started = Geç̌ǩapu (ceç̌apu) şeni amaxtit vana doliç̌arit +target-segment-first-card = Maarani hedefişi segmentis numxacamt. +target-segment-generic-card = Hedef segmentis numxacamt. +target-segment-add-voice = Nena-tkvani keǩunt̆alit +target-segment-learn-more = Daha fazla gaçkinas ## Contribution Nav Items +contribute-voice-collection-nav-header = Xomaşi ǩoleǩsioni +contribute-sentence-collection-nav-header = Cumleşi ǩoleǩsiyoniCumleşi ǩoleǩsiyoni ## Reporting +report = Lapori +report-title = Lapori Oncğoni +report-ask = Ham cumle şeni muperi sixintipe ntzorumt? +report-offensive-language = Peat̆i zit̆a +report-offensive-language-detail = Cumle tkvani antzalaburi do agresifi oren. +report-grammar-or-spelling = Nenaçkina/ ç̌ara xeta +report-grammar-or-spelling-detail = Cumles grameri vana oç̌aruşi xeta oren. +report-different-language = Farǩli nena +report-different-language-detail = Ma na visinapamşe farǩli nenate iç̌aru doren. +report-difficult-pronounce = Ozit̆u muşi çetini oren. +report-difficult-pronounce-detail = Okitxu do otku muşi çetini zit̆ape ren doloxe muşis. +report-offensive-speech = Agresifi osinapu +report-offensive-speech-detail = Klibis antzxalaburi do agresifi zit̆ape orenan. +report-other-comment = + .placeholder = Mesinapu +success = Gecginoba +continue = Golvayoni +report-success = Lapori zade vorsi mendaxtu ## Goals +streaks = Golağarape ## Dashboard +your-languages = Nenape-tkvani +toward-next-goal = Uǩaçxeni hedefi ǩale +goal-reached = Hedefişe mendilu +clips-you-recorded = Doloç̌arit Klibepe +clips-you-validated = Otzuranit Klibepe +todays-recorded-progress = Kaydedilen kliplerde bugünün Common Voice ilerlemesi +todays-validated-progress = Kliplerde bugünkü Common Voice ilerlemesi doğrulandı +stats = İstatistikler +awards = Ödüller +you = Si +everyone = İri +contribution-activity = Meşveluşi Aktivite +top-contributors = Eni dido na numxacupe +recorded-clips = Doliç̌aru ǩlibepe +validated-clips = t̆uraneri ǩlibepe +total-approved = Mteli Ditzuranu +overall-accuracy = Geneli tzuranoba +show-ranking = Gesvaru-çkimi motzirit ## Custom Goals +get-started-goals = Hedefepes gyoç̌ǩit +goal-type = Muperi hedefi getzopxu ginonan? +both-speak-and-listen = Juri aroğorda +both-speak-and-listen-long = Juri-ti (isinapi do işǩini) +daily-goal = Ndğaluri Hedefi +weekly-goal = Xafteri Hedefi +easy-difficulty = ǩolai +average-difficulty = Oşkena +difficult-difficulty = Zori +pro-difficulty = Profosyoneli +lose-goal-progress-warning = Hedefi tkvani sturesarit do na giğunan elaxtima tkvani doloç̌arit. +want-to-continue = Meyonu ginonan-i? +finish-editing = İpti osturesru oçodinu ginonan-i? +lose-changes-warning = Hatzi kogamaxtit-na, osturesarupe tkvani gogindunanen +build-custom-goal = Doxmeli hedefi getzopxit ## Profile Delete From 722655dc013d08c2e4e13717b8acba2d41c7852d Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 12:42:45 +0000 Subject: [PATCH 42/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 50 +++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index 6198c07c564f..fb3e5c82fbef 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -657,11 +657,16 @@ about-playbook-how-project-governance-content-7 = Muç̌o na mok glossary = Nenapuna localization = Lokaloba +localization-explanation = Hantepe (hani) internet̆is gorit +sentence-collection-explanation = Eğmaleri ǩlibepe +hours-recorded-explanation = Tzuraneri saatişi ǩoroba +hours-validated-explanation = Nenape çkuni: sst = Osinapu ç̌aras meonktu (STT) de-identified = Oçinoba-muşi dimpulu/ var içinapu ## Error pages +error-title-503 = Oç̌aru do Ot̆imbu error-code = Xeta { $code } ## Data @@ -670,6 +675,9 @@ data-download-button = Common Voiceşi Datape kogeiğit data-download-yes = Ho data-download-deny = Var data-download-license = Lisans: CC-0 +data-download-modal = Mixaresirit +data-subtitle = Oxori +data-explanatory-text = Reddi oxenu data-get-started = Osinapu Oçinobas Kogyoç̌ǩit data-other-title = Majura xomaşi datamarç̌ape data-other-goto = { $isname }'şe idi @@ -681,6 +689,7 @@ dataset-date = Tarixi license = Lisansi: { $license } license-mixed = Oǩont̆aleri data-download-singleword-title = Ar Zit̆a Noğire Boligina Kogeiğit +review-terms = Ağani nena şeni iǩitxi terms-agree = Ok'ovuvelut terms-disagree = Var Ok'ovuvelut review-aborted = Eğmalu ip̌t̆ali dixenu. Doloç̌arupe-tkvani gejilu ginonan-i? @@ -695,8 +704,11 @@ review-delete-recordings = Doloç̌arape-çkimi gejilit (cejirit) ## Datasets Page datasets-heading = Datamarç̌ape +datasets-headline = Ar xesap̌i kogetzopxit language = Nena download-dataset-header = datamarç̌a Kogeiğit +download-delta-explainer = Bretonuri +download-dataset-tag = İstatistiği # File size in gigabytes size = Boyut̆i validated-hr-total = Tzuraneri saatişi ǩoroba @@ -705,6 +717,9 @@ cv-license = Lisansi audio-format = Xomaşi Format'i number-of-voices = Xomaşi ǩoretsxa splits = Boginape +email-to-download = Native Language +why-email = Amolva var it̆işu. +confirm-size = Goan Konkanuri size-gigabyte = Didi Biritanya size-megabyte = MB confirm-no-identify = Common Voiceşi datamarç̌as na ren msinapupeşi noçinepe odziru şeni var inç̌itatenǩebuli atna @@ -712,12 +727,19 @@ download-language = { $language } doya geiğit validated-hours = İtzuranu Saatepe recorded-hours = Doliç̌aru Saatepe whats-inside = Common Voice datamarç̌aşi doloxe mupe orenan? +want-dataset-update = Ndğaluri Hedefi subscribe = Abone iyi get-started-speech = Osinapu Oçinus Kogyoç̌ǩit other-datasets = Majura Xomaşi Datamarç̌ape feedback-q = Uǩaçxeni gnapa giğunan-i? +resource-nemo-info = { "" } +resource-deepspeech-info = E posta abonobape okti +resource-coqui-info = Galiçuri community-playbook = Partiyaşi becit̆i kitabi data-other-ted-name = TED-LIUM ǩoroba +data-other-voxforge-description = Lapori Oncğoni +data-other-tatoeba-description = Nenaşi talebi t̆işineri dolinç̌aru, ntsaşa exti. +your-feedback = Abone iyi go-discourse = Zit̆aşe İdi missing-language = Nena-tkvani datamarç̌as var dziremt-i? Nena ogoru şeni Nenapeşi butkaşa idit. go-languages-page = Nena but̆ǩaşe idi @@ -848,7 +870,7 @@ target-segment-learn-more = Daha fazla gaçkinas ## Contribution Nav Items contribute-voice-collection-nav-header = Xomaşi ǩoleǩsioni -contribute-sentence-collection-nav-header = Cumleşi ǩoleǩsiyoniCumleşi ǩoleǩsiyoni +contribute-sentence-collection-nav-header = Cumleşi ǩoleǩsiyoni ## Reporting @@ -913,12 +935,38 @@ want-to-continue = Meyonu ginonan-i? finish-editing = İpti osturesru oçodinu ginonan-i? lose-changes-warning = Hatzi kogamaxtit-na, osturesarupe tkvani gogindunanen build-custom-goal = Doxmeli hedefi getzopxit +set-a-goal = Ar noğire nisimadi +cant-decide = ǩarari var megaçenan-i? +how-many-per-day = Dido ǩai! Ar ndğas naǩo klibi? +how-many-a-week = Dido ǩai! Ar xaftas naǩo klibi? +confirm-goal = Hedefi dotzurani. +goal-interval-weekly = Xafteri +share-goal-type-speak = Visinapam +share-goal-type-listen = Oşǩinu (Oucu/ Osiminu) +share-goal-type-both = Osinapu do Oşǩinu +weekly-goal-created = Ar xafteri hedefi tkvani kogeitzopxu +daily-goal-created = Ar ndğeri hedefi tkvani kogeitzopxu +track-progress = Elaxtimu tkvani hakolen do istatistiği butkaşen natxozit. +return-to-edit-goal = Mundes na ginonan (gorumt) hedefi-tkvani osturesaru şeni hak goiktit. +share-goal = Hedefi-çkimi gurti ## Profile Delete +keep = Şinaxi +remove = Moseli +profile-form-delete = Profili Gejiri ## Profile Download +download-q = Datape-tkvani geğmalu dogaç̌inan-i? +download-info = Mu geğmalu gorum çku domimçinit. +download-profile-title = Profili +download-profile-info = Doloxe-muşi e-posta, xmarace coxo do demografiǩuri çkinapape orenan, yeine ixmaren +download-profile-size = jur-sum bayt̆i +download-recordings-title = Doloç̌arape +download-recordings-info = Doloxe-muşi MP3-epeşi cumlepe renan, oxadziru-muşik amtsika ora gotzamiğanen +download-recordings-size = Tipiǩuri megabayti +download-size = Boyut̆i ## Landing From badb4971ceffd1b1f15654b0055b76ca05c0decc Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 12:52:41 +0000 Subject: [PATCH 43/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index fb3e5c82fbef..0e84980379f6 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -1,6 +1,6 @@ ## General -yes-receive-emails = Ho, ma e-post̆a momicğonit. Comman Voice Proje mu oren oçkinnu minon. +yes-receive-emails = Ho, e-post̆a momicğonit. Common Voice Proje mu oren oçkinnu minon. stayintouch = Mozillas xomaşi teknolojiş gomti ar ǩata geptzopxumt. Meyondğanupete, ağani data mondunepete oǩomçinu do data muç̌o ixmart çkva dido oçkinu minonan/ bgorumt. privacy-info = Çkinapape tkvani becit̆obate na psturesaratereşi nena dogidumt. Daha fazlamuşi T'obaşobaşi Tkvalasgaǩitxenan. return-to-cv = Comman Voiceşa Goikti. From 790bf201d91dda7a32cf2c08d18733193bcf5498 Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 13:03:55 +0000 Subject: [PATCH 44/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 72 ++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index 0e84980379f6..62da5d7ea22d 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -3,19 +3,19 @@ yes-receive-emails = Ho, e-post̆a momicğonit. Common Voice Proje mu oren oçkinnu minon. stayintouch = Mozillas xomaşi teknolojiş gomti ar ǩata geptzopxumt. Meyondğanupete, ağani data mondunepete oǩomçinu do data muç̌o ixmart çkva dido oçkinu minonan/ bgorumt. privacy-info = Çkinapape tkvani becit̆obate na psturesaratereşi nena dogidumt. Daha fazlamuşi T'obaşobaşi Tkvalasgaǩitxenan. -return-to-cv = Comman Voiceşa Goikti. +return-to-cv = Common Voiceşa Goikti email-input = .label = Emaili submit-form-action = Mendancğoni loading = Eyulun -email-opt-in-info = Comman Voiceşi noğire goşinupe, ixenu dulyapeşi meoğanupe do anbaişi bultenepe steri e-postape eç̌opumu minon. -email-opt-in-info-title = Comman Voiceşi maili listhes eǩomanthalit. -email-opt-in-info-sub-with-challenge = Comman Voiceşi omondunu do noğire goşinupe, ixenu dulyapeşi meoğanupe do anbaişi bultenepe steri e-post̆ape eç̌opit. -email-opt-in-privacy-v2 = E-post̆ape ǩebuli doyat-na Mozillaşi ham çkinapape na tku steri oxmaru-muşis izini na meçameri iyet Privacy Policy. -indicates-required = Ar murutsxite (*) neğareri svalepe opşalu diç̌irs. +email-opt-in-info = Common Voiceşi noğire goşinupe, ixenu dulyapeşi meoğanupe do anbaişi bultenepe steri e-postape eç̌opumu minon. +email-opt-in-info-title = Common Voiceşi maili list̆es eǩomant̆alit. +email-opt-in-info-sub-with-challenge = Common Voiceşi omondunu do noğire goşinupe, ixenu dulyapeşi meoğanupe do anbaişi bultenepe steri e-post̆ape eç̌opit. +email-opt-in-privacy-v2 = E-post̆ape ǩebuli doyat-na Mozillaşi ham çkinapape na tku steri oxmaru-muşis izini na meçameri iyet Privacy Policy. +indicates-required = Ar murutsxite (*) meğareri svalepe opşalu diç̌irs. not-available-abbreviation = H/V -banner-error-slow-1 = Mixarsuvit, Comman Voicek tamo itsadeburs/ içalişams. Memaǩatit şeni ntsaşa extit. -banner-error-slow-2 = Opşa trafiği ephç̌opumt do hus problemepe goviǩitxamt. +banner-error-slow-1 = Mixarsuvit, Common Voicek tamo itsadeburs/ içalişams. Memaǩatit şeni ntsaşa extit. +banner-error-slow-2 = Opşa trafiği ep̌ç̌opumt do hus problemepe goviǩitxamt. banner-error-slow-link = Butkaşi Xali error-something-went-wrong = Mixarsuvit, mutxanepe gemapaşes error-clip-upload = Ham ǩilibi var eiğmalinen, xolo geitsadinas-i? @@ -30,7 +30,7 @@ error-clip-upload-server = Ham ǩilibi var eiğmalinen, xolo geitsadinas-i? ab = Abaza ace = Adiğe ady = Atzuğe -af = Afrik'anuri +af = Afriǩanuri am = Aramikuri an = Aragonuri ar = Arap'uri @@ -64,25 +64,25 @@ de = Alamanuri dsb = Tzaleni Sorbinuri dv = Divexuri dyu = Dioluri -el = Yunanuri +el = Xorumuri en = İngilizuri eo = Esperanturi -es = İspanyoluri -et = Estonuri +es = Isp̌anyoluri +et = Est̆onuri eu = Basǩuri ewo = Evonduri fa = Farsuri ff = Fulaxuri fi = Finuri fo = Faroecuri -fr = Frenk'uri +fr = Frenǩuri fuf = Pularuri Ginuri fy-NL = Frizuri ga-IE = İrlandanuri gl = Galiçuri gn = Guaranuri gom = Goan Konkanuri -gu-IN = Gujaraturi +gu-IN = Guceraturi guc = Vayuunaikuri ha = Hausuri he = Çifut̆uri @@ -96,16 +96,16 @@ hy-AM = Sumexuri hyw = Gyulvani Sumexuri ia = Interlinguri id = Endonezuri -ie = İgburi -ig = İgbouri +ie = İnterlinguri +ig = İgburi is = İzlanduri it = İtalyanuri izh = İzxoruri ja = Japonuri jbo = Lojbanuri -jv = Javanuri +jv = Cavanuri ka = Korturi -kaa = Ǩaraǩalpaǩuri +kaa = ǩaraǩalpaǩuri kab = Kabiluri kbd = Kabarturi ki = Kikuyuri @@ -114,14 +114,14 @@ km = Kmeruri kmr = Kurmanci Kyurduri kn = Kannaduri knn = Konkanuri -ko = Ǩorenuri +ko = ǩorenuri kpv = Komi-Zyrianuri kw = Kornişuri -ky = Ǩirgizuri +ky = ǩirgizuri lb = Luksanburǩuri lg = Luganduri -lij = Luksanburǩuri -ln = Luganduri +lij = Ligurianuri +ln = Lingaluri lo = Laonuri lt = Lit̆vanuri ltg = Latgaluri @@ -130,7 +130,7 @@ lzz = Lazuri mai = Mait̆iluri mdf = Mokşuri mg = Malagasuri -mhr = Meadov Maruri +mhr = Meadow Maruri mk = Makedonuri ml = Malayalamuri mn = Moğoluri @@ -159,7 +159,7 @@ oc = Okzit̆anuri om = Afaan Oromuri or = Odianuri os = Oset̆uri -pa-IN = Pencaphuri +pa-IN = Pencap̌uri pap-AW = Papiamenturi (Aruburi) pl = Lexuri ps = Paşturi @@ -174,17 +174,17 @@ ru = Rusuri rw = Kinyarvanduri sah = Saxuri sat = Santaluri -sc = Sardinuri -scn = Siciluri +sc = Sardinianuri +scn = Sicilian sco = Skoturi sd = Sinduri -sdh = Oineturi Kyurduri -shi = Şilxanuri -si = Sinxaluri -sk = Slovakuri -skr = Saraikuri -sl = Slovenuri -snk = Soninkuri +sdh = Omjoruri Kyurduri +shi = Shilha +si = Sinhala +sk = Slovak +skr = Saraiki +sl = Slovenian +snk = Soninke so = Somaluri sq = Arnavut̆uri sr = Sirp̌uri @@ -212,16 +212,16 @@ tyv = Tuvanuri uby = Ubixuri udm = Udmurturi ug = Uygururi -uk = Uǩranuri +uk = Uǩraynuri ur = Urduri uz = Uzbeǩuri ve = Tşivenduri vec = Venetianuri vi = Viet̆namuri vmw = Votiǩuri -vot = Volofuri +vot = Votiǩuri wep = Xosauri -wo = Çifut̆uri +wo = Volofuri xh = Yoruburi yi = Çifut̆uri yo = Yoruburi From b1e1e457879db2f7f2f01b8d92dce9ed395de85a Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 13:13:02 +0000 Subject: [PATCH 45/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 92 ++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index 62da5d7ea22d..554c01b07dc1 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -222,7 +222,7 @@ vmw = Votiǩuri vot = Votiǩuri wep = Xosauri wo = Volofuri -xh = Yoruburi +xh = Xosauri yi = Çifut̆uri yo = Yoruburi yue = Kantonesuri @@ -240,10 +240,10 @@ zza = Zazanuri speak = İsinapi speak-now = Hatzi - hus - huy isinapi -datasets = Datamarç'a +datasets = Datamarç̌a languages = Nenape about = Hemuşeni -partner = Maneba +partner = Partneri profile = Profili help = Memişvelit contact = ǩont̆aǩt̆i @@ -253,7 +253,7 @@ cookies = ǩaǩape faq = FAQ content-license-text = Doloxdenepe Creative Commons license lisansişi tude koren. share-title = Nena-nişis memxacu şeni çkvape odzirus memişvelit. -share-text = Mtini ǩoçepek muçho isinapaman doguru şeni memişvelit, nena-skani mixarsuvit { $link } +share-text = Mtini ǩoçepek muç̌o isinapaman doguru şeni memişvelit, nena-skani mixarsuvit { $link } link-copied = Linki ǩopya dixenu. back-top = Tişa Kexti logout = Kogamaxtit @@ -262,15 +262,15 @@ donate = Mixaresirit ## Home Page home-title = Comman Voice, mtini k'oçepeşi osinapu makinapes doguru şeni na geiç'k'u/ ciç'u Mozillaşi insiyatifi ren. -default-tagline = Mozilla Comman Voice, mtini ǩoçepeşi osinapu makinapes doguru şeni na geidgu geç̌ǩapale ren. +default-tagline = Mozilla Common Voice, mtini ǩoçepeşi osinapu makinapes doguru şeni na geidgu ar geç̌ǩapale ren. home-cta = Nena eşiğit, hamsvanis numxacit! wall-of-text-start = Xoma natureli ren, xoma ǩoçi ren. Heşeni makinape çkuni şeni oxmaroni xomaşi teǩnoloji getzopxu ǩai matzonenan. Ama, xomaşi sist̆emepe getzopxu şeni dido dido xomaşi data domaç̌iran. wall-of-text-more-mobile = Didi şirǩet̆epek na oxmaraman datapeşi dido muşi ǩoçişi oxmarus gontzǩeri va ren. Ham xalik inovasiyonis gza cuğobams. Heşeni, iris xomaşi teǩnoloji axmaran ya do Comman Voice na gyodzin ham projes moǩoviç̌it. wall-of-text-more-desktop = Açkva xoma-tkvani mixaresirit do cihazepe do webi şeni iris ağanuri apliǩasiyonepe oxenu şeni na axmarasen ar xomaşi datambağu getzopxus memişvelit. Makinepes mtini ǩoçepeşi osinapu oxotzonapu şeni ar cumle iǩitxit-golionit-tkvit. Majura ǩatapeşi dulyapes otzǩedit do ǩalite mundzinit. Haǩu dulya! wall-of-text-first = Xoma natureli ren, xoma ǩoçi ren. Heşeni makinape çkuni şeni oxmaroni xomaşi teǩnoloji getzopxu şeni gomagzenan. Ama, xomaşi sist̆emepe getzopxu şeni dido dido xomaşi data diç̌irs. wall-of-text-second = Didi şirǩet̆epek na oxmaraman datapeşi dido muşi ǩoçişi oxmarus gontzǩeri va ren. Ham xalik inovasiyonis gza cuğobams. Heşeni, iris xomaşi teǩnoloji axmaran ya do Comman Voice na gyodzin ham projes moǩoviç̌it. -show-wall-of-text = Majurape iǩitxi/ golioni -help-us-title = Ham cumlepe getzuranu şeni memişvelit. +show-wall-of-text = Çkva İǩitxi +help-us-title = Cumlepe getzuranu şeni memişvelit. help-us-explain = Osteri/ Obiri tuşis gyobazgit. İucit-işǩinit-isiminit do cumle tzori/ ese iǩitxui mitzvit. no-clips-to-validate = Ham nenas oşǩinoni aina ǩlibi var giğuran steri idziren. Hatzi (hus) bazi ǩlibepe doloç̌arit do jilemona opşus meişvelit. vote-yes = Ho @@ -280,15 +280,15 @@ speak-subtitle = Nena-tkvani mixarsuvit speak-paragraph = Nenaşi ǩlibepe doloç̌aru goncameri data sistemi getzopxuşi enni vorsi gza oren. Ham artsope (bazepe) şeni oxoktinoni oren. speak-goal-text = Doloç̌areri ǩlibepe listen-subtitle = Xomape otzuranus memişvelit. -listen-paragraph = Xarsuveri ǩlibepeşi otzorinu (tzori na oren oxotzonu) Comman Voiceşi misyoni şeni eşit̆i derece becit̆i oren. Ar işǩinit (iucit) do ǩalitoni goncameri nenaşi data getzopxu şeni meişvelit. +listen-paragraph = Xarsuveri ǩlibepeşi otzorinu (tzori na oren oxotzonu) Common Voiceşi misyoni şeni eşit̆i derece becit̆i oren. Ar işǩinit (iucit) do ǩalitoni goncameri nenaşi data getzopxu şeni meişvelit. listen-goal-text = Doloç̌areri saatepe -hours-recorded = Tzorineri saatepe +hours-recorded = Doloç̌areri saatepe hours-validated = Tzorineri saatepe voices-online = Hus (hatzi) onlaini na oren xomape todays-progress = Andğaneri Ogzalapa help-reach-goal = { $goal } olva şeni meişvelit read-terms-q = Oxmaruşi şart̆epe iǩitxiti/ golioniti -ready-to-record = Xoma-tkvani oxorsuvu şeni xadziri oret-i? +ready-to-record = Xoma-tkvani oxarsuvu şeni xadziri oret-i? all-locales = İri/ Mteli today = Andğa x-weeks-short = @@ -309,12 +309,12 @@ x-years-short = help-make-dataset = Çku mağala ǩalitete, iris goncameri ar dataset̆i getzopxu şeni memişvelit. sign-up-account = Ar xesap̌i kogetzopxit email-subscription-title = E-posta oağanu şeni kodoliç̌arit. -email-subscription-title-new = Comman Voiceşi xaberi bultenepes, gonoşinupes do ogzaloni ondğalurepes doliç̌arit. +email-subscription-title-new = Common Voiceşi ambai bultenepes, gonoşinupes do ogzaloni ondğalurepes doliç̌arit. ## Account Benefits benefits = Pelapape -rich-data = Momincğonit datapeşi daha ǩai oxenu şeni bazi anonimi demografiǩuri datape momçit. Mteli demografiǩuri datape ǩamus p̌i gontzǩaşe noçinepe gotziğit. +rich-data = Na momincğonit datapeşi daha ǩai oxenu şeni bazi anonimi demografiǩuri datape momçit. Mteli demografiǩuri datape ǩamus p̌i gontzǩaşe noçinepe gotziğit. improve-audio = Profilişi çkinapape, osinapu çinapa tzorinoba oslop̌us na ixmaren xomaşi datape oǩaimams. keep-track = Megzalu do mezuma-tkvani arişen dido nenaşen otzǩedirt compare-progress = Megzalu-tkvani dunyaşi genelis majura memşvelupe-şkala muç̌o na oxitzonen dzirit. @@ -343,10 +343,10 @@ shortcut-play-toggle = d shortcut-play-toggle-label = İsteri/ Dodgiti # Must be one letter that appears in the { vote-yes } string. # Must be different from { shortcut-skip }, { shortcut-vote-no } and { shortcut-play-toggle } -shortcut-vote-yes = H +shortcut-vote-yes = h # Must be one letter that appears in the { vote-no } string. # Must be different from { shortcut-skip }, { shortcut-vote-yes } and { shortcut-play-toggle } -shortcut-vote-no = V +shortcut-vote-no = v ## Speak Shortcuts @@ -355,11 +355,11 @@ shortcut-vote-no = V shortcut-record-toggle = d shortcut-record-toggle-label = Doloç̌ari/ Dodgiti shortcut-rerecord-toggle = [1-5] -shortcut-rerecord-toggle-label = Nena gori +shortcut-rerecord-toggle-label = ǩilibi meyoç̌ari shortcut-discard-ongoing-recording = ESC shortcut-discard-ongoing-recording-label = Hatzineri doloç̌ara ip̌t̆ali doyi shortcut-submit = Goikti -shortcut-submit-label = K'ilibi mendancğoni +shortcut-submit-label = ǩilibi mendancğoni request-language-text = Common Voices daha nena-tkvani var dziremt-i? request-language-button = Ar Nena Gori @@ -389,7 +389,7 @@ profile-form-language = .label = Nena profile-form-variant = .label = { $language }şi nam varianti isinapam? -profile-form-variant-default-value = Aina varianti goşatsxuneri va oren. +profile-form-variant-default-value = Variasioni var goşiğmalu profile-form-accent = .label = Aksani profile-form-custom-accent-help-text = @@ -401,13 +401,13 @@ profile-form-gender-2 = .label = Cinsiyet'i leaderboard-visibility = .label = Leaderboard-işi tzirama -hidden = T'k'obaşe +hidden = t̆ǩobaşe visible = Native Language native-language = .label = Svaloni Nena profile-form-add-accent = Ağani ar aksani "{ $inputValue }" keǩumtsxvi profile-form-submit-save = Şinaxi -profile-form-submit-saved = Kodoliç'aru +profile-form-submit-saved = Kodoliç̌aru male_masculine = Mamuli female_feminine = Daduli intersex = Majura @@ -423,19 +423,19 @@ goals = Hedefepe settings = Getzopxi edit-profile = Profili getzopxi profile-create-success = Dobeceri, profili diç̌ǩadu (kogeitzopxu) -profile-close = Genk'oli +profile-close = Genǩoli profile-explanation = Ar profilite gamayonu-tkvanis nontxozit do xomaşi datape daha tzori oyapus memişvelit. thanks-for-account = Xesabi-tkvani na otzuranit şeni ntsaşa extit, hatzi (hus) profili-tkvani gep̌tzopxat. why-demographic = Ham muşeni becit̆i oren? why-demographic-explanation-2 = Tzana, cinsiyet̆i do aksani steri anonimi xeneri xmaraceşi datape, osinapu çinobua motorepeşi tzorinoba oslop̌u şeni na ixmaren xoma datapeşi oǩaimus nuşvelams. Xmarace coxo-tkvani do e-posta adresi-tkvani na moncğonit datape-ǩala p̌ot̆e var oǩimç̌ǩeşinasen. Xmarace coxo-tkvani ǩamus gontzǩeri vana ononimuri iyasen-i goşogatsxunanen. accept-privacy = Mozillaşi t̆obaşoba Polotiǩas ignapinu steri ham dataşi tkvani oxmaru momarçilen. -accept-privacy-title = T'obaşobaşi Polotik'a +accept-privacy-title = t̆obaşobaşi Polotiǩa accept-privacy-and-terms = Common Voiceşi Şart̆epe do t̆obaşoba Gognapa elemivelams. login-identity = Amaxtimui oçinoba login = Amaxti login-signup = Amaxti/ Doliç'ari edit = Sturesari -email-subscriptions = E-mailişi abonobape +email-subscriptions = E-posta Doloç̌areri download-profile = Datape-çkimi Kogeiği contribution-experience = Meşveluşi Getsadu skip-submission-feedback = Oncğonuşi ǩap̌ula Gnapas Moyuǩap̌i @@ -452,7 +452,7 @@ help-variants-explanation = Variantepe nenaşi meçkineri ar k̆ata ren. Meçkin browse-file-title = Ar resimişi dosya kogedvit browse-file = Dolotiri do dolodvi var na mendatzk̆edi -connect-gravatar = Gravatarite Nik'ori +connect-gravatar = Gravatarite Niǩori gravatar_not_found = Emaili şeni Gravatari var İdziru file_too_large = Goşatsxuneri dosya opşa didi ren avatar-uploaded = Avatari keiğu @@ -480,7 +480,7 @@ faq-how-get-a = Common Voiceşi Datamarç̌a, CC0 lis faq-when-release2-q = Majura nenapeşi Common Voice datamarç̌a mundes gamiğaten? faq-why-mission-q = Common Voice, Mozilla misyonişi muşeni ar notzile ren? faq-why-mission-a = - "Mozilla, mzesa k̆atai şeni gontzk̆imeri t̆as do k̆ataik + Mozilla, mzesa k̆atai şeni gontzk̆imeri t̆as do k̆ataik ixmaras ya do dik̆idu.Aya oxvenu şeni Common Voicei steri projepeten mzesa magetzopxepe omencelu diç̆irs. Xomaşi teknolojepe niche ap̆lik̆asyonepe mik̆ilan do @@ -492,7 +492,7 @@ faq-why-mission-a = ar goncameri otişe ren do mtel kianas na ren Mozillaşi k̆atapek çkini projepes ixmanan." faq-what-cv-and-deepspeech-q = Common Voice do Deep Speechşi oşkenas mu farki oren? faq-what-cv-and-deepspeech-a = - "Common Voice datamarçak, Mozillaşi goncameri + Common Voice datamarçak, Mozillaşi goncameri xoma oxotzonuşi mat̆ori Deep Speechis mxuci meçaps. Deep Speecişi maartani versiyoni 2017 Tzilvas gamaxtu do emuşen akole p̆ant̆a imralen. Common Voice datamarç̆aten, @@ -500,7 +500,7 @@ faq-what-cv-and-deepspeech-a = ren ya do visimadept. (........) " faq-is-goal-assistant-q = Common Voiceşi hedefi ar nenaşi asist̆ani otzopxu oren-i? faq-is-goal-assistant-a = - "Common Voice datamarç̆a mot yeçkindu? Kianas sotxani ort̆as, + Common Voice datamarç̆a mot yeçkindu? Kianas sotxani ort̆as, k̆atais xoma oxotzonu, mağarğale oxotzonu var na xoma oxmarinu na diç̆irs ar ap̆likasyoni getzipxus nuşvelas ya do. Ar xoma-memxace, datamarç̆a oxmaruten na gaxvenenanpeşi @@ -508,7 +508,7 @@ faq-is-goal-assistant-a = " faq-do-want-native-q = Ma svaluri na va ren ar msinapu vore do aksanite visinapam, colo-ti xoma-çkimi ginonan-i? faq-do-want-native-a = - "Ho, mtini tkvani xoma minonan! Common Voiceişi noğirepeşi + Ho, mtini tkvani xoma minonan! Common Voiceişi noğirepeşi ari, xoma oxotzonuşi sistemepe k̆atai şeni k̆ai içalişas ya do, na iqven k̆onari çkva do çkva aksanepe ok̆orobu ren. Aya, nana-nenamutepeşi Lazuri na varen k̆oçepeşi xoma ok̆orobu dido @@ -522,19 +522,19 @@ faq-why-my-lang-a = faq-what-quality-q = Data setis na ixmaren ar xomaşi ǩlibi şeni na diç̌irs xomaşi ǩaliteşi seviye mu oren? faq-why-10k-hours-q = Xomaşi oxotzonu şeni ǩat̆a nena şeni tzorineri 10,000 zit̆a hedefi geidu doren? faq-why-10k-hours-a = - "Aya aşo xomaşen ç̆ara na ixvenen ar sistemi oxvenu şeni + Aya aşo xomaşen ç̆ara na ixvenen ar sistemi oxvenu şeni na diç̆irs saat̆i ren." faq-how-calc-hours-q = Common Voicek saatepe muç̌o xesap̌ums? faq-how-calc-hours-a = - "Saat̆i oxesap̆u şeni k̆ata doloç̆areri xomaşi gindzenoba ptsadupt, + Saat̆i oxesap̆u şeni k̆ata doloç̆areri xomaşi gindzenoba ptsadupt, ok̆ule iya, mtelli nenapes na ixvenu mtelli doloç̆arapeşi k̆orotsxala k̆ala vomralapt." -faq-where-src-from-2-q = Monduni ç'ara solen mulun? +faq-where-src-from-2-q = Monduni ç̌ara solen mulun? faq-where-src-from-2-a = "Tzk̆artoli ç̆araçkini, mtini na mixarsuvupanpeşen do It’s a Wonderful Life steri goncameri filimi senaryopeşen na guşitsxunu ok̆oğarğalapeten dik̆idu." faq-why-not-ask-read-q = Muşeni k̆oçepes çkva do çkva nenapeşi sup̆arape do vikipediaşi ç̆arape ik̆itxit ya varutzumet? faq-why-not-ask-read-a = - "Common Voice datambağu na maxvenenan k̆onari, k̆olai + Common Voice datambağu na maxvenenan k̆onari, k̆olai na ixmarinen ar mutxani gaxadu şeni, xvala Goncameri (CCO) lisansişi doloxe na ren tzk̆ariştoli ç̆arapes nek̆na gomtzk̆at ya ptkvit. CCO standarti oxmaru, tzk̆ariştoli ç̆arape @@ -578,7 +578,7 @@ about-speak = İsinapi about-speak-text = Memşvelupek, xarsuveri cumlepete pşeri ar bankaşen iǩitxaman do ǩlibepe doloç̌aruman. about-listen-queue = Oşǩinuşi Sira about-listen-queue-text = Xomaşi ǩlibepe, hentepe oşǩinu şeni na xadzirums ar nocğone ǩudelis amilven. -about-listen = İuci - İşkini - İsimini +about-listen = İşǩini (İuci/ İsimini) about-listen-text = Maxmarepe, msinapuk cumle tzori iǩitxu-i ya do kontroli ikums do xarsuveri ǩlibepeşi tzorinoba tzorinums. about-is-it-valid = ǩlibi oxmaroni oren-i? about-is-it-valid-text = Maxmarek "Ho" ya do rei meçasi 'oxmaroni" ya do niğaren. @@ -635,7 +635,7 @@ about-playbook-how-grow-language-content-6 = Ortağepe do Mosape ## How to validate -about-playbook-how-validate = Nena doloç'areri geptzora vana mot geptzora muç'o oxovotzonare? +about-playbook-how-validate = Nena doloç̌areri geptzora vana mot geptzora muç̌o oxovotzonare? ## How to access dataset @@ -690,7 +690,7 @@ license = Lisansi: { $license } license-mixed = Oǩont̆aleri data-download-singleword-title = Ar Zit̆a Noğire Boligina Kogeiğit review-terms = Ağani nena şeni iǩitxi -terms-agree = Ok'ovuvelut +terms-agree = Oǩovuvelut terms-disagree = Var Ok'ovuvelut review-aborted = Eğmalu ip̌t̆ali dixenu. Doloç̌arupe-tkvani gejilu ginonan-i? review-submit-title = Tsadi do Moncğoni @@ -703,7 +703,7 @@ review-delete-recordings = Doloç̌arape-çkimi gejilit (cejirit) ## Datasets Page -datasets-heading = Datamarç̌ape +datasets-heading = Datamarç̌a datasets-headline = Ar xesap̌i kogetzopxit language = Nena download-dataset-header = datamarç̌a Kogeiğit @@ -714,7 +714,7 @@ size = Boyut̆i validated-hr-total = Tzuraneri saatişi ǩoroba overall-hr-total = Geneluri saatişi ǩoroba cv-license = Lisansi -audio-format = Xomaşi Format'i +audio-format = Xomaşi Format̆i number-of-voices = Xomaşi ǩoretsxa splits = Boginape email-to-download = Native Language @@ -745,14 +745,14 @@ missing-language = Nena-tkvani datamarç̌as var dziremt-i? Nena ogoru şeni Nen go-languages-page = Nena but̆ǩaşe idi ready-to-validate = Cumlepe getzuranus meşvelu şeni xadziri oret-i? more = Çkva -close = Genk'oliGenǩoli +close = Genǩoli download = Kogeiği -dataset-version = VersioniVersioni +dataset-version = Versioni sha256-checksum-copied = SHA256 Checksum ǩop̌ya dixenu! sha256-checksum-copied-error = SHA256 Checksum ǩop̌ya var ixenu! clipboard-not-supported = Panok var numxacams # dataset metadata - age of contributor -dataset-metadata-age = TzanaTzana +dataset-metadata-age = Tzana ## Download Modal @@ -772,7 +772,7 @@ contact-required = *diç̌irs request-language-title = Nenaşi Talebi request-language-form-language = - .label = NenaNena + .label = Nena request-language-success-title = Nenaşi talebi t̆işineri dolinç̌aru, ntsaşa exti. request-language-success-content = Common Voice'işa ar nena dodvalu muç̌o iyen otku şeni na mulun ndğalepes giç̌araten. select-language = Nena goşuğit… @@ -814,12 +814,12 @@ language-validation-progress = Otzuranuşi elaxtima action-click = Met̆aǩulu action-tap = Ombolina -contribute = MemaǩatitEǩoşvelu -listen = İuci - İşkini - İsimini -write = Ç'ari -review = MeotzǩediMeotzǩedi -skip = Moyok'ap'it -shortcuts = Gzamk'ule +contribute = Eǩoşvelu +listen = İşǩini (İuci/ İsimini) +write = ç̌ari +review = Meotzǩedi +skip = Moyoǩap̌i +shortcuts = Gzamǩulepe contribute-more = { $count -> [one] { $count } daha dido-muşi oxenus xadziri ore-i? From a654fc6165b0178fab5b35011bbf1fadcfcfd5f3 Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 13:52:35 +0000 Subject: [PATCH 46/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index 554c01b07dc1..394b9d38c117 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -2,7 +2,7 @@ yes-receive-emails = Ho, e-post̆a momicğonit. Common Voice Proje mu oren oçkinnu minon. stayintouch = Mozillas xomaşi teknolojiş gomti ar ǩata geptzopxumt. Meyondğanupete, ağani data mondunepete oǩomçinu do data muç̌o ixmart çkva dido oçkinu minonan/ bgorumt. -privacy-info = Çkinapape tkvani becit̆obate na psturesaratereşi nena dogidumt. Daha fazlamuşi T'obaşobaşi Tkvalasgaǩitxenan. +privacy-info = Çkinapepe tkvani mç return-to-cv = Common Voiceşa Goikti email-input = .label = Emaili From b9180d9be35e05bfd2fc40097b084824cf0848f0 Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 14:03:59 +0000 Subject: [PATCH 47/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index 394b9d38c117..6867d986a693 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -19,7 +19,7 @@ banner-error-slow-2 = Opşa trafiği ep̌ç̌opumt do hus problemepe goviǩitxam banner-error-slow-link = Butkaşi Xali error-something-went-wrong = Mixarsuvit, mutxanepe gemapaşes error-clip-upload = Ham ǩilibi var eiğmalinen, xolo geitsadinas-i? -error-clip-upload-server = Ham ǩilibi var eiğmalinen, xolo geitsadinas-i? +error-clip-upload-server = { "" } # Don't rename the following section, its contents are auto-inserted based on the name (see scripts/pontoon-languages-to-ftl.js) # [Languages] @@ -967,6 +967,12 @@ download-recordings-title = Doloç̌arape download-recordings-info = Doloxe-muşi MP3-epeşi cumlepe renan, oxadziru-muşik amtsika ora gotzamiğanen download-recordings-size = Tipiǩuri megabayti download-size = Boyut̆i +download-selected = Goşitsxunu +download-start = Profilişi datape kogeiği +download-request = Doloç̌aru gori +download-requests = Atxenuri doloç̌arerepe geğmaluşi gorapa +download-request-button = KogeiğiKogeiği +download-request-archive-single = Doloxemuşi tudenepe na oren ar ZIP dosya ## Landing From cac4156e3959d71db81ec34cf14a33c778d67c7f Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 14:13:02 +0000 Subject: [PATCH 48/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 142 +++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index 6867d986a693..f8f92b8bb208 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -973,27 +973,68 @@ download-request = Doloç̌aru gori download-requests = Atxenuri doloç̌arerepe geğmaluşi gorapa download-request-button = KogeiğiKogeiği download-request-archive-single = Doloxemuşi tudenepe na oren ar ZIP dosya +download-request-modal-title = Linkepe kogeiği +download-request-modal-description = ZIP dosyape na geiğaten linkepe hak oren. +download-request-link-text = Zip #{ $offset } / { $total } +download-request-metadata-link = Cumleşi ç̌ara ## Landing +welcome-staff = { $company } personelişe ǩaite moxtit! +login-company = { $company } e-posta adresite Amaxtit / Doliç̌arit +read-more-about = Çkunişeni butkaşe dido-muşi iǩitxit ## DemoLayout +demo-welcome = Common Voice'şa ǩaite moxtit ## Demo Datasets +card-button-next = Uǩaçxeni +card-button-back = ǩap̌ula ǩele +demo-language-select-label = Nenapes otzǩedi +demo-eofy-header = 2019 Tzana Eçourişi Gamamşkumale +demo-eofy-sub_header = Xomaşi Datamarç̌a, Geğmalu şeni xadziri oren +demo-account = Xesap̌i ## Demo Account +demo-account-enter-email = + .label = Doloç̌aruşi linki oncğonu şeni e-posta amaxtit +demo-account-sign-up = Doloç̌aruşi linki oncğoni ## Demo Contribute +demo-listen-subtitle = Eǩoǩatus xadziri ore-i? ## Demo Dashboard ## Validation criteria +contribution-criteria-nav = ǩriterepe +contribution-criteria-link = Meşveluşi kriterepe oxotzonit +contribution-criteria-page-title = Meşveluşi kriterepe +contribution-misreadings-title = Yanlişi oǩitxupe +contribution-misreadings-description-extended-list-4 = Doloç̌aru manişa meǩvatute eçouri zit̆aşi çodina ... +contribution-misreadings-description-extended-list-5 = Ar zit̆a oǩitxu şeni jur-sum fara getsadu. +contribution-misreadings-example-1-title = Triyasişi divi dinazorepe. +contribution-misreadings-example-6-explanation = [“çku” iyasen] +contribution-misreadings-example-7-title = ǩave eç̌opumu şeni gale gamavulurt. +contribution-misreadings-example-7-explanation = [Orijinali ç̌aras 'a' va ren] +contribution-misreadings-example-8-title = mtuti p̌ut̆uci manişa kogolaxtu. +contribution-misreadings-example-8-explanation = [Var eluvelun kontenti] +contribution-varying-pronunciations-title = Goimturu otkupe +contribution-varying-pronunciations-example-1-title = Tis kudi gyutut̆u. +contribution-varying-pronunciations-example-2-title = Xe keǩozdu. +contribution-background-noise-title = ǩap̌ulani nağarya +contribution-background-noise-example-2-explanation = [ç̌araşi ar notzile var diguren] +contribution-background-voices-title = ǩap̌ulani xomape +contribution-volume-title = Hacimi +contribution-reader-effects-title = Maǩitxeşi Efektepe +contribution-just-unsure-title = Vorsi var giçkinan-i? +see-more = Daha fazlamuşi dzirit +see-less = Daha mtsikamuşi otziri # Don't rename the following section, its contents are auto-inserted based on the name. These strings are # automatically exported from Sentence Collector. @@ -1002,39 +1043,108 @@ download-request-archive-single = Doloxemuşi tudenepe na oren ar ZIP dosya ## HEADER/FOOTER +sc-header-home = Oxori +sc-header-add = Eǩont̆alu/ Eǩodvalu +sc-header-review = Meotzǩedi +sc-header-rejected = Gokteri Cumlepe +sc-header-my = Cumlepe-çkimi +sc-header-statistics = İstatistiǩa +sc-header-profile = ProfiliProfili +sc-footer-discourse = Tkvala +sc-footer-report-bugs = Xet̆ape Milaporit +sc-footer-translate = Ham butka golakti +sc-footer-report-copyright = Telifişi xarǩi milaporit +sc-footer-privacy = t̆obaşobat̆obaşoba +sc-footer-terms = Şart̆epeŞart̆epe +sc-footer-cookies = ǩaǩapeǩaǩape +sc-login-signup-button = Amaxti/ Doliç̌ari +sc-logout-button = Gamaxti ## HOME +sc-home-title = Common Voiceşi Cumle Mǩorobus ǩaite Moxtit +sc-home-collect-title = Cumlepe ǩorobi +sc-home-review-title = Cumlepes ar daha otzǩedi ## GENERAL ## HOW-TO +sc-howto-title = Muç̌o +sc-howto-addlang-title = İçalişinasen nenape eǩumtsxvit +sc-howto-addsen-title = Ağani cumlepe eǩumtsxvit. +sc-howto-review-title = Cumlepes tsadi +sc-howto-review-subtitle = Cumlepeşi tudeni kriterepes na eluvelun vorsi ognit. +sc-howto-review-criteria-1 = Cumlepe tzori oç̌aru diç̌irs. +sc-howto-review-criteria-2 = Cumle grameruri tzori ort̆asen. +sc-howto-review-criteria-3 = Cumlepe osinaponi ort̆asen. +sc-howto-findpd-title = ǩamuşi Mondunis na oren cumlepe odziru +sc-howto-findpd-subtitle = Hantepe (hani) internet̆is gorit ## MY SENTENCES +sc-my-title = Cumlepe-çkimiCumlepe-çkimi +sc-my-loading = Cumlepe tkvani eiğmalinen... +sc-my-no-sentences = Aina cumle var idziru! +# Variables: +# $batchId (String) - A unique ID identifying the submission of sentences - sentences uploaded together all have the same batch ID +sc-my-submission = Oncğonu: { $batchID } +sc-my-delete = Goşitsxonu cumlepe gejili +sc-my-deleting = Goşitsxonu cumlepe geijilen... +sc-my-err-failed-delete = Cumlepe var geijilu... Ar daha kogeitsadit! ## REJECTED +sc-rejected-title = Gokteri CumlepeGokteri Cumlepe +sc-rejected-loading = Redi na ixenu cumlepe eiğmalinen... +sc-rejected-err-fetching = Cumlepe tkvani moiğmalet̆uşa xeta gamaxtu. Ar daha kogeitsadit. +sc-rejected-none-found = Redi na ixenu cumlepe var idziru! ## STATS +sc-stats-title = İstatistiǩaİstatistiǩa +sc-stats-updating = İndğaluren... ## ADD +sc-submit-err-select-lang = Ar nena goşuğit. +sc-submit-err-add-sentences = Cumlepe eǩudvit. +sc-submit-err-add-source = Ar cireǩi eǩudvit. +sc-submit-err-confirm-pd = Cumlepe ǩamuşi mali na oren oxotzonit +sc-submit-prompt = + .message = Cumlepe var incğonu, xolo gamaxtaten-i? +sc-submit-title = Cumle eǩudvi +sc-submit-select-language = + .labelText = Nena goşuği +sc-submit-ph-one-per-line = + .placeholder = ǩat̆a satiris ar cumle +sc-submit-button = + .submitText = Oncğonu ## ADD LANGUAGE +sc-add-lang-could-not-add = Nena var eǩimtsxu +sc-add-lang-sec-label = Meşvelu na ginonan nena eǩumtsxvit +sc-add-lang-sec-button = Nena EkumtsxviNena Ekumtsxvi +sc-add-err-unexpected = Serverişe var nişonen cuğap̌i goiktinu +sc-add-err-submission = Oncğonu xeta ## ADD SENTENCES CONFIRMATION +sc-confirm-are-you-sure = + .message = Cumlepe var incğonu, xolo gamaxtaten-i?Cumlepe var incğonu, xolo gamaxtaten-i? +sc-confirm-sentences-title = Ağani cumle getzurani ## LANGUAGE INFO +sc-lang-info-title-total = MteliMteli +sc-lang-info-title-personal = Şurineburi ## LOGIN +sc-login-err-failed = Amolva var it̆işu. +sc-login-err-try-again = Ar daha citsadit. ## PROFILE @@ -1050,12 +1160,44 @@ download-request-archive-single = Doloxemuşi tudenepe na oren ar ZIP dosya # [/SentenceCollector] +citation = + .label = Eşaç̌opu +reviewing-sentences-explanation-1 = Cumle jini ǩriteri-ǩala oǩuvelams na "Ho" butonis gyobazgit. ## WRITE PAGE +sentence = + .label = Cumle +sentence-input-value = ǩamuşi mali na ren cumle-tkvani hak ç̌arit +citation-input-value = Cumle-tkvanişi cireǩi (ǩaynaği) +citation = + .label = Eşaç̌opu +new-sentence-rule-1 = Telifişi xarǩi va renozdapa (cc-0) +new-sentence-rule-3 = Tzori nenaçkina ixmarit +new-sentence-rule-4 = Tzori oç̌aru do ot̆imbu işaret̆epe ixmarit +new-sentence-rule-5 = ǩoretsxa do doxmeli ǩarakteri va oren +new-sentence-rule-6 = Galeni bonca va oren +new-sentence-rule-7 = Eluvelun eşaç̌opu keǩunt̆ali +new-sentence-rule-8 = İdeali-muşi natureli do msinapu (cumle oǩitxu ǩolai iyasen) +how-to-cite = Muç̌o eşomaç̌opasen? +how-to-cite-explanation-bold = Ar URL linkite vana dulyaşi coxote elişinit. +guidelines = Oktalupe +contact-us = Çkuni-ǩala ǩontaǩt̆i dodvit +add-sentence-success = 1 cumle diǩorobu +add-sentence-error = Cumle eǩidvet̆uşani xeta gamaxtu +required-field = Ham svani opşit. ## REVIEW PAGE +sc-review-rules-title = Cumle ǩuralepes eluvelun-i? +sc-review-empty-state = Hatzi ham nenas itsadasen cumle va ren. +report-sc-different-language = Farǩli nena +report-sc-different-language-detail = Votzǩedi nenaşen çkva nenate iç̌aru. +sentences-fetch-error = Cumlepe eiç̌opet̆uşa ar xeta gamaxtu. +review-error = Ham cumle itsadet̆uşani ar xeta gamaxtu. +# SENTENCE-COLLECTOR-REDIRECT PAGE +sc-redirect-page-title = Didi a mutxape gokturamt. +sc-redirect-page-subtitle-2 = nan ## BULK SUBMISSION From 0f675dc10764db84b180394b3157449b124da4d9 Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 14:23:12 +0000 Subject: [PATCH 49/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 91 ++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index f8f92b8bb208..eae7bdf6a42d 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -658,6 +658,7 @@ about-playbook-how-project-governance-content-7 = Muç̌o na mok glossary = Nenapuna localization = Lokaloba localization-explanation = Hantepe (hani) internet̆is gorit +sentence-collection = Cumleşi ǩoleǩsiyoni sentence-collection-explanation = Eğmaleri ǩlibepe hours-recorded-explanation = Tzuraneri saatişi ǩoroba hours-validated-explanation = Nenape çkuni: @@ -1148,20 +1149,110 @@ sc-login-err-try-again = Ar daha citsadit. ## PROFILE +sc-personal-err-remove = Nena var moiselinu +sc-personal-your-languages = Nenape çkuni: +sc-personal-remove-button = moselu +# Variables: +# $sentences (Number) - Number of sentences that were added by the currently logged in user for this language +sc-personal-added-by-you = { $sentences } tkva eǩudvit +sc-personal-not-added = Daha aina nena var eǩudvit ## REVIEW CRITERIA +sc-criteria-modal = ⓘ Getsaduşi Kriterepe +sc-criteria-title = Getsaduşi Kriterepe +sc-criteria-make-sure = Cumlepeşi tudeni kriterepes na eluvelun vorsi ognit. +sc-criteria-item-1 = Cumlepe tzori oç̌aru diç̌irs.Cumlepe tzori oç̌aru diç̌irs. +sc-criteria-item-2 = Cumle grameruri tzori ort̆asen.Cumle grameruri tzori ort̆asen. +sc-criteria-item-3 = Cumlepe osinaponi ort̆asen.Cumlepe osinaponi ort̆asen. ## REVIEW +sc-review-title = Cumlepes tsadiCumlepes tsadi +sc-review-loading = Cumlepe eiğmalinen... +sc-review-form-button-reject = Reddi oxenu +sc-review-form-button-skip = Moyoǩap̌iMoyoǩap̌i +sc-review-form-button-approve = Otzuranu +sc-review-form-button-submit = + .submitText = Elaxtimu doçodinit. +sc-review-link = MeotzǩediMeotzǩedi ## SETTINGS +sc-settings-title = GetzopxiGetzopxi +sc-validation-no-numbers = Cumleşi doloxe reǩami var ort̆asen +sc-validation-no-symbols = Cumleşi doloxe semboli var ort̆asen +sc-validation-no-abbreviations = Cumlepes domǩulape var ort̆asen # [/SentenceCollector] +localization-select = + .label = Nena/ svamuşi goşuğit +# PARTNERSHIPS PAGE +partnerships-header = ortağepe +partnerships-get-in-touch = Kontakti miğut̆an +partnerships-become-a-partner = Common Voiceşi ortaği iyit +partnerships-foundations-header = Temelepe +partnerships-governments-header = Hukyumet̆epe +partnerships-our-partners = Çkuni ortağepe +# FIRST POST SUBMISSION CTA +first-cta-header-text = Xoma ǩlibepe-tkvani mixarsuvit şeni ntsaşa extit! +why-donate = Muşeni iǩitxam? +add-information-button = Çkinapa eǩudvi +continue-speaking-button = Var, ntsaşa exti, osinapus nayoni +thanks-for-voice-toast = Xoma çkinapape-tkvani şeni ntsaşa extit +thanks-for-voice-toast-error = Xoma çkinapa-tkvani incğonet̆uşa xeta iyu +create-profile-button = Profili getzopxi +# IMAGE TAGS +img-alt-success-checkmark = ot̆işu onayişi ğara +# GUIDELINES PAGE +guidelines-header = Meşveluşi ǩuralepe +voice-collection = Xomaşi ǩoleǩsioniXomaşi ǩoleǩsioni +sentence-collection = Cumleşi ǩoleǩsiyoni +varying-pronunciations = Goimturu otkupeGoimturu otkupe +misreadings = Yanlişi oǩitxupeYanlişi oǩitxupe +background-noise = ǩap̌ulani nağaryaǩap̌ulani nağarya +background-voices = ǩap̌ulani xomape +volume = HacimiHacimi +reader-effects = Maǩitxeşi EfektepeMaǩitxeşi Efektepe +just-unsure = Vorsi var giçkinan-i?Vorsi var giçkinan-i? +example = Evuli +varying-pronunciations-example = Rota var içkinen. +varying-pronunciations-tip-1 = [ǩanadaşi İngilizurik "rota" zit̆a "rowt" ya do datkven.] +varying-pronunciations-tip-2 = Britişuri İngilizuris "cici" axenen +misreadings-explanation-2 = Dido gontaxileri xeta hantepe renan: +misreadings-explanation-4 = Zit̆a eçouris "s" eǩsuği oren. +misreadings-explanation-6 = Doloç̌aru manişa meǩvatute eçouri zit̆aşi çodina ...Doloç̌aru manişa meǩvatute eçouri zit̆aşi çodina ... +misreadings-explanation-7 = Ar zit̆a oǩitxu şeni jur-sum fara getsadu.Ar zit̆a oǩitxu şeni jur-sum fara getsadu. +misreadings-example-2 = ǩave eç̌opumu şeni gale gamaptaten. +misreadings-example-3 = ǩave eç̌opumu şeni gale gamavulurt +misreadings-example-4 = mtuti p̌ut̆uci manişa kogolaxtu.mtuti p̌ut̆uci manişa kogolaxtu. +misreadings-tip-1 = [“çku” iyasen] +misreadings-tip-2 = [Orijinali ç̌aras 'a' va ren][Orijinali ç̌aras 'a' va ren] +misreadings-tip-3 = [Var eluvelun kontenti] +background-noise-explanation = Doloç̌arit ǩat̆a zit̆a vognaten. Makina doguruşi algoritmapeşi çeşit̆oni moǩo-pilani nağaryape axerxas minonan. Nispeten mağali xomape vana uneneli moǩo-pilani muziği-ti, ç̌araşi tamami-muşişi oxotzonus var nağa-şkule ǩebuli dixenen. ç̌ara dogurus na memağanen xareri ǩlibepe reddi oxenu diç̌irasen. +background-noise-example-1 = Triyasişi divi dinazorepe. +background-noise-tip-2 = [ç̌araşi ar notzile var diguren][ç̌araşi ar notzile var diguren] +still-have-questions = Xolo ǩitxalape giğunan-i? +contact-common-voice = Common Voiceşi ekibi şkala ikontaktit +public-domain = ǩamuşi Monduni +citing-sentences = Cumlepeşen ar muti eç̌opinu +adding-sentences = Cumle Oǩatu +reviewing-sentences = Cumlepe Otsadu +citing-sentences-subheader-websites = Web sitepe +citing-sentences-subheader-academic-reference = Akademiǩuri referansi +citing-sentences-subheader-offline-sources = Ofline Cireǩepe citation = .label = Eşaç̌opu +self-citation = Muşebura Eşaç̌opu +adding-sentences-subheader-length = Gundzenoba +adding-sentences-subheader-length-explanation = cumle 15-şen mtsika zit̆aşen geidgasen. +adding-sentences-subheader-spelling-punctuation = Oç̌aru do Ot̆imbu +adding-sentences-subheader-spelling-punctuation-explanation = Cumlepe tzori oç̌aru diç̌irs.Cumlepe tzori oç̌aru diç̌irs. +adding-sentences-subheader-speakable = Osinaponi +adding-sentences-subheader-numbers = ǩoretsxape +adding-sentences-subheader-abbreviations = Zit̆apeşi omǩulanupe do Umçane Boncapeşi Omǩulanupe +adding-sentences-subheader-punctuation = Ot̆imbu reviewing-sentences-explanation-1 = Cumle jini ǩriteri-ǩala oǩuvelams na "Ho" butonis gyobazgit. ## WRITE PAGE From bae4908ea88ce0d2e69e556b9f7b202d5b3d40e9 Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 14:42:37 +0000 Subject: [PATCH 50/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index eae7bdf6a42d..a3ccd1e2f592 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -692,7 +692,7 @@ license-mixed = Oǩont̆aleri data-download-singleword-title = Ar Zit̆a Noğire Boligina Kogeiğit review-terms = Ağani nena şeni iǩitxi terms-agree = Oǩovuvelut -terms-disagree = Var Ok'ovuvelut +terms-disagree = { "" } review-aborted = Eğmalu ip̌t̆ali dixenu. Doloç̌arupe-tkvani gejilu ginonan-i? review-submit-title = Tsadi do Moncğoni review-submit-msg = Doloç̌aritşeni ntsaşa extit! Hatzi klibepe tkvani tudendo otzedit do oncğonit. @@ -718,7 +718,7 @@ cv-license = Lisansi audio-format = Xomaşi Format̆i number-of-voices = Xomaşi ǩoretsxa splits = Boginape -email-to-download = Native Language +email-to-download = { "" } why-email = Amolva var it̆işu. confirm-size = Goan Konkanuri size-gigabyte = Didi Biritanya @@ -1104,7 +1104,7 @@ sc-rejected-none-found = Redi na ixenu cumlepe var idziru! ## STATS -sc-stats-title = İstatistiǩaİstatistiǩa +sc-stats-title = İstatistiǩa sc-stats-updating = İndğaluren... ## ADD @@ -1139,7 +1139,7 @@ sc-confirm-sentences-title = Ağani cumle getzurani ## LANGUAGE INFO -sc-lang-info-title-total = MteliMteli +sc-lang-info-title-total = Mteli sc-lang-info-title-personal = Şurineburi ## LOGIN @@ -1211,7 +1211,7 @@ voice-collection = Xomaşi ǩoleǩsioniXomaşi ǩoleǩsioni sentence-collection = Cumleşi ǩoleǩsiyoni varying-pronunciations = Goimturu otkupeGoimturu otkupe misreadings = Yanlişi oǩitxupeYanlişi oǩitxupe -background-noise = ǩap̌ulani nağaryaǩap̌ulani nağarya +background-noise = ǩap̌ulani nağarya background-voices = ǩap̌ulani xomape volume = HacimiHacimi reader-effects = Maǩitxeşi EfektepeMaǩitxeşi Efektepe From 1cd4496dd1f85d938a7f11e1cd616d30fcbb91ee Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 14:53:09 +0000 Subject: [PATCH 51/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index a3ccd1e2f592..d2496993290e 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -1085,7 +1085,7 @@ sc-howto-findpd-subtitle = Hantepe (hani) internet̆is gorit ## MY SENTENCES -sc-my-title = Cumlepe-çkimiCumlepe-çkimi +sc-my-title = Cumlepe-çkimi sc-my-loading = Cumlepe tkvani eiğmalinen... sc-my-no-sentences = Aina cumle var idziru! # Variables: From c99146216f5267059ee6e8cce029e77b14b7c591 Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 15:13:08 +0000 Subject: [PATCH 52/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index d2496993290e..00a94d122d25 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -1162,7 +1162,7 @@ sc-personal-not-added = Daha aina nena var eǩudvit sc-criteria-modal = ⓘ Getsaduşi Kriterepe sc-criteria-title = Getsaduşi Kriterepe sc-criteria-make-sure = Cumlepeşi tudeni kriterepes na eluvelun vorsi ognit. -sc-criteria-item-1 = Cumlepe tzori oç̌aru diç̌irs.Cumlepe tzori oç̌aru diç̌irs. +sc-criteria-item-1 = Cumlepe tzori oç̌aru diç̌irs. sc-criteria-item-2 = Cumle grameruri tzori ort̆asen.Cumle grameruri tzori ort̆asen. sc-criteria-item-3 = Cumlepe osinaponi ort̆asen.Cumlepe osinaponi ort̆asen. @@ -1226,13 +1226,13 @@ misreadings-explanation-6 = Doloç̌aru manişa meǩvatute eçouri zit̆aşi ço misreadings-explanation-7 = Ar zit̆a oǩitxu şeni jur-sum fara getsadu.Ar zit̆a oǩitxu şeni jur-sum fara getsadu. misreadings-example-2 = ǩave eç̌opumu şeni gale gamaptaten. misreadings-example-3 = ǩave eç̌opumu şeni gale gamavulurt -misreadings-example-4 = mtuti p̌ut̆uci manişa kogolaxtu.mtuti p̌ut̆uci manişa kogolaxtu. +misreadings-example-4 = mtuti p̌ut̆uci manişa kogolaxtu. misreadings-tip-1 = [“çku” iyasen] -misreadings-tip-2 = [Orijinali ç̌aras 'a' va ren][Orijinali ç̌aras 'a' va ren] +misreadings-tip-2 = [Orijinali ç̌aras 'a' va ren] misreadings-tip-3 = [Var eluvelun kontenti] background-noise-explanation = Doloç̌arit ǩat̆a zit̆a vognaten. Makina doguruşi algoritmapeşi çeşit̆oni moǩo-pilani nağaryape axerxas minonan. Nispeten mağali xomape vana uneneli moǩo-pilani muziği-ti, ç̌araşi tamami-muşişi oxotzonus var nağa-şkule ǩebuli dixenen. ç̌ara dogurus na memağanen xareri ǩlibepe reddi oxenu diç̌irasen. background-noise-example-1 = Triyasişi divi dinazorepe. -background-noise-tip-2 = [ç̌araşi ar notzile var diguren][ç̌araşi ar notzile var diguren] +background-noise-tip-2 = [ç̌araşi ar notzile var diguren] still-have-questions = Xolo ǩitxalape giğunan-i? contact-common-voice = Common Voiceşi ekibi şkala ikontaktit public-domain = ǩamuşi Monduni @@ -1248,7 +1248,7 @@ self-citation = Muşebura Eşaç̌opu adding-sentences-subheader-length = Gundzenoba adding-sentences-subheader-length-explanation = cumle 15-şen mtsika zit̆aşen geidgasen. adding-sentences-subheader-spelling-punctuation = Oç̌aru do Ot̆imbu -adding-sentences-subheader-spelling-punctuation-explanation = Cumlepe tzori oç̌aru diç̌irs.Cumlepe tzori oç̌aru diç̌irs. +adding-sentences-subheader-spelling-punctuation-explanation = Cumlepe tzori oç̌aru diç̌irs. adding-sentences-subheader-speakable = Osinaponi adding-sentences-subheader-numbers = ǩoretsxape adding-sentences-subheader-abbreviations = Zit̆apeşi omǩulanupe do Umçane Boncapeşi Omǩulanupe From 52df28acde166b93bfdb06447a70b937f5113c3a Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 15:22:34 +0000 Subject: [PATCH 53/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 42 ++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index 00a94d122d25..d6852d56d93a 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -657,17 +657,17 @@ about-playbook-how-project-governance-content-7 = Muç̌o na mok glossary = Nenapuna localization = Lokaloba -localization-explanation = Hantepe (hani) internet̆is gorit +localization-explanation = { "" } sentence-collection = Cumleşi ǩoleǩsiyoni -sentence-collection-explanation = Eğmaleri ǩlibepe -hours-recorded-explanation = Tzuraneri saatişi ǩoroba -hours-validated-explanation = Nenape çkuni: +sentence-collection-explanation = { "" } +hours-recorded-explanation = { "" } +hours-validated-explanation = { "" } sst = Osinapu ç̌aras meonktu (STT) de-identified = Oçinoba-muşi dimpulu/ var içinapu ## Error pages -error-title-503 = Oç̌aru do Ot̆imbu +error-title-503 = { "" } error-code = Xeta { $code } ## Data @@ -676,9 +676,9 @@ data-download-button = Common Voiceşi Datape kogeiğit data-download-yes = Ho data-download-deny = Var data-download-license = Lisans: CC-0 -data-download-modal = Mixaresirit +data-download-modal = { "" } data-subtitle = Oxori -data-explanatory-text = Reddi oxenu +data-explanatory-text = { "" } data-get-started = Osinapu Oçinobas Kogyoç̌ǩit data-other-title = Majura xomaşi datamarç̌ape data-other-goto = { $isname }'şe idi @@ -690,7 +690,7 @@ dataset-date = Tarixi license = Lisansi: { $license } license-mixed = Oǩont̆aleri data-download-singleword-title = Ar Zit̆a Noğire Boligina Kogeiğit -review-terms = Ağani nena şeni iǩitxi +review-terms = { "" } terms-agree = Oǩovuvelut terms-disagree = { "" } review-aborted = Eğmalu ip̌t̆ali dixenu. Doloç̌arupe-tkvani gejilu ginonan-i? @@ -705,11 +705,11 @@ review-delete-recordings = Doloç̌arape-çkimi gejilit (cejirit) ## Datasets Page datasets-heading = Datamarç̌a -datasets-headline = Ar xesap̌i kogetzopxit +datasets-headline = { "" } language = Nena download-dataset-header = datamarç̌a Kogeiğit -download-delta-explainer = Bretonuri -download-dataset-tag = İstatistiği +download-delta-explainer = { "" } +download-dataset-tag = { "" } # File size in gigabytes size = Boyut̆i validated-hr-total = Tzuraneri saatişi ǩoroba @@ -720,7 +720,7 @@ number-of-voices = Xomaşi ǩoretsxa splits = Boginape email-to-download = { "" } why-email = Amolva var it̆işu. -confirm-size = Goan Konkanuri +confirm-size = { "" } size-gigabyte = Didi Biritanya size-megabyte = MB confirm-no-identify = Common Voiceşi datamarç̌as na ren msinapupeşi noçinepe odziru şeni var inç̌itatenǩebuli atna @@ -728,19 +728,19 @@ download-language = { $language } doya geiğit validated-hours = İtzuranu Saatepe recorded-hours = Doliç̌aru Saatepe whats-inside = Common Voice datamarç̌aşi doloxe mupe orenan? -want-dataset-update = Ndğaluri Hedefi +want-dataset-update = { "" } subscribe = Abone iyi get-started-speech = Osinapu Oçinus Kogyoç̌ǩit other-datasets = Majura Xomaşi Datamarç̌ape feedback-q = Uǩaçxeni gnapa giğunan-i? resource-nemo-info = { "" } -resource-deepspeech-info = E posta abonobape okti +resource-deepspeech-info = { "" } resource-coqui-info = Galiçuri community-playbook = Partiyaşi becit̆i kitabi data-other-ted-name = TED-LIUM ǩoroba -data-other-voxforge-description = Lapori Oncğoni -data-other-tatoeba-description = Nenaşi talebi t̆işineri dolinç̌aru, ntsaşa exti. -your-feedback = Abone iyi +data-other-voxforge-description = { "" } +data-other-tatoeba-description = { "" } +your-feedback = { "" } go-discourse = Zit̆aşe İdi missing-language = Nena-tkvani datamarç̌as var dziremt-i? Nena ogoru şeni Nenapeşi butkaşa idit. go-languages-page = Nena but̆ǩaşe idi @@ -1055,9 +1055,9 @@ sc-footer-discourse = Tkvala sc-footer-report-bugs = Xet̆ape Milaporit sc-footer-translate = Ham butka golakti sc-footer-report-copyright = Telifişi xarǩi milaporit -sc-footer-privacy = t̆obaşobat̆obaşoba -sc-footer-terms = Şart̆epeŞart̆epe -sc-footer-cookies = ǩaǩapeǩaǩape +sc-footer-privacy = t̆obaşoba +sc-footer-terms = Şart̆epe +sc-footer-cookies = ǩaǩape sc-login-signup-button = Amaxti/ Doliç̌ari sc-logout-button = Gamaxti @@ -1097,7 +1097,7 @@ sc-my-err-failed-delete = Cumlepe var geijilu... Ar daha kogeitsadit! ## REJECTED -sc-rejected-title = Gokteri CumlepeGokteri Cumlepe +sc-rejected-title = Gokteri Cumlepe sc-rejected-loading = Redi na ixenu cumlepe eiğmalinen... sc-rejected-err-fetching = Cumlepe tkvani moiğmalet̆uşa xeta gamaxtu. Ar daha kogeitsadit. sc-rejected-none-found = Redi na ixenu cumlepe var idziru! From efb6ce9024a5faa9561ffc1172493ea8f489519c Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 15:33:29 +0000 Subject: [PATCH 54/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index d6852d56d93a..330ec7608f19 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -1127,14 +1127,14 @@ sc-submit-button = sc-add-lang-could-not-add = Nena var eǩimtsxu sc-add-lang-sec-label = Meşvelu na ginonan nena eǩumtsxvit -sc-add-lang-sec-button = Nena EkumtsxviNena Ekumtsxvi +sc-add-lang-sec-button = Nena Ekumtsxvi sc-add-err-unexpected = Serverişe var nişonen cuğap̌i goiktinu sc-add-err-submission = Oncğonu xeta ## ADD SENTENCES CONFIRMATION sc-confirm-are-you-sure = - .message = Cumlepe var incğonu, xolo gamaxtaten-i?Cumlepe var incğonu, xolo gamaxtaten-i? + .message = Cumlepe var incğonu, xolo gamaxtaten-i? sc-confirm-sentences-title = Ağani cumle getzurani ## LANGUAGE INFO @@ -1163,23 +1163,23 @@ sc-criteria-modal = ⓘ Getsaduşi Kriterepe sc-criteria-title = Getsaduşi Kriterepe sc-criteria-make-sure = Cumlepeşi tudeni kriterepes na eluvelun vorsi ognit. sc-criteria-item-1 = Cumlepe tzori oç̌aru diç̌irs. -sc-criteria-item-2 = Cumle grameruri tzori ort̆asen.Cumle grameruri tzori ort̆asen. -sc-criteria-item-3 = Cumlepe osinaponi ort̆asen.Cumlepe osinaponi ort̆asen. +sc-criteria-item-2 = Cumle grameruri tzori ort̆asen +sc-criteria-item-3 = Cumlepe osinaponi ort̆asen. ## REVIEW sc-review-title = Cumlepes tsadiCumlepes tsadi sc-review-loading = Cumlepe eiğmalinen... sc-review-form-button-reject = Reddi oxenu -sc-review-form-button-skip = Moyoǩap̌iMoyoǩap̌i +sc-review-form-button-skip = Moyoǩap̌i sc-review-form-button-approve = Otzuranu sc-review-form-button-submit = .submitText = Elaxtimu doçodinit. -sc-review-link = MeotzǩediMeotzǩedi +sc-review-link = Meotzǩedi ## SETTINGS -sc-settings-title = GetzopxiGetzopxi +sc-settings-title = Getzopxi sc-validation-no-numbers = Cumleşi doloxe reǩami var ort̆asen sc-validation-no-symbols = Cumleşi doloxe semboli var ort̆asen sc-validation-no-abbreviations = Cumlepes domǩulape var ort̆asen @@ -1207,23 +1207,23 @@ create-profile-button = Profili getzopxi img-alt-success-checkmark = ot̆işu onayişi ğara # GUIDELINES PAGE guidelines-header = Meşveluşi ǩuralepe -voice-collection = Xomaşi ǩoleǩsioniXomaşi ǩoleǩsioni +voice-collection = Xomaşi ǩoleǩsioni sentence-collection = Cumleşi ǩoleǩsiyoni -varying-pronunciations = Goimturu otkupeGoimturu otkupe -misreadings = Yanlişi oǩitxupeYanlişi oǩitxupe +varying-pronunciations = Goimturu otkupe +misreadings = Yanlişi oǩitxupe background-noise = ǩap̌ulani nağarya background-voices = ǩap̌ulani xomape -volume = HacimiHacimi -reader-effects = Maǩitxeşi EfektepeMaǩitxeşi Efektepe -just-unsure = Vorsi var giçkinan-i?Vorsi var giçkinan-i? +volume = Hacimi +reader-effects = Maǩitxeşi Efektepe +just-unsure = Vorsi var giçkinan-i? example = Evuli varying-pronunciations-example = Rota var içkinen. -varying-pronunciations-tip-1 = [ǩanadaşi İngilizurik "rota" zit̆a "rowt" ya do datkven.] +varying-pronunciations-tip-1 = [ǩanadaşi İngilizurik "rota" zit̆a "rowt" ya do datkven. varying-pronunciations-tip-2 = Britişuri İngilizuris "cici" axenen misreadings-explanation-2 = Dido gontaxileri xeta hantepe renan: misreadings-explanation-4 = Zit̆a eçouris "s" eǩsuği oren. -misreadings-explanation-6 = Doloç̌aru manişa meǩvatute eçouri zit̆aşi çodina ...Doloç̌aru manişa meǩvatute eçouri zit̆aşi çodina ... -misreadings-explanation-7 = Ar zit̆a oǩitxu şeni jur-sum fara getsadu.Ar zit̆a oǩitxu şeni jur-sum fara getsadu. +misreadings-explanation-6 = Doloç̌aru manişa meǩvatute eçouri zit̆aşi çodina ... +misreadings-explanation-7 = Ar zit̆a oǩitxu şeni jur-sum fara getsadu. misreadings-example-2 = ǩave eç̌opumu şeni gale gamaptaten. misreadings-example-3 = ǩave eç̌opumu şeni gale gamavulurt misreadings-example-4 = mtuti p̌ut̆uci manişa kogolaxtu. From 8a2be0bd4fae28cbab147c82a83e2ba414604b4d Mon Sep 17 00:00:00 2001 From: bucaklisi Date: Sun, 21 Apr 2024 15:52:50 +0000 Subject: [PATCH 55/69] Pontoon: Update Laz (lzz) localization of Common Voice Co-authored-by: bucaklisi --- web/locales/lzz/messages.ftl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/locales/lzz/messages.ftl b/web/locales/lzz/messages.ftl index 330ec7608f19..b4c59657a5e8 100644 --- a/web/locales/lzz/messages.ftl +++ b/web/locales/lzz/messages.ftl @@ -850,7 +850,7 @@ record-submit-tooltip = { $actionType } xadziri iyasis oncğoni clips-uploaded = Eğmaleri ǩlibepe record-abort-title = Maarani doloç̌aru oçodinu ginon-i? record-abort-text = Hatzi kogamaxtit-na elaxtimu tkvani gondinateren. -record-abort-submit = K'ilibi mendancğoniǩilibi mendancğoni +record-abort-submit = K'ilibi mendancğoni record-abort-continue = Doloç̌aru doçodini record-abort-delete = ǩlibepeşen Gamaxti § Gejili (Cejiri) listen-instruction = { $actionType }> cumle tzori iǩitxesi? @@ -972,7 +972,7 @@ download-selected = Goşitsxunu download-start = Profilişi datape kogeiği download-request = Doloç̌aru gori download-requests = Atxenuri doloç̌arerepe geğmaluşi gorapa -download-request-button = KogeiğiKogeiği +download-request-button = Kogeiği download-request-archive-single = Doloxemuşi tudenepe na oren ar ZIP dosya download-request-modal-title = Linkepe kogeiği download-request-modal-description = ZIP dosyape na geiğaten linkepe hak oren. @@ -1050,7 +1050,7 @@ sc-header-review = Meotzǩedi sc-header-rejected = Gokteri Cumlepe sc-header-my = Cumlepe-çkimi sc-header-statistics = İstatistiǩa -sc-header-profile = ProfiliProfili +sc-header-profile = Profili sc-footer-discourse = Tkvala sc-footer-report-bugs = Xet̆ape Milaporit sc-footer-translate = Ham butka golakti From 46301b29316dbc4f2a5cc81d12c68c9378aab2bc Mon Sep 17 00:00:00 2001 From: Vel Date: Mon, 22 Apr 2024 04:52:21 +0000 Subject: [PATCH 56/69] Pontoon: Update Goan Konkani (gom) localization of Common Voice Co-authored-by: Vel --- web/locales/gom/cross-locale.ftl | 1 + web/locales/gom/messages.ftl | 56 ++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/web/locales/gom/cross-locale.ftl b/web/locales/gom/cross-locale.ftl index 9001d5cd6de4..d5610809bc9b 100644 --- a/web/locales/gom/cross-locale.ftl +++ b/web/locales/gom/cross-locale.ftl @@ -1,2 +1,3 @@ ## Languages +get-involved-submit = Dhad diff --git a/web/locales/gom/messages.ftl b/web/locales/gom/messages.ftl index bd37072ece17..07c9953f67cb 100644 --- a/web/locales/gom/messages.ftl +++ b/web/locales/gom/messages.ftl @@ -2,6 +2,7 @@ yes-receive-emails = Hoi, maka emails send kôr. Maka khup khosi astili Common Voice Project'an bag govpak. stayintouch = Voice technology'cher ami ek community karma Mozilla'an. Ami chad khosi tumka update dovarpak, novo data duvpak and aikpak tumi koso ho data use karta toh. +return-to-cv = Porot voch Common Voice'acher email-input = .label = Email @@ -54,6 +55,40 @@ email-input = ## ABOUT US +## How does it work section + + +## Community Playbook Content +## What is a language + + +## How do I add a language + + +## How does localization work + + +## How to add sentences + + +## How to record quality + + +## How to grow language + + +## How to validate + + +## How to access dataset + + +## How are decisions made + + +## How is Common Voice funded + + ## Glossary @@ -75,12 +110,18 @@ email-input = ## Request Language Modal +## Request Language Pages + + ## Languages Overview ## Contribution +## Contribution Nav Items + + ## Reporting @@ -131,6 +172,9 @@ email-input = ## HOME +## GENERAL + + ## HOW-TO @@ -172,3 +216,15 @@ email-input = # [/SentenceCollector] + +## WRITE PAGE + + +## REVIEW PAGE + + +## BULK SUBMISSION + + +## Donate banner + From f22c6e3a7fb60d918405200cbaccc86d82860526 Mon Sep 17 00:00:00 2001 From: Vel Date: Mon, 22 Apr 2024 04:54:37 +0000 Subject: [PATCH 57/69] Pontoon: Update Goan Konkani (gom) localization of Common Voice Co-authored-by: Vel --- web/locales/gom/messages.ftl | 1 + 1 file changed, 1 insertion(+) diff --git a/web/locales/gom/messages.ftl b/web/locales/gom/messages.ftl index 07c9953f67cb..5a188076d516 100644 --- a/web/locales/gom/messages.ftl +++ b/web/locales/gom/messages.ftl @@ -5,6 +5,7 @@ stayintouch = Voice technology'cher ami ek community karma Mozilla'an. Ami chad return-to-cv = Porot voch Common Voice'acher email-input = .label = Email +submit-form-action = Submit # Don't rename the following section, its contents are auto-inserted based on the name (see scripts/pontoon-languages-to-ftl.js) # [Languages] From c566b03d4c4aef7085928ec2a3b0dd535f1c2c7b Mon Sep 17 00:00:00 2001 From: Vel Date: Mon, 22 Apr 2024 05:04:00 +0000 Subject: [PATCH 58/69] Pontoon: Update Goan Konkani (gom) localization of Common Voice Co-authored-by: Vel --- web/locales/gom/messages.ftl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/locales/gom/messages.ftl b/web/locales/gom/messages.ftl index 5a188076d516..e34e52a5439f 100644 --- a/web/locales/gom/messages.ftl +++ b/web/locales/gom/messages.ftl @@ -19,9 +19,12 @@ submit-form-action = Submit ## Layout +speak = Uloi +speak-now = Ata uloi ## Home Page +help-us-explain = Play kor, kan divun aik, ani sang: Temin asa toshech uloile? ## Account Benefits From 9627850e985dec1c4b2e5d9a651e3616fbabfc01 Mon Sep 17 00:00:00 2001 From: Alvyn Abranches Date: Mon, 22 Apr 2024 08:12:37 +0000 Subject: [PATCH 59/69] Pontoon: Update Goan Konkani (gom) localization of Common Voice Co-authored-by: Alvyn Abranches Co-authored-by: Vel --- web/locales/gom/messages.ftl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/locales/gom/messages.ftl b/web/locales/gom/messages.ftl index e34e52a5439f..972bdaa909d7 100644 --- a/web/locales/gom/messages.ftl +++ b/web/locales/gom/messages.ftl @@ -25,6 +25,8 @@ speak-now = Ata uloi ## Home Page help-us-explain = Play kor, kan divun aik, ani sang: Temin asa toshech uloile? +speak-subtitle = Tuje avaaz dan kor +listen-subtitle = Sarkeponn topasunk amche moddot kor ## Account Benefits From 14f3cd363e2aba467ea6390889fc76b4eb9384b5 Mon Sep 17 00:00:00 2001 From: Vel Date: Mon, 22 Apr 2024 08:29:50 +0000 Subject: [PATCH 60/69] Pontoon: Update Goan Konkani (gom) localization of Common Voice Co-authored-by: Vel --- web/locales/gom/messages.ftl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/locales/gom/messages.ftl b/web/locales/gom/messages.ftl index 972bdaa909d7..426530333163 100644 --- a/web/locales/gom/messages.ftl +++ b/web/locales/gom/messages.ftl @@ -27,6 +27,8 @@ speak-now = Ata uloi help-us-explain = Play kor, kan divun aik, ani sang: Temin asa toshech uloile? speak-subtitle = Tuje avaaz dan kor listen-subtitle = Sarkeponn topasunk amche moddot kor +todays-progress = Aiche Pravas +ready-to-record = Tuje avaaz divpak toiar asa? ## Account Benefits @@ -42,6 +44,7 @@ listen-subtitle = Sarkeponn topasunk amche moddot kor ## Speak Shortcuts +shortcut-submit-label = Clips submit kor ## ProjectStatus @@ -63,6 +66,7 @@ listen-subtitle = Sarkeponn topasunk amche moddot kor ## How does it work section +about-listen = Aik ## Community Playbook Content ## What is a language From c97fd0b0ec257260424ab1133dfe2fc93a19d56a Mon Sep 17 00:00:00 2001 From: Vel Date: Mon, 22 Apr 2024 08:33:14 +0000 Subject: [PATCH 61/69] Pontoon: Update Goan Konkani (gom) localization of Common Voice Co-authored-by: Alvyn Abranches Co-authored-by: Vel --- web/locales/gom/messages.ftl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/web/locales/gom/messages.ftl b/web/locales/gom/messages.ftl index 426530333163..81ee73ff177e 100644 --- a/web/locales/gom/messages.ftl +++ b/web/locales/gom/messages.ftl @@ -67,6 +67,7 @@ shortcut-submit-label = Clips submit kor ## How does it work section about-listen = Aik +about-listen-text = Users eka-mekache audio clips`ache sarkeponn topassun poitat ki je boroinn dille vakio asa, toshech vachla kai na. ## Community Playbook Content ## What is a language @@ -125,6 +126,10 @@ about-listen = Aik ## Languages Overview +language-section-in-progress = Pravas'an Asa +language-meter-in-progress = Pravas +language-speakers = Ulovpi +language-validation-progress = Topasniche Pravas ## Contribution From 8752a3ba67c3730daa3a49b7c064b991fa17fde7 Mon Sep 17 00:00:00 2001 From: Vel Date: Mon, 22 Apr 2024 08:42:48 +0000 Subject: [PATCH 62/69] Pontoon: Update Goan Konkani (gom) localization of Common Voice Co-authored-by: Alvyn Abranches Co-authored-by: Vel --- web/locales/gom/messages.ftl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/web/locales/gom/messages.ftl b/web/locales/gom/messages.ftl index 81ee73ff177e..01c67eb80195 100644 --- a/web/locales/gom/messages.ftl +++ b/web/locales/gom/messages.ftl @@ -133,6 +133,15 @@ language-validation-progress = Topasniche Pravas ## Contribution +action-tap = Damp +listen = Aik +write = Boroi +skip = Sod +record-error-too-long = Recording chod vhoddlem zale. +record-error-too-quiet = Recording samki ogi asa. +record-instruction = { $actionType } ani magir sentence mottean vach +record-stop-instruction = zale zaliar { $actionType } +record-again-instruction = Shabbas! Dusre clip record kor ## Contribution Nav Items From 0db43b33d14df92e510d7f7d3df5eb2cb73eb446 Mon Sep 17 00:00:00 2001 From: Alvyn Abranches Date: Mon, 22 Apr 2024 08:53:01 +0000 Subject: [PATCH 63/69] Pontoon: Update Goan Konkani (gom) localization of Common Voice Co-authored-by: Alvyn Abranches Co-authored-by: Vel --- web/locales/gom/messages.ftl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/web/locales/gom/messages.ftl b/web/locales/gom/messages.ftl index 01c67eb80195..d2478bee45e5 100644 --- a/web/locales/gom/messages.ftl +++ b/web/locales/gom/messages.ftl @@ -142,6 +142,15 @@ record-error-too-quiet = Recording samki ogi asa. record-instruction = { $actionType } ani magir sentence mottean vach record-stop-instruction = zale zaliar { $actionType } record-again-instruction = Shabbas! Dusre clip record kor +record-again-instruction2 = Borem asa, ani ek record kor +review-instruction = Check kor & goroz asa zaliar portun record kor +clips-uploaded = Clips Upload Zale +record-abort-title = Recording purai kor poilem? +record-abort-text = Ata sodun geliar tujhe clips pusun voitele +record-abort-continue = Recording purai kor +record-abort-delete = Sod ani clips delete kor +listen-instruction = { $actionType }. Ulovpin asa toshech uloile? +listen-again-instruction = Bore kam kele! Toiar zavun porot aik ## Contribution Nav Items From db903a478ac094b0ef47334a080199b57380374d Mon Sep 17 00:00:00 2001 From: Alvyn Abranches Date: Mon, 22 Apr 2024 09:03:49 +0000 Subject: [PATCH 64/69] Pontoon: Update Goan Konkani (gom) localization of Common Voice Co-authored-by: Alvyn Abranches Co-authored-by: Vel --- web/locales/gom/messages.ftl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/web/locales/gom/messages.ftl b/web/locales/gom/messages.ftl index d2478bee45e5..b73d90ee1cce 100644 --- a/web/locales/gom/messages.ftl +++ b/web/locales/gom/messages.ftl @@ -6,6 +6,7 @@ return-to-cv = Porot voch Common Voice'acher email-input = .label = Email submit-form-action = Submit +email-opt-in-info = Hoi, Mhaka asle emails dhad jitun Goal Reminders, Progress Updates anik Common Voice`acher novi novi khobryo-patra asta. # Don't rename the following section, its contents are auto-inserted based on the name (see scripts/pontoon-languages-to-ftl.js) # [Languages] @@ -151,6 +152,12 @@ record-abort-continue = Recording purai kor record-abort-delete = Sod ani clips delete kor listen-instruction = { $actionType }. Ulovpin asa toshech uloile? listen-again-instruction = Bore kam kele! Toiar zavun porot aik +listen-3rd-time-instruction = 2 zale, anik korun voch! +listen-last-time-instruction = Last ani ek! +listen-empty-state = Clips sople astole - page refresh kor, na zaliar magir try kor. +listen-abort-title = Clips'achi topasni korun zali? +listen-abort-confirm = Puro zale +record-button-label = Tuzo avaz di ## Contribution Nav Items @@ -166,6 +173,7 @@ listen-again-instruction = Bore kam kele! Toiar zavun porot ## Custom Goals +both-speak-and-listen-long = Donui (Uloi ani Aikui) ## Profile Delete From 62f699cfa0c02e80cce06ecb2139c6934c504c04 Mon Sep 17 00:00:00 2001 From: Dmitrij Feller <119537889+moz-dfeller@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:08:00 +0200 Subject: [PATCH 65/69] OI-3057: check if variant is matching the locale (#4450) * feat: refactor variant into it's own repository * feat: add check whether the sentence locale matches variant locale * feat: remove locale id from the add sentence endpoint * chore: remove trailing white space --- .../sentences/handler/add-sentence-handler.ts | 32 ++-- .../validation/pending-sentences-requests.ts | 6 +- .../sentences/repository/locale-repository.ts | 53 ++++++ .../repository/sentences-repository.ts | 26 --- .../repository/variant-repository.ts | 28 ++++ .../add-sentence-command-handler.ts | 67 +++++++- .../command/add-sentence-command.ts | 1 - server/src/core/types/locale.ts | 10 ++ server/src/core/types/variant.ts | 6 + .../add-sentence-command-handler.test.ts | 157 ++++++++++++++++-- 10 files changed, 322 insertions(+), 64 deletions(-) create mode 100644 server/src/application/sentences/repository/locale-repository.ts create mode 100644 server/src/application/sentences/repository/variant-repository.ts create mode 100644 server/src/core/types/locale.ts create mode 100644 server/src/core/types/variant.ts diff --git a/server/src/api/sentences/handler/add-sentence-handler.ts b/server/src/api/sentences/handler/add-sentence-handler.ts index bb54d498a345..0ee609efe38e 100644 --- a/server/src/api/sentences/handler/add-sentence-handler.ts +++ b/server/src/api/sentences/handler/add-sentence-handler.ts @@ -1,6 +1,5 @@ import { Request, Response } from 'express' import * as TE from 'fp-ts/TaskEither' -import * as T from 'fp-ts/Task' import * as O from 'fp-ts/Option' import * as I from 'fp-ts/Identity' import { pipe } from 'fp-ts/function' @@ -15,17 +14,17 @@ import { StatusCodes } from 'http-status-codes' import { validateSentence } from '../../../core/sentences' import { findDomainIdByNameInDb, - findVariantIdByTokenInDb, saveSentenceInDb, } from '../../../application/sentences/repository/sentences-repository' +import { findVariantByTagInDb } from '../../../application/sentences/repository/variant-repository' +import { findLocaleByNameInDb } from '../../../application/sentences/repository/locale-repository' export default async (req: Request, res: Response) => { - const { sentence, localeId, localeName, source, domains, variant } = req.body + const { sentence, localeName, source, domains, variant } = req.body const command: AddSentenceCommand = { clientId: req.client_id, sentence: sentence, - localeId: localeId, localeName: localeName, source: source, domains: domains, @@ -36,11 +35,12 @@ export default async (req: Request, res: Response) => { AddSentenceCommandHandler, I.ap(validateSentence), I.ap(findDomainIdByNameInDb), - I.ap(findVariantIdByTokenInDb), + I.ap(findVariantByTagInDb), + I.ap(findLocaleByNameInDb), I.ap(saveSentenceInDb) ) - return pipe( + const result = await pipe( command, cmdHandler, TE.mapLeft(createPresentableError), @@ -48,18 +48,20 @@ export default async (req: Request, res: Response) => { err => { switch (err.kind) { case SentenceRepositoryErrorKind: { - return T.of(res.status(StatusCodes.INTERNAL_SERVER_ERROR).json(err)) + res.status(StatusCodes.INTERNAL_SERVER_ERROR) + break + } + case SentenceValidationErrorKind: { + res.status(StatusCodes.BAD_REQUEST) + break } - case SentenceValidationErrorKind: - return T.of(res.status(StatusCodes.BAD_REQUEST).json(err)) } + + return err }, - () => - T.of( - res.json({ - message: 'Sentence added successfully', - }) - ) + () => ({ message: 'Sentence added successfully' }) ) )() + + return res.json(result) } diff --git a/server/src/api/sentences/validation/pending-sentences-requests.ts b/server/src/api/sentences/validation/pending-sentences-requests.ts index 0a31bc28fecb..29ebbc553708 100644 --- a/server/src/api/sentences/validation/pending-sentences-requests.ts +++ b/server/src/api/sentences/validation/pending-sentences-requests.ts @@ -3,7 +3,7 @@ import { sentenceDomains } from 'common' export const AddSentenceRequest: AllowedSchema = { type: 'object', - required: ['sentence', 'source', 'localeId', 'localeName', 'domains'], + required: ['sentence', 'source', 'localeName', 'domains'], properties: { sentence: { type: 'string', @@ -11,10 +11,6 @@ export const AddSentenceRequest: AllowedSchema = { source: { type: 'string', }, - localeId: { - type: 'integer', - minimum: 1, - }, localeName: { type: 'string', }, diff --git a/server/src/application/sentences/repository/locale-repository.ts b/server/src/application/sentences/repository/locale-repository.ts new file mode 100644 index 000000000000..ad3d28ea1671 --- /dev/null +++ b/server/src/application/sentences/repository/locale-repository.ts @@ -0,0 +1,53 @@ +import { option as O, taskEither as TE } from 'fp-ts' +import { ApplicationError } from '../../types/error' +import { queryDb } from '../../../infrastructure/db/mysql' +import { pipe } from 'fp-ts/lib/function' +import { createDatabaseError } from '../../helper/error-helper' +import { Locale, TextDirection } from '../../../core/types/locale' + +export type FindLocaleByName = ( + localeName: string +) => TE.TaskEither> + +type LocaleRow = { + id: number + name: string + targetSentenceCount: number + isContributable: number + isTranslated: number + textDirection: TextDirection +} + +export const findLocaleByNameInDb: FindLocaleByName = (localeName: string) => + pipe( + [localeName], + queryDb( + ` SELECT + id, + name, + target_sentence_count as targetSentenceCount, + is_contributable as isContributable, + is_translated as isTranslated, + text_direction as textDirection + FROM locales + WHERE name = ? + ` + ), + TE.mapLeft((err: Error) => + createDatabaseError( + `Error retrieving locale by name "${localeName}"`, + err + ) + ), + TE.map(([[result]]: Array>) => { + return pipe( + result, + O.fromNullable, + O.map(result => ({ + ...result, + isContributable: result.isContributable === 1, + isTranslated: result.isTranslated === 1, + })) + ) + }) + ) diff --git a/server/src/application/sentences/repository/sentences-repository.ts b/server/src/application/sentences/repository/sentences-repository.ts index 240de8186540..404ac4ab3040 100644 --- a/server/src/application/sentences/repository/sentences-repository.ts +++ b/server/src/application/sentences/repository/sentences-repository.ts @@ -22,9 +22,6 @@ export type SaveSentence = export type FindDomainIdByName = (domainName: string) => TE.TaskEither> -export type FindVariantIdByToken = - (variantToken: string) => TE.TaskEither> - const insertSentenceTransaction = async ( db: Mysql, sentence: SentenceSubmission @@ -273,31 +270,8 @@ const findDomainIdByName = ) ) -const findVariantIdByToken = - (db: Mysql) => - (variantToken: string): TE.TaskEither> => - TE.tryCatch( - async () => { - const [[row]] = await db.query( - ` - SELECT id FROM variants WHERE variant_token = ? - `, - [variantToken] - ) - return row ? O.some(row.id) : O.none - }, - (err: Error) => - createSentenceRepositoryError( - `Error retrieving variant id for token "${variantToken}"`, - err - ) - ) - export const saveSentenceInDb: SaveSentence = saveSentence(db) export const insertBulkSentencesIntoDb = insertBulkSentences(db) export const insertSentenceVoteIntoDb = insertSentenceVote(db) export const findSentencesForReviewInDb = findSentencesForReview(db) - export const findDomainIdByNameInDb: FindDomainIdByName = findDomainIdByName(db) -export const findVariantIdByTokenInDb: FindVariantIdByToken = - findVariantIdByToken(db) diff --git a/server/src/application/sentences/repository/variant-repository.ts b/server/src/application/sentences/repository/variant-repository.ts new file mode 100644 index 000000000000..039a10207ce9 --- /dev/null +++ b/server/src/application/sentences/repository/variant-repository.ts @@ -0,0 +1,28 @@ +import { option as O, taskEither as TE } from 'fp-ts' +import { ApplicationError } from '../../types/error' +import { Variant } from '../../../core/types/variant' +import { queryDb } from '../../../infrastructure/db/mysql' +import { pipe } from 'fp-ts/lib/function' +import { createDatabaseError } from '../../helper/error-helper' + +export type FindVariantByTag = ( + variantName: string +) => TE.TaskEither> + +export const findVariantByTagInDb: FindVariantByTag = (variantName: string) => + pipe( + [variantName], + queryDb( + ` SELECT v.id, l.name as locale, variant_name as name, variant_token as tag FROM variants v + INNER JOIN locales l ON (l.id = v.locale_id) + WHERE variant_token = ? + ` + ), + TE.mapLeft((err: Error) => + createDatabaseError( + `Error retrieving variant by name "${variantName}"`, + err + ) + ), + TE.map(([[result]]: Array>) => O.fromNullable(result)) + ) diff --git a/server/src/application/sentences/use-case/command-handler/add-sentence-command-handler.ts b/server/src/application/sentences/use-case/command-handler/add-sentence-command-handler.ts index 2ebcb370ec6f..ae439530491e 100644 --- a/server/src/application/sentences/use-case/command-handler/add-sentence-command-handler.ts +++ b/server/src/application/sentences/use-case/command-handler/add-sentence-command-handler.ts @@ -4,14 +4,19 @@ import { pipe } from 'fp-ts/lib/function' import { ValidateSentence, ValidatedSentence } from '../../../../core/sentences' import { FindDomainIdByName, - FindVariantIdByToken, SaveSentence, } from '../../repository/sentences-repository' import { AddSentenceCommand } from './command/add-sentence-command' import { either as E, taskEither as TE } from 'fp-ts' import { ApplicationError } from '../../../types/error' -import { createSentenceValidationError } from '../../../helper/error-helper' +import { + createSentenceValidationError, + createValidationError, +} from '../../../helper/error-helper' import { SentenceSubmission } from '../../../types/sentence-submission' +import { FindVariantByTag } from '../../repository/variant-repository' +import { Variant } from '../../../../core/types/variant' +import { FindLocaleByName } from '../../repository/locale-repository' const toValidatedSentence = (validateSentence: ValidateSentence) => @@ -41,10 +46,16 @@ const toDomainIds = ) } +const doesLocaleMatchVariant = + (locale: string) => + (variant: Variant): boolean => + variant.locale === locale + export const AddSentenceCommandHandler = (validateSentence: ValidateSentence) => (findDomainIdByName: FindDomainIdByName) => - (findVariantIdByToken: FindVariantIdByToken) => + (findVariantByToken: FindVariantByTag) => + (findLocaleByName: FindLocaleByName) => (saveSentence: SaveSentence) => (command: AddSentenceCommand): TE.TaskEither => pipe( @@ -60,18 +71,60 @@ export const AddSentenceCommandHandler = TE.bind('domainIds', () => toDomainIds(findDomainIdByName)(command.domains) ), - TE.bind('variantId', () => + TE.bind('variant', () => pipe( command.variant, - O.match(() => TE.of(O.none), findVariantIdByToken) + O.match( + () => TE.right(O.none), + variant => findVariantByToken(variant) + ) + ) + ), + TE.bind('doesLocaleMatchVariant', ({ variant }) => + pipe( + variant, + O.map(doesLocaleMatchVariant(command.localeName)), + O.match( + () => TE.right(true), + isMatching => + isMatching + ? TE.right(true) + : TE.left( + createValidationError('Locale does not match variant') + ) + ) + ) + ), + TE.bind('localeId', () => + pipe( + findLocaleByName(command.localeName), + TE.chain(locale => + pipe( + locale, + O.match( + () => TE.left(createValidationError('Locale not found')), + locale => TE.right(locale.id) + ) + ) + ) ) ), TE.map( - ({ validatedSentence, domainIds, variantId }): SentenceSubmission => { + ({ + validatedSentence, + localeId, + domainIds, + variant, + }): SentenceSubmission => { + const variantId = pipe( + variant, + O.map(variant => variant.id) + ) + return { sentence: validatedSentence, source: command.source, - locale_id: command.localeId, + locale_id: localeId, client_id: command.clientId, domain_ids: [...domainIds], variant_id: variantId, diff --git a/server/src/application/sentences/use-case/command-handler/command/add-sentence-command.ts b/server/src/application/sentences/use-case/command-handler/command/add-sentence-command.ts index b27769371678..7ce7c25b0b93 100644 --- a/server/src/application/sentences/use-case/command-handler/command/add-sentence-command.ts +++ b/server/src/application/sentences/use-case/command-handler/command/add-sentence-command.ts @@ -5,7 +5,6 @@ import { SentenceDomain } from "common" export type AddSentenceCommand = { clientId: string sentence: string - localeId: number localeName: string source: string, domains: SentenceDomain[] diff --git a/server/src/core/types/locale.ts b/server/src/core/types/locale.ts new file mode 100644 index 000000000000..7652a592b631 --- /dev/null +++ b/server/src/core/types/locale.ts @@ -0,0 +1,10 @@ +export type TextDirection = 'LTR' | 'RTL' | 'TTB' | 'BTT' + +export type Locale = { + id: number + name: string + targetSentenceCount: number + isContributable: boolean + isTranslated: boolean + textDirection: TextDirection +} diff --git a/server/src/core/types/variant.ts b/server/src/core/types/variant.ts new file mode 100644 index 000000000000..26216626a224 --- /dev/null +++ b/server/src/core/types/variant.ts @@ -0,0 +1,6 @@ +export type Variant = { + id: number + locale: string + name: string + tag: string +} diff --git a/server/src/test/application/sentences/use-case/command-handler/add-sentence-command-handler.test.ts b/server/src/test/application/sentences/use-case/command-handler/add-sentence-command-handler.test.ts index a587e419cd81..3eb3708a48e8 100644 --- a/server/src/test/application/sentences/use-case/command-handler/add-sentence-command-handler.test.ts +++ b/server/src/test/application/sentences/use-case/command-handler/add-sentence-command-handler.test.ts @@ -6,11 +6,12 @@ import { AddSentenceCommandHandler } from '../../../../../application/sentences/ import { ERR_TOO_LONG, ValidateSentence } from '../../../../../core/sentences' import { FindDomainIdByName, - FindVariantIdByToken, SaveSentence, } from '../../../../../application/sentences/repository/sentences-repository' import { AddSentenceCommand } from '../../../../../application/sentences/use-case/command-handler/command/add-sentence-command' import { SentenceSubmission } from '../../../../../application/types/sentence-submission' +import { FindVariantByTag } from '../../../../../application/sentences/repository/variant-repository' +import { FindLocaleByName } from '../../../../../application/sentences/repository/locale-repository' describe('Add sentence command handler', () => { it('should save the sentence in the repository', async () => { @@ -20,15 +21,29 @@ describe('Add sentence command handler', () => { const findDomainIdByNameMock: FindDomainIdByName = jest.fn(() => TE.right(O.some(1)) ) - const findVariantIdByTokenMock: FindVariantIdByToken = jest.fn(() => - TE.right(O.some(1)) + const findVariantByTokenMock: FindVariantByTag = jest.fn(() => + TE.right( + O.some({ id: 1, name: 'Central', tag: 'ca-central', locale: 'ca' }) + ) + ) + const findLocaleByNameMock: FindLocaleByName = jest.fn(() => + TE.right( + O.some({ + id: 27, + name: 'ca', + targetSentenceCount: 0, + isContributable: true, + isTranslated: true, + textDirection: 'LTR', + }) + ) ) + const saveSentenceMock: SaveSentence = jest.fn(() => TE.right(constVoid())) const cmd: AddSentenceCommand = { clientId: 'abc', sentence: 'This is a sentence', - localeId: 1, localeName: 'en', source: 'Myself', domains: ['finance'], @@ -38,7 +53,7 @@ describe('Add sentence command handler', () => { const expectedSentenceSubmission: SentenceSubmission = { sentence: 'This is a sentence', source: 'Myself', - locale_id: 1, + locale_id: 27, client_id: 'abc', domain_ids: [1], variant_id: O.none, @@ -48,7 +63,8 @@ describe('Add sentence command handler', () => { AddSentenceCommandHandler, I.ap(validateSentenceMock), I.ap(findDomainIdByNameMock), - I.ap(findVariantIdByTokenMock), + I.ap(findVariantByTokenMock), + I.ap(findLocaleByNameMock), I.ap(saveSentenceMock) ) @@ -68,15 +84,28 @@ describe('Add sentence command handler', () => { const findDomainIdByNameMock: FindDomainIdByName = jest.fn(() => TE.right(O.some(1)) ) - const findVariantIdByTokenMock: FindVariantIdByToken = jest.fn(() => - TE.right(O.some(1)) + const findVariantByTokenMock: FindVariantByTag = jest.fn(() => + TE.right( + O.some({ id: 1, name: 'Central', tag: 'ca-central', locale: 'ca' }) + ) + ) + const findLocaleByNameMock: FindLocaleByName = jest.fn(() => + TE.right( + O.some({ + id: 27, + name: 'ca', + targetSentenceCount: 0, + isContributable: true, + isTranslated: true, + textDirection: 'LTR', + }) + ) ) const saveSentenceMock: SaveSentence = jest.fn(() => TE.right(constVoid())) const cmd: AddSentenceCommand = { clientId: 'abc', sentence: 'This is a sentence', - localeId: 1, localeName: 'en', source: 'Myself', domains: ['finance'], @@ -87,12 +116,120 @@ describe('Add sentence command handler', () => { AddSentenceCommandHandler, I.ap(validateSentenceMock), I.ap(findDomainIdByNameMock), - I.ap(findVariantIdByTokenMock), + I.ap(findVariantByTokenMock), + I.ap(findLocaleByNameMock), + I.ap(saveSentenceMock) + ) + + const result = await pipe(cmd, cmdHandler)() + expect(E.isLeft(result)).toBeTruthy() + expect(saveSentenceMock).toHaveBeenCalledTimes(0) + }) + + it('should return validation error when locale does not match variant', async () => { + const validateSentenceMock: ValidateSentence = jest.fn( + () => () => E.right('This is a sentence') + ) + const findDomainIdByNameMock: FindDomainIdByName = jest.fn(() => + TE.right(O.some(1)) + ) + const findVariantByTokenMock: FindVariantByTag = jest.fn(() => + TE.right( + O.some({ id: 1, name: 'Central', tag: 'ca-central', locale: 'ca' }) + ) + ) + const findLocaleByNameMock: FindLocaleByName = jest.fn(() => + TE.right( + O.some({ + id: 27, + name: 'ca', + targetSentenceCount: 0, + isContributable: true, + isTranslated: true, + textDirection: 'LTR', + }) + ) + ) + const saveSentenceMock: SaveSentence = jest.fn(() => TE.right(constVoid())) + + const cmd: AddSentenceCommand = { + clientId: 'abc', + sentence: 'This is a sentence', + localeName: 'en', + source: 'Myself', + domains: ['finance'], + variant: O.some('ca-central'), + } + + const cmdHandler = pipe( + AddSentenceCommandHandler, + I.ap(validateSentenceMock), + I.ap(findDomainIdByNameMock), + I.ap(findVariantByTokenMock), + I.ap(findLocaleByNameMock), + I.ap(saveSentenceMock) + ) + + const result = await pipe(cmd, cmdHandler)() + const errMsg = pipe( + result, + E.match( + err => err.message, + () => 'should not happen' + ) + ) + + expect(E.isLeft(result)).toBeTruthy() + expect(errMsg).toBe('Locale does not match variant') + expect(saveSentenceMock).toHaveBeenCalledTimes(0) + }) + + it('should return validation error when locale is not found', async () => { + const validateSentenceMock: ValidateSentence = jest.fn( + () => () => E.right('This is a sentence') + ) + const findDomainIdByNameMock: FindDomainIdByName = jest.fn(() => + TE.right(O.some(1)) + ) + const findVariantByTokenMock: FindVariantByTag = jest.fn(() => + TE.right( + O.some({ id: 1, name: 'Central', tag: 'ca-central', locale: 'ca' }) + ) + ) + const findLocaleByNameMock: FindLocaleByName = jest.fn(() => + TE.right(O.none) + ) + const saveSentenceMock: SaveSentence = jest.fn(() => TE.right(constVoid())) + + const cmd: AddSentenceCommand = { + clientId: 'abc', + sentence: 'This is a sentence', + localeName: 'ca', + source: 'Myself', + domains: ['finance'], + variant: O.some('ca-central'), + } + + const cmdHandler = pipe( + AddSentenceCommandHandler, + I.ap(validateSentenceMock), + I.ap(findDomainIdByNameMock), + I.ap(findVariantByTokenMock), + I.ap(findLocaleByNameMock), I.ap(saveSentenceMock) ) const result = await pipe(cmd, cmdHandler)() + const errMsg = pipe( + result, + E.match( + err => err.message, + () => 'should not happen' + ) + ) + expect(E.isLeft(result)).toBeTruthy() + expect(errMsg).toBe('Locale not found') expect(saveSentenceMock).toHaveBeenCalledTimes(0) }) }) From 257799c8fef5539812f6f7874126609c3874265c Mon Sep 17 00:00:00 2001 From: Dmitrij Feller <119537889+moz-dfeller@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:08:13 +0200 Subject: [PATCH 66/69] feat: add is_preferred_option to user's variants response (#4451) --- common/language.ts | 6 +++++- server/src/lib/model/user-client.ts | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/common/language.ts b/common/language.ts index df2f5a1a7075..3fbd0187a2e5 100644 --- a/common/language.ts +++ b/common/language.ts @@ -29,12 +29,16 @@ export type Variant = { token: string; }; +export type UserVariant = Variant & { + is_preferred_option: boolean; +} + /* an object storing all accent/locale/variant data for a user */ export type UserLanguage = { locale: string; - variant?: Variant; + variant?: UserVariant; accents?: Accent[]; }; diff --git a/server/src/lib/model/user-client.ts b/server/src/lib/model/user-client.ts index 903eefd3e8e7..c98c557a2217 100644 --- a/server/src/lib/model/user-client.ts +++ b/server/src/lib/model/user-client.ts @@ -45,6 +45,7 @@ const compileLanguages = (clientLanguages: any, row: any) => { id: row.variant_id, name: row.variant_name, token: row.variant_token, + is_preferred_option: row.is_preferred_option === 1, }; if (result[row.locale]) { @@ -413,6 +414,7 @@ const UserClient = { v.variant_name, v.variant_token, v.id as variant_id, + uv.is_preferred_option, locales.name AS locale, ages.age, genders.gender, @@ -472,6 +474,7 @@ const UserClient = { row, 'accent', 'variant', + 'is_preferred_option', 'age', 'email', 'gender', From fbf1d02a62ab57e41109f52d846fa176b7c10e2c Mon Sep 17 00:00:00 2001 From: Alvyn Abranches Date: Mon, 22 Apr 2024 17:22:36 +0000 Subject: [PATCH 67/69] Pontoon: Update Goan Konkani (gom) localization of Common Voice Co-authored-by: Alvyn Abranches Co-authored-by: Vel --- web/locales/gom/messages.ftl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/locales/gom/messages.ftl b/web/locales/gom/messages.ftl index b73d90ee1cce..ce4bdae4d57e 100644 --- a/web/locales/gom/messages.ftl +++ b/web/locales/gom/messages.ftl @@ -6,7 +6,9 @@ return-to-cv = Porot voch Common Voice'acher email-input = .label = Email submit-form-action = Submit +loading = Load zata... email-opt-in-info = Hoi, Mhaka asle emails dhad jitun Goal Reminders, Progress Updates anik Common Voice`acher novi novi khobryo-patra asta. +email-opt-in-info-title = Common Voice mailing list join kor # Don't rename the following section, its contents are auto-inserted based on the name (see scripts/pontoon-languages-to-ftl.js) # [Languages] @@ -138,12 +140,14 @@ action-tap = Damp listen = Aik write = Boroi skip = Sod +record-error-too-short = Recording samke begin sopoile. record-error-too-long = Recording chod vhoddlem zale. record-error-too-quiet = Recording samki ogi asa. record-instruction = { $actionType } ani magir sentence mottean vach record-stop-instruction = zale zaliar { $actionType } record-again-instruction = Shabbas! Dusre clip record kor record-again-instruction2 = Borem asa, ani ek record kor +record-last-instruction = Last ek! review-instruction = Check kor & goroz asa zaliar portun record kor clips-uploaded = Clips Upload Zale record-abort-title = Recording purai kor poilem? From c4821033565de21269306ba1db2ab9aa07009e2c Mon Sep 17 00:00:00 2001 From: Dmitrij Feller <119537889+moz-dfeller@users.noreply.github.com> Date: Tue, 23 Apr 2024 11:27:36 +0200 Subject: [PATCH 68/69] feat: save the selected preferred variant on the profile page (#4455) --- .../db/utils/getVariantsToBeUpdated.test.ts | 54 +++++++++++++++ .../model/db/utils/getVariantsToBeUpdated.ts | 19 ++++++ server/src/lib/model/user-client.ts | 65 ++++++++++++------- 3 files changed, 116 insertions(+), 22 deletions(-) create mode 100644 server/src/lib/model/db/utils/getVariantsToBeUpdated.test.ts create mode 100644 server/src/lib/model/db/utils/getVariantsToBeUpdated.ts diff --git a/server/src/lib/model/db/utils/getVariantsToBeUpdated.test.ts b/server/src/lib/model/db/utils/getVariantsToBeUpdated.test.ts new file mode 100644 index 000000000000..ba21a602e96f --- /dev/null +++ b/server/src/lib/model/db/utils/getVariantsToBeUpdated.test.ts @@ -0,0 +1,54 @@ +import { UserVariant } from 'common' +import { getVariantsToBeUpdated } from './getVariantsToBeUpdated' + +describe('Test getVariantsToBeUpdated', () => { + it('should return correct list of variants to be updated', () => { + const requestedVariants: UserVariant[] = [ + { id: 1, name: 'a', token: 'a', is_preferred_option: false }, + { id: 2, name: 'b', token: 'b', is_preferred_option: true }, + { id: 3, name: 'c', token: 'c', is_preferred_option: false }, + ] + const savedVariants: UserVariant[] = [ + { id: 1, name: 'a', token: 'a', is_preferred_option: true }, + { id: 2, name: 'b', token: 'b', is_preferred_option: false }, + { id: 3, name: 'c', token: 'c', is_preferred_option: false }, + ] + + const variantsToBeUpdated = getVariantsToBeUpdated( + requestedVariants, + savedVariants + ) + + expect(variantsToBeUpdated).toEqual([ + { id: 1, name: 'a', token: 'a', is_preferred_option: false }, + { id: 2, name: 'b', token: 'b', is_preferred_option: true }, + ]) + }) + + it('should return empty list of variants to be updated', () => { + const requestedVariants: UserVariant[] = [ + { id: 1, name: 'a', token: 'a', is_preferred_option: true }, + { id: 2, name: 'b', token: 'b', is_preferred_option: true }, + { id: 3, name: 'c', token: 'c', is_preferred_option: false }, + ] + const savedVariants: UserVariant[] = [ + { id: 1, name: 'a', token: 'a', is_preferred_option: true }, + { id: 2, name: 'b', token: 'b', is_preferred_option: true }, + { id: 3, name: 'c', token: 'c', is_preferred_option: false }, + ] + + const variantsToBeUpdated = getVariantsToBeUpdated( + requestedVariants, + savedVariants + ) + + const emptyDifference = getVariantsToBeUpdated([], []) + const noRequestedVariants = getVariantsToBeUpdated([], savedVariants) + const noSavedVariants = getVariantsToBeUpdated(requestedVariants, []) + + expect(variantsToBeUpdated).toEqual([]) + expect(emptyDifference).toEqual([]) + expect(noRequestedVariants).toEqual([]) + expect(noSavedVariants).toEqual([]) + }) +}) diff --git a/server/src/lib/model/db/utils/getVariantsToBeUpdated.ts b/server/src/lib/model/db/utils/getVariantsToBeUpdated.ts new file mode 100644 index 000000000000..1f5004922f4c --- /dev/null +++ b/server/src/lib/model/db/utils/getVariantsToBeUpdated.ts @@ -0,0 +1,19 @@ +import { UserVariant } from 'common' + +const haveSamePreference = (a: UserVariant, b: UserVariant) => { + return a.is_preferred_option === b.is_preferred_option +} +export const getVariantsToBeUpdated = ( + requestedVariants: UserVariant[], + savedVariants: UserVariant[] +): UserVariant[] => { + const variantsToBeUpdated = requestedVariants.filter(requestedVariant => { + const savedVariant = savedVariants.find( + savedVariant => savedVariant.id === requestedVariant.id + ) + if (!savedVariant) return false + + return !haveSamePreference(requestedVariant, savedVariant) + }) + return variantsToBeUpdated +} diff --git a/server/src/lib/model/user-client.ts b/server/src/lib/model/user-client.ts index c98c557a2217..c042c14498a8 100644 --- a/server/src/lib/model/user-client.ts +++ b/server/src/lib/model/user-client.ts @@ -1,6 +1,6 @@ import pick = require('lodash.pick'); -import { UserClient as UserClientType } from 'common'; +import { UserClient as UserClientType, UserVariant } from 'common'; import Awards from './awards'; import CustomGoal from './custom-goal'; import { getLocaleId } from './db'; @@ -14,6 +14,7 @@ import { UserLanguage, } from 'common'; import { getDifferenceInIds } from './db/utils/getDiff'; +import { getVariantsToBeUpdated } from './db/utils/getVariantsToBeUpdated'; const db = getMySQLInstance(); @@ -230,37 +231,38 @@ async function updateLanguages(clientId: string, languages: UserLanguage[]) { */ async function updateVariants(clientId: string, languages: UserLanguage[]) { // flatten request obj to get a list of all variant_ids - const requestedVariants: { - locale_token: string; - variant_id: number; - }[] = []; + const requestedVariants: UserVariant[] = []; languages.forEach(language => { if (!language?.variant?.id) return; - const temp = { - locale_token: language.locale, - variant_id: language?.variant?.id, - }; - requestedVariants.push(temp); + requestedVariants.push(language.variant); }); // query all existing variants for user - const [savedVariants]: [{ variant_id: number }[]] = await db.query( + const [savedVariants]: [UserVariant[]] = await db.query( ` - SELECT variant_id + SELECT + v.id, + v.variant_name as name, + v.variant_token as token, + is_preferred_option FROM user_client_variants ucv + INNER JOIN variants v ON ucv.variant_id = v.id WHERE client_id = ? ORDER BY id `, [clientId] ); - const savedVariantIds = savedVariants.map(row => row.variant_id); + const requestedVariantIds = requestedVariants.map(variant => variant.id); + const savedVariantIds = savedVariants.map(variant => variant.id); const { idsToBeAdded, idsToBeRemoved } = getDifferenceInIds( - requestedVariants.map((variant: any) => variant.variant_id), + requestedVariantIds, savedVariantIds ); + const variantsToUpdate = getVariantsToBeUpdated(requestedVariants, savedVariants) + //If the user has removed variants, remove entry from db if (idsToBeRemoved.length > 0) { await db.query( @@ -278,18 +280,37 @@ async function updateVariants(clientId: string, languages: UserLanguage[]) { `SELECT v.id as variant_id, l.name as locale_name, l.id as locale_id FROM variants v JOIN locales l on v.locale_id = l.id where v.id in (?)`, [idsToBeAdded] - )) || []; + )) || [] if (validIds.length > 0) { - const formattedIds = validIds.map(variantRow => [ - clientId, - variantRow.variant_id, - variantRow.locale_id, - ]); //format array so query can insert multiple + const formattedIds = validIds.map(variantRow => { + const preferred = requestedVariants.find( + variant => variant.id === variantRow.variant_id + ) + return [ + clientId, + variantRow.variant_id, + variantRow.locale_id, + preferred.is_preferred_option || 0, + ] + }) //format array so query can insert multiple await db.query( - 'INSERT INTO user_client_variants (client_id, variant_id, locale_id) VALUES ?', + 'INSERT INTO user_client_variants (client_id, variant_id, locale_id, is_preferred_option) VALUES ?', [formattedIds] - ); + ) + } + } + + if (variantsToUpdate.length > 0) { + const variantData = variantsToUpdate.map(variant => { + return [variant.is_preferred_option, clientId, variant.id] + }) + + for (const variant of variantData) { + await db.query( + 'UPDATE user_client_variants SET is_preferred_option = ? WHERE client_id = ? AND variant_id = ?', + variant + ) } } } From 50a338da53a5b472bfbe909b49a4e6a5f3e264f6 Mon Sep 17 00:00:00 2001 From: moz-rotimib <113194143+moz-rotimib@users.noreply.github.com> Date: Wed, 24 Apr 2024 10:43:43 +0200 Subject: [PATCH 69/69] OI-2971: Add Variant option to sentence submission UIs (#4427) * chore: add useSingleSubmission hook - remove getString prop from SingleSubmissionWrite component * feat: display mock sentence variants - add actions for setting sentence variant * chore: fetch variants from the BE * chore: update copy for write page - add required to citation input field * feat: add select component for selecting sentence variant - fix single sentence submission test * test: fix write-container test * chore: remove localeId from create sentence request body * test: fix single submission write test * fix: fix domain dropdown to work with arrow and enter keys - other minor fixes * fix: add border to sentence variant select - fix height of sentence domain dropdown - fix width of combobox selected items list * chore: add localeId to create sentence request * test: add e2e test for adding sentence with variant * chore: remove localeId from sentence creation request * chore: fix general language key --- common/sentences.ts | 2 +- .../single-submission-write-page.action.ts | 22 ++- .../e2e/single-submission-write-page.cy.ts | 22 ++- web/locales/en/messages.ftl | 43 ++++- .../components/multiple-combobox/index.tsx | 43 ++--- .../multiple-combobox/multiple-combobox.css | 53 +++++- .../multiple-combobox/selected-items-list.tsx | 10 +- .../use-multiple-combobox.ts | 35 ++++ .../multiple-combobox/use-multiple-combox.ts | 42 ----- .../sentence-input-and-rules/constants.ts | 16 -- .../write/sentence-input-and-rules/rules.css | 4 +- .../sentence-input-and-rules.tsx | 37 +++- .../hooks/use-get-variants.ts | 32 ++++ .../hooks/use-single-submission-write.ts | 145 +++++++++++++++ .../single-submission-write.css | 12 +- .../single-submission-write.reducer.ts | 15 ++ .../single-submission-write.test.tsx | 59 +++--- .../single-submission-write.tsx | 171 +++--------------- .../write/write-container.test.tsx | 31 ++-- .../write/write-container.tsx | 11 +- web/src/components/select/index.tsx | 81 +++++++++ web/src/components/select/select.css | 86 +++++++++ web/src/services/api.ts | 10 +- 23 files changed, 674 insertions(+), 308 deletions(-) create mode 100644 web/src/components/multiple-combobox/use-multiple-combobox.ts delete mode 100644 web/src/components/multiple-combobox/use-multiple-combox.ts delete mode 100644 web/src/components/pages/contribution/sentence-collector/write/sentence-input-and-rules/constants.ts create mode 100644 web/src/components/pages/contribution/sentence-collector/write/single-submission-write/hooks/use-get-variants.ts create mode 100644 web/src/components/pages/contribution/sentence-collector/write/single-submission-write/hooks/use-single-submission-write.ts create mode 100644 web/src/components/select/index.tsx create mode 100644 web/src/components/select/select.css diff --git a/common/sentences.ts b/common/sentences.ts index 99fd08e7a019..63a0558803bb 100644 --- a/common/sentences.ts +++ b/common/sentences.ts @@ -1,9 +1,9 @@ export type SentenceSubmission = { sentence: string source: string - localeId: number localeName: string domains: string[] + variant?: string } export enum SentenceSubmissionError { diff --git a/web/cypress/actions/single-submission-write-page.action.ts b/web/cypress/actions/single-submission-write-page.action.ts index bf062f9b0f18..7db2b61d5757 100644 --- a/web/cypress/actions/single-submission-write-page.action.ts +++ b/web/cypress/actions/single-submission-write-page.action.ts @@ -3,23 +3,33 @@ export const submitSingleSubmissionForm = () => { cy.get('[data-testid=single-submission-form]').submit() } +type SingleSubmissionParams = { + sentence: string + shouldTypeCitation?: boolean + shouldSelectDomain?: boolean + shouldSelectVariant?: boolean +} + export const typeSingleSubmission = ({ sentence, shouldTypeCitation, shouldSelectDomain, -}: { - sentence: string - shouldTypeCitation?: boolean - shouldSelectDomain?: boolean -}) => { + shouldSelectVariant, +}: SingleSubmissionParams) => { cy.get('[data-testid=sentence-textarea]').type(sentence) if (shouldSelectDomain) { - cy.get('[data-testid=sentence-domain-select]').click() + cy.get('[data-testid=multiple-combobox-dropdown]').click() // Select "General" as domain cy.get('[data-testid=general]').click() } + if (shouldSelectVariant) { + cy.get('[data-testid=select-toggle-btn]').click() + // select second element in dropdown + cy.get('[data-testid=select-items-list] > li').eq(1).click() + } + if (shouldTypeCitation) { cy.get('[data-testid=citation-input]').type('self-citation') } diff --git a/web/cypress/e2e/single-submission-write-page.cy.ts b/web/cypress/e2e/single-submission-write-page.cy.ts index ae127bafd701..7b3bb4e50551 100644 --- a/web/cypress/e2e/single-submission-write-page.cy.ts +++ b/web/cypress/e2e/single-submission-write-page.cy.ts @@ -1,4 +1,4 @@ -import { fakerEN as faker, fakerRU } from '@faker-js/faker' +import { fakerEN as faker, fakerRU, fakerPT_PT } from '@faker-js/faker' import { submitSingleSubmissionForm, @@ -57,6 +57,26 @@ describe('The Write Page - Single Submission', () => { cy.get('.notification-pill').contains('1 sentence collected') }) + it('adds sentence with variant', () => { + // Portuguese has variants + cy.visit('/pt/write') + + const portugueseSentence = `${fakerPT_PT.lorem.sentence(10)}` + + typeSingleSubmission({ + sentence: portugueseSentence, + shouldTypeCitation: true, + shouldSelectVariant: true, + }) + + submitSingleSubmissionForm() + + // assert text area is empty after adding a sentence + cy.get('[data-testid=sentence-textarea]').should('have.value', '') + + cy.get('.notification-pill').contains('1 frase coletada') + }) + it('requires citation to add a sentence', () => { cy.visit('/write') diff --git a/web/locales/en/messages.ftl b/web/locales/en/messages.ftl index 2bf6eb95f89f..38acd445e592 100644 --- a/web/locales/en/messages.ftl +++ b/web/locales/en/messages.ftl @@ -1742,7 +1742,7 @@ write-page-subtitle = Sentences contributed here will be added to a publicly ava sentence = .label = Sentence sentence-input-value = Enter your public domain sentence here -citation-input-value = Source of your sentence +citation-input-placeholder = Reference the source of your sentence (required) citation = .label = Citation sc-write-submit-confirm = I confirm that this sentence is public domain and I have permission to upload it. @@ -1767,9 +1767,8 @@ single-sentence-submission = Single Sentence Submission bulk-sentence-submission = Bulk Sentence Submission single-sentence = Single Sentence bulk-sentences = Bulk Sentences -sentence-domain-select = - .label = Sentence Domain -sentence-domain-select-placeholder = Select up to three domains +sentence-domain-combobox-label = Sentence Domain +sentence-domain-select-placeholder = Select up to three domains (optional) # Sentence Domain dropdown option agriculture = Agriculture # Sentence Domain dropdown option @@ -1794,6 +1793,42 @@ nature_environment = Nature and Environment news_current_affairs = News and Current Affairs # Sentence Domain dropdown option technology_robotics = Technology and Robotics +sentence-variant-select-label = Sentence Variant +sentence-variant-select-placeholder = Select a variant (optional) +sentence-variant-select-multiple-variants = General language / multiple variants + +## LANGUAGE VARIANT CODES +ca-algueres = Alguerès +ca-central = Central +ca-balear = Balear +ca-nwestern = Nord-Occidental +ca-northern = Septentrional +ca-valencia-tortosi = Tortosí +ca-valencia-central = Valencià central +ca-valencia-northern = Valencià septentrional +ca-valencia-southern = Valencià meridional +ca-valencia-alacant = Alacantí +cy-northwes = North-Western Welsh +cy-northeas = North-Eastern Welsh +cy-midwales = Mid Wales +cy-southwes = South-Western Welsh +cy-southeas = South-Eastern Welsh +cy-wladfa = Patagonian Welsh +pt-BR = Portuguese (Brasil) +pt-PT = Portuguese (Portugal) +sw-sanifu = Kiswahili Sanifu (EA) +sw-barake = Kiswahili cha Bara ya Kenya +sw-baratz = Kiswahili cha Bara ya Tanzania +sw-kingwana = Kingwana (DRC) +sw-kimvita = Kimvita (KE) - Central dialect +sw-kibajuni = Kibajuni (KE) - Northern dialect +sw-kimrima = Kimrima (TZ) - Northern dialect +sw-kiunguja = Kiunguja (TZ) - Southern dialect +sw-kipemba = Kipemba (TZ) - Southern dialect +sw-kikae = Kimakunduchi/Kikae (TZ) - Southern dialect +zgh-shi = ⵜⴰⵛⵍⵃⵉⵜ (Tachelhit) +zgh-tzm = ⵜⴰⵎⴰⵣⵉⵖⵜ ⵏ ⵡⴰⵟⵍⴰⵚ ⴰⵏⴰⵎⵎⴰⵙ (Central Atlas Tamazight) +zgh-rif = ⵜⴰⵔⵉⴼⵉⵜ (Tarifit) ## REVIEW PAGE # will be replace with an icon that represents review diff --git a/web/src/components/multiple-combobox/index.tsx b/web/src/components/multiple-combobox/index.tsx index e6155cc42fbd..d95d9278fdb8 100644 --- a/web/src/components/multiple-combobox/index.tsx +++ b/web/src/components/multiple-combobox/index.tsx @@ -1,14 +1,11 @@ import * as React from 'react' import { useCombobox, useMultipleSelection } from 'downshift' -import { Localized, useLocalization } from '@fluent/react' +import { useLocalization } from '@fluent/react' -import { LabeledInput } from '../ui/ui' import { SelectedItemsList } from './selected-items-list' import './multiple-combobox.css' -const Input = LabeledInput - type Props = { items: string[] maxNumberOfSelectedElements?: number @@ -16,6 +13,7 @@ type Props = { setInputValue: React.Dispatch> setSelectedItems: (items: string[]) => void inputValue: string + label: string } export const MultipleCombobox: React.FC = ({ @@ -25,6 +23,7 @@ export const MultipleCombobox: React.FC = ({ maxNumberOfSelectedElements, inputValue, setInputValue, + label, }) => { const { l10n } = useLocalization() @@ -48,6 +47,7 @@ export const MultipleCombobox: React.FC = ({ isOpen, getMenuProps, getInputProps, + getLabelProps, highlightedIndex, getItemProps, openMenu, @@ -107,22 +107,24 @@ export const MultipleCombobox: React.FC = ({ } return ( -
+
+ + {label} +
- - - +
    @@ -135,8 +137,7 @@ export const MultipleCombobox: React.FC = ({ : {} } key={`${item}${index}`} - {...getItemProps({ item, index })} - data-testid={item}> + {...getItemProps({ item, index, 'data-testid': item })}> {l10n.getString(item)} ))} diff --git a/web/src/components/multiple-combobox/multiple-combobox.css b/web/src/components/multiple-combobox/multiple-combobox.css index e55e1e9ab302..e3d3d5235419 100644 --- a/web/src/components/multiple-combobox/multiple-combobox.css +++ b/web/src/components/multiple-combobox/multiple-combobox.css @@ -1,9 +1,9 @@ @import url('../media.css'); -.multiple-sentence-domain-select { +.multiple-combobox { + position: relative; ul { background: #fff; - margin: 0px 0 30px; position: absolute; z-index: var(--override-z-index); @@ -19,7 +19,7 @@ border: 1px solid var(--light-grey); box-shadow: 0 2px 5px 0 var(--light-grey); overflow: auto; - max-height: 500px; + max-height: 350px; } li { @@ -38,7 +38,36 @@ } } + .multiple-combobox-label { + background: var(--white); + color: var(--near-black); + font-size: var(--font-size-xs); + margin-inline-start: 9px; + padding: 0 5px; + position: absolute; + top: -8px; + z-index: var(--middle-z-index); + } + input[type='text'] { + border: 1.6px solid #e6e4e1; + border-radius: 2px; + padding: 13px; + font-size: var(--font-size); + font-family: var(--base-font-family); + color: var(--black); + background-color: var(--white); + width: 100%; + + &:focus { + border-color: var(--black); + } + + &:disabled { + color: var(--warm-grey); + cursor: not-allowed; + } + @media (--xs-down) { font-size: var(--font-size-xs); @@ -49,10 +78,10 @@ } } -.selected-domains-list { +.selected-items-list { margin-block-start: 30px; - .selected-domain { + .selected-item { display: inline-flex; align-items: center; padding-inline-start: 1.5rem; @@ -60,9 +89,21 @@ margin-bottom: 1.5rem; background: var(--light-grey); border-radius: 15rem; + + p { + display: inline-block; + max-width: 150px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + + @media (--xs-down) { + max-width: 250px; + } + } } - .selected-domain--button { + .selected-item--button { border: none; padding: 0.8rem 1.5rem; padding-inline-start: 1rem; diff --git a/web/src/components/multiple-combobox/selected-items-list.tsx b/web/src/components/multiple-combobox/selected-items-list.tsx index c13801397047..55bf5a018b28 100644 --- a/web/src/components/multiple-combobox/selected-items-list.tsx +++ b/web/src/components/multiple-combobox/selected-items-list.tsx @@ -16,18 +16,18 @@ export const SelectedItemsList: React.FC = ({ const { l10n } = useLocalization() return ( -
    +
    {selectedItems.map(item => ( - - {l10n.getString(item)} +
    +

    {l10n.getString(item)}

    - +
    ))}
    ) diff --git a/web/src/components/multiple-combobox/use-multiple-combobox.ts b/web/src/components/multiple-combobox/use-multiple-combobox.ts new file mode 100644 index 000000000000..8eaae1d33179 --- /dev/null +++ b/web/src/components/multiple-combobox/use-multiple-combobox.ts @@ -0,0 +1,35 @@ +import { useCallback, useMemo, useState } from 'react' + +type UseMultipleComboBoxParams = { + items: readonly string[] + selectedItems: string[] +} + +export const useMultipleComboBox = ({ + items, + selectedItems, +}: UseMultipleComboBoxParams) => { + const [inputValue, setInputValue] = useState('') + + const getFilteredItems = useCallback( + ({ inputValue }: { inputValue: string }) => { + return items.filter( + item => + !selectedItems.includes(item) && + item.toLowerCase().startsWith(inputValue.toLowerCase()) + ) + }, + [items, selectedItems] + ) + + const multipleComboBoxItems = useMemo( + () => getFilteredItems({ inputValue }), + [getFilteredItems, inputValue] + ) + + return { + multipleComboBoxItems, + inputValue, + setInputValue, + } +} diff --git a/web/src/components/multiple-combobox/use-multiple-combox.ts b/web/src/components/multiple-combobox/use-multiple-combox.ts deleted file mode 100644 index 1fa090026814..000000000000 --- a/web/src/components/multiple-combobox/use-multiple-combox.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { useMemo, useState } from 'react' - -type UseMultipleComboBoxParams = { - items: readonly string[] - selectedItems: string[] -} - -export const useMultipleComboBox = ({ - items, - selectedItems, -}: UseMultipleComboBoxParams) => { - const [inputValue, setInputValue] = useState('') - - const getFilteredItems = ({ - elements, - selectedItems, - inputValue, - }: { - elements: readonly string[] - selectedItems: string[] - inputValue: string - }) => { - const lowerCasedInputValue = inputValue.toLowerCase() - - return elements.filter( - element => - !selectedItems.includes(element) && - element.toLowerCase().startsWith(lowerCasedInputValue) - ) - } - - const multipleComboBoxItems = useMemo( - () => getFilteredItems({ elements: items, selectedItems, inputValue }), - [selectedItems, inputValue] - ) - - return { - multipleComboBoxItems, - inputValue, - setInputValue, - } -} diff --git a/web/src/components/pages/contribution/sentence-collector/write/sentence-input-and-rules/constants.ts b/web/src/components/pages/contribution/sentence-collector/write/sentence-input-and-rules/constants.ts deleted file mode 100644 index e91d71640585..000000000000 --- a/web/src/components/pages/contribution/sentence-collector/write/sentence-input-and-rules/constants.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { SentenceDomain } from 'common' - -export const SENTENCE_DOMAIN_MAPPING: Record = { - agriculture: 'Agriculture', - automotive: 'Automotive', - finance: 'Finance', - food_service_retail: 'Food, Service and Retail', - general: 'General', - healthcare: 'Healthcare', - history_law_government: 'History, Law and Government', - language_fundamentals: 'Language Fundamentals (e.g. Digits, Letters, Money)', - media_entertainment: 'Media and Entertainment', - nature_environment: 'Nature and Environment', - news_current_affairs: 'News and Current Affairs', - technology_robotics: 'Technology and Robotics', -} diff --git a/web/src/components/pages/contribution/sentence-collector/write/sentence-input-and-rules/rules.css b/web/src/components/pages/contribution/sentence-collector/write/sentence-input-and-rules/rules.css index 4a762a369b9d..1463c98203d8 100644 --- a/web/src/components/pages/contribution/sentence-collector/write/sentence-input-and-rules/rules.css +++ b/web/src/components/pages/contribution/sentence-collector/write/sentence-input-and-rules/rules.css @@ -118,13 +118,13 @@ .rules.write-rules { @media (--xl-up) { - height: calc(30vh + 82px); + height: calc(30vh + 50px); min-height: 440px; max-height: 500px; } @media (--lg-only) { - max-height: 445px; + max-height: 415px; } @media (--md-down) { diff --git a/web/src/components/pages/contribution/sentence-collector/write/sentence-input-and-rules/sentence-input-and-rules.tsx b/web/src/components/pages/contribution/sentence-collector/write/sentence-input-and-rules/sentence-input-and-rules.tsx index 6414e45dd86b..3542e71629d7 100644 --- a/web/src/components/pages/contribution/sentence-collector/write/sentence-input-and-rules/sentence-input-and-rules.tsx +++ b/web/src/components/pages/contribution/sentence-collector/write/sentence-input-and-rules/sentence-input-and-rules.tsx @@ -1,47 +1,54 @@ import * as React from 'react' -import { Localized } from '@fluent/react' +import { Localized, useLocalization } from '@fluent/react' import classNames from 'classnames' import { EditIcon } from '../../../../../ui/icons' import { LabeledInput } from '../../../../../ui/ui' import { MultipleCombobox } from '../../../../../multiple-combobox' -import { SingleSubmissionWriteProps } from '../single-submission-write/single-submission-write' import { Rules } from './rules' import { Instruction } from '../../instruction' import ExpandableInformation from '../../../../../expandable-information/expandable-information' +import { Select } from '../../../../../select' import { SentenceSubmissionError } from 'common' import { LabeledTextArea } from '../../../../../ui/ui' import { LocaleLink } from '../../../../../locale-helpers' import URLS from '../../../../../../urls' -import { useMultipleComboBox } from '../../../../../multiple-combobox/use-multiple-combox' +import { useMultipleComboBox } from '../../../../../multiple-combobox/use-multiple-combobox' type Props = { - getString: SingleSubmissionWriteProps['getString'] handleSentenceInputChange: ( event: React.ChangeEvent ) => void handleCitationChange: (event: React.ChangeEvent) => void + handleSentenceVariantChange: (item: string) => void selectedSentenceDomains: string[] setSelectedSentenceDomains: (domains: string[]) => void sentence: string citation: string sentenceDomains: readonly string[] error: SentenceSubmissionError + variantTokens: string[] + selectedVariant?: string } export const SentenceInputAndRules: React.FC = ({ - getString, handleCitationChange, handleSentenceInputChange, + handleSentenceVariantChange, sentenceDomains, selectedSentenceDomains, setSelectedSentenceDomains, sentence, citation, error, + variantTokens, + selectedVariant, }) => { const isSentenceError = error && error !== SentenceSubmissionError.NO_CITATION const isCitationError = error === SentenceSubmissionError.NO_CITATION + const hasVariants = variantTokens && variantTokens.length > 0 + + const { l10n } = useLocalization() const { multipleComboBoxItems, inputValue, setInputValue } = useMultipleComboBox({ @@ -59,9 +66,10 @@ export const SentenceInputAndRules: React.FC = ({
    = ({ + {hasVariants && ( +