Compare commits

...

91 Commits

Author SHA1 Message Date
Sabe Jones
2d4ee636ae 5.24.0 2024-04-26 15:22:08 -05:00
Natalie
de62207504 May 2024 Content Prebuild (#15185)
* 2024-05 css update

* add May subscriber items, enchanted armoire (text placeholders), potions, and quest bundles

* typo correction

* add May achievement

* content fixes after local testing

* canonical date fix

* fix potion descriptions, add periods to background descriptions

* fix canonical date

* updated armoire items

* fix stat display on item

* Fixing merge conflicts

* resolve merge conflicts

* add leading zero to mp drain for mushroom quest

* fix timezones

* proofreading pass

* fix linting errors

* date fixes & linter fixes

* correct armoire expression at end of file

* fix(autolint): roll back Prettier change

---------

Co-authored-by: Sabe Jones <sabe@habitica.com>
2024-04-26 15:14:45 -05:00
Sabe Jones
ee93c8bec5 5.23.0 2024-04-08 15:49:20 -05:00
Sabe Jones
c65e93e514 chore(git): update subproject 2024-04-08 15:49:17 -05:00
Sabe Jones
0fd808727c Squashed commit of the following:
commit 3c3787091a2e8a94857352c3655f60138a3b20b7
Merge: 76a00d6308 76d7f02fe8
Author: Sabe Jones <sabe@habitica.com>
Date:   Mon Apr 8 15:47:35 2024 -0500

    Merge branch 'release' into 2024-04-april-fool-items

commit 76a00d6308997c50ae5f5e9d6170a09a1a8cbac7
Author: Sabe Jones <sabe@habitica.com>
Date:   Thu Mar 28 16:08:39 2024 -0500

    fix(quest): revise rage text

commit c2e13f8af245993f61eb614d6be609c833c2e711
Author: Sabe Jones <sabe@habitica.com>
Date:   Thu Mar 28 12:57:17 2024 -0500

    fix(quest): correct rage and "guscompletion"

commit ecdeb82df998ab75eceae3e877c1758187b1d22c
Author: Sabe Jones <sabe@habitica.com>
Date:   Thu Mar 28 08:55:18 2024 -0500

    fix(events): correct dates and times

commit 232de436bbe7ba4c13f04ed66cc3b8a4a794d884
Author: Sabe Jones <sabe@habitica.com>
Date:   Wed Mar 27 09:03:06 2024 -0500

    fix(content): a few more unruly Fungus

commit 955e6e73387788797d1a83a037f73aa472515cec
Author: Sabe Jones <sabe@habitica.com>
Date:   Wed Mar 27 09:00:03 2024 -0500

    feat(content): wacky potions 2024 by @CuriousMagpie

commit 34b72be4f447f00c31169c4cd6e8ba79655adf8a
Author: Sabe Jones <sabe@habitica.com>
Date:   Wed Mar 27 08:56:27 2024 -0500

    feat(event): AF by @CuriousMagpie
2024-04-08 15:48:32 -05:00
Sabe Jones
76d7f02fe8 5.22.3 2024-04-02 15:20:17 -05:00
Sabe Jones
5a9f2c610a Revert "fix(content): adjust release dates"
This reverts commit 0b230b0a87.
2024-04-02 15:20:04 -05:00
Sabe Jones
8a88d165e6 fix(event): end AF earlier 2024-04-02 11:28:07 -05:00
Sabe Jones
ed790c1c4d 5.22.2 2024-04-01 15:50:13 -05:00
Sabe Jones
0b230b0a87 fix(content): adjust release dates 2024-04-01 15:48:43 -05:00
Sabe Jones
9b72221482 5.22.1 2024-03-28 17:17:32 -05:00
Sabe Jones
ef1f27c09f Squashed commit of the following:
commit 0eb12305a58c148027759ea257f0f287796afdda
Author: Sabe Jones <sabe@habitica.com>
Date:   Thu Mar 28 17:13:05 2024 -0500

    feat(event): start April 1 midnight end April 2 8pm

commit de75cf2b9616ad4fe56051d5644c556bd40b874e
Author: Sabe Jones <sabe@habitica.com>
Date:   Thu Mar 28 08:52:01 2024 -0500

    fix(event): correct start timing

commit 34b72be4f447f00c31169c4cd6e8ba79655adf8a
Author: Sabe Jones <sabe@habitica.com>
Date:   Wed Mar 27 08:56:27 2024 -0500

    feat(event): AF by @CuriousMagpie
2024-03-28 17:17:17 -05:00
Sabe Jones
c762146ec9 fix(quests): egg availability, again 2024-03-26 13:09:41 -05:00
Sabe Jones
39fc6248d6 fix(event): adjust Egg quest release date 2024-03-26 06:48:45 -05:00
Sabe Jones
ff0bb9d005 5.22.0 2024-03-21 15:32:41 -05:00
Sabe Jones
6425afd58d Merge branch 'develop' into release 2024-03-21 15:32:36 -05:00
Weblate
c8498bd4e3 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (282 of 282 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Ukrainian)

Currently translated at 63.5% (1930 of 3035 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (3035 of 3035 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (764 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (230 of 230 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (60 of 60 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (282 of 282 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (3035 of 3035 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Russian)

Currently translated at 29.1% (40 of 137 strings)

Translated using Weblate (Russian)

Currently translated at 29.1% (40 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (15 of 15 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (764 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (91 of 91 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (110 of 110 strings)

Translated using Weblate (German)

Currently translated at 96.9% (828 of 854 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (282 of 282 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Japanese)

Currently translated at 98.4% (841 of 854 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (110 of 110 strings)

Translated using Weblate (Japanese)

Currently translated at 98.1% (161 of 164 strings)

Translated using Weblate (Korean)

Currently translated at 3.6% (5 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (282 of 282 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (22 of 22 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (3035 of 3035 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (54 of 54 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (110 of 110 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (164 of 164 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (230 of 230 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (60 of 60 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (282 of 282 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (110 of 110 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (230 of 230 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (54 of 54 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (377 of 377 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (110 of 110 strings)

Translated using Weblate (Spanish)

Currently translated at 91.2% (125 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (Japanese)

Currently translated at 97.8% (418 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (282 of 282 strings)

Translated using Weblate (Spanish)

Currently translated at 86.1% (118 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (377 of 377 strings)

Translated using Weblate (Japanese)

Currently translated at 97.6% (834 of 854 strings)

Translated using Weblate (Japanese)

Currently translated at 97.5% (160 of 164 strings)

Translated using Weblate (Korean)

Currently translated at 74.3% (122 of 164 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (164 of 164 strings)

Translated using Weblate (Spanish)

Currently translated at 82.4% (113 of 137 strings)

Translated using Weblate (Ukrainian)

Currently translated at 63.5% (1929 of 3035 strings)

Translated using Weblate (German)

Currently translated at 96.7% (739 of 764 strings)

Translated using Weblate (German)

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (German)

Currently translated at 94.7% (218 of 230 strings)

Translated using Weblate (French)

Currently translated at 100.0% (60 of 60 strings)

Translated using Weblate (German)

Currently translated at 98.7% (236 of 239 strings)

Translated using Weblate (German)

Currently translated at 97.2% (177 of 182 strings)

Translated using Weblate (German)

Currently translated at 100.0% (377 of 377 strings)

Co-authored-by: Finrod <963505255@qq.com>
Co-authored-by: Jaime Martí <jaumemarti77@icloud.com>
Co-authored-by: Javiera <javipuga99@gmail.com>
Co-authored-by: Kem Kembo <medamamef@gmail.com>
Co-authored-by: Mencius <beautyalinap@gmail.com>
Co-authored-by: Nikita Maximov <ruvemaximus@gmail.com>
Co-authored-by: Polina Reshetnikova <resh4096@gmail.com>
Co-authored-by: Sophie LE MASLE <sophiesuff@gmail.com>
Co-authored-by: Srish <ouawcloud@gmail.com>
Co-authored-by: Tetiana <merekka13@gmail.com>
Co-authored-by: Toro Mor <thomas.bizer@gmx.de>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: 윤성열 <existmaster@gmail.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/de/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/character/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/content/de/
Translate-URL: https://translate.habitica.com/projects/habitica/content/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/death/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/defaulttasks/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/es/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/front/de/
Translate-URL: https://translate.habitica.com/projects/habitica/front/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/front/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/de/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/quests/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/de/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/spells/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/de/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/de/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/zh_Hans/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Challenge
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Death
Translation: Habitica/Defaulttasks
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Limited
Translation: Habitica/Loginincentives
Translation: Habitica/Messages
Translation: Habitica/Npc
Translation: Habitica/Pets
Translation: Habitica/Quests
Translation: Habitica/Questscontent
Translation: Habitica/Spells
Translation: Habitica/Subscriber
Translation: Habitica/Tasks
2024-03-21 21:31:35 +01:00
Natalie
64f5c170d0 update(content): 2024-04 content prebuild (#15176)
* update(content): starting april prebuild

* update(content): april prebuild

* update(content): april prebuild
2024-03-21 15:25:33 -05:00
Sabe Jones
515b62d1ce chore(npm): update package lock 2024-03-15 14:45:24 -05:00
Sabe Jones
7e29c7d624 5.21.0 2024-03-13 16:36:29 -05:00
Sabe Jones
669d24fe43 Merge branch 'develop' into release 2024-03-13 16:36:22 -05:00
Weblate
439451a7e8 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (3035 of 3035 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (377 of 377 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (3035 of 3035 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (47 of 47 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Romanian)

Currently translated at 71.7% (165 of 230 strings)

Translated using Weblate (Romanian)

Currently translated at 89.3% (117 of 131 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (183 of 183 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (3035 of 3035 strings)

Translated using Weblate (Spanish)

Currently translated at 77.3% (106 of 137 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (110 of 110 strings)

Translated using Weblate (Spanish)

Currently translated at 75.1% (103 of 137 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (164 of 164 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (282 of 282 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (282 of 282 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (3035 of 3035 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (3035 of 3035 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (3035 of 3035 strings)

Translated using Weblate (Spanish)

Currently translated at 64.2% (88 of 137 strings)

Translated using Weblate (Spanish)

Currently translated at 64.2% (88 of 137 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (15 of 15 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (764 of 764 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (164 of 164 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (164 of 164 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (164 of 164 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (164 of 164 strings)

Translated using Weblate (Spanish)

Currently translated at 99.5% (3020 of 3035 strings)

Translated using Weblate (German)

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (German)

Currently translated at 89.6% (2720 of 3035 strings)

Translated using Weblate (German)

Currently translated at 97.9% (234 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (German)

Currently translated at 96.4% (737 of 764 strings)

Translated using Weblate (German)

Currently translated at 98.1% (108 of 110 strings)

Translated using Weblate (German)

Currently translated at 96.1% (821 of 854 strings)

Translated using Weblate (German)

Currently translated at 98.5% (138 of 140 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (230 of 230 strings)

Translated using Weblate (German)

Currently translated at 100.0% (60 of 60 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.9% (3034 of 3035 strings)

Translated using Weblate (Spanish)

Currently translated at 99.2% (3013 of 3035 strings)

Translated using Weblate (German)

Currently translated at 96.6% (231 of 239 strings)

Translated using Weblate (German)

Currently translated at 98.9% (187 of 189 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (110 of 110 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (854 of 854 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (854 of 854 strings)

Translated using Weblate (French)

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Spanish)

Currently translated at 98.5% (2991 of 3035 strings)

Translated using Weblate (French)

Currently translated at 100.0% (110 of 110 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (60 of 60 strings)

Translated using Weblate (Spanish)

Currently translated at 98.1% (2979 of 3035 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (91 of 91 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (110 of 110 strings)

Translated using Weblate (German)

Currently translated at 89.4% (2716 of 3035 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (230 of 230 strings)

Translated using Weblate (Russian)

Currently translated at 99.5% (229 of 230 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (German)

Currently translated at 95.5% (108 of 113 strings)

Translated using Weblate (German)

Currently translated at 98.4% (129 of 131 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (22 of 22 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (3035 of 3035 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (German)

Currently translated at 89.3% (2712 of 3035 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (54 of 54 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (German)

Currently translated at 100.0% (47 of 47 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (109 of 109 strings)

Translated using Weblate (German)

Currently translated at 98.1% (107 of 109 strings)

Translated using Weblate (German)

Currently translated at 95.1% (813 of 854 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (159 of 159 strings)

Co-authored-by: AGM <yoartgm@gmail.com>
Co-authored-by: Céu <marcel.ufscar@gmail.com>
Co-authored-by: Delta S <deseji93@gmail.com>
Co-authored-by: Finrod <963505255@qq.com>
Co-authored-by: Gabriela <gabisouzars5@gmail.com>
Co-authored-by: Ike Osenberg <ike.osenberg@gmail.com>
Co-authored-by: Jaime Martí <jaumemarti77@icloud.com>
Co-authored-by: Javiera <javipuga99@gmail.com>
Co-authored-by: Nik Ermilov <edaonh@gmail.com>
Co-authored-by: Quim Martínez Lara <quimml60@gmail.com>
Co-authored-by: Raul Royo Rubio <royografico@gmail.com>
Co-authored-by: Sophie LE MASLE <sophiesuff@gmail.com>
Co-authored-by: Toro Mor <thomas.bizer@gmx.de>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fanxiaoxi <fanxiaoxi1115@gmail.com>
Co-authored-by: Χρήστος Joia <hristosjoia@gmail.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/es/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/de/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/es/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/de/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/es/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/character/de/
Translate-URL: https://translate.habitica.com/projects/habitica/character/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/content/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/de/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/death/es/
Translate-URL: https://translate.habitica.com/projects/habitica/defaulttasks/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/es/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/front/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/de/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/de/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/es/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/es/
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/de/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/de/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/es/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/ro/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/overview/de/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/de/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/de/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/es/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/es/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ro/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/de/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/zh_Hans/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Challenge
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Contrib
Translation: Habitica/Death
Translation: Habitica/Defaulttasks
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Limited
Translation: Habitica/Loginincentives
Translation: Habitica/Messages
Translation: Habitica/Npc
Translation: Habitica/Overview
Translation: Habitica/Pets
Translation: Habitica/Questscontent
Translation: Habitica/Subscriber
Translation: Habitica/Tasks
2024-03-13 22:35:45 +01:00
Natalie
3e5226de67 update(content): add 2024 Spring Fling (#15168)
* update(content): add spring fling images, items, and placeholder text

* update(dates) : set canonical dates

* update(dates/quests): set canonical dates for both, add egg quest availability

* update(date): update quest availability start date

* update(content): add magic hatching potions

* fix(dates): canonical dates

* fix(event): add correct event name to potions

* fix(dates): canonical dates

* fix(dates): fix UTC offset, remove package.json and package-lock.json

* fix(dates): canonical

* fix: re-added package.json and package-lock.json

* update(content): add gear strings

* update(content): add Rogue off-hand string, canonical dates
2024-03-13 16:34:41 -05:00
Sabe Jones
8c7a0b4861 5.20.0 2024-03-11 10:00:05 -05:00
Sabe Jones
8fa91a3805 chore(node): upgrade to Node 20 2024-03-11 09:59:57 -05:00
Sabe Jones
c554a1a57d 5.19.1 2024-03-04 14:25:14 -06:00
Sabe Jones
9406f0fa22 Merge branch 'develop' into release 2024-03-04 14:25:10 -06:00
Weblate
d081a2bdba Translated using Weblate (French)
Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (French)

Currently translated at 100.0% (164 of 164 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (230 of 230 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.9% (3034 of 3035 strings)

Translated using Weblate (Portuguese)

Currently translated at 58.4% (1775 of 3035 strings)

Translated using Weblate (Romanian)

Currently translated at 95.3% (228 of 239 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.2% (136 of 137 strings)

Translated using Weblate (Russian)

Currently translated at 97.6% (746 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (91 of 91 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (377 of 377 strings)

Translated using Weblate (German)

Currently translated at 94.4% (103 of 109 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (164 of 164 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (164 of 164 strings)

Translated using Weblate (German)

Currently translated at 100.0% (164 of 164 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (183 of 183 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 71.4% (65 of 91 strings)

Translated using Weblate (Russian)

Currently translated at 97.2% (106 of 109 strings)

Translated using Weblate (Portuguese)

Currently translated at 96.7% (826 of 854 strings)

Translated using Weblate (Russian)

Currently translated at 99.3% (160 of 161 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (109 of 109 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 75.9% (104 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 73.7% (101 of 137 strings)

Translated using Weblate (French)

Currently translated at 100.0% (3035 of 3035 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (230 of 230 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (3035 of 3035 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.9% (3034 of 3035 strings)

Translated using Weblate (Russian)

Currently translated at 21.8% (30 of 137 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 91.2% (125 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (854 of 854 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (854 of 854 strings)

Translated using Weblate (French)

Currently translated at 100.0% (230 of 230 strings)

Translated using Weblate (French)

Currently translated at 99.9% (3033 of 3035 strings)

Translated using Weblate (French)

Currently translated at 99.9% (3033 of 3035 strings)

Translated using Weblate (Spanish)

Currently translated at 97.6% (2965 of 3035 strings)

Translated using Weblate (Portuguese)

Currently translated at 25.5% (35 of 137 strings)

Translated using Weblate (Portuguese)

Currently translated at 96.0% (820 of 854 strings)

Translated using Weblate (French)

Currently translated at 100.0% (854 of 854 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (183 of 183 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (282 of 282 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (377 of 377 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (847 of 847 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (229 of 229 strings)

Translated using Weblate (Spanish)

Currently translated at 98.4% (2965 of 3013 strings)

Co-authored-by: Alcatraz Huo <alrcatraz@gmail.com>
Co-authored-by: Céu <marcel.ufscar@gmail.com>
Co-authored-by: Finrod <963505255@qq.com>
Co-authored-by: Gabriela <gabisouzars5@gmail.com>
Co-authored-by: Icaro <icaro.mascarenhas@outlook.com>
Co-authored-by: Jaime Martí <jaumemarti77@icloud.com>
Co-authored-by: Natalie Luhrs <eilatan@gmail.com>
Co-authored-by: Phyan Phoenix <kirill.farick@gmail.com>
Co-authored-by: Sophie LE MASLE <sophiesuff@gmail.com>
Co-authored-by: Toro Mor <thomas.bizer@gmx.de>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: YuyingLiang <standingfish.malina@gmail.com>
Co-authored-by: Χρήστος Joia <hristosjoia@gmail.com>
Co-authored-by: Данила Мальцев <maltsev-danila@inbox.ru>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/de/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/de/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/character/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/content/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/content/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/front/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/front/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/ro/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/spells/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/es/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Challenge
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Limited
Translation: Habitica/Questscontent
Translation: Habitica/Spells
Translation: Habitica/Subscriber
2024-03-04 20:03:54 +01:00
Sabe Jones
dac09a9027 chore(news): remove obsolete link 2024-02-29 15:38:03 -06:00
Sabe Jones
f8e56c02f0 Squashed commit of the following:
commit d30dff2311087ff2fe5f3e2a913c594abeee6b0e
Author: Sabe Jones <sabe@habitica.com>
Date:   Tue Feb 27 16:01:11 2024 -0600

    fix(challenge): move isOfficial to mount process

commit ae52dca3cd0b4fd490f07b1979049803ce2f1e2f
Merge: 2b20ff1e46 2c6e82a58a
Author: Sabe Jones <sabe@habitica.com>
Date:   Tue Feb 27 15:20:40 2024 -0600

    Merge branch 'release' into phillip/challenges_official

commit 2b20ff1e46b1447eac3f9dbdf29566154c9fa656
Author: Sabe Jones <sabe@habitica.com>
Date:   Wed Feb 14 15:31:22 2024 -0600

    fix(tests): correct lint and TypeError

commit 5dae5c716f11db4c652e423eab43805ddfac3455
Merge: 29d9edc7aa 1a3c2f64e4
Author: Sabe Jones <sabe@habitica.com>
Date:   Wed Feb 14 15:01:18 2024 -0600

    Merge branch 'release' into phillip/challenges_official

commit 29d9edc7aa7445d24f5be24ca923719a4ab5f70d
Author: Sabe Jones <sabe@habitica.com>
Date:   Wed Feb 14 14:41:16 2024 -0600

    fix(challenges): don't momentarily show Report on official

commit f994d12775107cba7ec816ee522cfeb0c69ef567
Author: Phillip Thelen <phillip@habitica.com>
Date:   Tue Feb 13 10:08:08 2024 +0100

    hide report button for official challenges

commit ac06dcaca701b91913d5fc5307626b1616a9e0e8
Author: Phillip Thelen <phillip@habitica.com>
Date:   Tue Feb 13 10:04:49 2024 +0100

    prevent official challenges from being flagged

commit a07ce1e6de66a2c833c6f392cf396a7743ca0f97
Author: Phillip Thelen <phillip@habitica.com>
Date:   Mon Feb 5 19:12:17 2024 +0100

    test shouldn’t be exclusive

commit 4c2436a1a0fa905530b7e1cd66f75a2b07be5810
Author: Phillip Thelen <phillip@habitica.com>
Date:   Mon Feb 5 19:11:20 2024 +0100

    remove log

commit 292f3a578d51fd08c572afc574cc73d08356f46a
Author: Phillip Thelen <phillip@habitica.com>
Date:   Mon Feb 5 19:10:13 2024 +0100

    Automatically set official field on challenges if habitica_official cateogory is set
2024-02-28 14:31:05 -06:00
Sabe Jones
56f73a35b0 5.19.0 2024-02-27 17:31:59 -06:00
Sabe Jones
3842b633d7 Merge branch 'develop' into release 2024-02-27 17:27:50 -06:00
Natalie
caa73057d8 update(content): March 2024 content (#15161)
* feat(content): add February subscriber item, backgrounds, and enchanted armoire gear

* feat(content): add spritesheet

* feat(content): bug smashing

* fix(file): revert package.json to release

* feat(content): add quest bundles

* feat(content): add new achievement

* feat(content): add achievement script

* fix(curlies): remove stray curly boi

* fix(date): add canonical date

* fix(dates): updated background & armoire to canonical dates

* feat(content): add armoire strings & stats

* fix(migration): Golden Squirrel

* fix(backgrounds): trim extra whitespace

* fix(test): cuddle timing

---------

Co-authored-by: Sabe Jones <sabe@habitica.com>
Co-authored-by: Sabe Jones <sabrecat@gmail.com>
2024-02-27 17:25:57 -06:00
Weblate
72d83d242d Translated using Weblate (Spanish (Latin America))
Currently translated at 88.4% (749 of 847 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (161 of 161 strings)

Translated using Weblate (French)

Currently translated at 100.0% (3023 of 3023 strings)

Translated using Weblate (Spanish)

Currently translated at 96.7% (2914 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 64.9% (89 of 137 strings)

Translated using Weblate (Spanish)

Currently translated at 58.3% (80 of 137 strings)

Translated using Weblate (Spanish)

Currently translated at 96.1% (2897 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 95.8% (2889 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (3023 of 3023 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 64.2% (88 of 137 strings)

Translated using Weblate (Czech)

Currently translated at 18.9% (26 of 137 strings)

Translated using Weblate (Czech)

Currently translated at 87.0% (737 of 847 strings)

Translated using Weblate (Croatian)

Currently translated at 6.5% (9 of 137 strings)

Translated using Weblate (Croatian)

Currently translated at 53.7% (123 of 229 strings)

Translated using Weblate (Croatian)

Currently translated at 56.5% (1708 of 3023 strings)

Translated using Weblate (Czech)

Currently translated at 86.2% (113 of 131 strings)

Translated using Weblate (Ukrainian)

Currently translated at 63.4% (1918 of 3023 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.9% (3020 of 3023 strings)

Translated using Weblate (Czech)

Currently translated at 66.9% (2023 of 3023 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 63.5% (87 of 137 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 84.6% (116 of 137 strings)

Translated using Weblate (Czech)

Currently translated at 16.7% (23 of 137 strings)

Translated using Weblate (Czech)

Currently translated at 100.0% (377 of 377 strings)

Translated using Weblate (Czech)

Currently translated at 97.8% (185 of 189 strings)

Translated using Weblate (Czech)

Currently translated at 85.9% (728 of 847 strings)

Translated using Weblate (Czech)

Currently translated at 99.3% (160 of 161 strings)

Translated using Weblate (Polish)

Currently translated at 93.0% (788 of 847 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.1% (227 of 229 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.8% (3019 of 3023 strings)

Translated using Weblate (French)

Currently translated at 99.7% (3016 of 3023 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (60 of 60 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 94.3% (216 of 229 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (229 of 229 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 88.6% (250 of 282 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (377 of 377 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 85.3% (723 of 847 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 95.6% (154 of 161 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 95.6% (154 of 161 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 95.6% (154 of 161 strings)

Translated using Weblate (Spanish)

Currently translated at 97.5% (275 of 282 strings)

Translated using Weblate (French)

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.6% (3013 of 3023 strings)

Translated using Weblate (French)

Currently translated at 99.4% (3005 of 3023 strings)

Translated using Weblate (Spanish)

Currently translated at 94.7% (2855 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 43.0% (59 of 137 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (91 of 91 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (377 of 377 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (847 of 847 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (161 of 161 strings)

Co-authored-by: Alberto Pesquera <dashmilel@gmail.com>
Co-authored-by: Alexandre Colombier <arsthenos.colombier@gmail.com>
Co-authored-by: Finrod <963505255@qq.com>
Co-authored-by: Gean Ribeiro <geanribeirok@gmail.com>
Co-authored-by: Ivona Muškinja <ivonamuskinja@gmail.com>
Co-authored-by: Jaime Martí <jaumemarti77@icloud.com>
Co-authored-by: Javiera <javipuga99@gmail.com>
Co-authored-by: Kae <karengong@yeah.net>
Co-authored-by: Karolína Kolčavová <kaja-kolca@seznam.cz>
Co-authored-by: Leslie Munguía <moongeeuh@gmail.com>
Co-authored-by: Marcin Mermela <fishexo@gmail.com>
Co-authored-by: Natalie Luhrs <eilatan@gmail.com>
Co-authored-by: Sophie LE MASLE <sophiesuff@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/cs/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/cs/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/es/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/character/cs/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/es/
Translate-URL: https://translate.habitica.com/projects/habitica/content/cs/
Translate-URL: https://translate.habitica.com/projects/habitica/content/es/
Translate-URL: https://translate.habitica.com/projects/habitica/content/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/cs/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/es/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/cs/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/es/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/cs/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/es/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/pt_BR/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Faq
Translation: Habitica/Gear
Translation: Habitica/Groups
Translation: Habitica/Limited
Translation: Habitica/Messages
Translation: Habitica/Npc
Translation: Habitica/Subscriber
2024-02-27 00:42:12 +01:00
Sabe Jones
2c6e82a58a fix(groups): remove more "Guild" refs 2024-02-21 17:24:16 -06:00
Sabe Jones
e1f0bccb81 fix(backgrounds): fix missing icon and some canvases 2024-02-20 17:58:27 -06:00
Sabe Jones
cd706445f6 5.18.1 2024-02-15 14:50:54 -06:00
Sabe Jones
3896fdd6a2 Merge branch 'develop' into release 2024-02-15 14:50:49 -06:00
Natalie
1842480088 Update Melior Image (#15116)
* add melior.svg

* update melior on header (app & static), footer, and loading

* update loading screen

* update static screens, fix double meliors

* update melior + wordmark size and adjust static page menu spacing

* update package.json

* update index.html, forgot password page, and the static header

* various updates

* static header update

* update mobile web view

* update login page menu bar

* updated purple logo

* removed extraneous class

* update bottom padding on login page(s)

* fix(lint): remove unneeded rule escape

---------

Co-authored-by: Sabe Jones <sabe@habitica.com>
Co-authored-by: Sabe Jones <sabrecat@gmail.com>
2024-02-15 20:48:42 +00:00
Weblate
bb850867c8 Translated using Weblate (Japanese)
Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.4% (3007 of 3023 strings)

Translated using Weblate (Portuguese)

Currently translated at 50.5% (46 of 91 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.2% (3001 of 3023 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 83.9% (115 of 137 strings)

Translated using Weblate (French)

Currently translated at 100.0% (229 of 229 strings)

Translated using Weblate (French)

Currently translated at 100.0% (282 of 282 strings)

Translated using Weblate (French)

Currently translated at 99.7% (426 of 427 strings)

Translated using Weblate (French)

Currently translated at 99.2% (3000 of 3023 strings)

Translated using Weblate (French)

Currently translated at 100.0% (377 of 377 strings)

Translated using Weblate (French)

Currently translated at 100.0% (847 of 847 strings)

Translated using Weblate (Spanish)

Currently translated at 94.3% (2842 of 3013 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.5% (238 of 239 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 83.2% (114 of 137 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (764 of 764 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (377 of 377 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (847 of 847 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 56.9% (78 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (3023 of 3023 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 56.2% (77 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (282 of 282 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 54.0% (74 of 137 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 77.3% (106 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (54 of 54 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 98.1% (750 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (259 of 259 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 98.4% (255 of 259 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 98.0% (253 of 258 strings)

Translated using Weblate (Spanish)

Currently translated at 93.3% (2813 of 3013 strings)

Co-authored-by: Alexandre Colombier <arsthenos.colombier@gmail.com>
Co-authored-by: Finrod <963505255@qq.com>
Co-authored-by: Gean Ribeiro <geanribeirok@gmail.com>
Co-authored-by: Jaime Martí <jaumemarti77@icloud.com>
Co-authored-by: Luã Fhelyp Pacheco Guimarães <fhelypg@gmail.com>
Co-authored-by: TOMA Mitsuru <toma0001@gmail.com>
Co-authored-by: Vinicius Rodrigues <suburbanizar@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/character/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/content/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/content/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/defaulttasks/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/fr/
Translation: Habitica/Backgrounds
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Defaulttasks
Translation: Habitica/Faq
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Limited
Translation: Habitica/Pets
Translation: Habitica/Questscontent
Translation: Habitica/Settings
Translation: Habitica/Subscriber
2024-02-15 17:42:11 +01:00
Sabe Jones
1a3c2f64e4 5.18.0 2024-02-08 14:50:11 -06:00
Sabe Jones
2f42422d35 Squashed commit of the following:
commit 44b1c8c7ba8b45cb682973fb89b70445d0f5c478
Merge: 489c15b7fd 4dadb64af0
Author: Sabe Jones <sabe@habitica.com>
Date:   Thu Feb 8 14:49:05 2024 -0600

    Merge branch 'release' into phillip/panel_profile

commit 489c15b7fd
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Dec 14 13:29:32 2022 +0100

    allow profiles to be edited in admin panel

commit 1afaaf4089
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Dec 14 12:50:47 2022 +0100

    include month for next hourglass date in admin panel
2024-02-08 14:49:37 -06:00
Phillip Thelen
4dadb64af0 Add Customizations and Achievements to admin panel (#15114)
* allow owned customizations to be edited in admin panel

* Allow subscription termination date to be edited more flexibly

* begin adding achievements to admin panel page

* better display for customizations in admin panel

* allow achievements to be modified in admin panel

* fix lint

* fix errors

* Improve how achievements, customizations and items are listed in admin panel

* fix naming

* fix lint error

* Fix issues with achievements in admin panel and add some tests

* handle some edgecases better

* Fix lint

* Fix sort/search on member selection modal (#15066)

* fix(birthday): correct birthday robe ownership check

* feat(content): add February items (#15090)

* update(content): add February 2024 items

* feat(content): add October content

* feat(content):update February Content

* feat(content): finish up February content

* fix(backgrounds): tweak consistency

* fix(strings): remove extra whitespace

* fix(event): add missing Valentine features

---------

Co-authored-by: Sabe Jones <sabrecat@gmail.com>
Co-authored-by: Sabe Jones <sabe@habitica.com>

* 5.17.0

* Translated using Weblate (Ukrainian)

Currently translated at 63.6% (1918 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (61 of 61 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Spanish)

Currently translated at 88.5% (2668 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Bulgarian)

Currently translated at 15.3% (21 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (748 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 88.0% (96 of 109 strings)

Translated using Weblate (Bulgarian)

Currently translated at 98.9% (187 of 189 strings)

Translated using Weblate (Bulgarian)

Currently translated at 59.8% (503 of 840 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.6% (282 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 87.7% (2643 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 87.7% (2643 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (748 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 98.3% (235 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (748 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (47 of 47 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (22 of 22 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 48.1% (66 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (54 of 54 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (748 of 764 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (109 of 109 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 97.8% (822 of 840 strings)

Deleted translation using Weblate (Chinese (Simplified) (zh_HK))

Deleted translation using Weblate (Chinese (Simplified) (zh_HK))

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (22 of 22 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (256 of 256 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (256 of 256 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (256 of 256 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Spanish)

Currently translated at 94.2% (215 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (61 of 61 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.5% (279 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (22 of 22 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 91.3% (390 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Italian)

Currently translated at 94.5% (226 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 37.9% (52 of 137 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 38.6% (53 of 137 strings)

Translated using Weblate (Italian)

Currently translated at 1.4% (2 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (15 of 15 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (748 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 56.0% (51 of 91 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (376 of 376 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (256 of 256 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (256 of 256 strings)

Translated using Weblate (Japanese)

Currently translated at 98.5% (2970 of 3013 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Japanese)

Currently translated at 99.2% (424 of 427 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (109 of 109 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Ukrainian)

Currently translated at 63.0% (1900 of 3013 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (109 of 109 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 97.7% (821 of 840 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 94.4% (2847 of 3013 strings)

Translated using Weblate (Ukrainian)

Currently translated at 62.9% (1897 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (376 of 376 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Ukrainian)

Currently translated at 99.0% (108 of 109 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (840 of 840 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.8% (223 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 94.4% (2845 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 37.9% (52 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.8% (223 of 228 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 91.9% (148 of 161 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 94.4% (2845 of 3013 strings)

Translated using Weblate (Korean)

Currently translated at 2.1% (3 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (13 of 13 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2 of 2 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (1 of 1 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (748 of 764 strings)

Translated using Weblate (Spanish)

Currently translated at 60.4% (55 of 91 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (748 of 764 strings)

Translated using Weblate (Italian)

Currently translated at 98.6% (225 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 94.2% (2841 of 3013 strings)

Translated using Weblate (Russian)

Currently translated at 18.9% (26 of 137 strings)

Translated using Weblate (Italian)

Currently translated at 93.9% (789 of 840 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (161 of 161 strings)

Translated using Weblate (Russian)

Currently translated at 75.7% (194 of 256 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 94.2% (2841 of 3013 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 91.3% (147 of 161 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 94.2% (2841 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 59.3% (54 of 91 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (47 of 47 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (840 of 840 strings)

Translated using Weblate (Italian)

Currently translated at 98.1% (158 of 161 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (161 of 161 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 94.2% (2841 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (748 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (840 of 840 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (256 of 256 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Spanish)

Currently translated at 92.1% (210 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (13 of 13 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (61 of 61 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (61 of 61 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.5% (279 of 283 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 94.0% (2835 of 3013 strings)

Translated using Weblate (Ukrainian)

Currently translated at 62.8% (1894 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (224 of 224 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 21.1% (29 of 137 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (764 of 764 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (47 of 47 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (376 of 376 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (109 of 109 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (840 of 840 strings)

Translated using Weblate (Spanish)

Currently translated at 78.1% (200 of 256 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.1% (816 of 840 strings)

Co-authored-by: Alberto Pesquera <dashmilel@gmail.com>
Co-authored-by: Alcatraz Huo <alrcatraz@gmail.com>
Co-authored-by: Alessandro Losi <pipipe550@hotmail.com>
Co-authored-by: Delta S <deseji93@gmail.com>
Co-authored-by: Dimitar Kraev <dimkraeff@gmail.com>
Co-authored-by: Finrod <963505255@qq.com>
Co-authored-by: Gean Ribeiro <geanribeirok@gmail.com>
Co-authored-by: Ike Osenberg <ike.osenberg@gmail.com>
Co-authored-by: Jaime Martí <jaumemarti77@icloud.com>
Co-authored-by: Jerry Chen <minecjraft@qq.com>
Co-authored-by: Kedr <sergeysamori.ua@gmail.com>
Co-authored-by: Nikita Maximov <ruvemaximus@gmail.com>
Co-authored-by: Omar Bertolla <scaram@icloud.com>
Co-authored-by: Phillip Thelen <phillip@habitica.com>
Co-authored-by: Roberto Tramontano <roberto.tramontano1@gmail.com>
Co-authored-by: TOMA Mitsuru <toma0001@gmail.com>
Co-authored-by: Vinicius Rodrigues <suburbanizar@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: nelly <nellychopyuk@gmail.com>
Co-authored-by: tony <duzhe163908@gmail.com>
Co-authored-by: 이수진 <govl09876@naver.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/es/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/it/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/bg/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/es/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/it/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/es/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/character/bg/
Translate-URL: https://translate.habitica.com/projects/habitica/character/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/character/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/es/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/content/es/
Translate-URL: https://translate.habitica.com/projects/habitica/content/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/content/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/es/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/death/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/defaulttasks/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/bg/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/it/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/front/es/
Translate-URL: https://translate.habitica.com/projects/habitica/front/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/es/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/it/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/es/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/inventory/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/merch/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/es/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/noscript/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/overview/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/quests/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/es/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/rebirth/es/
Translate-URL: https://translate.habitica.com/projects/habitica/rebirth/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/es/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/spells/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/es/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/it/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/es/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/zh_Hans/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Challenge
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Contrib
Translation: Habitica/Death
Translation: Habitica/Defaulttasks
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Inventory
Translation: Habitica/Limited
Translation: Habitica/Loginincentives
Translation: Habitica/Merch
Translation: Habitica/Messages
Translation: Habitica/Noscript
Translation: Habitica/Npc
Translation: Habitica/Overview
Translation: Habitica/Pets
Translation: Habitica/Quests
Translation: Habitica/Questscontent
Translation: Habitica/Rebirth
Translation: Habitica/Settings
Translation: Habitica/Spells
Translation: Habitica/Subscriber
Translation: Habitica/Tasks

* fix(content): fix February background release date

* 5.17.1

* chore(repo): remove duplicate file

* chore(migrations): move various files to archive
and remove erroneous comment bars

* Translated using Weblate (Portuguese)

Currently translated at 96.4% (109 of 113 strings)

Translated using Weblate (Portuguese)

Currently translated at 97.1% (816 of 840 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.9% (2982 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.9% (2982 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.8% (2978 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.2% (2961 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (2951 of 3013 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Korean)

Currently translated at 58.0% (1748 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (2951 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 92.1% (2777 of 3013 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 73.7% (101 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (47 of 47 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (2951 of 3013 strings)

Translated using Weblate (French)

Currently translated at 98.8% (2978 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 90.9% (2741 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (376 of 376 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.2% (2871 of 3013 strings)

Translated using Weblate (French)

Currently translated at 98.5% (2969 of 3013 strings)

Translated using Weblate (French)

Currently translated at 100.0% (183 of 183 strings)

Translated using Weblate (Spanish)

Currently translated at 32.8% (45 of 137 strings)

Translated using Weblate (French)

Currently translated at 100.0% (109 of 109 strings)

Translated using Weblate (French)

Currently translated at 100.0% (840 of 840 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.2% (2989 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 90.5% (2729 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 90.5% (2729 of 3013 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.0% (2983 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 89.7% (2703 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 89.4% (2695 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 98.2% (2959 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 89.1% (2685 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Spanish)

Currently translated at 93.9% (266 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (183 of 183 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (258 of 258 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 91.9% (148 of 161 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 99.4% (182 of 183 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (376 of 376 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (258 of 258 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (258 of 258 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 97.3% (2932 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (183 of 183 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (91 of 91 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (376 of 376 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (109 of 109 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (840 of 840 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (61 of 61 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (183 of 183 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (183 of 183 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (748 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 88.0% (96 of 109 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (840 of 840 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (258 of 258 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 73.2% (189 of 258 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.6% (837 of 840 strings)

Co-authored-by: Delta S <deseji93@gmail.com>
Co-authored-by: Finrod <963505255@qq.com>
Co-authored-by: Gean Ribeiro <geanribeirok@gmail.com>
Co-authored-by: Icaro <icaro.mascarenhas@outlook.com>
Co-authored-by: Jaime Martí <jaumemarti77@icloud.com>
Co-authored-by: Natalie Luhrs <eilatan@gmail.com>
Co-authored-by: Quim Martínez Lara <quimml60@gmail.com>
Co-authored-by: Sophie LE MASLE <sophiesuff@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: 김경은 <kekim.lang@gmail.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/character/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/es/
Translate-URL: https://translate.habitica.com/projects/habitica/content/es/
Translate-URL: https://translate.habitica.com/projects/habitica/content/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/es/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/front/es/
Translate-URL: https://translate.habitica.com/projects/habitica/front/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/front/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/front/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/es/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/quests/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/es/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/spells/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/spells/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/zh_Hans/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Challenge
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Contrib
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Limited
Translation: Habitica/Messages
Translation: Habitica/Npc
Translation: Habitica/Pets
Translation: Habitica/Quests
Translation: Habitica/Questscontent
Translation: Habitica/Settings
Translation: Habitica/Spells
Translation: Habitica/Subscriber
Translation: Habitica/Tasks

---------

Co-authored-by: Leonardo Chappuis <40621126+leonardochappuis@users.noreply.github.com>
Co-authored-by: Sabe Jones <sabe@habitica.com>
Co-authored-by: Natalie <78037386+CuriousMagpie@users.noreply.github.com>
Co-authored-by: Sabe Jones <sabrecat@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Alberto Pesquera <dashmilel@gmail.com>
Co-authored-by: Alcatraz Huo <alrcatraz@gmail.com>
Co-authored-by: Alessandro Losi <pipipe550@hotmail.com>
Co-authored-by: Delta S <deseji93@gmail.com>
Co-authored-by: Dimitar Kraev <dimkraeff@gmail.com>
Co-authored-by: Finrod <963505255@qq.com>
Co-authored-by: Gean Ribeiro <geanribeirok@gmail.com>
Co-authored-by: Ike Osenberg <ike.osenberg@gmail.com>
Co-authored-by: Jaime Martí <jaumemarti77@icloud.com>
Co-authored-by: Jerry Chen <minecjraft@qq.com>
Co-authored-by: Kedr <sergeysamori.ua@gmail.com>
Co-authored-by: Nikita Maximov <ruvemaximus@gmail.com>
Co-authored-by: Omar Bertolla <scaram@icloud.com>
Co-authored-by: Roberto Tramontano <roberto.tramontano1@gmail.com>
Co-authored-by: TOMA Mitsuru <toma0001@gmail.com>
Co-authored-by: Vinicius Rodrigues <suburbanizar@gmail.com>
Co-authored-by: nelly <nellychopyuk@gmail.com>
Co-authored-by: tony <duzhe163908@gmail.com>
Co-authored-by: 이수진 <govl09876@naver.com>
Co-authored-by: CuriousMagpie <eilatan@gmail.com>
Co-authored-by: Icaro <icaro.mascarenhas@outlook.com>
Co-authored-by: Quim Martínez Lara <quimml60@gmail.com>
Co-authored-by: Sophie LE MASLE <sophiesuff@gmail.com>
Co-authored-by: 김경은 <kekim.lang@gmail.com>
2024-02-08 14:45:07 -06:00
Sabe Jones
88611aeb80 Merge branch 'sabrecat/gmail-oneclick' into release 2024-02-08 14:33:36 -06:00
Sabe Jones
29f555ac5c Merge branch 'develop' into release 2024-02-08 14:31:06 -06:00
Weblate
49082714d7 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (22 of 22 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (3023 of 3023 strings)

Translated using Weblate (Russian)

Currently translated at 96.3% (2912 of 3023 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (183 of 183 strings)

Translated using Weblate (Russian)

Currently translated at 19.7% (27 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (377 of 377 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (377 of 377 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (109 of 109 strings)

Translated using Weblate (Russian)

Currently translated at 77.1% (199 of 258 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (3023 of 3023 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (183 of 183 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (109 of 109 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.1% (2997 of 3023 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 91.4% (236 of 258 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.1% (2997 of 3023 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.0% (2993 of 3023 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.0% (2993 of 3023 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.9% (2991 of 3023 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (229 of 229 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (282 of 282 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.7% (2986 of 3023 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (377 of 377 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (847 of 847 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (258 of 258 strings)

Translated using Weblate (Spanish)

Currently translated at 92.8% (2797 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (258 of 258 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 82.9% (214 of 258 strings)

Translated using Weblate (Spanish)

Currently translated at 92.8% (2797 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 92.8% (2797 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 92.6% (2792 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 92.3% (2784 of 3013 strings)

Co-authored-by: Alcatraz Huo <alrcatraz@gmail.com>
Co-authored-by: Finrod <963505255@qq.com>
Co-authored-by: Gean Ribeiro <geanribeirok@gmail.com>
Co-authored-by: Ike Osenberg <ike.osenberg@gmail.com>
Co-authored-by: Jaime Martí <jaumemarti77@icloud.com>
Co-authored-by: Valeria <dbrvvk@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/content/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/content/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/front/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/front/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/zh_Hans/
Translation: Habitica/Backgrounds
Translation: Habitica/Challenge
Translation: Habitica/Content
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Limited
Translation: Habitica/Loginincentives
Translation: Habitica/Settings
Translation: Habitica/Subscriber
Translation: Habitica/Tasks
2024-02-08 21:27:44 +01:00
CuriousMagpie
5be019864f chore(git): update .gitignore 2024-02-07 17:31:58 -05:00
Sabe Jones
91795875b5 feat(email): allow unsub via POST request 2024-02-07 16:09:23 -06:00
Phillip Thelen
67a6e6f8ac Add Content Release notification type (#15101) 2024-02-06 14:06:44 -06:00
Sabe Jones
e95f1cf003 5.17.2 2024-02-06 13:58:08 -06:00
Sabe Jones
90bd743816 Merge branch 'develop' into release 2024-02-06 13:58:01 -06:00
Weblate
76e5e8c069 Translated using Weblate (Portuguese)
Currently translated at 96.4% (109 of 113 strings)

Translated using Weblate (Portuguese)

Currently translated at 97.1% (816 of 840 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.9% (2982 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.9% (2982 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.8% (2978 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.2% (2961 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (2951 of 3013 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Korean)

Currently translated at 58.0% (1748 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (2951 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 92.1% (2777 of 3013 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 73.7% (101 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (47 of 47 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (2951 of 3013 strings)

Translated using Weblate (French)

Currently translated at 98.8% (2978 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 90.9% (2741 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (376 of 376 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.2% (2871 of 3013 strings)

Translated using Weblate (French)

Currently translated at 98.5% (2969 of 3013 strings)

Translated using Weblate (French)

Currently translated at 100.0% (183 of 183 strings)

Translated using Weblate (Spanish)

Currently translated at 32.8% (45 of 137 strings)

Translated using Weblate (French)

Currently translated at 100.0% (109 of 109 strings)

Translated using Weblate (French)

Currently translated at 100.0% (840 of 840 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.2% (2989 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 90.5% (2729 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 90.5% (2729 of 3013 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.0% (2983 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 89.7% (2703 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 89.4% (2695 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 98.2% (2959 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 89.1% (2685 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Spanish)

Currently translated at 93.9% (266 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (183 of 183 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (258 of 258 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 91.9% (148 of 161 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 99.4% (182 of 183 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (376 of 376 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (258 of 258 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (258 of 258 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 97.3% (2932 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (183 of 183 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (91 of 91 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (376 of 376 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (109 of 109 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (840 of 840 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (749 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (61 of 61 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (183 of 183 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (183 of 183 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (748 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 88.0% (96 of 109 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (840 of 840 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (258 of 258 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 73.2% (189 of 258 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.6% (837 of 840 strings)

Co-authored-by: Delta S <deseji93@gmail.com>
Co-authored-by: Finrod <963505255@qq.com>
Co-authored-by: Gean Ribeiro <geanribeirok@gmail.com>
Co-authored-by: Icaro <icaro.mascarenhas@outlook.com>
Co-authored-by: Jaime Martí <jaumemarti77@icloud.com>
Co-authored-by: Natalie Luhrs <eilatan@gmail.com>
Co-authored-by: Quim Martínez Lara <quimml60@gmail.com>
Co-authored-by: Sophie LE MASLE <sophiesuff@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: 김경은 <kekim.lang@gmail.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/character/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/es/
Translate-URL: https://translate.habitica.com/projects/habitica/content/es/
Translate-URL: https://translate.habitica.com/projects/habitica/content/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/es/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/front/es/
Translate-URL: https://translate.habitica.com/projects/habitica/front/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/front/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/front/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/es/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/quests/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/es/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/spells/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/spells/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/zh_Hans/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Challenge
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Contrib
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Limited
Translation: Habitica/Messages
Translation: Habitica/Npc
Translation: Habitica/Pets
Translation: Habitica/Quests
Translation: Habitica/Questscontent
Translation: Habitica/Settings
Translation: Habitica/Spells
Translation: Habitica/Subscriber
Translation: Habitica/Tasks
2024-02-06 20:57:18 +01:00
Sabe Jones
12c75b7488 Merge branch 'develop' into release 2024-02-06 11:50:47 -06:00
Sabe Jones
eed7c9aabc fix(test): no longer expect keepAlive 2024-02-05 17:27:37 -06:00
Sabe Jones
f74160c16a chore(deprecations): clean out some warnings 2024-02-05 16:50:06 -06:00
Sabe Jones
2ba74f1645 chore(migrations): move various files to archive
and remove erroneous comment bars
2024-02-05 15:34:53 -06:00
Sabe Jones
200af2cf16 chore(migrations): move various files to archive
and remove erroneous comment bars
2024-02-05 15:34:43 -06:00
negue
8b373b9283 allow liking their own message (#15117) 2024-02-05 14:55:46 -06:00
SabreCat
2fa26db93f chore(repo): remove duplicate file 2024-02-02 14:50:02 -06:00
Sabe Jones
bd5c669374 5.17.1 2024-02-01 15:34:35 -06:00
CuriousMagpie
5626991074 fix(content): fix February background release date 2024-02-01 15:43:11 -05:00
Sabe Jones
a3fd55d56e Merge branch 'develop' into release 2024-01-26 16:44:36 -06:00
Weblate
27eedaf347 Merge branch 'origin/develop' into Weblate. 2024-01-26 23:42:51 +01:00
Sabe Jones
11baeda71e 5.17.0 2024-01-26 16:35:55 -06:00
Natalie
0b5ce61555 feat(content): add February items (#15090)
* update(content): add February 2024 items

* feat(content): add October content

* feat(content):update February Content

* feat(content): finish up February content

* fix(backgrounds): tweak consistency

* fix(strings): remove extra whitespace

* fix(event): add missing Valentine features

---------

Co-authored-by: Sabe Jones <sabrecat@gmail.com>
Co-authored-by: Sabe Jones <sabe@habitica.com>
2024-01-26 16:35:02 -06:00
Weblate
1c617d90aa Translated using Weblate (Ukrainian)
Currently translated at 63.6% (1918 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (61 of 61 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Spanish)

Currently translated at 88.5% (2668 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Bulgarian)

Currently translated at 15.3% (21 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (748 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 88.0% (96 of 109 strings)

Translated using Weblate (Bulgarian)

Currently translated at 98.9% (187 of 189 strings)

Translated using Weblate (Bulgarian)

Currently translated at 59.8% (503 of 840 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.6% (282 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 87.7% (2643 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 87.7% (2643 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (748 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 98.3% (235 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (748 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (47 of 47 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (22 of 22 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 48.1% (66 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (54 of 54 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (748 of 764 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (109 of 109 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 97.8% (822 of 840 strings)

Deleted translation using Weblate (Chinese (Simplified) (zh_HK))

Deleted translation using Weblate (Chinese (Simplified) (zh_HK))

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (22 of 22 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (256 of 256 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (256 of 256 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (256 of 256 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Spanish)

Currently translated at 94.2% (215 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (61 of 61 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.5% (279 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (22 of 22 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 91.3% (390 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Italian)

Currently translated at 94.5% (226 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 37.9% (52 of 137 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 38.6% (53 of 137 strings)

Translated using Weblate (Italian)

Currently translated at 1.4% (2 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (15 of 15 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (748 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 56.0% (51 of 91 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (376 of 376 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (256 of 256 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (256 of 256 strings)

Translated using Weblate (Japanese)

Currently translated at 98.5% (2970 of 3013 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Japanese)

Currently translated at 99.2% (424 of 427 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (109 of 109 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.1% (2867 of 3013 strings)

Translated using Weblate (Ukrainian)

Currently translated at 63.0% (1900 of 3013 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (109 of 109 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 97.7% (821 of 840 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (228 of 228 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (283 of 283 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 94.4% (2847 of 3013 strings)

Translated using Weblate (Ukrainian)

Currently translated at 62.9% (1897 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (376 of 376 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Ukrainian)

Currently translated at 99.0% (108 of 109 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (840 of 840 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.8% (223 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 94.4% (2845 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 37.9% (52 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.8% (223 of 228 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 91.9% (148 of 161 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 94.4% (2845 of 3013 strings)

Translated using Weblate (Korean)

Currently translated at 2.1% (3 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (13 of 13 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2 of 2 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (1 of 1 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (748 of 764 strings)

Translated using Weblate (Spanish)

Currently translated at 60.4% (55 of 91 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (748 of 764 strings)

Translated using Weblate (Italian)

Currently translated at 98.6% (225 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 94.2% (2841 of 3013 strings)

Translated using Weblate (Russian)

Currently translated at 18.9% (26 of 137 strings)

Translated using Weblate (Italian)

Currently translated at 93.9% (789 of 840 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (161 of 161 strings)

Translated using Weblate (Russian)

Currently translated at 75.7% (194 of 256 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 94.2% (2841 of 3013 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 91.3% (147 of 161 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 94.2% (2841 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 59.3% (54 of 91 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (47 of 47 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (840 of 840 strings)

Translated using Weblate (Italian)

Currently translated at 98.1% (158 of 161 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (161 of 161 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 94.2% (2841 of 3013 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.9% (748 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (840 of 840 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (256 of 256 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Spanish)

Currently translated at 92.1% (210 of 228 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (13 of 13 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (61 of 61 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (61 of 61 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.5% (279 of 283 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 94.0% (2835 of 3013 strings)

Translated using Weblate (Ukrainian)

Currently translated at 62.8% (1894 of 3013 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (224 of 224 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 21.1% (29 of 137 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (764 of 764 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (47 of 47 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (376 of 376 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (109 of 109 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (840 of 840 strings)

Translated using Weblate (Spanish)

Currently translated at 78.1% (200 of 256 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.1% (816 of 840 strings)

Co-authored-by: Alberto Pesquera <dashmilel@gmail.com>
Co-authored-by: Alcatraz Huo <alrcatraz@gmail.com>
Co-authored-by: Alessandro Losi <pipipe550@hotmail.com>
Co-authored-by: Delta S <deseji93@gmail.com>
Co-authored-by: Dimitar Kraev <dimkraeff@gmail.com>
Co-authored-by: Finrod <963505255@qq.com>
Co-authored-by: Gean Ribeiro <geanribeirok@gmail.com>
Co-authored-by: Ike Osenberg <ike.osenberg@gmail.com>
Co-authored-by: Jaime Martí <jaumemarti77@icloud.com>
Co-authored-by: Jerry Chen <minecjraft@qq.com>
Co-authored-by: Kedr <sergeysamori.ua@gmail.com>
Co-authored-by: Nikita Maximov <ruvemaximus@gmail.com>
Co-authored-by: Omar Bertolla <scaram@icloud.com>
Co-authored-by: Phillip Thelen <phillip@habitica.com>
Co-authored-by: Roberto Tramontano <roberto.tramontano1@gmail.com>
Co-authored-by: TOMA Mitsuru <toma0001@gmail.com>
Co-authored-by: Vinicius Rodrigues <suburbanizar@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: nelly <nellychopyuk@gmail.com>
Co-authored-by: tony <duzhe163908@gmail.com>
Co-authored-by: 이수진 <govl09876@naver.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/es/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/it/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/bg/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/es/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/it/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/es/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/character/bg/
Translate-URL: https://translate.habitica.com/projects/habitica/character/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/character/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/es/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/content/es/
Translate-URL: https://translate.habitica.com/projects/habitica/content/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/content/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/es/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/death/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/defaulttasks/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/bg/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/it/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/front/es/
Translate-URL: https://translate.habitica.com/projects/habitica/front/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/es/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/it/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/es/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/inventory/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/merch/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/es/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/noscript/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/overview/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/quests/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/es/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/rebirth/es/
Translate-URL: https://translate.habitica.com/projects/habitica/rebirth/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/es/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/spells/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/es/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/it/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/es/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/zh_Hans/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Challenge
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Contrib
Translation: Habitica/Death
Translation: Habitica/Defaulttasks
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Inventory
Translation: Habitica/Limited
Translation: Habitica/Loginincentives
Translation: Habitica/Merch
Translation: Habitica/Messages
Translation: Habitica/Noscript
Translation: Habitica/Npc
Translation: Habitica/Overview
Translation: Habitica/Pets
Translation: Habitica/Quests
Translation: Habitica/Questscontent
Translation: Habitica/Rebirth
Translation: Habitica/Settings
Translation: Habitica/Spells
Translation: Habitica/Subscriber
Translation: Habitica/Tasks
2024-01-26 21:46:26 +01:00
Sabe Jones
724c710636 fix(birthday): correct birthday robe ownership check 2024-01-23 15:08:20 -06:00
Leonardo Chappuis
6d62ecdf17 Fix sort/search on member selection modal (#15066) 2024-01-23 15:06:54 -06:00
Sabe Jones
bfe7c263cb 5.16.1 2024-01-18 15:52:21 -06:00
Sabe Jones
987b6949c9 fix(hall): mark items modified 2024-01-18 15:52:18 -06:00
Phillip Thelen
1ade4c6b3e Fix resetting account for social accounts (#15087)
* Fix resetting account for social accounts

* added integration tests

* chore(packages): reinstall modules

* only enable reset button if user typed RESET

* fix enabling reset button

---------

Co-authored-by: negue <eugen.bolz@gmail.com>
Co-authored-by: Sabe Jones <sabe@habitica.com>
2024-01-18 15:51:36 -06:00
Sabe Jones
67069b1adc 5.16.0 2024-01-16 15:40:53 -06:00
Weblate
29e4a62ba7 Merge branch 'origin/develop' into Weblate. 2024-01-16 22:34:32 +01:00
Weblate
87eb067fb5 Translated using Weblate (Spanish)
Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (424 of 424 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (424 of 424 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (424 of 424 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (108 of 108 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 89.4% (144 of 161 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 89.4% (144 of 161 strings)

Translated using Weblate (Spanish)

Currently translated at 91.0% (254 of 279 strings)

Translated using Weblate (Spanish)

Currently translated at 88.4% (2627 of 2969 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Spanish)

Currently translated at 92.3% (769 of 833 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (161 of 161 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (161 of 161 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.3% (110 of 113 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.3% (2832 of 2969 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.8% (229 of 239 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 96.9% (808 of 833 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Spanish)

Currently translated at 87.4% (2597 of 2969 strings)

Translated using Weblate (Spanish)

Currently translated at 31.3% (43 of 137 strings)

Translated using Weblate (Spanish)

Currently translated at 99.3% (160 of 161 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 13.1% (18 of 137 strings)

Translated using Weblate (Spanish)

Currently translated at 99.3% (160 of 161 strings)

Translated using Weblate (Spanish)

Currently translated at 99.3% (160 of 161 strings)

Translated using Weblate (Portuguese)

Currently translated at 20.4% (28 of 137 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (161 of 161 strings)

Translated using Weblate (German)

Currently translated at 100.0% (161 of 161 strings)

Translated using Weblate (French)

Currently translated at 100.0% (91 of 91 strings)

Translated using Weblate (French)

Currently translated at 99.9% (2968 of 2969 strings)

Translated using Weblate (Korean)

Currently translated at 75.1% (121 of 161 strings)

Translated using Weblate (Korean)

Currently translated at 73.9% (119 of 161 strings)

Translated using Weblate (Korean)

Currently translated at 73.9% (119 of 161 strings)

Translated using Weblate (Korean)

Currently translated at 73.2% (118 of 161 strings)

Translated using Weblate (Korean)

Currently translated at 73.2% (118 of 161 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (161 of 161 strings)

Translated using Weblate (Ukrainian)

Currently translated at 58.1% (1727 of 2969 strings)

Translated using Weblate (Russian)

Currently translated at 14.5% (20 of 137 strings)

Translated using Weblate (Ukrainian)

Currently translated at 58.0% (1723 of 2969 strings)

Translated using Weblate (Ukrainian)

Currently translated at 57.9% (1722 of 2969 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (833 of 833 strings)

Translated using Weblate (Ukrainian)

Currently translated at 99.2% (827 of 833 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Dutch)

Currently translated at 97.3% (184 of 189 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (256 of 256 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (227 of 227 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (424 of 424 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (279 of 279 strings)

Translated using Weblate (French)

Currently translated at 100.0% (227 of 227 strings)

Translated using Weblate (French)

Currently translated at 99.9% (2968 of 2969 strings)

Translated using Weblate (French)

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (91 of 91 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (2969 of 2969 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (256 of 256 strings)

Translated using Weblate (Japanese)

Currently translated at 70.8% (97 of 137 strings)

Translated using Weblate (Spanish)

Currently translated at 22.6% (31 of 137 strings)

Translated using Weblate (Japanese)

Currently translated at 67.1% (92 of 137 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (833 of 833 strings)

Translated using Weblate (Japanese)

Currently translated at 33.5% (46 of 137 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (256 of 256 strings)

Translated using Weblate (Spanish)

Currently translated at 21.1% (29 of 137 strings)

Translated using Weblate (Japanese)

Currently translated at 30.6% (42 of 137 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (108 of 108 strings)

Translated using Weblate (French)

Currently translated at 100.0% (833 of 833 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (279 of 279 strings)

Translated using Weblate (Japanese)

Currently translated at 99.2% (139 of 140 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (226 of 226 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (91 of 91 strings)

Translated using Weblate (Japanese)

Currently translated at 85.1% (218 of 256 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (161 of 161 strings)

Translated using Weblate (Japanese)

Currently translated at 98.3% (2921 of 2969 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (764 of 764 strings)

Translated using Weblate (Japanese)

Currently translated at 21.8% (30 of 137 strings)

Translated using Weblate (Spanish)

Currently translated at 18.2% (25 of 137 strings)

Translated using Weblate (Spanish)

Currently translated at 15.3% (21 of 137 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (424 of 424 strings)

Translated using Weblate (Ukrainian)

Currently translated at 57.4% (1707 of 2969 strings)

Translated using Weblate (Spanish)

Currently translated at 6.5% (9 of 137 strings)

Translated using Weblate (Spanish)

Currently translated at 5.1% (7 of 137 strings)

Translated using Weblate (Japanese)

Currently translated at 99.5% (225 of 226 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 2.9% (4 of 137 strings)

Translated using Weblate (French)

Currently translated at 86.8% (119 of 137 strings)

Translated using Weblate (Spanish)

Currently translated at 2.1% (3 of 137 strings)

Translated using Weblate (Japanese)

Currently translated at 7.2% (10 of 137 strings)

Translated using Weblate (Japanese)

Currently translated at 96.2% (104 of 108 strings)

Translated using Weblate (Ukrainian)

Currently translated at 57.4% (1707 of 2969 strings)

Translated using Weblate (Ukrainian)

Currently translated at 56.3% (1673 of 2969 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (764 of 764 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (161 of 161 strings)

Translated using Weblate (French)

Currently translated at 84.6% (116 of 137 strings)

Translated using Weblate (Russian)

Currently translated at 98.3% (2911 of 2961 strings)

Translated using Weblate (French)

Currently translated at 75.9% (104 of 137 strings)

Translated using Weblate (French)

Currently translated at 100.0% (764 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.2% (254 of 256 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.4% (252 of 256 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Ukrainian)

Currently translated at 55.7% (1650 of 2961 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (108 of 108 strings)

Translated using Weblate (French)

Currently translated at 74.4% (102 of 137 strings)

Translated using Weblate (French)

Currently translated at 51.8% (71 of 137 strings)

Translated using Weblate (French)

Currently translated at 48.9% (67 of 137 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 5.8% (8 of 137 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (764 of 764 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (424 of 424 strings)

Translated using Weblate (Japanese)

Currently translated at 99.5% (238 of 239 strings)

Translated using Weblate (French)

Currently translated at 43.0% (59 of 137 strings)

Translated using Weblate (Ukrainian)

Currently translated at 54.1% (1603 of 2961 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (764 of 764 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (424 of 424 strings)

Translated using Weblate (Ukrainian)

Currently translated at 99.2% (136 of 137 strings)

Translated using Weblate (Ukrainian)

Currently translated at 84.6% (116 of 137 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 81.2% (2406 of 2961 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 95.5% (108 of 113 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 80.8% (2394 of 2961 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 0.7% (1 of 137 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 89.8% (97 of 108 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 62.8% (161 of 256 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (226 of 226 strings)

Translated using Weblate (Ukrainian)

Currently translated at 83.9% (115 of 137 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (764 of 764 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (826 of 826 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (161 of 161 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.3% (110 of 113 strings)

Translated using Weblate (French)

Currently translated at 99.9% (2960 of 2961 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 4.3% (6 of 137 strings)

Translated using Weblate (French)

Currently translated at 100.0% (764 of 764 strings)

Translated using Weblate (Korean)

Currently translated at 48.3% (88 of 182 strings)

Translated using Weblate (Korean)

Currently translated at 75.5% (624 of 826 strings)

Translated using Weblate (Korean)

Currently translated at 53.7% (150 of 279 strings)

Translated using Weblate (Korean)

Currently translated at 100.0% (376 of 376 strings)

Translated using Weblate (Korean)

Currently translated at 65.6% (168 of 256 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.3% (157 of 158 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 87.5% (224 of 256 strings)

Translated using Weblate (French)

Currently translated at 100.0% (226 of 226 strings)

Translated using Weblate (French)

Currently translated at 98.7% (2923 of 2961 strings)

Translated using Weblate (French)

Currently translated at 100.0% (108 of 108 strings)

Translated using Weblate (French)

Currently translated at 100.0% (826 of 826 strings)

Translated using Weblate (French)

Currently translated at 100.0% (161 of 161 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.4% (154 of 158 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 97.8% (137 of 140 strings)

Translated using Weblate (Portuguese)

Currently translated at 7.2% (10 of 137 strings)

Translated using Weblate (German)

Currently translated at 98.5% (135 of 137 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (91 of 91 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (108 of 108 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (819 of 819 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (812 of 812 strings)

Translated using Weblate (German)

Currently translated at 4.3% (6 of 137 strings)

Translated using Weblate (German)

Currently translated at 99.3% (157 of 158 strings)

Deleted translation using Weblate (tl_PH (generated) (tl_PH))

Deleted translation using Weblate (tl_PH (generated) (tl_PH))

Deleted translation using Weblate (no (generated) (no))

Deleted translation using Weblate (no (generated) (no))

Deleted translation using Weblate (hi (generated))

Deleted translation using Weblate (hi (generated))

Deleted translation using Weblate (fa (generated))

Deleted translation using Weblate (fa (generated))

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (158 of 158 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (158 of 158 strings)

Co-authored-by: AGM <yoartgm@gmail.com>
Co-authored-by: Alberto Pesquera <dashmilel@gmail.com>
Co-authored-by: Alcatraz Huo <alrcatraz@gmail.com>
Co-authored-by: Artem StolyROV <stolyarov11303@gmail.com>
Co-authored-by: Bruno Marvin <itsbruno42@gmail.com>
Co-authored-by: Delta S <deseji93@gmail.com>
Co-authored-by: Finrod <963505255@qq.com>
Co-authored-by: Gean Ribeiro <geanribeirok@gmail.com>
Co-authored-by: Henrique Lavezzo <hlavezzo@hey.com>
Co-authored-by: Icaro Alves Pinto <fly-too-high@hotmail.com>
Co-authored-by: Jaime Martí <jaumemarti77@icloud.com>
Co-authored-by: Jan met de Pet <stijn.koppers@gmail.com>
Co-authored-by: Juan Esteban Marín <juanmarin690@gmail.com>
Co-authored-by: Lapin <sirocuro01@gmail.com>
Co-authored-by: Lauren Chiang <laurenrenc@gmail.com>
Co-authored-by: Lorea <loreamartinez@yahoo.es>
Co-authored-by: LucilleL <lecointrefreelancing@gmail.com>
Co-authored-by: Luã Fhelyp Pacheco Guimarães <fhelypg@gmail.com>
Co-authored-by: Maria Otonuo <mariaotonio@gmail.com>
Co-authored-by: Marius <mariusschmid11@gmail.com>
Co-authored-by: Martim Pinto Paiva <pintopaivam@gmail.com>
Co-authored-by: Natalie Luhrs <eilatan@gmail.com>
Co-authored-by: Nathan Monteiro <nathanspeeds1@outlook.com>
Co-authored-by: Nazar Paruna <nazarparuna@gmail.com>
Co-authored-by: Oli Chag <sifto11@hotmail.com>
Co-authored-by: Phillip Thelen <phillip@habitica.com>
Co-authored-by: Rodrigo Gonçalves Braga <rgbraga@gmail.com>
Co-authored-by: Sophie LE MASLE <sophiesuff@gmail.com>
Co-authored-by: SunshineRain <suusykraft@gmail.com>
Co-authored-by: TOMA Mitsuru <toma0001@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Yan <1223889952@qq.com>
Co-authored-by: Yan <ariamao0802@gmail.com>
Co-authored-by: doyo <doyochoi@kaist.ac.kr>
Co-authored-by: endriw cisersa batistela correa <endriwbatistela@gmail.com>
Co-authored-by: fred4real <1487463579@qq.com>
Co-authored-by: theBlinking <lingocommonwealth@schneekatze.nl>
Co-authored-by: 張鈞崴 <qoo94230@gmail.com>
Co-authored-by: 박동훈 <creator98@naver.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/de/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/es/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/nl/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/es/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/es/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/character/es/
Translate-URL: https://translate.habitica.com/projects/habitica/character/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/character/nl/
Translate-URL: https://translate.habitica.com/projects/habitica/character/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/character/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/character/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/content/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/de/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/es/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/front/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/front/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/es/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/es/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/es/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/overview/es/
Translate-URL: https://translate.habitica.com/projects/habitica/overview/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/es/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/uk/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Challenge
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Limited
Translation: Habitica/Npc
Translation: Habitica/Overview
Translation: Habitica/Pets
Translation: Habitica/Questscontent
Translation: Habitica/Settings
Translation: Habitica/Subscriber
Translation: Habitica/Tasks
2024-01-16 22:34:23 +01:00
Phillip Thelen
f8d315ff6e Upgrade to mongoose 7 (#14971)
* remove some unused dependencies

* update mongoose version

* make common tests pass

* Make unit tests pass

* make api v3 integration tests pass

* fix lint issues

* fix issue with package-lock

* fix(lint): we don't need no .js

* fix(lint): update to latest config-habitrpg

* chore(npm): update package locks

* fix(test): replace deprecated fn

* chore(package): update eslint-habitrpg again

* fix(lint): server linting

* fix(lint): client linting

* fix(client): correct mangled common imports

* chore(npm): update package-locks

* fix(lint): punctuation, module

---------

Co-authored-by: SabreCat <sabrecat@gmail.com>
Co-authored-by: SabreCat <sabe@habitica.com>
2024-01-16 15:18:47 -06:00
Phillip Thelen
d0e4b533e3 Add new fields to admin panel (#14943)
* Add new fields to admin panel

* fix lint

* Update hall.js

* fix(plab): plab

* fix(lint): destructure assignment

* fix(subs): coerce offset to number

---------

Co-authored-by: SabreCat <sabe@habitica.com>
2024-01-16 14:45:57 -06:00
Natalie
d6d131647a Report Post Modal Design Refresh (#14774)
* WIP(chat flags): initial commit

* WIP(chat flags): actually disabling the button

* wip(chat flags): remove duplicated code

* fix(css): target intended modal

* WIP(report post modal): fix blockquote & missing string

* WIP(report post): blockquote formatting

* fix(sanity): remove dup string

---------

Co-authored-by: SabreCat <sabe@habitica.com>
Co-authored-by: Sabe Jones <sabrecat@gmail.com>
2024-01-16 14:42:02 -06:00
Natalie
4cbc3d7664 Slur swear blocker challenges redux (#15089)
* update packages on local/origin repo

* feat(challenges): add banned words & slur blocker to challenges

* feat(challenges): slur blocker work

* feat(challenges): slur blocker

* feat(challenges): more slur blocker

* feat(challenges): even more slur blocker

* feat(challenges): swear and slur blocker

* feat(challenges): update behavior based on public/private groups

* feat(profiles): slur/swear blocker

* feat(profiles): slur/swear blocker

* feat(profiles/PMs): slur/swear blocker upgrade

* feat(slur/swear): working on it

* feat(profiles/challenges): work on profile block & slack report

* feat(slur/swear blocker): work on Profiles

* feat(slur blocker): refactoring code

* feat(slur blocker): more refactoring

* feat(slur blocker): arghhhhhh

* fix(profiles): improve profanity check logic

* fix(slack): update Slack notification to include authorEmail and remove undefined

* feat(s/s blocker): work on challenges

* feat(s/s blocker): challenge update

* feat(s/s blocker): slack notifs refinements

* feat(s/s blocker): refine slack notifs & disallow use of challenges POST API route if user is chatRevoked:true in db

* update package.json and package-lock.json

* attempt to disable create challenge button for muted users

* another attempt to disable create challenge

* block muted users from creating challenges

* CSS button fun

* fix CSS button

* refactor(css): move button style to global
Also, disable Clone button if user is chat revoked

* fix(lint): remove unused fn

* fix(challenges): handle null slur check

* fix(groups): throw notFound earlier

* fix(challenges): CSS and logic updates

* fix(lint): remove whitespace

* fix(challenges): don't disable create buttons

* fix(slack): restore broken profile flag fields

* chore(cleanup): remove comments and whitespace

* chore(cleanup): one more white space

---------

Co-authored-by: SabreCat <sabe@habitica.com>
2024-01-16 14:22:03 -06:00
KasaHNO3
8b2e13b5fd fix(faq): add language query in FAQ store action. (#15079)
Co-authored-by: Sabe Jones <sabe@habitica.com>
2024-01-10 17:00:13 -06:00
Sabe Jones
e5b873c9aa 5.15.2 2024-01-10 15:20:49 -06:00
Sabe Jones
2e904dcda0 fix(stable): default to empty string for current animals 2024-01-10 15:19:09 -06:00
Sabe Jones
5300de834f Squashed commit of the following:
commit 4950f403782ba12e54e2254a894b608673e27621
Author: SabreCat <sabrecat@gmail.com>
Date:   Fri Jan 5 16:02:08 2024 -0600

    fix(armoire): remove unreleased items at definition time

commit b195f0c45581c81f8aec7f5ddb105f5fc5aa7767
Author: SabreCat <sabrecat@gmail.com>
Date:   Fri Jan 5 15:37:09 2024 -0600

    Revert "fix(content): filter out unreleased gear"

    This reverts commit 6f9e526d94b1e473eba37e5f40fa6b889cccff1c.

commit 6f9e526d94b1e473eba37e5f40fa6b889cccff1c
Author: SabreCat <sabrecat@gmail.com>
Date:   Thu Jan 4 16:22:39 2024 -0600

    fix(content): filter out unreleased gear
2024-01-10 15:18:36 -06:00
Sabe Jones
b7def686e9 Squashed commit of the following:
commit 83bcd07e20
Author: SabreCat <sabrecat@gmail.com>
Date:   Fri Dec 22 17:24:45 2023 -0600

    fix(profile): revert state on error

commit 6aa6278727
Author: SabreCat <sabrecat@gmail.com>
Date:   Fri Dec 22 14:37:28 2023 -0600

    fix(test): no longer care about swears in profile

commit 0882c77038
Author: SabreCat <sabe@habitica.com>
Date:   Fri Dec 22 14:15:42 2023 -0600

    fix(lint): remove unused functions

commit 9b275ef72d
Author: SabreCat <sabe@habitica.com>
Date:   Fri Dec 22 14:09:11 2023 -0600

    fix(profiles): restore reporting functionality
    Also remove unused and/or unrelated code and clean up comments

commit f4ed8c1461
Merge: da16aa9c75 f8ba191eea
Author: SabreCat <sabe@habitica.com>
Date:   Fri Dec 22 12:11:00 2023 -0600

    Merge branch 'release' into slur-swear-blocker

commit da16aa9c75
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Thu Dec 21 13:20:28 2023 -0500

    feat(s/s blocker): challenge updates to slack

commit 51bed61c4c
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Dec 19 15:36:59 2023 -0500

    feat(s/s blocker): work on challenges

commit 139cbcb21c
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Wed Dec 13 13:20:45 2023 -0500

    fix(slack): update Slack notification to include authorEmail and remove undefined

commit 805b287721
Author: SabreCat <sabe@habitica.com>
Date:   Tue Dec 12 16:35:54 2023 -0600

    fix(profiles): improve profanity check logic

commit 02ef7e8822
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Dec 12 17:22:29 2023 -0500

    feat(slur blocker): arghhhhhh

commit 949dee9b1e
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Dec 12 13:57:29 2023 -0500

    feat(slur blocker): more refactoring

commit bf953998f4
Merge: d21aa687b7 f572aa442e
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Mon Dec 11 15:20:06 2023 -0500

    Merge branch 'release' into slur-swear-blocker

commit d21aa687b7
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Thu Dec 7 18:00:29 2023 -0500

    feat(slur blocker): refactoring code

commit f2db90c494
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Wed Dec 6 12:12:55 2023 -0500

    feat(slur/swear blocker): work on Profiles

commit 8f9822ffe8
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Mon Dec 4 17:25:17 2023 -0500

    feat(profiles/challenges): work on profile block & slack report

commit bdb2e06e5e
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Fri Dec 1 16:11:27 2023 -0500

    feat(slur/swear): working on it

commit 7277b5cad5
Merge: 24d14277ab 941f1f976c
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Fri Dec 1 15:04:46 2023 -0500

    Merge branch 'profile-slur-swear-blocker' into slur-swear-blocker

commit 941f1f976c
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Thu Nov 30 14:34:30 2023 -0500

    feat(profiles/PMs): slur/swear blocker upgrade

commit 0863017efc
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Nov 28 16:21:21 2023 -0500

    feat(profiles): slur/swear blocker

commit e9937d864f
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Mon Nov 27 15:24:37 2023 -0500

    feat(profiles): slur/swear blocker

commit 24d14277ab
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Mon Nov 27 14:12:46 2023 -0500

    feat(challenges): update behavior based on public/private groups

commit 1251f5b6a7
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Nov 14 16:28:29 2023 -0500

    feat(challenges): swear and slur blocker

commit a771045ca7
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Nov 14 15:46:16 2023 -0500

    feat(challenges): even more slur blocker

commit e5e91aa78a
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Nov 14 14:31:25 2023 -0500

    feat(challenges): more slur blocker

commit 50e824e4e3
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Mon Nov 13 15:12:14 2023 -0500

    feat(challenges): slur blocker

commit 315ea24ef4
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Fri Nov 3 12:31:12 2023 -0400

    feat(challenges): slur blocker work

commit 0f742d219f
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Thu Nov 2 16:22:31 2023 -0400

    feat(challenges): add banned words & slur blocker to challenges

commit 40d6b60ee3
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Mon Oct 23 13:00:46 2023 -0400

    update packages on local/origin repo
2024-01-10 15:14:11 -06:00
Sabe Jones
7a2c7c5b30 Merge branch 'develop' into release 2024-01-10 14:57:42 -06:00
SabreCat
167e6b2bf1 5.15.1 2024-01-04 14:33:04 -06:00
SabreCat
9b54e4d80a fix(backgrounds): correct index of bbash 2024-01-04 14:32:47 -06:00
SabreCat
987a27ffa1 5.15.0 2023-12-29 16:07:57 -06:00
SabreCat
7fb1c9db8c Squashed commit of the following:
commit 5b2f90356b
Author: SabreCat <sabrecat@gmail.com>
Date:   Fri Dec 15 16:19:02 2023 -0600

    fix(migration): full URL

commit a2962c0d10
Author: SabreCat <sabrecat@gmail.com>
Date:   Fri Dec 15 15:57:21 2023 -0600

    feat(migration): add birthday notif

commit 9da8e39dd0
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Fri Dec 15 12:32:25 2023 -0500

    feat(script): awards 2024 Habitica birthday robes

commit 7de6b80ee6
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Thu Dec 14 13:11:07 2023 -0500

    feat(content): add Habitica birthday item

commit 1bb95f5867
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Thu Dec 14 11:43:12 2023 -0500

    fix(dates): fix availability dates to canonical

commit 8e7f49f253
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Thu Dec 14 11:37:44 2023 -0500

    feat(content): make 2024 default backgroumd, fix errors

commit acc30f044e
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Wed Dec 13 16:53:33 2023 -0500

    feat(content): the rest of the January content

commit 6a5e45c6d0
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Wed Dec 13 16:49:33 2023 -0500

    feat(content): January content
2023-12-29 16:07:43 -06:00
SabreCat
f66b05f707 fix(potions): use normal release date notes 2023-12-29 15:57:46 -06:00
negue
5a19c25fea Pin Habitica Eslint Config (#15057)
* Pin Habitica Eslint Config

* fix lint
2023-12-27 18:20:49 +01:00
SabreCat
f8ba191eea fix(gala): correct seasonal shop quests/spell 2023-12-19 10:07:32 -06:00
817 changed files with 39574 additions and 32440 deletions

View File

@@ -1,6 +1,11 @@
/* eslint-disable import/no-commonjs */
module.exports = {
root: true,
extends: [
'habitrpg/lib/node'
'habitrpg/lib/node',
],
}
rules: {
'prefer-regex-literals': 'warn',
'import/no-extraneous-dependencies': 'off',
},
};

View File

@@ -10,19 +10,20 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x]
node-version: [21.x]
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: sudo apt-get -y install libkrb5-dev
- run: cp config.json.example config.json
- name: npm install
run: |
npm ci
npm i
env:
CI: true
NODE_ENV: test
@@ -31,19 +32,20 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x]
node-version: [21.x]
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: sudo apt-get -y install libkrb5-dev
- run: cp config.json.example config.json
- name: npm install
run: |
npm ci
npm i
env:
CI: true
NODE_ENV: test
@@ -52,19 +54,20 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x]
node-version: [21.x]
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: sudo apt-get -y install libkrb5-dev
- run: cp config.json.example config.json
- name: npm install
run: |
npm ci
npm i
env:
CI: true
NODE_ENV: test
@@ -74,19 +77,20 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x]
node-version: [21.x]
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: sudo apt-get -y install libkrb5-dev
- run: cp config.json.example config.json
- name: npm install
run: |
npm ci
npm i
env:
CI: true
NODE_ENV: test
@@ -95,19 +99,20 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x]
node-version: [21.x]
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: sudo apt-get -y install libkrb5-dev
- run: cp config.json.example config.json
- name: npm install
run: |
npm ci
npm i
env:
CI: true
NODE_ENV: test
@@ -117,14 +122,14 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x]
node-version: [21.x]
mongodb-version: [4.2]
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Start MongoDB ${{ matrix.mongodb-version }} Replica Set
@@ -132,10 +137,11 @@ jobs:
with:
mongodb-version: ${{ matrix.mongodb-version }}
mongodb-replica-set: rs
- run: sudo apt-get -y install libkrb5-dev
- run: cp config.json.example config.json
- name: npm install
run: |
npm ci
npm i
env:
CI: true
NODE_ENV: test
@@ -146,14 +152,14 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x]
node-version: [21.x]
mongodb-version: [4.2]
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Start MongoDB ${{ matrix.mongodb-version }} Replica Set
@@ -161,10 +167,11 @@ jobs:
with:
mongodb-version: ${{ matrix.mongodb-version }}
mongodb-replica-set: rs
- run: sudo apt-get -y install libkrb5-dev
- run: cp config.json.example config.json
- name: npm install
run: |
npm ci
npm i
env:
CI: true
NODE_ENV: test
@@ -175,14 +182,14 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x]
node-version: [21.x]
mongodb-version: [4.2]
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Start MongoDB ${{ matrix.mongodb-version }} Replica Set
@@ -190,10 +197,11 @@ jobs:
with:
mongodb-version: ${{ matrix.mongodb-version }}
mongodb-replica-set: rs
- run: sudo apt-get -y install libkrb5-dev
- run: cp config.json.example config.json
- name: npm install
run: |
npm ci
npm i
env:
CI: true
NODE_ENV: test
@@ -205,19 +213,20 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x]
node-version: [21.x]
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: sudo apt-get -y install libkrb5-dev
- run: cp config.json.example config.json
- name: npm install
run: |
npm ci
npm i
env:
CI: true
NODE_ENV: test
@@ -228,15 +237,16 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x]
node-version: [21.x]
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: sudo apt-get -y install libkrb5-dev
- run: cp config.json.example config.json
- name: npm install
run: |

1
.gitignore vendored
View File

@@ -40,6 +40,7 @@ yarn.lock
!.elasticbeanstalk/*.global.yml
/.vscode
habitica.code-workspace
# webstorm fake webpack for path intellisense
webpack.webstorm.config

2
.nvmrc
View File

@@ -1 +1 @@
14
20

View File

@@ -1,30 +0,0 @@
FROM node:14
ENV ADMIN_EMAIL admin@habitica.com
ENV EMAILS_COMMUNITY_MANAGER_EMAIL admin@habitica.com
ENV AMAZON_PAYMENTS_CLIENT_ID amzn1.application-oa2-client.68ed9e6904ef438fbc1bf86bf494056e
ENV AMAZON_PAYMENTS_SELLER_ID AMQ3SB4SG5E91
ENV AMPLITUDE_KEY e8d4c24b3d6ef3ee73eeba715023dd43
ENV BASE_URL https://habitica.com
ENV FACEBOOK_KEY 128307497299777
ENV GA_ID UA-33510635-1
ENV GOOGLE_CLIENT_ID 1035232791481-32vtplgnjnd1aufv3mcu1lthf31795fq.apps.googleusercontent.com
ENV LOGGLY_CLIENT_TOKEN ab5663bf-241f-4d14-8783-7d80db77089a
ENV NODE_ENV production
ENV STRIPE_PUB_KEY pk_85fQ0yMECHNfHTSsZoxZXlPSwSNfA
ENV APPLE_AUTH_CLIENT_ID 9Q9SMRMCNN.com.habitrpg.ios.Habitica
# Install global packages
RUN npm install -g gulp-cli mocha
# Clone Habitica repo and install dependencies
RUN mkdir -p /usr/src/habitrpg
WORKDIR /usr/src/habitrpg
RUN git clone --branch release --depth 1 https://github.com/HabitRPG/habitica.git /usr/src/habitrpg
RUN git config --global url."https://".insteadOf git://
RUN npm set unsafe-perm true
RUN npm install
# Start Habitica
EXPOSE 80 8080 36612
CMD ["node", "./website/transpiled-babel/index.js"]

View File

@@ -1,4 +1,4 @@
FROM node:14
FROM node:20
# Install global packages
RUN npm install -g gulp-cli mocha

View File

@@ -87,5 +87,5 @@
"REDIS_HOST": "aaabbbcccdddeeefff",
"REDIS_PORT": "1234",
"REDIS_PASSWORD": "12345678",
"TRUSTED_DOMAINS": "localhost,habitica.com"
"TRUSTED_DOMAINS": "localhost,https://habitica.com"
}

View File

@@ -2,7 +2,6 @@ import mongoose from 'mongoose';
import nconf from 'nconf';
import repl from 'repl';
import gulp from 'gulp';
import logger from '../website/server/libs/logger';
import {
getDevelopmentConnectionUrl,
getDefaultConnectionOptions,
@@ -39,10 +38,6 @@ const improveRepl = context => {
mongoose.connect(
connectionUrl,
mongooseOptions,
err => {
if (err) throw err;
logger.info('Connected with Mongoose');
},
);
};

View File

@@ -59,13 +59,15 @@ gulp.task('test:prepare:mongo', cb => {
const mongooseOptions = getDefaultConnectionOptions();
const connectionUrl = getDevelopmentConnectionUrl(TEST_DB_URI);
mongoose.connect(connectionUrl, mongooseOptions, err => {
if (err) return cb(`Unable to connect to mongo database. Are you sure it's running? \n\n${err}`);
return mongoose.connection.dropDatabase(err2 => {
if (err2) return cb(err2);
return mongoose.connection.close(cb);
mongoose.connect(connectionUrl, mongooseOptions)
.then(() => mongoose.connection.dropDatabase())
.then(() => mongoose.connection.close()).then(() => {
cb();
})
.catch(err => {
if (err) return cb(`Unable to connect to mongo database. Are you sure it's running? \n\n${err}`);
throw err;
});
});
});
gulp.task('test:prepare:server', gulp.series('test:prepare:mongo', done => {
@@ -116,8 +118,10 @@ gulp.task('test:common:safe', gulp.series('test:prepare:build', cb => {
pipe(runner);
}));
gulp.task('test:content', gulp.series('test:prepare:build',
runInChildProcess(CONTENT_TEST_COMMAND, LIMIT_MAX_BUFFER_OPTIONS)));
gulp.task('test:content', gulp.series(
'test:prepare:build',
runInChildProcess(CONTENT_TEST_COMMAND, LIMIT_MAX_BUFFER_OPTIONS),
));
gulp.task('test:content:clean', cb => {
pipe(exec(testBin(CONTENT_TEST_COMMAND), LIMIT_MAX_BUFFER_OPTIONS, () => cb()));
@@ -142,16 +146,20 @@ gulp.task('test:content:safe', gulp.series('test:prepare:build', cb => {
pipe(runner);
}));
gulp.task('test:api:unit:run',
runInChildProcess(integrationTestCommand('test/api/unit', 'coverage/api-unit')));
gulp.task(
'test:api:unit:run',
runInChildProcess(integrationTestCommand('test/api/unit', 'coverage/api-unit')),
);
gulp.task('test:api:unit:watch', () => gulp.watch(['website/server/libs/*', 'test/api/unit/**/*', 'website/server/controllers/**/*'], gulp.series('test:api:unit:run', done => done())));
gulp.task('test:api-v3:integration', gulp.series('test:prepare:mongo',
gulp.task('test:api-v3:integration', gulp.series(
'test:prepare:mongo',
runInChildProcess(
integrationTestCommand('test/api/v3/integration', 'coverage/api-v3-integration'),
LIMIT_MAX_BUFFER_OPTIONS,
)));
),
));
gulp.task('test:api-v3:integration:watch', () => gulp.watch([
'website/server/controllers/api-v3/**/*', 'common/script/ops/*', 'website/server/libs/*.js',
@@ -164,11 +172,13 @@ gulp.task('test:api-v3:integration:separate-server', runInChildProcess(
'LOAD_SERVER=0',
));
gulp.task('test:api-v4:integration', gulp.series('test:prepare:mongo',
gulp.task('test:api-v4:integration', gulp.series(
'test:prepare:mongo',
runInChildProcess(
integrationTestCommand('test/api/v4', 'api-v4-integration'),
LIMIT_MAX_BUFFER_OPTIONS,
)));
),
));
gulp.task('test:api-v4:integration:separate-server', runInChildProcess(
'mocha test/api/v4 --recursive --require ./test/helpers/start-server',

View File

@@ -3,6 +3,6 @@ module.exports = {
root: false,
rules: {
'no-console': 0,
'no-use-before-define': ['error', { functions: false }]
}
}
'no-use-before-define': ['error', { functions: false }],
},
};

View File

@@ -51,7 +51,8 @@ function getAchievementUpdate (newUser, oldUser) {
// Rebirth level
if (achievementsUpdate.rebirthLevel) {
achievementsUpdate.rebirthLevel = Math.max(
achievementsUpdate.rebirthLevel, oldAchievements.rebirthLevel,
achievementsUpdate.rebirthLevel,
oldAchievements.rebirthLevel,
);
} else if (oldAchievements.rebirthLevel) {
achievementsUpdate.rebirthLevel = oldAchievements.rebirthLevel;

View File

@@ -61,7 +61,7 @@ async function updateUser (user) {
export default async function processUsers () {
let query = {
// migration: {$ne: MIGRATION_NAME},
migration: {$ne: MIGRATION_NAME},
'auth.timestamps.loggedin': {$gt: new Date('2021-01-01')},
};

View File

@@ -105,7 +105,7 @@ async function updateUser (user) {
export default async function processUsers () {
let query = {
// migration: { $ne: MIGRATION_NAME },
migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: new Date('2021-08-01') },
};

View File

@@ -145,7 +145,7 @@ async function updateUser (user) {
export default async function processUsers () {
let query = {
// migration: { $ne: MIGRATION_NAME },
migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: new Date('2021-08-01') },
};

View File

@@ -105,7 +105,7 @@ async function updateUser (user) {
export default async function processUsers () {
let query = {
// migration: { $ne: MIGRATION_NAME },
migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: new Date('2021-08-01') },
};

View File

@@ -95,7 +95,7 @@ async function updateUser (user) {
export default async function processUsers () {
let query = {
// migration: { $ne: MIGRATION_NAME },
migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: new Date('2022-01-01') },
};

View File

@@ -86,7 +86,7 @@ async function updateUser (user) {
export default async function processUsers () {
let query = {
// migration: { $ne: MIGRATION_NAME },
migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: new Date('2022-01-01') },
};

View File

@@ -63,7 +63,7 @@ async function updateUser (user) {
&& pets['Wolf-Shade']
&& pets['Wolf-Skeleton']
&& pets['Wolf-White']
&& pets['Wolf-Zombie'] {
&& pets['Wolf-Zombie']) {
set['achievements.polarPro'] = true;
}
}
@@ -75,7 +75,7 @@ async function updateUser (user) {
export default async function processUsers () {
let query = {
// migration: { $ne: MIGRATION_NAME },
migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: new Date('2022-11-01') },
};

View File

@@ -125,7 +125,7 @@ async function updateUser (user) {
export default async function processUsers () {
let query = {
// migration: { $ne: MIGRATION_NAME },
migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: new Date('2023-04-15') },
};

View File

@@ -110,7 +110,7 @@ async function updateUser (user) {
export default async function processUsers () {
let query = {
migration: {$ne: MIGRATION_NAME},
// 'auth.timestamps.loggedin': { $gt: new Date('2023-07-08') },
'auth.timestamps.loggedin': { $gt: new Date('2023-07-08') },
};
const fields = {

View File

@@ -0,0 +1,102 @@
/* eslint-disable no-console */
import { v4 as uuid } from 'uuid';
import { model as User } from '../../../website/server/models/user';
const MIGRATION_NAME = '20240131_habit_birthday';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count += 1;
const inc = {
'items.food.Cake_Skeleton': 1,
'items.food.Cake_Base': 1,
'items.food.Cake_CottonCandyBlue': 1,
'items.food.Cake_CottonCandyPink': 1,
'items.food.Cake_Shade': 1,
'items.food.Cake_White': 1,
'items.food.Cake_Golden': 1,
'items.food.Cake_Zombie': 1,
'items.food.Cake_Desert': 1,
'items.food.Cake_Red': 1,
'achievements.habitBirthdays': 1,
};
const set = {};
const push = {
notifications: {
type: 'ITEM_RECEIVED',
data: {
icon: 'notif_namingDay_cake',
title: 'Happy Habit Birthday!',
text: 'Habitica turns 11 today! Enjoy free party robes and cake!',
destination: 'inventory/equipment',
},
seen: false,
},
};
set.migration = MIGRATION_NAME;
if (typeof user.items.gear.owned.armor_special_birthday2023 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2024'] = true;
} else if (typeof user.items.gear.owned.armor_special_birthday2022 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2023'] = true;
} else if (typeof user.items.gear.owned.armor_special_birthday2021 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2022'] = true;
} else if (typeof user.items.gear.owned.armor_special_birthday2020 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2021'] = true;
} else if (typeof user.items.gear.owned.armor_special_birthday2019 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2020'] = true;
} else if (typeof user.items.gear.owned.armor_special_birthday2018 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2019'] = true;
} else if (typeof user.items.gear.owned.armor_special_birthday2017 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2018'] = true;
} else if (typeof user.items.gear.owned.armor_special_birthday2016 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2017'] = true;
} else if (typeof user.items.gear.owned.armor_special_birthday2015 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2016'] = true;
} else if (typeof user.items.gear.owned.armor_special_birthday !== 'undefined') {
set['items.gear.owned.armor_special_birthday2015'] = true;
} else {
set['items.gear.owned.armor_special_birthday'] = true;
}
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await User.updateOne({_id: user._id}, {$inc: inc, $set: set, $push: push}).exec();
}
export default async function processUsers () {
let query = {
migration: {$ne: MIGRATION_NAME},
'auth.timestamps.loggedin': {$gt: new Date('2023-12-23')},
};
const fields = {
_id: 1,
items: 1,
};
while (true) { // eslint-disable-line no-constant-condition
const users = await User // eslint-disable-line no-await-in-loop
.find(query)
.limit(250)
.sort({_id: 1})
.select(fields)
.lean()
.exec();
if (users.length === 0) {
console.warn('All appropriate users found and modified.');
console.warn(`\n${count} users processed\n`);
break;
} else {
query._id = {
$gt: users[users.length - 1],
};
}
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
}
};

View File

@@ -0,0 +1,89 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '202403_pet_group_achievements';
import { model as User } from '../../../website/server/models/user';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count++;
let set = {
migration: MIGRATION_NAME,
};
if (user && user.items && user.items.pets) {
const pets = user.items.pets;
if (pets['GuineaPig-Zombie'] > 0
&& pets['GuineaPig-Skeleton'] > 0
&& pets['GuineaPig-Base'] > 0
&& pets['GuineaPig-Desert'] > 0
&& pets['GuineaPig-Red'] > 0
&& pets['GuineaPig-Shade'] > 0
&& pets['GuineaPig-White']> 0
&& pets['GuineaPig-Golden'] > 0
&& pets['GuineaPig-CottonCandyBlue'] > 0
&& pets['GuineaPig-CottonCandyPink'] > 0
&& pets['Squirrel-Zombie'] > 0
&& pets['Squirrel-Skeleton'] > 0
&& pets['Squirrel-Base'] > 0
&& pets['Squirrel-Desert'] > 0
&& pets['Squirrel-Red'] > 0
&& pets['Squirrel-Shade'] > 0
&& pets['Squirrel-White'] > 0
&& pets['Squirrel-Golden'] > 0
&& pets['Squirrel-CottonCandyBlue'] > 0
&& pets['Squirrel-CottonCandyPink'] > 0
&& pets['Rat-Zombie'] > 0
&& pets['Rat-Skeleton'] > 0
&& pets['Rat-Base'] > 0
&& pets['Rat-Desert'] > 0
&& pets['Rat-Red'] > 0
&& pets['Rat-Shade'] > 0
&& pets['Rat-White'] > 0
&& pets['Rat-Golden'] > 0
&& pets['Rat-CottonCandyBlue'] > 0
&& pets['Rat-CottonCandyPink'] > 0 ) {
set['achievements.rodentRuler'] = true;
}
}
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await User.updateOne({ _id: user._id }, { $set: set }).exec();
}
export default async function processUsers () {
let query = {
migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: new Date('2024-02-01') },
};
const fields = {
_id: 1,
items: 1,
};
while (true) { // eslint-disable-line no-constant-condition
const users = await User // eslint-disable-line no-await-in-loop
.find(query)
.limit(250)
.sort({_id: 1})
.select(fields)
.lean()
.exec();
if (users.length === 0) {
console.warn('All appropriate users found and modified.');
console.warn(`\n${count} users processed\n`);
break;
} else {
query._id = {
$gt: users[users.length - 1]._id,
};
}
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
}
};

View File

@@ -0,0 +1,99 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '202405_pet_group_achievements';
import { model as User } from '../../../website/server/models/user';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count++;
let set = {
migration: MIGRATION_NAME,
};
if (user && user.items && user.items.pets) {
const pets = user.items.pets;
if (pets['LionCub-Zombie'] > 0
&& pets['LionCub-Skeleton'] > 0
&& pets['LionCub-Base'] > 0
&& pets['LionCub-Desert'] > 0
&& pets['LionCub-Red'] > 0
&& pets['LionCub-Shade'] > 0
&& pets['LionCub-White']> 0
&& pets['LionCub-Golden'] > 0
&& pets['LionCub-CottonCandyBlue'] > 0
&& pets['LionCub-CottonCandyPink'] > 0
&& pets['TigerCub-Zombie'] > 0
&& pets['TigerCub-Skeleton'] > 0
&& pets['TigerCub-Base'] > 0
&& pets['TigerCub-Desert'] > 0
&& pets['TigerCub-Red'] > 0
&& pets['TigerCub-Shade'] > 0
&& pets['TigerCub-White'] > 0
&& pets['TigerCub-Golden'] > 0
&& pets['TigerCub-CottonCandyBlue'] > 0
&& pets['TigerCub-CottonCandyPink'] > 0
&& pets['Sabretooth-Zombie'] > 0
&& pets['Sabretooth-Skeleton'] > 0
&& pets['Sabretooth-Base'] > 0
&& pets['Sabretooth-Desert'] > 0
&& pets['Sabretooth-Red'] > 0
&& pets['Sabretooth-Shade'] > 0
&& pets['Sabretooth-White'] > 0
&& pets['Sabretooth-Golden'] > 0
&& pets['Sabretooth-CottonCandyBlue'] > 0
&& pets['Sabretooth-CottonCandyPink'] > 0
&& pets['Cheetah-Zombie'] > 0
&& pets['Cheetah-Skeleton'] > 0
&& pets['Cheetah-Base'] > 0
&& pets['Cheetah-Desert'] > 0
&& pets['Cheetah-Red'] > 0
&& pets['Cheetah-Shade'] > 0
&& pets['Cheetah-White'] > 0
&& pets['Cheetah-Golden'] > 0
&& pets['Cheetah-CottonCandyBlue'] > 0
&& pets['Cheetah-CottonCandyPink'] > 0 ) {
set['achievements.cats'] = true;
}
}
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await User.updateOne({ _id: user._id }, { $set: set }).exec();
}
export default async function processUsers () {
let query = {
migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: new Date('2024-03-01') },
};
const fields = {
_id: 1,
items: 1,
};
while (true) { // eslint-disable-line no-constant-condition
const users = await User // eslint-disable-line no-await-in-loop
.find(query)
.limit(250)
.sort({_id: 1})
.select(fields)
.lean()
.exec();
if (users.length === 0) {
console.warn('All appropriate users found and modified.');
console.warn(`\n${count} users processed\n`);
break;
} else {
query._id = {
$gt: users[users.length - 1]._id,
};
}
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
}
};

View File

@@ -1,118 +0,0 @@
let migrationName = '20180904_takeThis.js'; // Update per month
let authorName = 'Sabe'; // in case script author needs to know when their ...
let authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
/*
* Award Take This ladder items to participants in this month's challenge
*/
import monk from 'monk';
import nconf from 'nconf';
const CONNECTION_STRING = nconf.get('MIGRATION_CONNECT_STRING'); // FOR TEST DATABASE
let dbUsers = monk(CONNECTION_STRING).get('users', { castIds: false });
function processUsers (lastId) {
// specify a query to limit the affected users (empty for all users):
let query = {
migration: {$ne: migrationName},
challenges: {$in: ['1044ec0c-4a85-48c5-9f36-d51c0c62c7d3']}, // Update per month
};
if (lastId) {
query._id = {
$gt: lastId,
};
}
dbUsers.find(query, {
sort: {_id: 1},
limit: 250,
fields: [
'items.gear.owned',
], // specify fields we are interested in to limit retrieved data (empty if we're not reading data):
})
.then(updateUsers)
.catch((err) => {
console.log(err);
return exiting(1, `ERROR! ${ err}`);
});
}
let progressCount = 1000;
let count = 0;
function updateUsers (users) {
if (!users || users.length === 0) {
console.warn('All appropriate users found and modified.');
displayData();
return;
}
let userPromises = users.map(updateUser);
let lastUser = users[users.length - 1];
return Promise.all(userPromises)
.then(() => {
processUsers(lastUser._id);
});
}
function updateUser (user) {
count++;
let set = {};
let push;
if (typeof user.items.gear.owned.back_special_takeThis !== 'undefined') {
set = {migration: migrationName};
} else if (typeof user.items.gear.owned.body_special_takeThis !== 'undefined') {
set = {migration: migrationName, 'items.gear.owned.back_special_takeThis': false};
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.back_special_takeThis', _id: monk.id()}};
} else if (typeof user.items.gear.owned.head_special_takeThis !== 'undefined') {
set = {migration: migrationName, 'items.gear.owned.body_special_takeThis': false};
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.body_special_takeThis', _id: monk.id()}};
} else if (typeof user.items.gear.owned.armor_special_takeThis !== 'undefined') {
set = {migration: migrationName, 'items.gear.owned.head_special_takeThis': false};
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.head_special_takeThis', _id: monk.id()}};
} else if (typeof user.items.gear.owned.weapon_special_takeThis !== 'undefined') {
set = {migration: migrationName, 'items.gear.owned.armor_special_takeThis': false};
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_takeThis', _id: monk.id()}};
} else if (typeof user.items.gear.owned.shield_special_takeThis !== 'undefined') {
set = {migration: migrationName, 'items.gear.owned.weapon_special_takeThis': false};
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.weapon_special_takeThis', _id: monk.id()}};
} else {
set = {migration: migrationName, 'items.gear.owned.shield_special_takeThis': false};
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.shield_special_takeThis', _id: monk.id()}};
}
if (push) {
dbUsers.update({_id: user._id}, {$set: set, $push: push});
} else {
dbUsers.update({_id: user._id}, {$set: set});
}
if (count % progressCount === 0) console.warn(`${count } ${ user._id}`);
if (user._id === authorUuid) console.warn(`${authorName } processed`);
}
function displayData () {
console.warn(`\n${ count } users processed\n`);
return exiting(0);
}
function exiting (code, msg) {
code = code || 0; // 0 = success
if (code && !msg) {
msg = 'ERROR!';
}
if (msg) {
if (code) {
console.error(msg);
} else {
console.log(msg);
}
}
process.exit(code);
}
module.exports = processUsers;

View File

@@ -1,10 +0,0 @@
import csv
with open(r"/home/slappybag/Documents/SurveyScrape.csv") as f:
reader = csv.reader(f, delimiter=',', quotechar='"')
column = []
for row in reader:
if row:
column.append(row[4])
print column

View File

@@ -21,12 +21,14 @@ async function handOutJackalopes () {
if (user.party._id) groupList.push(user.party._id);
groupList = groupList.concat(user.guilds);
const subscribedGroup = await Group.findOne({
_id: { $in: groupList },
'purchased.plan.planId': 'group_monthly',
'purchased.plan.dateTerminated': null,
},
{ _id: 1 });
const subscribedGroup = await Group.findOne(
{
_id: { $in: groupList },
'purchased.plan.planId': 'group_monthly',
'purchased.plan.dateTerminated': null,
},
{ _id: 1 },
);
if (subscribedGroup) {
User.update({ _id: user._id }, { $set: { 'items.mounts.Jackalope-RoyalPurple': true } }).exec();

View File

@@ -16,6 +16,7 @@ async function updateUser (user) {
if (count % progressCount === 0) {
console.warn(`${count} ${user._id}`);
// eslint-disable-next-line no-promise-executor-return
await new Promise(resolve => setTimeout(resolve, 5000));
}

View File

@@ -51,7 +51,7 @@ async function updateUser (user) {
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return User.update({ _id: user._id }, { $set: set }).exec();
return User.updateOne({ _id: user._id }, { $set: set }).exec();
}
export default async function processUsers () {

View File

@@ -3,7 +3,7 @@ import { v4 as uuid } from 'uuid';
import { model as User } from '../../website/server/models/user';
const MIGRATION_NAME = '20230314_pi_day';
const MIGRATION_NAME = '20240314_pi_day';
const progressCount = 1000;
let count = 0;

25051
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
{
"name": "habitica",
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
"version": "5.14.2",
"version": "5.24.0",
"main": "./website/server/index.js",
"dependencies": {
"@babel/core": "^7.22.10",
@@ -24,8 +24,8 @@
"csv-stringify": "^5.6.5",
"cwait": "^1.1.1",
"domain-middleware": "~0.1.0",
"eslint": "^6.8.0",
"eslint-config-habitrpg": "^6.2.0",
"eslint": "^8.55.0",
"eslint-config-habitrpg": "^6.2.3",
"eslint-plugin-mocha": "^5.0.0",
"express": "^4.18.2",
"express-basic-auth": "^1.2.1",
@@ -36,11 +36,9 @@
"gulp-babel": "^8.0.0",
"gulp-imagemin": "^7.1.0",
"gulp-nodemon": "^2.5.0",
"nodemon": "^2.0.20",
"gulp.spritesmith": "^6.13.0",
"habitica-markdown": "^3.0.0",
"helmet": "^4.6.0",
"image-size": "^1.0.2",
"in-app-purchase": "^1.11.3",
"js2xmlparser": "^5.0.0",
"jsonwebtoken": "^9.0.2",
@@ -50,10 +48,11 @@
"method-override": "^3.0.0",
"moment": "^2.29.4",
"moment-recur": "^1.0.7",
"mongoose": "^5.13.20",
"mongoose": "^7.6.3",
"morgan": "^1.10.0",
"nconf": "^0.12.1",
"node-gcm": "^1.0.5",
"nodemon": "^2.0.20",
"on-headers": "^1.0.2",
"passport": "^0.5.3",
"passport-facebook": "^3.0.0",
@@ -64,7 +63,6 @@
"ps-tree": "^1.0.0",
"rate-limiter-flexible": "^2.4.2",
"redis": "^3.1.2",
"regenerator-runtime": "^0.13.11",
"remove-markdown": "^0.5.0",
"rimraf": "^3.0.2",
"short-uuid": "^4.2.2",
@@ -74,15 +72,14 @@
"useragent": "^2.1.9",
"uuid": "^9.0.0",
"validator": "^13.11.0",
"vinyl-buffer": "^1.0.1",
"winston": "^3.10.0",
"winston-loggly-bulk": "^3.3.0",
"xml2js": "^0.6.2"
},
"private": true,
"engines": {
"node": "^14",
"npm": "^6"
"node": "20",
"npm": "^10"
},
"scripts": {
"lint": "eslint --ext .js --fix . && cd website/client && npm run lint",
@@ -106,7 +103,7 @@
"client:unit": "cd website/client && npm run test:unit",
"start": "gulp nodemon",
"debug": "gulp nodemon --inspect",
"mongo:dev": "run-rs -v 4.1.1 -l ubuntu1804 --keep --dbpath mongodb-data --number 1 --quiet",
"mongo:dev": "run-rs -v 5.0.23 -l ubuntu1804 --keep --dbpath mongodb-data --number 1 --quiet",
"postinstall": "git config --global url.\"https://\".insteadOf git:// && gulp build && cd website/client && npm install",
"apidoc": "gulp apidoc"
},
@@ -126,6 +123,5 @@
"sinon": "^15.2.0",
"sinon-chai": "^3.7.0",
"sinon-stub-promise": "^4.0.0"
},
"optionalDependencies": {}
}
}

View File

@@ -44,6 +44,7 @@ async function deleteHabiticaData (user, email) {
{ _id: user._id },
{ $set: set },
);
// eslint-disable-next-line no-promise-executor-return
await new Promise(resolve => setTimeout(resolve, 1000));
const response = await axios.delete(
`${BASE_URL}/api/v3/user`,
@@ -96,6 +97,7 @@ async function processEmailAddress (email) {
return console.log(`No users found with email address ${email}`);
}
// eslint-disable-next-line no-promise-executor-return
await new Promise(resolve => setTimeout(resolve, 1000));
return Promise.all(users.map(user => (async () => {
await deleteAmplitudeData(user._id, email); // eslint-disable-line no-await-in-loop

View File

@@ -1,3 +1,5 @@
/* eslint-disable import/no-commonjs */
module.exports = {
extends: [
'habitrpg/lib/mocha',
@@ -7,6 +9,9 @@ module.exports = {
chai: true,
expect: true,
sinon: true,
sandbox: true
sandbox: true,
},
}
rules: {
'import/no-extraneous-dependencies': 'off',
},
};

View File

@@ -1,4 +1,4 @@
import apiError from '../../../../website/server/libs/apiError';
import { apiError } from '../../../../website/server/libs/apiError';
describe('API Messages', () => {
const message = 'Only public guilds support pagination.';

View File

@@ -26,9 +26,7 @@ describe('bug-report', () => {
_id: userId,
});
const result = await bugReportLogic(
user, userMail, userMessage, userAgent,
);
const result = await bugReportLogic(user, userMail, userMessage, userAgent);
expect(emailLib.sendTxn).to.be.called;
expect(result).to.deep.equal({

View File

@@ -44,7 +44,7 @@ describe('mongodb', () => {
const mongoLibOverride = requireAgain(pathToMongoLib);
const options = mongoLibOverride.getDefaultConnectionOptions();
expect(options).to.have.all.keys(['useNewUrlParser', 'useUnifiedTopology', 'keepAlive', 'keepAliveInitialDelay']);
expect(options).to.have.all.keys(['useNewUrlParser', 'useUnifiedTopology']);
});
});
});

View File

@@ -227,7 +227,7 @@ describe('Password Utilities', () => {
expiresAt: moment().subtract({ minutes: 1 }),
}));
await user.update({
await user.updateOne({
'auth.local.passwordResetCode': code,
});
@@ -264,7 +264,7 @@ describe('Password Utilities', () => {
expiresAt: moment().add({ days: 1 }),
}));
await user.update({
await user.updateOne({
'auth.local.passwordResetCode': 'invalid',
});
@@ -280,7 +280,7 @@ describe('Password Utilities', () => {
expiresAt: moment().add({ days: 1 }),
}));
await user.update({
await user.updateOne({
'auth.local.passwordResetCode': code,
});

View File

@@ -2,7 +2,7 @@ import { model as User } from '../../../../../../website/server/models/user';
import amzLib from '../../../../../../website/server/libs/payments/amazon';
import payments from '../../../../../../website/server/libs/payments/payments';
import common from '../../../../../../website/common';
import apiError from '../../../../../../website/server/libs/apiError';
import { apiError } from '../../../../../../website/server/libs/apiError';
import * as gems from '../../../../../../website/server/libs/payments/gems';
const { i18n } = common;

View File

@@ -342,10 +342,12 @@ describe('Apple Payments', () => {
}]);
sub = common.content.subscriptionBlocks[newOption.subKey];
await applePayments.subscribe(user,
await applePayments.subscribe(
user,
receipt,
headers,
nextPaymentProcessing);
nextPaymentProcessing,
);
expect(iapSetupStub).to.be.calledOnce;
expect(iapValidateStub).to.be.calledOnce;
@@ -387,10 +389,12 @@ describe('Apple Payments', () => {
}]);
sub = common.content.subscriptionBlocks[newOption.subKey];
await applePayments.subscribe(user,
await applePayments.subscribe(
user,
receipt,
headers,
nextPaymentProcessing);
nextPaymentProcessing,
);
expect(iapSetupStub).to.be.calledOnce;
expect(iapValidateStub).to.be.calledOnce;
@@ -517,9 +521,7 @@ describe('Apple Payments', () => {
const secondUser = new User();
await secondUser.save();
await expect(applePayments.subscribe(
secondUser, receipt, headers, nextPaymentProcessing,
))
await expect(applePayments.subscribe(secondUser, receipt, headers, nextPaymentProcessing))
.to.eventually.be.rejected.and.to.eql({
httpCode: 401,
name: 'NotAuthorized',
@@ -559,9 +561,7 @@ describe('Apple Payments', () => {
const thirdUser = new User();
await thirdUser.save();
await expect(applePayments.subscribe(
thirdUser, receipt, headers, nextPaymentProcessing,
))
await expect(applePayments.subscribe(thirdUser, receipt, headers, nextPaymentProcessing))
.to.eventually.be.rejected.and.to.eql({
httpCode: 401,
name: 'NotAuthorized',

View File

@@ -1382,18 +1382,6 @@ describe('payments/index', () => {
expect(user.purchased.plan.mysteryItems).to.have.a.lengthOf(1);
expect(user.purchased.plan.mysteryItems).to.include('head_mystery_201605');
});
it('does not award mystery item when user already has the item in the mystery box', async () => {
user.purchased.plan.mysteryItems = [mayMysteryItem];
sandbox.spy(user.purchased.plan.mysteryItems, 'push');
data = { paymentMethod: 'PaymentMethod', user, sub: { key: 'basic_3mo' } };
await api.createSubscription(data);
expect(user.purchased.plan.mysteryItems.push).to.be.calledOnce;
expect(user.purchased.plan.mysteryItems.push).to.be.calledWith('head_mystery_201605');
});
});
});
@@ -1599,10 +1587,10 @@ describe('payments/index', () => {
it('sends gem donation message in each participant\'s language', async () => {
// TODO using english for both users because other languages are not loaded
// for api.buyGems
await recipient.update({
await recipient.updateOne({
'preferences.language': 'en',
});
await user.update({
await user.updateOne({
'preferences.language': 'en',
});
await api.buyGems(data);

View File

@@ -4,7 +4,7 @@ import nconf from 'nconf';
import paypalPayments from '../../../../../../website/server/libs/payments/paypal';
import { model as User } from '../../../../../../website/server/models/user';
import common from '../../../../../../website/common';
import apiError from '../../../../../../website/server/libs/apiError';
import { apiError } from '../../../../../../website/server/libs/apiError';
import * as gems from '../../../../../../website/server/libs/payments/gems';
const BASE_URL = nconf.get('BASE_URL');

View File

@@ -1,4 +1,4 @@
import apiError from '../../../../../../website/server/libs/apiError';
import { apiError } from '../../../../../../website/server/libs/apiError';
import common from '../../../../../../website/common';
import {
getOneTimePaymentInfo,

View File

@@ -53,11 +53,9 @@ describe('cron middleware', () => {
cronMiddleware(req, res, err => {
if (err) return reject(err);
Tasks.Task.findOne({ _id: task }, (secondErr, taskFound) => {
if (secondErr) return reject(err);
expect(secondErr).to.not.exist;
expect(taskFound).to.not.exist;
return resolve();
Tasks.Task.findOne({ _id: task }).then(foundTask => {
expect(foundTask).to.not.exist;
resolve();
});
return null;
@@ -78,10 +76,8 @@ describe('cron middleware', () => {
await new Promise((resolve, reject) => {
cronMiddleware(req, res, err => {
if (err) return reject(err);
Tasks.Task.findOne({ _id: task }, (secondErr, taskFound) => {
if (secondErr) return reject(secondErr);
expect(secondErr).to.not.exist;
expect(taskFound).to.exist;
Tasks.Task.findOne({ _id: task }).then(foundTask => {
expect(foundTask).to.exist;
return resolve();
});
return null;
@@ -103,10 +99,8 @@ describe('cron middleware', () => {
await new Promise((resolve, reject) => {
cronMiddleware(req, res, err => {
if (err) return reject(err);
Tasks.Task.findOne({ _id: task }, (secondErr, taskFound) => {
if (secondErr) return reject(secondErr);
expect(secondErr).to.not.exist;
expect(taskFound).to.not.exist;
Tasks.Task.findOne({ _id: task }).then(foundTask => {
expect(foundTask).to.not.exist;
return resolve();
});
return null;
@@ -170,8 +164,7 @@ describe('cron middleware', () => {
await new Promise((resolve, reject) => {
cronMiddleware(req, res, err => {
if (err) return reject(err);
return User.findOne({ _id: user._id }, (secondErr, updatedUser) => {
if (secondErr) return reject(secondErr);
return User.findOne({ _id: user._id }).then(updatedUser => {
expect(updatedUser.stats.hp).to.be.lessThan(hpBefore);
return resolve();
});
@@ -188,8 +181,7 @@ describe('cron middleware', () => {
await new Promise((resolve, reject) => {
cronMiddleware(req, res, err => {
if (err) return reject(err);
return Tasks.Task.findOne({ _id: todo._id }, (secondErr, todoFound) => {
if (secondErr) return reject(secondErr);
return Tasks.Task.findOne({ _id: todo._id }).then(todoFound => {
expect(todoFound.value).to.be.lessThan(todoValueBefore);
return resolve();
});
@@ -224,8 +216,7 @@ describe('cron middleware', () => {
await new Promise((resolve, reject) => {
cronMiddleware(req, res, err => {
if (err) return reject(err);
return User.findOne({ _id: user._id }, (secondErr, updatedUser) => {
if (secondErr) return reject(secondErr);
return User.findOne({ _id: user._id }).then(updatedUser => {
expect(updatedUser.stats.hp).to.be.lessThan(hpBefore);
return resolve();
});
@@ -238,7 +229,7 @@ describe('cron middleware', () => {
await user.save();
const updatedUser = user.toObject();
updatedUser.nMatched = 0;
updatedUser.matchedCount = 0;
sandbox.spy(cronLib, 'recoverCron');
@@ -269,7 +260,7 @@ describe('cron middleware', () => {
it('cronSignature less than an hour ago should error', async () => {
user.lastCron = moment(new Date()).subtract({ days: 2 });
const now = new Date();
await User.update({
await User.updateOne({
_id: user._id,
}, {
$set: {
@@ -291,7 +282,7 @@ describe('cron middleware', () => {
it('cronSignature longer than an hour ago should allow cron', async () => {
user.lastCron = moment(new Date()).subtract({ days: 2 });
const now = new Date();
await User.update({
await User.updateOne({
_id: user._id,
}, {
$set: {

View File

@@ -6,7 +6,7 @@ import {
} from '../../../helpers/api-unit.helper';
import { ensurePermission } from '../../../../website/server/middlewares/ensureAccessRight';
import { NotAuthorized } from '../../../../website/server/libs/errors';
import apiError from '../../../../website/server/libs/apiError';
import { apiError } from '../../../../website/server/libs/apiError';
describe('ensure access middlewares', () => {
let res; let req; let

View File

@@ -6,7 +6,7 @@ import {
generateNext,
} from '../../../helpers/api-unit.helper';
import { Forbidden } from '../../../../website/server/libs/errors';
import apiError from '../../../../website/server/libs/apiError';
import { apiError } from '../../../../website/server/libs/apiError';
function checkErrorThrown (next) {
expect(next).to.have.been.calledOnce;

View File

@@ -7,7 +7,7 @@ import {
generateNext,
} from '../../../helpers/api-unit.helper';
import { TooManyRequests } from '../../../../website/server/libs/errors';
import apiError from '../../../../website/server/libs/apiError';
import { apiError } from '../../../../website/server/libs/apiError';
import logger from '../../../../website/server/libs/logger';
describe('rateLimiter middleware', () => {

View File

@@ -1358,7 +1358,7 @@ describe('Group Model', () => {
describe('#sendChat', () => {
beforeEach(() => {
sandbox.spy(User, 'update');
sandbox.spy(User, 'updateOne');
sandbox.spy(User, 'updateMany');
});
@@ -1450,7 +1450,7 @@ describe('Group Model', () => {
party.sendChat({ message: 'message' });
expect(User.update).to.not.be.called;
expect(User.updateMany).to.not.be.called;
});
it('skips sending messages to the tavern', () => {
@@ -1458,7 +1458,7 @@ describe('Group Model', () => {
party.sendChat({ message: 'message' });
expect(User.update).to.not.be.called;
expect(User.updateMany).to.not.be.called;
});
});

View File

@@ -103,7 +103,7 @@ describe('NewsPost Model', () => {
beforeEach(async () => {
// Delete all existing posts from the database
await NewsPost.remove();
await NewsPost.deleteMany();
});
afterEach(() => {
@@ -116,7 +116,7 @@ describe('NewsPost Model', () => {
_id: v4(), publishDate: new Date(), published: true,
};
NewsPost.updateLastNewsPost(previousPost);
intervalId = refreshNewsPost(50); // refreshes every 50ms
intervalId = refreshNewsPost(100); // refreshes every 100ms
await sleep(0.1); // wait 100ms to make sure the new post has a more recent publishDate
const newPost = await NewsPost.create({

View File

@@ -221,7 +221,8 @@ describe('Task Model', () => {
it('returns task by alias', async () => {
const foundTasks = await Tasks.Task.findMultipleByIdOrAlias(
[taskWithAlias.alias], user._id,
[taskWithAlias.alias],
user._id,
);
expect(foundTasks[0].text).to.eql(taskWithAlias.text);
@@ -229,7 +230,8 @@ describe('Task Model', () => {
it('returns multiple tasks', async () => {
const foundTasks = await Tasks.Task.findMultipleByIdOrAlias(
[taskWithAlias.alias, secondTask._id], user._id,
[taskWithAlias.alias, secondTask._id],
user._id,
);
expect(foundTasks.length).to.eql(2);
@@ -239,7 +241,8 @@ describe('Task Model', () => {
it('returns a task only once if searched by both id and alias', async () => {
const foundTasks = await Tasks.Task.findMultipleByIdOrAlias(
[taskWithAlias.alias, taskWithAlias._id], user._id,
[taskWithAlias.alias, taskWithAlias._id],
user._id,
);
expect(foundTasks.length).to.eql(1);

View File

@@ -188,7 +188,7 @@ describe('User Model', () => {
it('removes invalid tags when loading the user', async () => {
let user = new User();
await user.save();
await user.update({
await user.updateOne({
$set: {
tags: [
null, // invalid, not an object
@@ -212,7 +212,7 @@ describe('User Model', () => {
it('removes invalid push devices when loading the user', async () => {
let user = new User();
await user.save();
await user.update({
await user.updateOne({
$set: {
pushDevices: [
null, // invalid, not an object
@@ -236,7 +236,7 @@ describe('User Model', () => {
it('removes duplicate push devices when loading the user', async () => {
let user = new User();
await user.save();
await user.update({
await user.updateOne({
$set: {
pushDevices: [
{ type: 'android', regId: '1234' },
@@ -258,7 +258,7 @@ describe('User Model', () => {
it('removes invalid notifications when loading the user', async () => {
let user = new User();
await user.save();
await user.update({
await user.updateOne({
$set: {
notifications: [
null, // invalid, not an object
@@ -284,7 +284,7 @@ describe('User Model', () => {
it('removes multiple NEW_CHAT_MESSAGE for the same group', async () => {
let user = new User();
await user.save();
await user.update({
await user.updateOne({
$set: {
notifications: [
{

View File

@@ -1,7 +1,7 @@
import { v4 as generateUUID } from 'uuid';
import { model as Webhook } from '../../../../website/server/models/webhook';
import { BadRequest } from '../../../../website/server/libs/errors';
import apiError from '../../../../website/server/libs/apiError';
import { apiError } from '../../../../website/server/libs/apiError';
describe('Webhook Model', () => {
context('Instance Methods', () => {

View File

@@ -87,7 +87,7 @@ describe('DELETE /challenges/:challengeId', () => {
const testTask = _.find(tasks, task => task.text === taskText);
expect(testTask.challenge.broken).to.eql('CHALLENGE_DELETED');
expect(testTask.challenge.winner).to.be.null;
expect(testTask.challenge.winner).to.be.undefined;
});
});
});

View File

@@ -74,7 +74,7 @@ describe('GET /challenges/:challengeId/export/csv', () => {
});
it('should successfully return when it contains erroneous residue user data', async () => {
await members[0].update({ challenges: [] });
await members[0].updateOne({ challenges: [] });
const res = await members[1].get(`/challenges/${challenge._id}/export/csv`);
const sortedMembers = _.sortBy([members[1], members[2], groupLeader], '_id');
const splitRes = res.split('\n');

View File

@@ -186,7 +186,7 @@ describe('GET challenges/groups/:groupId', () => {
before(async () => {
user = await generateUser();
await user.update({ balance: 0.5 });
await user.updateOne({ balance: 0.5 });
tavern = await user.get(`/groups/${TAVERN_ID}`);
challenge = await generateChallenge(user, tavern, { prize: 1 });
@@ -269,7 +269,7 @@ describe('GET challenges/groups/:groupId', () => {
let officialChallenge; let unofficialChallenges;
before(async () => {
await user.update({
await user.updateOne({
'permissions.challengeAdmin': true,
balance: 3,
});

View File

@@ -68,7 +68,7 @@ describe('GET challenges/user', () => {
challenge = await generateChallenge(user, group);
challenge2 = await generateChallenge(user, group);
await user.update({ balance: 0.25 });
await user.updateOne({ balance: 0.25 });
publicChallenge = await generateChallenge(user, tavern, { prize: 1 });
await member.post(`/challenges/${challenge._id}/join`);
@@ -234,7 +234,7 @@ describe('GET challenges/user', () => {
upgradeToGroupPlan: true,
}));
await user.update({
await user.updateOne({
'permissions.challengeAdmin': true,
});
@@ -308,7 +308,7 @@ describe('GET challenges/user', () => {
guild = group;
member = members[0]; // eslint-disable-line prefer-destructuring
await user.update({ balance: 20 });
await user.updateOne({ balance: 20 });
for (let i = 0; i < 11; i += 1) {
let challenge = await generateChallenge(user, group); // eslint-disable-line

View File

@@ -7,6 +7,7 @@ import {
describe('POST /challenges/:challengeId/flag', () => {
let user;
let challengeGroup;
let challenge;
beforeEach(async () => {
@@ -20,6 +21,7 @@ describe('POST /challenges/:challengeId/flag', () => {
});
user = groupLeader;
challengeGroup = group;
challenge = await generateChallenge(user, group);
});
@@ -41,7 +43,7 @@ describe('POST /challenges/:challengeId/flag', () => {
});
it('flags a challenge with a higher count when from an admin', async () => {
await user.update({ 'contributor.admin': true });
await user.updateOne({ 'contributor.admin': true });
const flagResult = await user.post(`/challenges/${challenge._id}/flag`);
@@ -59,4 +61,19 @@ describe('POST /challenges/:challengeId/flag', () => {
message: t('messageChallengeFlagAlreadyReported'),
});
});
it('returns an error when user tries to flag an official challenge', async () => {
await user.updateOne({
permissions: {
challengeAdmin: true,
},
});
challenge = await generateChallenge(user, challengeGroup, { official: true });
await expect(user.post(`/challenges/${challenge._id}/flag`))
.to.eventually.be.rejected.and.eql({
code: 404,
error: 'NotFound',
message: t('messageChallengeFlagOfficial'),
});
});
});

View File

@@ -23,7 +23,7 @@ describe('POST /challenges/:challengeId/clearflags', () => {
admin = groupLeader;
[nonAdmin] = members;
await admin.update({ 'permissions.moderator': true });
await admin.updateOne({ 'permissions.moderator': true });
challenge = await generateChallenge(admin, group);
await admin.post(`/challenges/${challenge._id}/flag`);

View File

@@ -79,7 +79,7 @@ describe('POST /challenges', () => {
});
groupLeader = await populatedGroup.groupLeader.sync();
await groupLeader.update({ permissions: {} });
await groupLeader.updateOne({ permissions: {} });
group = populatedGroup.group;
groupMember = populatedGroup.members[0]; // eslint-disable-line prefer-destructuring
});
@@ -177,7 +177,7 @@ describe('POST /challenges', () => {
const oldUserBalance = groupLeader.balance;
const prize = 8;
await group.update({ balance: 0 });
await group.updateOne({ balance: 0 });
await groupLeader.post('/challenges', {
group: group._id,
name: 'Test Challenge',
@@ -202,7 +202,7 @@ describe('POST /challenges', () => {
});
it('sets challenge as official if created by admin and official flag is set', async () => {
await groupLeader.update({
await groupLeader.updateOne({
permissions: {
challengeAdmin: true,
},
@@ -331,5 +331,71 @@ describe('POST /challenges', () => {
expect(updatedChallenge.summary).to.eql(summary);
});
it('sets categories for challenges', async () => {
const testCategory = { _id: '65c1172997c0b24600371ea9', slug: 'test', name: 'Test' };
const challenge = await groupLeader.post('/challenges', {
group: group._id,
name: 'Test Challenge',
shortName: 'TC Label',
categories: [testCategory],
});
const updatedChallenge = await groupLeader.get(`/challenges/${challenge._id}`);
expect(updatedChallenge.categories).to.eql([testCategory]);
});
it('does not set habitica_official category for non-admins', async () => {
const testCategory = { _id: '65c1172997c0b24600371ea9', slug: 'habitica_official', name: 'habitica_official' };
await expect(groupLeader.post('/challenges', {
group: group._id,
name: 'Test Challenge',
shortName: 'TC Label',
categories: [testCategory],
})).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('noPrivAccess'),
});
});
it('sets habitica_official category for admins', async () => {
await groupLeader.updateOne({
permissions: {
challengeAdmin: true,
},
});
const testCategory = { _id: '65c1172997c0b24600371ea9', slug: 'habitica_official', name: 'habitica_official' };
const challenge = await groupLeader.post('/challenges', {
group: group._id,
name: 'Test Challenge',
shortName: 'TC Label',
categories: [testCategory],
});
const updatedChallenge = await groupLeader.get(`/challenges/${challenge._id}`);
expect(updatedChallenge.categories).to.eql([testCategory]);
});
it('sets official if the habitica_official category is set for admins', async () => {
await groupLeader.updateOne({
permissions: {
challengeAdmin: true,
},
});
const testCategory = { _id: '65c1172997c0b24600371ea9', slug: 'habitica_official', name: 'habitica_official' };
const challenge = await groupLeader.post('/challenges', {
group: group._id,
name: 'Test Challenge',
shortName: 'TC Label',
categories: [testCategory],
});
const updatedChallenge = await groupLeader.get(`/challenges/${challenge._id}`);
expect(updatedChallenge.official).to.eql(true);
});
});
});

View File

@@ -128,10 +128,10 @@ describe('POST /challenges/:challengeId/winner/:winnerId', () => {
const oldBalance = winningUser.balance;
const oldLeaderBalance = (await groupLeader.sync()).balance;
await winningUser.update({
await winningUser.updateOne({
'purchased.plan.customerId': 'group-plan',
});
await group.update({
await group.updateOne({
'leaderOnly.getGems': true,
'purchased.plan.customerId': 123,
});

View File

@@ -28,7 +28,7 @@ describe('DELETE /groups/:groupId/chat/:chatId', () => {
message = message.message;
userThatDidNotCreateChat = members[0]; // eslint-disable-line prefer-destructuring
admin = members[1]; // eslint-disable-line prefer-destructuring
await admin.update({ permissions: { moderator: true } });
await admin.updateOne({ permissions: { moderator: true } });
});
context('Chat errors', () => {

View File

@@ -27,11 +27,11 @@ describe('POST /chat/:chatId/flag', () => {
}));
[admin, anotherUser, newUser, userToDelete] = members;
await user.update({ permissions: {} });
await admin.update({ permissions: { moderator: true } });
await anotherUser.update({ 'auth.timestamps.created': moment().subtract(USER_AGE_FOR_FLAGGING + 1, 'days').toDate() });
await newUser.update({ 'auth.timestamps.created': moment().subtract(1, 'days').toDate() });
await userToDelete.update({
await user.updateOne({ permissions: {} });
await admin.updateOne({ permissions: { moderator: true } });
await anotherUser.updateOne({ 'auth.timestamps.created': moment().subtract(USER_AGE_FOR_FLAGGING + 1, 'days').toDate() });
await newUser.updateOne({ 'auth.timestamps.created': moment().subtract(1, 'days').toDate() });
await userToDelete.updateOne({
'auth.timestamps.created': moment().subtract(1, 'days').toDate(),
'purchased.plan.dateTerminated': moment().subtract(1, 'minutes').toDate(),
});

View File

@@ -27,7 +27,7 @@ describe('POST /chat/:chatId/like', () => {
}));
[anotherUser] = members;
await anotherUser.update({ 'auth.timestamps.created': new Date('2022-01-01') });
await anotherUser.updateOne({ 'auth.timestamps.created': new Date('2022-01-01') });
});
it('Returns an error when chat message is not found', async () => {
@@ -39,17 +39,6 @@ describe('POST /chat/:chatId/like', () => {
});
});
it('Returns an error when user tries to like their own message', async () => {
const message = await user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
await expect(user.post(`/groups/${groupWithChat._id}/chat/${message.message.id}/like`))
.to.eventually.be.rejected.and.eql({
code: 404,
error: 'NotFound',
message: t('messageGroupChatLikeOwnMessage'),
});
});
it('Likes a chat', async () => {
const message = await anotherUser.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
@@ -63,6 +52,19 @@ describe('POST /chat/:chatId/like', () => {
expect(messageToCheck.likes[user._id]).to.equal(true);
});
it('Allows to likes their own chat message', async () => {
const message = await user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
const likeResult = await user.post(`/groups/${groupWithChat._id}/chat/${message.message.id}/like`);
expect(likeResult.likes[user._id]).to.equal(true);
const groupWithChatLikes = await user.get(`/groups/${groupWithChat._id}`);
const messageToCheck = find(groupWithChatLikes.chat, { id: message.message.id });
expect(messageToCheck.likes[user._id]).to.equal(true);
});
it('Unlikes a chat', async () => {
const message = await anotherUser.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });

View File

@@ -30,14 +30,14 @@ describe('POST /chat', () => {
upgradeToGroupPlan: true,
});
user = groupLeader;
await user.update({
await user.updateOne({
'contributor.level': SPAM_MIN_EXEMPT_CONTRIB_LEVEL,
'auth.timestamps.created': new Date('2022-01-01'),
}); // prevent tests accidentally throwing messageGroupChatSpam
groupWithChat = group;
[member, additionalMember] = members;
await member.update({ 'auth.timestamps.created': new Date('2022-01-01') });
await additionalMember.update({ 'auth.timestamps.created': new Date('2022-01-01') });
await member.updateOne({ 'auth.timestamps.created': new Date('2022-01-01') });
await additionalMember.updateOne({ 'auth.timestamps.created': new Date('2022-01-01') });
});
it('Returns an error when no message is provided', async () => {
@@ -77,11 +77,11 @@ describe('POST /chat', () => {
describe('mute user', () => {
afterEach(() => {
member.update({ 'flags.chatRevoked': false });
member.updateOne({ 'flags.chatRevoked': false });
});
it('does not error when chat privileges are revoked when sending a message to a private guild', async () => {
await member.update({
await member.updateOne({
'flags.chatRevoked': true,
});
@@ -101,7 +101,7 @@ describe('POST /chat', () => {
});
const privatePartyMemberWithChatsRevoked = members[0];
await privatePartyMemberWithChatsRevoked.update({
await privatePartyMemberWithChatsRevoked.updateOne({
'flags.chatRevoked': true,
'auth.timestamps.created': new Date('2022-01-01'),
});
@@ -120,11 +120,11 @@ describe('POST /chat', () => {
afterEach(() => {
sandbox.restore();
member.update({ 'flags.chatShadowMuted': false });
member.updateOne({ 'flags.chatShadowMuted': false });
});
it('creates a chat with zero flagCount when sending a message to a private guild', async () => {
await member.update({
await member.updateOne({
'flags.chatShadowMuted': true,
});
@@ -145,7 +145,7 @@ describe('POST /chat', () => {
});
const userWithChatShadowMuted = members[0];
await userWithChatShadowMuted.update({
await userWithChatShadowMuted.updateOne({
'flags.chatShadowMuted': true,
'auth.timestamps.created': new Date('2022-01-01'),
});
@@ -167,7 +167,7 @@ describe('POST /chat', () => {
},
members: 1,
});
await members[0].update({ 'auth.timestamps.created': new Date('2022-01-01') });
await members[0].updateOne({ 'auth.timestamps.created': new Date('2022-01-01') });
const message = await members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage });
@@ -189,7 +189,7 @@ describe('POST /chat', () => {
afterEach(() => {
sandbox.restore();
user.update({ 'flags.chatRevoked': false });
user.updateOne({ 'flags.chatRevoked': false });
});
it('allows slurs in private groups', async () => {
@@ -201,7 +201,7 @@ describe('POST /chat', () => {
},
members: 1,
});
await members[0].update({ 'auth.timestamps.created': new Date('2022-01-01') });
await members[0].updateOne({ 'auth.timestamps.created': new Date('2022-01-01') });
const message = await members[0].post(`/groups/${group._id}/chat`, { message: testSlurMessage });
@@ -210,14 +210,14 @@ describe('POST /chat', () => {
});
it('errors when user account is too young', async () => {
await user.update({ 'auth.timestamps.created': new Date() });
await user.updateOne({ 'auth.timestamps.created': new Date() });
await expect(user.post(`/groups/${groupWithChat._id}/chat`, { message: 'hi im new' }))
.to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: t('chatTemporarilyUnavailable'),
});
await user.update({ 'auth.timestamps.created': new Date('2022-01-01') });
await user.updateOne({ 'auth.timestamps.created': new Date('2022-01-01') });
});
it('creates a chat', async () => {
@@ -258,7 +258,7 @@ describe('POST /chat', () => {
it('chat message with mentions - mention link should not count towards 3000 chars limit', async () => {
const memberUsername = 'memberUsername';
await member.update({ 'auth.local.username': memberUsername });
await member.updateOne({ 'auth.local.username': memberUsername });
const messageWithMentions = `hi @${memberUsername} 123456789
123456789 123456789 123456789 123456789 123456789 123456789 89 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 12345678 END.`;
@@ -278,7 +278,7 @@ describe('POST /chat', () => {
const mount = 'test-mount';
const pet = 'test-pet';
const style = 'test-style';
await user.update({
await user.updateOne({
'items.currentMount': mount,
'items.currentPet': pet,
'preferences.style': style,
@@ -308,7 +308,7 @@ describe('POST /chat', () => {
});
it('creates costume to user styles', async () => {
await user.update({ 'preferences.costume': true });
await user.updateOne({ 'preferences.costume': true });
const message = await user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
@@ -323,7 +323,7 @@ describe('POST /chat', () => {
tier: 800,
tokensApplied: true,
};
await user.update({
await user.updateOne({
backer: backerInfo,
});
@@ -375,7 +375,7 @@ describe('POST /chat', () => {
context('chat notifications', () => {
beforeEach(() => {
member.update({ newMessages: {}, notifications: [] });
member.updateOne({ newMessages: {}, notifications: [] });
});
it('notifies other users of new messages for a guild', async () => {

View File

@@ -28,8 +28,8 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
groupWithChat = group;
author = groupLeader;
[nonAdmin, admin] = members;
await nonAdmin.update({ 'auth.timestamps.created': moment().subtract(USER_AGE_FOR_FLAGGING + 1, 'days').toDate() });
await admin.update({ 'permissions.moderator': true });
await nonAdmin.updateOne({ 'auth.timestamps.created': moment().subtract(USER_AGE_FOR_FLAGGING + 1, 'days').toDate() });
await admin.updateOne({ 'permissions.moderator': true });
message = await author.post(`/groups/${groupWithChat._id}/chat`, { message: 'Some message' });
message = message.message;
@@ -71,7 +71,7 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
members: 2,
});
await members[0].update({ 'auth.timestamps.created': new Date('2022-01-01') });
await members[0].updateOne({ 'auth.timestamps.created': new Date('2022-01-01') });
let privateMessage = await members[0].post(`/groups/${group._id}/chat`, { message: 'Some message' });
privateMessage = privateMessage.message;
@@ -104,7 +104,7 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
const member = members[0];
// make member that can use skills
await member.update({
await member.updateOne({
'stats.lvl': 100,
'stats.mp': 400,
'stats.class': 'wizard',

View File

@@ -2,7 +2,7 @@ import {
generateUser,
resetHabiticaDB,
} from '../../../../helpers/api-integration/v3';
import apiError from '../../../../../website/server/libs/apiError';
import { apiError } from '../../../../../website/server/libs/apiError';
describe('GET /coupons/', () => {
let user;
@@ -24,7 +24,7 @@ describe('GET /coupons/', () => {
});
it('should return the coupons in CSV format ordered by creation date', async () => {
await user.update({
await user.updateOne({
'permissions.coupons': true,
});

View File

@@ -4,7 +4,7 @@ import {
translate as t,
resetHabiticaDB,
} from '../../../../helpers/api-integration/v3';
import apiError from '../../../../../website/server/libs/apiError';
import { apiError } from '../../../../../website/server/libs/apiError';
describe('POST /coupons/generate/:event', () => {
let user;
@@ -19,7 +19,7 @@ describe('POST /coupons/generate/:event', () => {
});
it('returns an error if user has no coupons permission', async () => {
await user.update({
await user.updateOne({
'permissions.coupons': false,
});
@@ -47,7 +47,7 @@ describe('POST /coupons/generate/:event', () => {
});
it('should generate coupons', async () => {
await user.update({
await user.updateOne({
'permissions.coupons': true,
});

View File

@@ -24,7 +24,7 @@ describe('POST /debug/quest-progress', () => {
});
it('increases boss quest progress by 1000', async () => {
await user.update({
await user.updateOne({
'party.quest.key': 'whale',
});
@@ -36,7 +36,7 @@ describe('POST /debug/quest-progress', () => {
});
it('increases collection quest progress by 300 items', async () => {
await user.update({
await user.updateOne({
'party.quest.key': 'evilsanta2',
});

View File

@@ -37,7 +37,7 @@ describe('GET /groups', () => {
upgradeToGroupPlan: true,
}));
[user] = members;
await user.update({ balance: 4 });
await user.updateOne({ balance: 4 });
({ group: secondGroup, groupLeader: secondLeader } = await createAndPopulateGroup({
groupDetails: {

View File

@@ -153,7 +153,7 @@ describe('GET /groups/:id', () => {
it('removes non-existent guild from user\'s guild list', async () => {
const guildId = generateUUID();
await user.update({
await user.updateOne({
guilds: [guildId, generateUUID()],
});
@@ -173,7 +173,7 @@ describe('GET /groups/:id', () => {
it('removes non-existent party from user\'s party object', async () => {
const partyId = generateUUID();
await user.update({
await user.updateOne({
party: { _id: partyId },
});
@@ -290,7 +290,7 @@ describe('GET /groups/:id', () => {
beforeEach(async () => {
[admin] = members;
await admin.update({ permissions: { moderator: true } });
await admin.updateOne({ permissions: { moderator: true } });
});
it('includes all messages', async () => {

View File

@@ -110,7 +110,7 @@ describe('POST /group', () => {
});
it('creates a party when the user has no chat privileges', async () => {
await user.update({ 'flags.chatRevoked': true });
await user.updateOne({ 'flags.chatRevoked': true });
const party = await user.post('/groups', {
name: partyName,
type: partyType,
@@ -120,7 +120,7 @@ describe('POST /group', () => {
});
it('does not require gems to create a party', async () => {
await user.update({ balance: 0 });
await user.updateOne({ balance: 0 });
const party = await user.post('/groups', {
name: partyName,

View File

@@ -78,7 +78,7 @@ describe('POST /group/:groupId/join', () => {
});
it('does not increment basilist quest count to inviter with basilist when joining a guild', async () => {
await user.update({ 'items.quests.basilist': 1 });
await user.updateOne({ 'items.quests.basilist': 1 });
await invitedUser.post(`/groups/${guild._id}/join`);
@@ -146,7 +146,7 @@ describe('POST /group/:groupId/join', () => {
});
it('Issue #12291: accepting a redundant party invite will let the user stay in the party', async () => {
await invitedUser.update({
await invitedUser.updateOne({
'party._id': party._id,
});
await expect(invitedUser.get('/user')).to.eventually.have.nested.property('party._id', party._id);
@@ -193,7 +193,7 @@ describe('POST /group/:groupId/join', () => {
});
it('increments basilist quest item count to inviter when joining a party', async () => {
await user.update({ 'items.quests.basilist': 1 });
await user.updateOne({ 'items.quests.basilist': 1 });
await invitedUser.post(`/groups/${party._id}/join`);
@@ -201,7 +201,7 @@ describe('POST /group/:groupId/join', () => {
});
it('invites joining member to active quest', async () => {
await user.update({
await user.updateOne({
[`items.quests.${PET_QUEST}`]: 1,
});
await user.post(`/groups/${party._id}/quests/invite/${PET_QUEST}`);

View File

@@ -30,7 +30,7 @@ describe('POST /groups/:groupId/leave', () => {
[member] = members;
memberCount = groupToLeave.memberCount;
await leader.update({ 'auth.timestamps.created': new Date('2022-01-01') });
await leader.updateOne({ 'auth.timestamps.created': new Date('2022-01-01') });
});
it('prevents non members from leaving', async () => {
@@ -135,7 +135,7 @@ describe('POST /groups/:groupId/leave', () => {
[member] = members;
[invitedUser] = invitees;
memberCount = groupToLeave.memberCount;
await leader.update({ 'auth.timestamps.created': new Date('2022-01-01') });
await leader.updateOne({ 'auth.timestamps.created': new Date('2022-01-01') });
});
it('prevents non members from leaving', async () => {
@@ -317,7 +317,7 @@ describe('POST /groups/:groupId/leave', () => {
upgradeToGroupPlan: true,
}));
[member] = members;
await member.update({
await member.updateOne({
'purchased.plan.extraMonths': extraMonths,
});
});

View File

@@ -212,7 +212,7 @@ describe('POST /groups/:groupId/removeMember/:memberId', () => {
it('removes user from quest when removing user from party after quest starts', async () => {
const petQuest = 'whale';
await partyLeader.update({
await partyLeader.updateOne({
[`items.quests.${petQuest}`]: 1,
});
@@ -234,7 +234,7 @@ describe('POST /groups/:groupId/removeMember/:memberId', () => {
it('removes user from quest when removing user from party before quest starts', async () => {
const petQuest = 'whale';
await partyLeader.update({
await partyLeader.updateOne({
[`items.quests.${petQuest}`]: 1,
});
await partyInvitedUser.post(`/groups/${party._id}/join`);
@@ -257,7 +257,7 @@ describe('POST /groups/:groupId/removeMember/:memberId', () => {
it('prevents user from being removed if they are the quest owner', async () => {
const petQuest = 'whale';
await partyMember.update({
await partyMember.updateOne({
[`items.quests.${petQuest}`]: 1,
});

View File

@@ -49,7 +49,7 @@ describe('Post /groups/:groupId/invite', () => {
});
it('returns error when recipient has blocked the senders', async () => {
const inviterNoBlocks = await inviter.update({ 'inbox.blocks': [] });
const inviterNoBlocks = await inviter.updateOne({ 'inbox.blocks': [] });
const userWithBlockedInviter = await generateUser({ 'inbox.blocks': [inviter._id] });
await expect(inviterNoBlocks.post(`/groups/${group._id}/invite`, {
usernames: [userWithBlockedInviter.auth.local.lowerCaseUsername],
@@ -107,7 +107,7 @@ describe('Post /groups/:groupId/invite', () => {
describe('user id invites', () => {
it('returns an error when inviter has no chat privileges', async () => {
const inviterMuted = await inviter.update({ 'flags.chatRevoked': true });
const inviterMuted = await inviter.updateOne({ 'flags.chatRevoked': true });
const userToInvite = await generateUser();
await expect(inviterMuted.post(`/groups/${group._id}/invite`, {
uuids: [userToInvite._id],
@@ -197,7 +197,7 @@ describe('Post /groups/:groupId/invite', () => {
});
it('returns error when recipient has blocked the senders', async () => {
const inviterNoBlocks = await inviter.update({ 'inbox.blocks': [] });
const inviterNoBlocks = await inviter.updateOne({ 'inbox.blocks': [] });
const userWithBlockedInviter = await generateUser({ 'inbox.blocks': [inviter._id] });
await expect(inviterNoBlocks.post(`/groups/${group._id}/invite`, {
uuids: [userWithBlockedInviter._id],
@@ -269,7 +269,7 @@ describe('Post /groups/:groupId/invite', () => {
const testInvite = { name: 'test', email: 'test@habitica.com' };
it('returns an error when inviter has no chat privileges', async () => {
const inviterMuted = await inviter.update({ 'flags.chatRevoked': true });
const inviterMuted = await inviter.updateOne({ 'flags.chatRevoked': true });
await expect(inviterMuted.post(`/groups/${group._id}/invite`, {
emails: [testInvite],
inviter: 'inviter name',
@@ -439,7 +439,7 @@ describe('Post /groups/:groupId/invite', () => {
describe('party invites', () => {
it('returns an error when inviter has no chat privileges', async () => {
const inviterMuted = await inviter.update({ 'flags.chatRevoked': true });
const inviterMuted = await inviter.updateOne({ 'flags.chatRevoked': true });
const userToInvite = await generateUser();
await expect(inviterMuted.post(`/groups/${group._id}/invite`, {
uuids: [userToInvite._id],

View File

@@ -170,7 +170,7 @@ describe('PUT /group', () => {
},
upgradeToGroupPlan: true,
});
await groupLeader.update({ permissions: {} });
await groupLeader.updateOne({ permissions: {} });
const updateGroupDetails = {
id: group._id,

View File

@@ -9,7 +9,7 @@ describe('GET /heroes/:heroId', () => {
const heroFields = [
'_id', 'id', 'auth', 'balance', 'contributor', 'flags', 'items',
'lastCron', 'party', 'preferences', 'profile', 'purchased', 'secret',
'lastCron', 'party', 'preferences', 'profile', 'purchased', 'secret', 'achievements',
];
before(async () => {

View File

@@ -4,7 +4,7 @@ import {
generateGroup,
translate as t,
} from '../../../../helpers/api-integration/v3';
import apiError from '../../../../../website/server/libs/apiError';
import { apiError } from '../../../../../website/server/libs/apiError';
describe('GET /heroes/party/:groupId', () => {
let user; // admin user

View File

@@ -10,7 +10,7 @@ describe('PUT /heroes/:heroId', () => {
const heroFields = [
'_id', 'auth', 'balance', 'contributor', 'flags', 'items', 'lastCron',
'party', 'preferences', 'profile', 'purchased', 'secret', 'permissions',
'party', 'preferences', 'profile', 'purchased', 'secret', 'permissions', 'achievements',
];
before(async () => {
@@ -251,4 +251,159 @@ describe('PUT /heroes/:heroId', () => {
expect(updatedHero.apiToken).to.not.equal(originalToken);
expect(updatedHero.apiTokenObscured).to.not.exist;
});
it('updates purchased hair customization', async () => {
const hero = await generateUser();
const heroRes = await user.put(`/hall/heroes/${hero._id}`, {
purchasedPath: 'purchased.hair.bangs.1',
purchasedVal: true,
});
// test response
expect(heroRes).to.have.all.keys(heroFields);
expect(heroRes.auth.local).not.to.have.keys(['salt', 'hashed_password']);
expect(heroRes.profile).to.have.all.keys(['name']);
// test response values
expect(heroRes.purchased.hair.bangs['1']).to.equal(true);
// test hero values
await hero.sync();
expect(hero.purchased.hair.bangs['1']).to.equal(true);
});
it('updates purchased customization', async () => {
const hero = await generateUser();
const heroRes = await user.put(`/hall/heroes/${hero._id}`, {
purchasedPath: 'purchased.background.beach',
purchasedVal: true,
});
// test response
expect(heroRes).to.have.all.keys(heroFields);
expect(heroRes.auth.local).not.to.have.keys(['salt', 'hashed_password']);
expect(heroRes.profile).to.have.all.keys(['name']);
// test response values
expect(heroRes.purchased.background.beach).to.equal(true);
// test hero values
await hero.sync();
expect(hero.purchased.background.beach).to.equal(true);
});
it('updates giving nested achievement', async () => {
const hero = await generateUser();
const heroRes = await user.put(`/hall/heroes/${hero._id}`, {
achievementPath: 'achievements.quests.dilatory',
achievementVal: 2,
});
// test response
expect(heroRes).to.have.all.keys(heroFields);
expect(heroRes.auth.local).not.to.have.keys(['salt', 'hashed_password']);
expect(heroRes.profile).to.have.all.keys(['name']);
// test response values
expect(heroRes.achievements.quests.dilatory).to.equal(2);
// test hero values
await hero.sync();
expect(hero.achievements.quests.dilatory).to.equal(2);
});
it('updates taking away nested achievement', async () => {
const hero = await generateUser({ 'achievements.quests.dilatory': 3 });
expect(hero.achievements.quests.dilatory).to.equal(3);
const heroRes = await user.put(`/hall/heroes/${hero._id}`, {
achievementPath: 'achievements.quests.dilatory',
achievementVal: 0,
});
// test response
expect(heroRes).to.have.all.keys(heroFields);
expect(heroRes.auth.local).not.to.have.keys(['salt', 'hashed_password']);
expect(heroRes.profile).to.have.all.keys(['name']);
// test response values
expect(heroRes.achievements.quests.dilatory).to.equal(0);
// test hero values
await hero.sync();
expect(hero.achievements.quests.dilatory).to.equal(0);
});
it('updates giving achievement', async () => {
const hero = await generateUser();
const heroRes = await user.put(`/hall/heroes/${hero._id}`, {
achievementPath: 'achievements.partyOn',
achievementVal: true,
});
// test response
expect(heroRes).to.have.all.keys(heroFields);
expect(heroRes.auth.local).not.to.have.keys(['salt', 'hashed_password']);
expect(heroRes.profile).to.have.all.keys(['name']);
// test response values
expect(heroRes.achievements.partyOn).to.equal(true);
// test hero values
await hero.sync();
expect(hero.achievements.partyOn).to.equal(true);
});
it('updates taking away achievement', async () => {
const hero = await generateUser({ 'achievements.partyUp': true });
expect(hero.achievements.partyUp).to.equal(true);
const heroRes = await user.put(`/hall/heroes/${hero._id}`, {
achievementPath: 'achievements.partyUp',
achievementVal: false,
});
// test response
expect(heroRes).to.have.all.keys(heroFields);
expect(heroRes.auth.local).not.to.have.keys(['salt', 'hashed_password']);
expect(heroRes.profile).to.have.all.keys(['name']);
// test response values
expect(heroRes.achievements.partyUp).to.equal(false);
// test hero values
await hero.sync();
expect(hero.achievements.partyUp).to.equal(false);
});
it('updates giving numbered achievement', async () => {
const hero = await generateUser();
const heroRes = await user.put(`/hall/heroes/${hero._id}`, {
achievementPath: 'achievements.streak',
achievementVal: 42,
});
// test response
expect(heroRes).to.have.all.keys(heroFields);
expect(heroRes.auth.local).not.to.have.keys(['salt', 'hashed_password']);
expect(heroRes.profile).to.have.all.keys(['name']);
// test response values
expect(heroRes.achievements.streak).to.equal(42);
// test hero values
await hero.sync();
expect(hero.achievements.streak).to.equal(42);
});
it('updates setting numbered achievement to 0', async () => {
const hero = await generateUser({ 'achievements.streak': 42 });
expect(hero.achievements.streak).to.equal(42);
const heroRes = await user.put(`/hall/heroes/${hero._id}`, {
achievementPath: 'achievements.streak',
achievementVal: 0,
});
// test response
expect(heroRes).to.have.all.keys(heroFields);
expect(heroRes.auth.local).not.to.have.keys(['salt', 'hashed_password']);
expect(heroRes.profile).to.have.all.keys(['name']);
// test response values
expect(heroRes.achievements.streak).to.equal(0);
// test hero values
await hero.sync();
expect(hero.achievements.streak).to.equal(0);
});
});

View File

@@ -69,8 +69,6 @@ describe('POST /members/:memberId/flag', () => {
await reporter.post(`/members/${target._id}/flag`);
const updatedTarget = await admin.get(`/hall/heroes/${target._id}`);
expect(updatedTarget.profile.flags[reporter._id]).to.have.all.keys([
'comment',
'source',
'timestamp',
]);
expect(moment(updatedTarget.profile.flags[reporter._id].timestamp).toDate()).to.be.a('date');

View File

@@ -181,7 +181,8 @@ describe('POST /members/transfer-gems', () => {
const updatedSender = await userToSendMessage.get('/user');
const sendersMessageInReceiversInbox = findMessage(
updatedReceiver.inbox.messages, userToSendMessage._id,
updatedReceiver.inbox.messages,
userToSendMessage._id,
);
const sendersMessageInSendersInbox = findMessage(updatedSender.inbox.messages, receiver._id);
@@ -212,7 +213,8 @@ describe('POST /members/transfer-gems', () => {
const updatedSender = await userToSendMessage.get('/user');
const sendersMessageInReceiversInbox = findMessage(
updatedReceiver.inbox.messages, userToSendMessage._id,
updatedReceiver.inbox.messages,
userToSendMessage._id,
);
const sendersMessageInSendersInbox = findMessage(updatedSender.inbox.messages, receiver._id);
@@ -233,10 +235,10 @@ describe('POST /members/transfer-gems', () => {
});
it('sends transfer gems message in each participant\'s language', async () => {
await receiver.update({
await receiver.updateOne({
'preferences.language': 'es',
});
await userToSendMessage.update({
await userToSendMessage.updateOne({
'preferences.language': 'cs',
});
await userToSendMessage.post('/members/transfer-gems', {
@@ -248,7 +250,8 @@ describe('POST /members/transfer-gems', () => {
const updatedSender = await userToSendMessage.get('/user');
const sendersMessageInReceiversInbox = findMessage(
updatedReceiver.inbox.messages, userToSendMessage._id,
updatedReceiver.inbox.messages,
userToSendMessage._id,
);
const sendersMessageInSendersInbox = findMessage(updatedSender.inbox.messages, receiver._id);

View File

@@ -27,7 +27,7 @@ describe('POST /notifications/:notificationId/read', () => {
const id = generateUUID();
const id2 = generateUUID();
await user.update({
await user.updateOne({
notifications: [{
id,
type: 'DROPS_ENABLED',

View File

@@ -27,7 +27,7 @@ describe('POST /notifications/:notificationId/see', () => {
const id = generateUUID();
const id2 = generateUUID();
await user.update({
await user.updateOne({
notifications: [{
id,
type: 'DROPS_ENABLED',

View File

@@ -30,7 +30,7 @@ describe('POST /notifications/read', () => {
const id2 = generateUUID();
const id3 = generateUUID();
await user.update({
await user.updateOne({
notifications: [{
id,
type: 'DROPS_ENABLED',

View File

@@ -30,7 +30,7 @@ describe('POST /notifications/see', () => {
const id2 = generateUUID();
const id3 = generateUUID();
await user.update({
await user.updateOne({
notifications: [{
id,
type: 'DROPS_ENABLED',

Some files were not shown because too many files have changed in this diff Show More