Compare commits

...

267 Commits

Author SHA1 Message Date
SabreCat 5ea82fe87f 4.224.3 2022-03-15 16:08:58 -05:00
SabreCat a24651e395 fix(content): bundle ends March not May 2022-03-15 16:08:53 -05:00
SabreCat 6339e9066f 4.224.2 2022-03-15 15:01:11 -05:00
SabreCat c2d48480a0 chore(content): rerelease cuddle bubbles 2022-03-15 15:00:58 -05:00
SabreCat d9240f7887 fix(migration): actually count 2022-03-14 15:06:57 -05:00
SabreCat dd86b96433 4.224.1 2022-03-14 14:30:20 -05:00
SabreCat 3e082fe127 chore(event): Pi Day 2022 2022-03-14 14:29:57 -05:00
SabreCat c38781e154 4.224.0 2022-03-09 16:17:28 -06:00
SabreCat 3c7df419b7 chore(submodule): update habitica-images 2022-03-09 16:17:23 -06:00
SabreCat 52d1480844 chore(sprites): build CSS 2022-03-09 16:16:44 -06:00
CuriousMagpie d9f593d53a added migration script 2022-03-09 15:55:31 -06:00
SabreCat 7cc17d0369 feat(content): Armoire and Backgrounds 2022-03-09 15:50:31 -06:00
CuriousMagpie 43be5f0490 Add Rooster and Peacock 2022-03-08 16:52:43 -05:00
CuriousMagpie fc4145700c image update! 2022-03-08 13:06:33 -05:00
CuriousMagpie aa1b9a5e94 added achievement Birds of a Feather 2022-03-08 12:43:38 -05:00
CuriousMagpie ce57a70e64 habitica images update 2022-03-08 12:37:49 -05:00
SabreCat e66f722311 4.223.0 2022-02-28 09:49:27 -06:00
SabreCat 05a54e505c chore(mystery): update images, run sprites 2022-02-28 09:49:21 -06:00
CuriousMagpie 82e9c2e896 2022-03 Subscriber Items 2022-02-28 09:37:57 -06:00
CuriousMagpie 8dbb55f3b7 2022-03 Subscriber Items 2022-02-28 09:37:49 -06:00
SabreCat 4295b55339 4.222.2 2022-02-22 12:18:20 -06:00
SabreCat 08352c5f49 fix(subs): correct cancellation check logic and test 2022-02-22 11:26:15 -06:00
SabreCat 7080715bcc fix(tests): renewig typos 2022-02-22 10:13:32 -06:00
Phillip Thelen c6d07983b2 Fix issue with validating android sub cancellation 2022-02-22 10:12:10 -06:00
SabreCat a5c141407e 4.222.1 2022-02-17 14:38:13 -06:00
SabreCat 70be356968 chore(content): enable Mythical Marvels for end of February 2022-02-17 14:27:17 -06:00
SabreCat 1fd931d935 4.222.0 2022-02-14 15:31:19 -06:00
SabreCat 77751223d3 fix(valentines): adjust empty event daterange 2022-02-14 15:20:37 -06:00
CuriousMagpie d1ef90db29 Fixed end dates to Feb 18 2022-02-14 15:03:38 -06:00
CuriousMagpie 79cda5d1f6 updates for 2022-02 magic hatching potions & valentine's week 2022-02-14 15:03:32 -06:00
SabreCat be5756469c 4.221.3 2022-02-14 14:48:09 -06:00
SabreCat d9e2069995 fix(packages) new fix attempt from last known good 2022-02-14 14:37:26 -06:00
SabreCat d8cbc2c4b2 4.221.1 2022-02-09 11:17:26 -06:00
SabreCat 81363feb26 revert Bailey datetime PR 2022-02-09 11:17:15 -06:00
SabreCat 2ac5ebe01a 4.221.0 2022-02-08 14:10:47 -06:00
Weblate bfacfd2db8 Merge branch 'origin/develop' into Weblate. 2022-02-08 21:09:15 +01:00
dependabot[bot] eb820a2902 build(deps): bump @storybook/addon-actions in /website/client (#13839)
Bumps [@storybook/addon-actions](https://github.com/storybookjs/storybook/tree/HEAD/addons/actions) from 6.4.17 to 6.4.18.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.18/addons/actions)

---
updated-dependencies:
- dependency-name: "@storybook/addon-actions"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-08 12:14:42 -05:00
dependabot[bot] efabd7ca15 build(deps): bump winston from 3.5.0 to 3.5.1 (#13830)
Bumps [winston](https://github.com/winstonjs/winston) from 3.5.0 to 3.5.1.
- [Release notes](https://github.com/winstonjs/winston/releases)
- [Changelog](https://github.com/winstonjs/winston/blob/master/CHANGELOG.md)
- [Commits](https://github.com/winstonjs/winston/compare/v3.5.0...v3.5.1)

---
updated-dependencies:
- dependency-name: winston
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-08 12:13:59 -05:00
dependabot[bot] 0266c46aee build(deps): bump stripe from 8.201.0 to 8.202.0 (#13829)
Bumps [stripe](https://github.com/stripe/stripe-node) from 8.201.0 to 8.202.0.
- [Release notes](https://github.com/stripe/stripe-node/releases)
- [Changelog](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stripe/stripe-node/compare/v8.201.0...v8.202.0)

---
updated-dependencies:
- dependency-name: stripe
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-08 12:13:43 -05:00
dependabot[bot] df3447afa6 build(deps): bump @storybook/addons in /website/client (#13824)
Bumps [@storybook/addons](https://github.com/storybookjs/storybook/tree/HEAD/lib/addons) from 6.4.17 to 6.4.18.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.18/lib/addons)

---
updated-dependencies:
- dependency-name: "@storybook/addons"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-08 12:12:37 -05:00
dependabot[bot] 6dc46a664a build(deps): bump accepts from 1.3.7 to 1.3.8 (#13823)
Bumps [accepts](https://github.com/jshttp/accepts) from 1.3.7 to 1.3.8.
- [Release notes](https://github.com/jshttp/accepts/releases)
- [Changelog](https://github.com/jshttp/accepts/blob/master/HISTORY.md)
- [Commits](https://github.com/jshttp/accepts/compare/1.3.7...1.3.8)

---
updated-dependencies:
- dependency-name: accepts
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-08 12:12:19 -05:00
dependabot[bot] 7e7c85a419 build(deps): bump @babel/register from 7.16.9 to 7.17.0 (#13822)
Bumps [@babel/register](https://github.com/babel/babel/tree/HEAD/packages/babel-register) from 7.16.9 to 7.17.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.17.0/packages/babel-register)

---
updated-dependencies:
- dependency-name: "@babel/register"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-08 12:12:04 -05:00
SabreCat 9e740e7092 fix(heroes): still more indents 2022-02-08 11:10:39 -06:00
SabreCat 169634f205 fix(heroes): remove broken td and correct indentation 2022-02-08 11:09:05 -06:00
SabreCat 094cf899d8 fix(heroes): remove duplicated column 2022-02-08 10:39:11 -06:00
Weblate 30420210f5 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (365 of 365 strings)

Translated using Weblate (Ukrainian)

Currently translated at 80.4% (2039 of 2533 strings)

Translated using Weblate (Ukrainian)

Currently translated at 75.5% (96 of 127 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (675 of 675 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (675 of 675 strings)

Translated using Weblate (Japanese)

Currently translated at 93.2% (192 of 206 strings)

Translated using Weblate (Ukrainian)

Currently translated at 73.3% (143 of 195 strings)

Translated using Weblate (Ukrainian)

Currently translated at 98.1% (109 of 111 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (61 of 61 strings)

Translated using Weblate (Ukrainian)

Currently translated at 73.4% (158 of 215 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (365 of 365 strings)

Translated using Weblate (Ukrainian)

Currently translated at 80.6% (2038 of 2527 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Ukrainian)

Currently translated at 97.7% (174 of 178 strings)

Translated using Weblate (Ukrainian)

Currently translated at 50.0% (28 of 56 strings)

Translated using Weblate (Ukrainian)

Currently translated at 84.4% (630 of 746 strings)

Translated using Weblate (Ukrainian)

Currently translated at 75.5% (96 of 127 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (372 of 372 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (128 of 128 strings)

Translated using Weblate (Japanese)

Currently translated at 91.2% (188 of 206 strings)

Translated using Weblate (Czech)

Currently translated at 92.6% (619 of 668 strings)

Translated using Weblate (German)

Currently translated at 100.0% (128 of 128 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (2527 of 2527 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (128 of 128 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (195 of 195 strings)

Translated using Weblate (Spanish)

Currently translated at 99.8% (2523 of 2527 strings)

Translated using Weblate (Spanish)

Currently translated at 99.0% (204 of 206 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (130 of 130 strings)

Translated using Weblate (Spanish)

Currently translated at 99.8% (2522 of 2527 strings)

Translated using Weblate (Spanish)

Currently translated at 97.5% (201 of 206 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (2527 of 2527 strings)

Translated using Weblate (Japanese)

Currently translated at 99.8% (2523 of 2527 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.2% (127 of 128 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (202 of 206 strings)

Translated using Weblate (Ukrainian)

Currently translated at 98.1% (109 of 111 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (372 of 372 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (372 of 372 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (128 of 128 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (195 of 195 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (365 of 365 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (128 of 128 strings)

Translated using Weblate (Ukrainian)

Currently translated at 93.6% (104 of 111 strings)

Translated using Weblate (Ukrainian)

Currently translated at 94.6% (123 of 130 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Ukrainian)

Currently translated at 83.3% (622 of 746 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (372 of 372 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (128 of 128 strings)

Translated using Weblate (Ukrainian)

Currently translated at 92.7% (103 of 111 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (61 of 61 strings)

Translated using Weblate (Ukrainian)

Currently translated at 73.4% (158 of 215 strings)

Translated using Weblate (Ukrainian)

Currently translated at 73.4% (158 of 215 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (365 of 365 strings)

Translated using Weblate (Ukrainian)

Currently translated at 75.5% (96 of 127 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (128 of 128 strings)

Translated using Weblate (Danish)

Currently translated at 98.4% (126 of 128 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (206 of 206 strings)

Translated using Weblate (Japanese)

Currently translated at 90.7% (187 of 206 strings)

Translated using Weblate (Ukrainian)

Currently translated at 75.5% (96 of 127 strings)

Translated using Weblate (Ukrainian)

Currently translated at 75.5% (96 of 127 strings)

Translated using Weblate (German)

Currently translated at 100.0% (130 of 130 strings)

Translated using Weblate (German)

Currently translated at 99.8% (2523 of 2527 strings)

Translated using Weblate (Ukrainian)

Currently translated at 74.0% (94 of 127 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (130 of 130 strings)

Translated using Weblate (Ukrainian)

Currently translated at 72.0% (155 of 215 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (372 of 372 strings)

Translated using Weblate (Hebrew)

Currently translated at 66.7% (446 of 668 strings)

Translated using Weblate (Hebrew)

Currently translated at 62.5% (80 of 128 strings)

Translated using Weblate (Japanese)

Currently translated at 90.2% (186 of 206 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (195 of 195 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (130 of 130 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.6% (2519 of 2527 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (2527 of 2527 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (746 of 746 strings)

Co-authored-by: Asta Jensen <asta.raae@live.dk>
Co-authored-by: Jonas Nardes Braga <ionabi@gmail.com>
Co-authored-by: Kedr <sergeysamori.ua@gmail.com>
Co-authored-by: Maikel Roelofs <maikel_roelofs@live.nl>
Co-authored-by: Mara Dolichotis <marascherzer@gmail.com>
Co-authored-by: Martin Bartak <martin.bartak@gmail.com>
Co-authored-by: Nazar Paruna <nazarparuna@gmail.com>
Co-authored-by: Ofek yeshurun <ofek.yeshurun@gmail.com>
Co-authored-by: Pardinus <artemisadlg@gmail.com>
Co-authored-by: Sciuridae <sweetvshoney@163.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: mattya 226 <worldworld1114@gmail.com>
Co-authored-by: Володимир <wishreacher@gmail.com>
Co-authored-by: Естай <akseleu@yahoo.com>
Co-authored-by: そら <comi4work@gmail.com>
Co-authored-by: 张大鸣 <3063837415@qq.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/da/
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/he/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/nl/
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/cs/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/he/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/character/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/uk/
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/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/front/uk/
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/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/generic/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/uk/
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/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/uk/
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/settings/es/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/es/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/uk/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
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/Messages
Translation: Habitica/Npc
Translation: Habitica/Pets
Translation: Habitica/Questscontent
Translation: Habitica/Settings
Translation: Habitica/Subscriber
2022-02-08 14:21:01 +01:00
SabreCat fd4d139fc2 Merge remote-tracking branch 'CuriousMagpie/2022-02-backgrounds-armoire' into develop 2022-02-07 10:51:23 -06:00
Sabe Jones a8859d51b1 fix(backgrounds): string syntax consistency 2022-02-07 10:49:18 -06:00
Alys d464b98d9b add words to list of banned swear words - TRIGGER / CONTENT WARNING: assault, slurs, swearwords, etc 2022-02-06 15:50:25 +10:00
Weblate ff806ec491 Merge branch 'origin/develop' into Weblate. 2022-02-01 22:34:50 +01:00
SabreCat ca4df96902 Merge branch 'release' into develop 2022-02-01 15:29:35 -06:00
SabreCat f43a12acb2 4.220.0 2022-02-01 15:22:45 -06:00
SabreCat 82d0251fed fix(event): extend 24h because i derped 2022-02-01 15:21:53 -06:00
SabreCat 9e5948df64 chore(sprites): compile 2022-02-01 15:21:03 -06:00
SabreCat 269c420bfa fix(zodiac): tiger cubs lol 2022-02-01 15:20:08 -06:00
SabreCat 83c2e1774b Merge remote-tracking branch 'CuriousMagpie/zodiac-zookeeper' into release 2022-02-01 14:30:02 -06:00
SabreCat 2093932af6 Merge remote-tracking branch 'CuriousMagpie/2022-02-subscriber-items' into release 2022-02-01 14:29:28 -06:00
SabreCat b383574438 fix(event): it's 2022 now, lol 2022-02-01 14:27:08 -06:00
SabreCat 9a9449e001 chore(deps): update package lock 2022-02-01 14:25:16 -06:00
Weblate 91718fbe3f Translated using Weblate (Italian)
Currently translated at 100.0% (2523 of 2523 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (2523 of 2523 strings)

Co-authored-by: Chap <chalda82+nogravatar@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Естай <akseleu@yahoo.com>
Translate-URL: https://translate.habitica.com/projects/habitica/gear/it/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ru/
Translation: Habitica/Gear
2022-02-01 11:48:26 +01:00
SabreCat 844e0d7cf4 fix(dependencies): add moment-timezone 2022-01-31 22:19:03 -06:00
SabreCat c8e949a425 Merge branch 'release' into develop 2022-01-31 19:17:26 -06:00
SabreCat e2450b69b2 4.219.1 2022-01-31 19:17:15 -06:00
SabreCat 2ae36f64ad fix(birthday): market cake 2022-01-31 19:17:08 -06:00
SabreCat fb73ec3ad9 Merge remote-tracking branch 'Lyqst/news-post-datetime' into develop 2022-01-31 15:41:33 -06:00
SabreCat e7dc233fc9 Merge remote-tracking branch 'origin/feature/sprites-cdn' into develop 2022-01-31 15:40:27 -06:00
Phillip Thelen 6e43d4dc79 Add Transaction log for gem and hourglass changes (#13589)
* Log all gem transactions to database

* Also store hourglass transactions

* Fix tests

* Display transaction history in hall of heroes for admins

* add tests to new API call

* hide transaction settings tab for non admins

* fix(lint): remove console

* fix(lint): various automatic corrections

* fix(transactions): use enum expected pluralizations

* fix api unit tests

* fix lint

* fix failing test

* Fix minor inconsistencies

* Log all gem transactions to database

* Also store hourglass transactions

* Fix tests

* Display transaction history in hall of heroes for admins

* add tests to new API call

* hide transaction settings tab for non admins

* fix(lint): remove console

* fix(lint): various automatic corrections

* fix(transactions): use enum expected pluralizations

* fix api unit tests

* fix lint

* Fix minor inconsistencies

Co-authored-by: Sabe Jones <sabrecat@gmail.com>
2022-01-31 15:36:15 -06:00
Vanathi G 5beb29305d Fix selection highlight in avatar editor (#13746) 2022-01-31 15:35:17 -06:00
Aleksander Pentchev b3925d6c7a #13731 - Changed account reset button pop-up text (#13751)
Co-authored-by: Aleksander Pentchev <aleksander.pentchev@roche.com>
2022-01-31 15:33:28 -06:00
Natalie L de70ad65f5 Update Orb of Rebirth to ignore completed todos (#13773)
* added logic to exclude completed tasks from having task.value set to 0

* logic refinement

* fix(rebirth): complete D

Co-authored-by: SabreCat <sabe@habitica.com>
2022-01-31 15:33:11 -06:00
SabreCat f3cd461145 4.219.0 2022-01-31 15:23:16 -06:00
Weblate 3a28fd58ef Translated using Weblate (Polish)
Currently translated at 69.1% (1744 of 2523 strings)

Co-authored-by: Sabe Jones <sabe@habitica.com>
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pl/
Translation: Habitica/Gear
2022-01-31 22:21:54 +01:00
Weblate bfa3838069 Merge branch 'origin/develop' into Weblate. 2022-01-31 22:07:27 +01:00
SabreCat de477ebb4a Revert "Revert "Revert "Prerequisites to removing Facebook authentication (#13683)"""
This reverts commit e3ffd7acbc.
2022-01-31 14:52:22 -06:00
dependabot[bot] a2f50815d8 build(deps): bump @storybook/addons in /website/client (#13809)
Bumps [@storybook/addons](https://github.com/storybookjs/storybook/tree/HEAD/lib/addons) from 6.4.14 to 6.4.17.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.17/lib/addons)

---
updated-dependencies:
- dependency-name: "@storybook/addons"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-31 14:03:03 -05:00
dependabot[bot] f647f8080d build(deps): bump @storybook/addon-links in /website/client (#13802)
Bumps [@storybook/addon-links](https://github.com/storybookjs/storybook/tree/HEAD/addons/links) from 6.4.14 to 6.4.17.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.17/addons/links)

---
updated-dependencies:
- dependency-name: "@storybook/addon-links"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-31 12:30:37 -05:00
dependabot[bot] 14eaeb256e build(deps): bump winston from 3.4.0 to 3.5.0 (#13811)
Bumps [winston](https://github.com/winstonjs/winston) from 3.4.0 to 3.5.0.
- [Release notes](https://github.com/winstonjs/winston/releases)
- [Changelog](https://github.com/winstonjs/winston/blob/master/CHANGELOG.md)
- [Commits](https://github.com/winstonjs/winston/compare/v3.4.0...v3.5.0)

---
updated-dependencies:
- dependency-name: winston
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-31 12:28:15 -05:00
dependabot[bot] ec83a7e213 build(deps): bump amplitude-js from 8.16.0 to 8.16.1 in /website/client (#13810)
Bumps [amplitude-js](https://github.com/amplitude/amplitude-javascript) from 8.16.0 to 8.16.1.
- [Release notes](https://github.com/amplitude/amplitude-javascript/releases)
- [Changelog](https://github.com/amplitude/Amplitude-JavaScript/blob/main/CHANGELOG.md)
- [Commits](https://github.com/amplitude/amplitude-javascript/compare/v8.16.0...v8.16.1)

---
updated-dependencies:
- dependency-name: amplitude-js
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-31 12:27:44 -05:00
dependabot[bot] cd57289bc8 build(deps): bump stripe from 8.199.0 to 8.201.0 (#13807)
Bumps [stripe](https://github.com/stripe/stripe-node) from 8.199.0 to 8.201.0.
- [Release notes](https://github.com/stripe/stripe-node/releases)
- [Changelog](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stripe/stripe-node/compare/v8.199.0...v8.201.0)

---
updated-dependencies:
- dependency-name: stripe
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-31 12:27:07 -05:00
dependabot[bot] 94c7b0d62c build(deps): bump chai from 4.3.4 to 4.3.6 in /website/client (#13806)
Bumps [chai](https://github.com/chaijs/chai) from 4.3.4 to 4.3.6.
- [Release notes](https://github.com/chaijs/chai/releases)
- [Changelog](https://github.com/chaijs/chai/blob/4.x.x/History.md)
- [Commits](https://github.com/chaijs/chai/compare/v4.3.4...v4.3.6)

---
updated-dependencies:
- dependency-name: chai
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-31 12:26:45 -05:00
dependabot[bot] 57580caf60 build(deps-dev): bump chai from 4.3.4 to 4.3.6 (#13805)
Bumps [chai](https://github.com/chaijs/chai) from 4.3.4 to 4.3.6.
- [Release notes](https://github.com/chaijs/chai/releases)
- [Changelog](https://github.com/chaijs/chai/blob/4.x.x/History.md)
- [Commits](https://github.com/chaijs/chai/compare/v4.3.4...v4.3.6)

---
updated-dependencies:
- dependency-name: chai
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-31 12:26:31 -05:00
SabreCat ba9a65c500 chore(sprites): compile 2022-01-31 10:58:02 -06:00
SabreCat 5937635b3f feat(event): award to new users today
Also correct filename of 2022 migration
2022-01-31 10:57:49 -06:00
SabreCat 0a264c0912 Merge remote-tracking branch 'CuriousMagpie/2022-birthday-bash' into develop 2022-01-31 10:09:50 -06:00
dependabot[bot] 1bdea0dda3 build(deps): bump @storybook/addon-actions in /website/client (#13814)
Bumps [@storybook/addon-actions](https://github.com/storybookjs/storybook/tree/HEAD/addons/actions) from 6.4.14 to 6.4.17.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.17/addons/actions)

---
updated-dependencies:
- dependency-name: "@storybook/addon-actions"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-31 10:05:52 -06:00
Weblate ca9bc00396 Translated using Weblate (Portuguese (Brazil))
Currently translated at 98.5% (211 of 214 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (125 of 125 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (125 of 125 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (125 of 125 strings)

Translated using Weblate (Romanian)

Currently translated at 64.8% (81 of 125 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.0% (213 of 215 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (215 of 215 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (179 of 179 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (668 of 668 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (668 of 668 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.1% (210 of 214 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (194 of 194 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (98 of 98 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (179 of 179 strings)

Translated using Weblate (French)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (179 of 179 strings)

Translated using Weblate (German)

Currently translated at 100.0% (179 of 179 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (179 of 179 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (215 of 215 strings)

Translated using Weblate (French)

Currently translated at 100.0% (365 of 365 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.1% (210 of 214 strings)

Translated using Weblate (French)

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (French)

Currently translated at 100.0% (179 of 179 strings)

Translated using Weblate (French)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Vietnamese)

Currently translated at 81.9% (77 of 94 strings)

Translated using Weblate (Vietnamese)

Currently translated at 80.8% (101 of 125 strings)

Translated using Weblate (French)

Currently translated at 100.0% (365 of 365 strings)

Translated using Weblate (French)

Currently translated at 100.0% (2521 of 2521 strings)

Translated using Weblate (French)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (French)

Currently translated at 100.0% (372 of 372 strings)

Translated using Weblate (French)

Currently translated at 100.0% (668 of 668 strings)

Translated using Weblate (French)

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (French)

Currently translated at 100.0% (2521 of 2521 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (98 of 98 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (134 of 134 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (194 of 194 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (215 of 215 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (178 of 178 strings)

Translated using Weblate (Spanish)

Currently translated at 71.4% (40 of 56 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (372 of 372 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (2521 of 2521 strings)

Translated using Weblate (Spanish)

Currently translated at 98.4% (125 of 127 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (98 of 98 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (668 of 668 strings)

Translated using Weblate (Spanish)

Currently translated at 99.6% (2513 of 2521 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.1% (210 of 214 strings)

Translated using Weblate (French)

Currently translated at 100.0% (365 of 365 strings)

Translated using Weblate (French)

Currently translated at 100.0% (178 of 178 strings)

Translated using Weblate (Dutch)

Currently translated at 98.3% (657 of 668 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 96.1% (2424 of 2521 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 95.9% (2419 of 2521 strings)

Translated using Weblate (Ukrainian)

Currently translated at 95.3% (123 of 129 strings)

Translated using Weblate (Ukrainian)

Currently translated at 95.3% (123 of 129 strings)

Translated using Weblate (Ukrainian)

Currently translated at 95.3% (123 of 129 strings)

Translated using Weblate (Turkish)

Currently translated at 60.8% (118 of 194 strings)

Translated using Weblate (Ukrainian)

Currently translated at 95.3% (123 of 129 strings)

Translated using Weblate (Turkish)

Currently translated at 68.1% (1718 of 2521 strings)

Translated using Weblate (Turkish)

Currently translated at 99.4% (185 of 186 strings)

Translated using Weblate (Turkish)

Currently translated at 69.3% (463 of 668 strings)

Translated using Weblate (Turkish)

Currently translated at 88.0% (110 of 125 strings)

Translated using Weblate (Ukrainian)

Currently translated at 95.3% (123 of 129 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.1% (210 of 214 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.1% (210 of 214 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (668 of 668 strings)

Translated using Weblate (Ukrainian)

Currently translated at 95.3% (123 of 129 strings)

Translated using Weblate (Ukrainian)

Currently translated at 95.3% (123 of 129 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (365 of 365 strings)

Translated using Weblate (Ukrainian)

Currently translated at 95.3% (123 of 129 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Vietnamese)

Currently translated at 82.4% (551 of 668 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (668 of 668 strings)

Translated using Weblate (Vietnamese)

Currently translated at 94.4% (120 of 127 strings)

Translated using Weblate (Japanese)

Currently translated at 99.7% (666 of 668 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Japanese)

Currently translated at 99.4% (664 of 668 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (2521 of 2521 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 99.1% (662 of 668 strings)

Translated using Weblate (Japanese)

Currently translated at 99.1% (662 of 668 strings)

Translated using Weblate (German)

Currently translated at 100.0% (194 of 194 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (2521 of 2521 strings)

Translated using Weblate (German)

Currently translated at 100.0% (2521 of 2521 strings)

Translated using Weblate (German)

Currently translated at 100.0% (668 of 668 strings)

Translated using Weblate (German)

Currently translated at 99.2% (663 of 668 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (365 of 365 strings)

Translated using Weblate (Vietnamese)

Currently translated at 94.4% (120 of 127 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (2521 of 2521 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (178 of 178 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (2521 of 2521 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (15 of 15 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (668 of 668 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (194 of 194 strings)

Translated using Weblate (Japanese)

Currently translated at 99.9% (2519 of 2521 strings)

Translated using Weblate (Italian)

Currently translated at 99.4% (2506 of 2521 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (365 of 365 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (365 of 365 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Vietnamese)

Currently translated at 94.4% (120 of 127 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (194 of 194 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (194 of 194 strings)

Translated using Weblate (French)

Currently translated at 100.0% (194 of 194 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.8% (2518 of 2521 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (2521 of 2521 strings)

Translated using Weblate (Japanese)

Currently translated at 99.8% (2517 of 2521 strings)

Translated using Weblate (French)

Currently translated at 100.0% (2521 of 2521 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.1% (210 of 214 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (668 of 668 strings)

Translated using Weblate (French)

Currently translated at 100.0% (668 of 668 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (125 of 125 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.6% (2513 of 2521 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.8% (2491 of 2521 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.6% (2488 of 2521 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.5% (214 of 215 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.6% (2488 of 2521 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.0% (213 of 215 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.4% (2482 of 2521 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.1% (210 of 214 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.3% (204 of 214 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.4% (664 of 668 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.4% (664 of 668 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 98.9% (661 of 668 strings)

Translated using Weblate (Ukrainian)

Currently translated at 72.0% (155 of 215 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (365 of 365 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (668 of 668 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (365 of 365 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Russian)

Currently translated at 99.1% (662 of 668 strings)

Co-authored-by: Alice Scalamandrè <alice.scalamandre@me.com>
Co-authored-by: Benoit Hetru <me+hbtc@gahanka.net>
Co-authored-by: Bo-Hsiang Chen <rubybhchen@gmail.com>
Co-authored-by: Brici Sebastian Lucian <bricisebastian@gmail.com>
Co-authored-by: Can <uzuner@mailbox.org>
Co-authored-by: Chap <chalda82+nogravatar@gmail.com>
Co-authored-by: Delta S <deseji93@gmail.com>
Co-authored-by: Flower Petal <flower.petal1618@gmail.com>
Co-authored-by: Jerry Chen <minecjraft@qq.com>
Co-authored-by: John Forcolin <gianluca.forcolin@hotmail.it>
Co-authored-by: Jonas Nardes Braga <ionabi@gmail.com>
Co-authored-by: Maikel Roelofs <maikel_roelofs@live.nl>
Co-authored-by: Mara Dolichotis <marascherzer@gmail.com>
Co-authored-by: Moa Davou <moa.davou99@gmail.com>
Co-authored-by: Nazar Paruna <nazarparuna@gmail.com>
Co-authored-by: PenariaToji <tojipeh@gmail.com>
Co-authored-by: Sciuridae <sweetvshoney@163.com>
Co-authored-by: Võ Trần Nhã Linh <vtrnnhlinh@outlook.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: blacksheep47 <1760906326@qq.com>
Co-authored-by: mattya 226 <worldworld1114@gmail.com>
Co-authored-by: Естай <akseleu@yahoo.com>
Co-authored-by: そら <comi4work@gmail.com>
Co-authored-by: 陈 <494887366@qq.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ro/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/vi/
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/es/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/it/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/nl/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/es/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/character/sv/
Translate-URL: https://translate.habitica.com/projects/habitica/character/tr/
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/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/vi/
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/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/death/it/
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/front/de/
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/it/
Translate-URL: https://translate.habitica.com/projects/habitica/front/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/front/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/front/vi/
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/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/it/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/tr/
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/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/ru/
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/fr/
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/groups/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/inventory/it/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/es/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/nl/
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/npc/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/quests/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/es/
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/settings/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/de/
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/it/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/es/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Challenge
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Death
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Inventory
Translation: Habitica/Limited
Translation: Habitica/Npc
Translation: Habitica/Quests
Translation: Habitica/Questscontent
Translation: Habitica/Settings
Translation: Habitica/Subscriber
Translation: Habitica/Tasks
2022-01-31 15:58:11 +01:00
CuriousMagpie f2f3a1f0eb added Zodiac Zookeeper achievement 2022-01-28 17:14:50 -05:00
SabreCat 86ba6055b9 chore(submodule): pull habitica-images 2022-01-28 14:44:19 -06:00
CuriousMagpie e717880f64 added 2022 birthday bash robes & updated migration script 2022-01-28 15:05:04 -05:00
SabreCat 1a76ad5dca fix(news): use Moment timezone package 2022-01-27 15:54:03 -06:00
SabreCat 988f594298 Merge branch 'develop' into news-post-datetime 2022-01-27 15:34:18 -06:00
SabreCat e3ffd7acbc Revert "Revert "Prerequisites to removing Facebook authentication (#13683)""
This reverts commit b3c466ad5a.
2022-01-27 14:50:04 -06:00
CuriousMagpie 4d18169ebc added set name to violetFloppyHat 2022-01-27 14:38:09 -05:00
Natalie L 84fcb1d4ad Merge branch 'HabitRPG:develop' into 2022-02-backgrounds-armoire 2022-01-27 14:35:49 -05:00
CuriousMagpie a32bde3ec2 fix typo 2022-01-27 13:02:16 -05:00
CuriousMagpie bd9911fe61 updated armoire item strings 2022-01-27 12:58:53 -05:00
CuriousMagpie 75e2261e3e added Violet Loungewear Set information to hat, suit, and pillow 2022-01-27 11:39:08 -05:00
CuriousMagpie 73a2552b30 subproject commit 2022-01-26 17:07:24 -05:00
CuriousMagpie a23522d516 fix typo 2022-01-26 17:02:46 -05:00
CuriousMagpie fce53898d8 2022-02 armoire items -- missing description strings & stats 2022-01-26 16:57:45 -05:00
CuriousMagpie 8637d55d2b changed a few stray 2021s to 2022 2022-01-26 16:45:54 -05:00
CuriousMagpie 412f9b7898 fix typo in string 2022-01-26 16:40:48 -05:00
CuriousMagpie 40588f5ca4 2022-02 backgrounds 2022-01-26 16:33:57 -05:00
CuriousMagpie 7465c8e4ed subproject commit 2022-01-26 16:15:56 -05:00
Natalie L aedbc10630 Merge branch 'HabitRPG:develop' into 2022-02-subscriber-items 2022-01-26 15:36:27 -05:00
CuriousMagpie 306241fa49 subproject commit 2022-01-26 13:06:29 -05:00
dependabot[bot] e687140cfc build(deps): bump @storybook/addons in /website/client (#13789)
Bumps [@storybook/addons](https://github.com/storybookjs/storybook/tree/HEAD/lib/addons) from 6.4.13 to 6.4.14.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.14/lib/addons)

---
updated-dependencies:
- dependency-name: "@storybook/addons"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-26 11:20:34 -05:00
dependabot[bot] c4d0f82673 build(deps): bump axios from 0.24.0 to 0.25.0 in /website/client (#13790)
Bumps [axios](https://github.com/axios/axios) from 0.24.0 to 0.25.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/master/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.24.0...v0.25.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-26 11:20:11 -05:00
CuriousMagpie 0db8c4e2a3 add 2022-02 subscriber items 2022-01-25 17:32:31 -05:00
SabreCat 620801ef61 Revert "build(deps): bump helmet from 4.6.0 to 5.0.1 (#13735)"
This reverts commit dcffd8b032.
2022-01-25 15:37:09 -06:00
SabreCat d8c6237173 Revert "build(deps): bump helmet from 5.0.1 to 5.0.2 (#13787)"
This reverts commit 62a7c4bc28.
2022-01-25 15:35:51 -06:00
dependabot[bot] 755ff8d22d build(deps): bump @storybook/addon-actions in /website/client (#13785)
Bumps [@storybook/addon-actions](https://github.com/storybookjs/storybook/tree/HEAD/addons/actions) from 6.4.13 to 6.4.14.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.14/addons/actions)

---
updated-dependencies:
- dependency-name: "@storybook/addon-actions"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-25 13:12:55 -05:00
dependabot[bot] e4e3eb4376 build(deps): bump @babel/preset-env from 7.16.8 to 7.16.11 (#13784)
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.16.8 to 7.16.11.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.11/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-25 13:11:40 -05:00
dependabot[bot] e0c75e6afd build(deps): bump node-fetch from 2.6.1 to 2.6.7 (#13794)
Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.1 to 2.6.7.
- [Release notes](https://github.com/node-fetch/node-fetch/releases)
- [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.1...v2.6.7)

---
updated-dependencies:
- dependency-name: node-fetch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-25 13:09:56 -05:00
dependabot[bot] 2ec1fc20db build(deps): bump amplitude-js from 8.15.0 to 8.16.0 in /website/client (#13791)
Bumps [amplitude-js](https://github.com/amplitude/amplitude-javascript) from 8.15.0 to 8.16.0.
- [Release notes](https://github.com/amplitude/amplitude-javascript/releases)
- [Changelog](https://github.com/amplitude/Amplitude-JavaScript/blob/main/CHANGELOG.md)
- [Commits](https://github.com/amplitude/amplitude-javascript/compare/v8.15.0...v8.16.0)

---
updated-dependencies:
- dependency-name: amplitude-js
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-25 13:09:25 -05:00
dependabot[bot] 62a7c4bc28 build(deps): bump helmet from 5.0.1 to 5.0.2 (#13787)
Bumps [helmet](https://github.com/helmetjs/helmet) from 5.0.1 to 5.0.2.
- [Release notes](https://github.com/helmetjs/helmet/releases)
- [Changelog](https://github.com/helmetjs/helmet/blob/main/CHANGELOG.md)
- [Commits](https://github.com/helmetjs/helmet/compare/v5.0.1...v5.0.2)

---
updated-dependencies:
- dependency-name: helmet
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-25 12:59:44 -05:00
dependabot[bot] d2e1265b62 build(deps-dev): bump axios from 0.24.0 to 0.25.0 (#13786)
Bumps [axios](https://github.com/axios/axios) from 0.24.0 to 0.25.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/master/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.24.0...v0.25.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-25 12:59:22 -05:00
dependabot[bot] 92e8e24bfc build(deps): bump @storybook/addon-links in /website/client (#13783)
Bumps [@storybook/addon-links](https://github.com/storybookjs/storybook/tree/HEAD/addons/links) from 6.4.13 to 6.4.14.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.14/addons/links)

---
updated-dependencies:
- dependency-name: "@storybook/addon-links"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-25 12:43:40 -05:00
dependabot[bot] cc79902900 build(deps): bump @babel/core from 7.16.7 to 7.16.12 (#13782)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.16.7 to 7.16.12.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.12/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-25 12:43:16 -05:00
dependabot[bot] 7358edb98e build(deps): bump superagent from 7.0.2 to 7.1.1 (#13780)
Bumps [superagent](https://github.com/visionmedia/superagent) from 7.0.2 to 7.1.1.
- [Release notes](https://github.com/visionmedia/superagent/releases)
- [Changelog](https://github.com/visionmedia/superagent/blob/master/HISTORY.md)
- [Commits](https://github.com/visionmedia/superagent/compare/v7.0.2...v7.1.1)

---
updated-dependencies:
- dependency-name: superagent
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-25 12:39:43 -05:00
dependabot[bot] a0860e62e8 build(deps): bump nanoid from 3.1.30 to 3.2.0 in /website/client (#13778)
Bumps [nanoid](https://github.com/ai/nanoid) from 3.1.30 to 3.2.0.
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ai/nanoid/compare/3.1.30...3.2.0)

---
updated-dependencies:
- dependency-name: nanoid
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-25 12:30:47 -05:00
SabreCat b3c466ad5a Revert "Prerequisites to removing Facebook authentication (#13683)"
This reverts commit 1177ad8b8c.
2022-01-25 09:30:37 -06:00
SabreCat 9a6b05fe67 Revert "build(deps): bump redis from 3.1.2 to 4.0.2 (#13757)"
This reverts commit 8e93ddf06c.
2022-01-25 08:24:04 -06:00
Phillip Thelen 1177ad8b8c Prerequisites to removing Facebook authentication (#13683)
* Don't sign in user when trying to connect a social account that was already created

* Log social users into matching local auth accounts

If the social account has an email that already exists as a local user, instead of creating a new account log them into their account and add the social auth to the account

* If possible set local authentication email for social users

* Allow password reset emails to be sent to social login users

* lint fixes

* Fix issues and tests

* fix tests

* Fix lint error.
2022-01-21 15:15:58 -06:00
abigley d11810677c Fixed issue with mystery sets, pets, and mounts staying pinned in the rewards column after purchasing. Added logic to look up item info and remove from pinned list by path. (#13701) 2022-01-21 15:10:50 -06:00
SabreCat f01c352969 fix(chat): Enter key improvement by @maryketa 2022-01-21 14:55:34 -06:00
dependabot[bot] 9f0747c36f build(deps): bump stripe from 8.195.0 to 8.199.0 (#13776)
Bumps [stripe](https://github.com/stripe/stripe-node) from 8.195.0 to 8.199.0.
- [Release notes](https://github.com/stripe/stripe-node/releases)
- [Changelog](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stripe/stripe-node/compare/v8.195.0...v8.199.0)

---
updated-dependencies:
- dependency-name: stripe
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-20 16:11:30 -06:00
dependabot[bot] dcffd8b032 build(deps): bump helmet from 4.6.0 to 5.0.1 (#13735)
Bumps [helmet](https://github.com/helmetjs/helmet) from 4.6.0 to 5.0.1.
- [Release notes](https://github.com/helmetjs/helmet/releases)
- [Changelog](https://github.com/helmetjs/helmet/blob/main/CHANGELOG.md)
- [Commits](https://github.com/helmetjs/helmet/compare/v4.6.0...v5.0.1)

---
updated-dependencies:
- dependency-name: helmet
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-20 15:38:43 -06:00
dependabot[bot] 7ccc1221da build(deps): bump superagent from 6.1.0 to 7.0.2 (#13752)
Bumps [superagent](https://github.com/visionmedia/superagent) from 6.1.0 to 7.0.2.
- [Release notes](https://github.com/visionmedia/superagent/releases)
- [Changelog](https://github.com/visionmedia/superagent/blob/master/HISTORY.md)
- [Commits](https://github.com/visionmedia/superagent/compare/v6.1.0...v7.0.2)

---
updated-dependencies:
- dependency-name: superagent
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-20 15:31:49 -06:00
dependabot[bot] 8e93ddf06c build(deps): bump redis from 3.1.2 to 4.0.2 (#13757)
Bumps [redis](https://github.com/redis/node-redis) from 3.1.2 to 4.0.2.
- [Release notes](https://github.com/redis/node-redis/releases)
- [Changelog](https://github.com/redis/node-redis/blob/master/CHANGELOG.md)
- [Commits](https://github.com/redis/node-redis/commits)

---
updated-dependencies:
- dependency-name: redis
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-20 15:30:23 -06:00
dependabot[bot] cfc35f62a8 build(deps): bump @storybook/addon-actions in /website/client (#13768)
Bumps [@storybook/addon-actions](https://github.com/storybookjs/storybook/tree/HEAD/addons/actions) from 6.4.10 to 6.4.13.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.13/addons/actions)

---
updated-dependencies:
- dependency-name: "@storybook/addon-actions"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-20 15:27:52 -06:00
dependabot[bot] 356e737f4d build(deps): bump @babel/preset-env from 7.16.7 to 7.16.8 (#13766)
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.16.7 to 7.16.8.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.8/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-19 10:49:49 -05:00
dependabot[bot] a6010e7097 build(deps): bump @storybook/addons in /website/client (#13756)
Bumps [@storybook/addons](https://github.com/storybookjs/storybook/tree/HEAD/lib/addons) from 6.4.10 to 6.4.13.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.13/lib/addons)

---
updated-dependencies:
- dependency-name: "@storybook/addons"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-19 10:49:03 -05:00
dependabot[bot] 0fe40e6ba8 build(deps): bump core-js from 3.20.2 to 3.20.3 in /website/client (#13764)
Bumps [core-js](https://github.com/zloirock/core-js) from 3.20.2 to 3.20.3.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/compare/v3.20.2...v3.20.3)

---
updated-dependencies:
- dependency-name: core-js
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-19 10:48:31 -05:00
dependabot[bot] 1b9348099a build(deps): bump @slack/webhook from 6.0.0 to 6.1.0 (#13765)
Bumps [@slack/webhook](https://github.com/slackapi/node-slack-sdk) from 6.0.0 to 6.1.0.
- [Release notes](https://github.com/slackapi/node-slack-sdk/releases)
- [Commits](https://github.com/slackapi/node-slack-sdk/compare/@slack/webhook@6.0.0...@slack/webhook@6.1.0)

---
updated-dependencies:
- dependency-name: "@slack/webhook"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-17 16:30:31 -05:00
dependabot[bot] a2200d64b1 build(deps): bump @babel/register from 7.16.7 to 7.16.9 (#13763)
Bumps [@babel/register](https://github.com/babel/babel/tree/HEAD/packages/babel-register) from 7.16.7 to 7.16.9.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.9/packages/babel-register)

---
updated-dependencies:
- dependency-name: "@babel/register"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-17 16:30:03 -05:00
dependabot[bot] 923dd00e32 build(deps): bump image-size from 1.0.0 to 1.0.1 (#13761)
Bumps [image-size](https://github.com/image-size/image-size) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/image-size/image-size/releases)
- [Commits](https://github.com/image-size/image-size/compare/v1.0.0...v1.0.1)

---
updated-dependencies:
- dependency-name: image-size
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-17 16:29:06 -05:00
dependabot[bot] 8c76ee3e8d build(deps-dev): bump run-rs from 0.7.5 to 0.7.6 (#13760)
Bumps [run-rs](https://github.com/vkarpov15/run-rs) from 0.7.5 to 0.7.6.
- [Release notes](https://github.com/vkarpov15/run-rs/releases)
- [Changelog](https://github.com/vkarpov15/run-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vkarpov15/run-rs/compare/0.7.5...0.7.6)

---
updated-dependencies:
- dependency-name: run-rs
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-17 16:28:47 -05:00
dependabot[bot] 20d18c701d build(deps): bump @storybook/addon-links in /website/client (#13754)
Bumps [@storybook/addon-links](https://github.com/storybookjs/storybook/tree/HEAD/addons/links) from 6.4.10 to 6.4.13.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.13/addons/links)

---
updated-dependencies:
- dependency-name: "@storybook/addon-links"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-17 16:26:44 -05:00
dependabot[bot] 16621ef2a0 build(deps): bump winston from 3.3.4 to 3.4.0 (#13753)
Bumps [winston](https://github.com/winstonjs/winston) from 3.3.4 to 3.4.0.
- [Release notes](https://github.com/winstonjs/winston/releases)
- [Changelog](https://github.com/winstonjs/winston/blob/master/CHANGELOG.md)
- [Commits](https://github.com/winstonjs/winston/compare/v3.3.4...v3.4.0)

---
updated-dependencies:
- dependency-name: winston
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-17 16:26:00 -05:00
dependabot[bot] b4e782baa5 build(deps): bump follow-redirects in /website/client (#13748)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.4 to 1.14.7.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.4...v1.14.7)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-17 16:16:15 -05:00
dependabot[bot] 4e51841aa4 build(deps): bump follow-redirects from 1.14.4 to 1.14.7 (#13747)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.4 to 1.14.7.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.4...v1.14.7)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-17 16:15:48 -05:00
dependabot[bot] f0c50386f4 build(deps): bump @storybook/addons in /website/client (#13743)
Bumps [@storybook/addons](https://github.com/storybookjs/storybook/tree/HEAD/lib/addons) from 6.4.9 to 6.4.10.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.10/lib/addons)

---
updated-dependencies:
- dependency-name: "@storybook/addons"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-11 12:40:37 -05:00
dependabot[bot] d881c03ba9 build(deps): bump @storybook/addon-links in /website/client (#13739)
Bumps [@storybook/addon-links](https://github.com/storybookjs/storybook/tree/HEAD/addons/links) from 6.4.9 to 6.4.10.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.10/addons/links)

---
updated-dependencies:
- dependency-name: "@storybook/addon-links"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-10 16:16:36 -05:00
dependabot[bot] a4ffefdc54 build(deps): bump @storybook/vue in /website/client (#13745)
Bumps [@storybook/vue](https://github.com/storybookjs/storybook/tree/HEAD/app/vue) from 6.3.12 to 6.3.13.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.3.13/app/vue)

---
updated-dependencies:
- dependency-name: "@storybook/vue"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-10 11:28:00 -05:00
dependabot[bot] 01e8809abf build(deps): bump amplitude-js from 8.14.1 to 8.15.0 in /website/client (#13742)
Bumps [amplitude-js](https://github.com/amplitude/amplitude-javascript) from 8.14.1 to 8.15.0.
- [Release notes](https://github.com/amplitude/amplitude-javascript/releases)
- [Changelog](https://github.com/amplitude/Amplitude-JavaScript/blob/main/CHANGELOG.md)
- [Commits](https://github.com/amplitude/amplitude-javascript/compare/v8.14.1...v8.15.0)

---
updated-dependencies:
- dependency-name: amplitude-js
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-10 11:27:18 -05:00
dependabot[bot] 3732058764 build(deps): bump winston from 3.3.3 to 3.3.4 (#13737)
Bumps [winston](https://github.com/winstonjs/winston) from 3.3.3 to 3.3.4.
- [Release notes](https://github.com/winstonjs/winston/releases)
- [Changelog](https://github.com/winstonjs/winston/blob/master/CHANGELOG.md)
- [Commits](https://github.com/winstonjs/winston/compare/v3.3.3...3.3.4)

---
updated-dependencies:
- dependency-name: winston
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-10 11:25:26 -05:00
dependabot[bot] 4682223235 build(deps): bump @storybook/addon-actions in /website/client (#13736)
Bumps [@storybook/addon-actions](https://github.com/storybookjs/storybook/tree/HEAD/addons/actions) from 6.4.9 to 6.4.10.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.10/addons/actions)

---
updated-dependencies:
- dependency-name: "@storybook/addon-actions"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-10 11:24:48 -05:00
dependabot[bot] 8954c6409c build(deps): bump copy-props from 2.0.4 to 2.0.5 (#13732)
Bumps [copy-props](https://github.com/gulpjs/copy-props) from 2.0.4 to 2.0.5.
- [Release notes](https://github.com/gulpjs/copy-props/releases)
- [Changelog](https://github.com/gulpjs/copy-props/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gulpjs/copy-props/compare/2.0.4...2.0.5)

---
updated-dependencies:
- dependency-name: copy-props
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-07 16:33:55 -05:00
negue 1ec227b14c remove console 2022-01-07 22:32:02 +01:00
negue 21a3a81d5b Sprites: only create the css which points to the CDN 2022-01-07 22:12:43 +01:00
Weblate 322d47360b Merge branch 'origin/develop' into Weblate. 2022-01-06 23:30:02 +01:00
SabreCat 039851a8c2 Merge branch 'release' into develop 2022-01-06 16:28:58 -06:00
SabreCat 8707ecf01a 4.218.0 2022-01-06 16:28:41 -06:00
SabreCat 586801a1cf chore(sprites): compile 2022-01-06 16:28:29 -06:00
SabreCat 82ad85e564 feat(content): Armoire and Backgrounds Jan 2022 2022-01-06 16:28:16 -06:00
Weblate 3642e6f69d Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (111 of 111 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 99.8% (660 of 661 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 99.5% (213 of 214 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (372 of 372 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 99.5% (658 of 661 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (134 of 134 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Hungarian)

Currently translated at 48.8% (61 of 125 strings)

Translated using Weblate (Vietnamese)

Currently translated at 88.9% (113 of 127 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (365 of 365 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (215 of 215 strings)

Translated using Weblate (Italian)

Currently translated at 99.2% (2495 of 2515 strings)

Translated using Weblate (French)

Currently translated at 100.0% (2515 of 2515 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (111 of 111 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (129 of 129 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% (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 100.0% (372 of 372 strings)

Translated using Weblate (Vietnamese)

Currently translated at 87.4% (111 of 127 strings)

Translated using Weblate (German)

Currently translated at 100.0% (2515 of 2515 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (2515 of 2515 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (111 of 111 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (134 of 134 strings)

Translated using Weblate (Vietnamese)

Currently translated at 86.6% (110 of 127 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (365 of 365 strings)

Translated using Weblate (Japanese)

Currently translated at 99.8% (2511 of 2515 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Ukrainian)

Currently translated at 92.7% (103 of 111 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Ukrainian)

Currently translated at 96.4% (54 of 56 strings)

Translated using Weblate (Ukrainian)

Currently translated at 92.6% (338 of 365 strings)

Translated using Weblate (Ukrainian)

Currently translated at 92.3% (337 of 365 strings)

Translated using Weblate (Ukrainian)

Currently translated at 91.2% (333 of 365 strings)

Translated using Weblate (Ukrainian)

Currently translated at 90.9% (332 of 365 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (215 of 215 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (2509 of 2509 strings)

Translated using Weblate (Russian)

Currently translated at 99.7% (2503 of 2509 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (134 of 134 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (129 of 129 strings)

Co-authored-by: Benoit Hetru <me+hbtc@gahanka.net>
Co-authored-by: Bo-Hsiang Chen <rubybhchen@gmail.com>
Co-authored-by: Chap <chalda82+nogravatar@gmail.com>
Co-authored-by: Jerry Chen <minecjraft@qq.com>
Co-authored-by: Mara Dolichotis <marascherzer@gmail.com>
Co-authored-by: Márton Csibrik <csibrikmarton@gmail.com>
Co-authored-by: Nazar Paruna <nazarparuna@gmail.com>
Co-authored-by: Sciuridae <sweetvshoney@163.com>
Co-authored-by: Võ Trần Nhã Linh <vtrnnhlinh@outlook.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: blacksheep47 <1760906326@qq.com>
Co-authored-by: mattya 226 <worldworld1114@gmail.com>
Co-authored-by: Естай <akseleu@yahoo.com>
Co-authored-by: 陈 <494887366@qq.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/hu/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/character/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/vi/
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/content/zh_Hant/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/de/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/it/
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/generic/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/zh_Hant/
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/it/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/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/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/spells/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/zh_Hans/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Inventory
Translation: Habitica/Limited
Translation: Habitica/Loginincentives
Translation: Habitica/Npc
Translation: Habitica/Overview
Translation: Habitica/Pets
Translation: Habitica/Spells
Translation: Habitica/Tasks
2022-01-06 16:27:08 +01:00
Alys 6c841fbe17 add adult terms to list of swear words - TRIGGER / CONTENT WARNING: assault, slurs, swearwords, etc 2022-01-05 15:31:14 +10:00
dependabot[bot] 4d4a955292 build(deps): bump @babel/preset-env from 7.16.5 to 7.16.7 (#13726)
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.16.5 to 7.16.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.7/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-04 11:52:02 -05:00
dependabot[bot] d537c53ab9 build(deps): bump core-js from 3.20.1 to 3.20.2 in /website/client (#13729)
Bumps [core-js](https://github.com/zloirock/core-js) from 3.20.1 to 3.20.2.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/compare/v3.20.1...v3.20.2)

---
updated-dependencies:
- dependency-name: core-js
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-03 14:21:40 -05:00
dependabot[bot] 890224a460 build(deps): bump @babel/register from 7.16.5 to 7.16.7 (#13724)
Bumps [@babel/register](https://github.com/babel/babel/tree/HEAD/packages/babel-register) from 7.16.5 to 7.16.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.7/packages/babel-register)

---
updated-dependencies:
- dependency-name: "@babel/register"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-03 14:18:50 -05:00
dependabot[bot] d2dc36a431 build(deps): bump @babel/core from 7.16.5 to 7.16.7 (#13723)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.16.5 to 7.16.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.7/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-03 14:18:33 -05:00
dependabot[bot] 97fd87c08c build(deps-dev): bump @babel/plugin-proposal-optional-chaining (#13722)
Bumps [@babel/plugin-proposal-optional-chaining](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-proposal-optional-chaining) from 7.16.5 to 7.16.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.7/packages/babel-plugin-proposal-optional-chaining)

---
updated-dependencies:
- dependency-name: "@babel/plugin-proposal-optional-chaining"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-03 14:18:14 -05:00
CuriousMagpie 7afdd22e1d migration-runner.js reset 2022-01-03 11:49:25 -05:00
SabreCat ad268334f3 fix(deployment): add Heroku .slugignore 2021-12-31 13:23:56 -06:00
SabreCat a2134084d5 fix(deployment): add Heroku .slugignore 2021-12-31 13:23:39 -06:00
SabreCat 8824f6ac16 fix(sprites): add habitica-images as submodule 2021-12-31 13:03:02 -06:00
SabreCat 2fe8e5bf82 4.217.0 2021-12-30 13:35:59 -06:00
SabreCat 4c0f67befb Merge branch 'develop' into release 2021-12-30 13:35:52 -06:00
Weblate 5dc7d3c3cc Translated using Weblate (Vietnamese)
Currently translated at 70.1% (1759 of 2509 strings)

Translated using Weblate (Russian)

Currently translated at 99.4% (2496 of 2509 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (2509 of 2509 strings)

Translated using Weblate (Japanese)

Currently translated at 99.0% (212 of 214 strings)

Translated using Weblate (Persian)

Currently translated at 90.2% (121 of 134 strings)

Translated using Weblate (Persian)

Currently translated at 85.0% (114 of 134 strings)

Translated using Weblate (Japanese)

Currently translated at 99.9% (2507 of 2509 strings)

Co-authored-by: Ali Ghaffaari <ali.ghaffaari@gmail.com>
Co-authored-by: An Nguyen <nguyen.thienan.business@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: mattya 226 <worldworld1114@gmail.com>
Co-authored-by: Естай <akseleu@yahoo.com>
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/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/fa/
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Tasks
2021-12-30 20:35:01 +01:00
SabreCat 2e09f2d4fb chore(sprites): compile 2021-12-30 13:34:11 -06:00
SabreCat 5973bca327 feat(event): New Year's Eve 2021 2021-12-30 13:34:04 -06:00
SabreCat bcfea31ffb fix(quests): fix erroneous Egg Hunt and Waffle quest appearances 2021-12-29 13:36:12 -06:00
Weblate cae29e63ae Merge branch 'origin/develop' into Weblate. 2021-12-28 21:40:12 +01:00
SabreCat 9eea0687ba 4.216.0 2021-12-28 14:39:05 -06:00
SabreCat e2b506eb3c chore(sprites): compile 2021-12-28 14:38:54 -06:00
SabreCat 9bf25c49ae feat(content): Subscriber Items January 2022 2021-12-28 14:38:43 -06:00
Weblate 837d1246d5 Translated using Weblate (Japanese)
Currently translated at 99.8% (2505 of 2509 strings)

Translated using Weblate (Japanese)

Currently translated at 99.6% (2501 of 2509 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (46 of 46 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (193 of 193 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.8% (2481 of 2509 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (661 of 661 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (134 of 134 strings)

Translated using Weblate (Polish)

Currently translated at 96.8% (187 of 193 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (111 of 111 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (365 of 365 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (178 of 178 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (13 of 13 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (129 of 129 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (15 of 15 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (372 of 372 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (98 of 98 strings)

Translated using Weblate (Polish)

Currently translated at 94.8% (183 of 193 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (129 of 129 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (125 of 125 strings)

Translated using Weblate (Japanese)

Currently translated at 99.4% (2496 of 2509 strings)

Translated using Weblate (Vietnamese)

Currently translated at 85.0% (108 of 127 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 94.4% (118 of 125 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 94.4% (118 of 125 strings)

Translated using Weblate (Japanese)

Currently translated at 99.4% (2495 of 2509 strings)

Translated using Weblate (Japanese)

Currently translated at 98.1% (210 of 214 strings)

Translated using Weblate (Japanese)

Currently translated at 99.2% (2491 of 2509 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (46 of 46 strings)

Translated using Weblate (French)

Currently translated at 100.0% (215 of 215 strings)

Translated using Weblate (French)

Currently translated at 100.0% (2509 of 2509 strings)

Translated using Weblate (German)

Currently translated at 100.0% (2509 of 2509 strings)

Translated using Weblate (French)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (German)

Currently translated at 99.8% (2506 of 2509 strings)

Translated using Weblate (German)

Currently translated at 100.0% (215 of 215 strings)

Translated using Weblate (Japanese)

Currently translated at 99.1% (2487 of 2509 strings)

Translated using Weblate (Ukrainian)

Currently translated at 99.5% (213 of 214 strings)

Translated using Weblate (German)

Currently translated at 99.8% (2505 of 2509 strings)

Translated using Weblate (Russian)

Currently translated at 98.5% (211 of 214 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (661 of 661 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (134 of 134 strings)

Translated using Weblate (Ukrainian)

Currently translated at 74.0% (143 of 193 strings)

Translated using Weblate (Ukrainian)

Currently translated at 88.2% (98 of 111 strings)

Translated using Weblate (Ukrainian)

Currently translated at 82.9% (107 of 129 strings)

Translated using Weblate (Ukrainian)

Currently translated at 87.1% (318 of 365 strings)

Translated using Weblate (Ukrainian)

Currently translated at 81.1% (2036 of 2509 strings)

Translated using Weblate (Ukrainian)

Currently translated at 99.5% (213 of 214 strings)

Translated using Weblate (Ukrainian)

Currently translated at 97.7% (174 of 178 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (372 of 372 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (98 of 98 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (657 of 657 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Japanese)

Currently translated at 98.9% (2483 of 2509 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Japanese)

Currently translated at 97.1% (208 of 214 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.8% (745 of 746 strings)

Translated using Weblate (Vietnamese)

Currently translated at 67.8% (38 of 56 strings)

Translated using Weblate (German)

Currently translated at 100.0% (214 of 214 strings)

Co-authored-by: Benoit Hetru <me+hbtc@gahanka.net>
Co-authored-by: César Orlando Pallares Delgado <copdeb@gmail.com>
Co-authored-by: Juan Esteban Marín <juanmarin690@gmail.com>
Co-authored-by: Klaudia Bojk <b.brekker@gmail.com>
Co-authored-by: Mara Dolichotis <marascherzer@gmail.com>
Co-authored-by: Nazar Paruna <nazarparuna@gmail.com>
Co-authored-by: Sciuridae <sweetvshoney@163.com>
Co-authored-by: Võ Trần Nhã Linh <vtrnnhlinh@outlook.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: blacksheep47 <1760906326@qq.com>
Co-authored-by: mattya 226 <worldworld1114@gmail.com>
Co-authored-by: Естай <akseleu@yahoo.com>
Co-authored-by: そら <comi4work@gmail.com>
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/ru/
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/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/character/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/character/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/content/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/content/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/death/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/front/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/front/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/de/
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/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/de/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/rebirth/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/spells/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/pl/
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/pl/
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/Contrib
Translation: Habitica/Death
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Limited
Translation: Habitica/Npc
Translation: Habitica/Pets
Translation: Habitica/Questscontent
Translation: Habitica/Rebirth
Translation: Habitica/Settings
Translation: Habitica/Spells
Translation: Habitica/Subscriber
Translation: Habitica/Tasks
2021-12-28 18:54:30 +01:00
dependabot[bot] 1015b6ea51 build(deps-dev): bump @babel/plugin-proposal-optional-chaining (#13704)
Bumps [@babel/plugin-proposal-optional-chaining](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-proposal-optional-chaining) from 7.16.0 to 7.16.5.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.5/packages/babel-plugin-proposal-optional-chaining)

---
updated-dependencies:
- dependency-name: "@babel/plugin-proposal-optional-chaining"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-28 12:46:17 -05:00
Natalie L 15c9694227 Merge pull request #13717 from HabitRPG/dependabot/npm_and_yarn/website/client/core-js-3.20.1
build(deps): bump core-js from 3.19.3 to 3.20.1 in /website/client
2021-12-28 12:45:27 -05:00
dependabot[bot] ce2e7cb0ab build(deps): bump cookie-session from 1.4.0 to 2.0.0 (#13710)
Bumps [cookie-session](https://github.com/expressjs/cookie-session) from 1.4.0 to 2.0.0.
- [Release notes](https://github.com/expressjs/cookie-session/releases)
- [Changelog](https://github.com/expressjs/cookie-session/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/cookie-session/compare/1.4.0...v2.0.0)

---
updated-dependencies:
- dependency-name: cookie-session
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-28 11:09:08 -06:00
dependabot[bot] d69327bbf5 build(deps): bump core-js from 3.19.3 to 3.20.1 in /website/client
Bumps [core-js](https://github.com/zloirock/core-js) from 3.19.3 to 3.20.1.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/compare/v3.19.3...v3.20.1)

---
updated-dependencies:
- dependency-name: core-js
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-28 16:54:43 +00:00
Natalie L f38135dffe Merge pull request #13720 from HabitRPG/dependabot/npm_and_yarn/website/client/amplitude-js-8.14.1
build(deps): bump amplitude-js from 8.13.1 to 8.14.1 in /website/client
2021-12-28 11:51:54 -05:00
Natalie L c4e2cccd51 Merge pull request #13716 from HabitRPG/dependabot/npm_and_yarn/apidoc-0.50.3
build(deps): bump apidoc from 0.50.2 to 0.50.3
2021-12-28 11:50:21 -05:00
Natalie L f294192800 Merge pull request #13711 from HabitRPG/dependabot/npm_and_yarn/babel/preset-env-7.16.5
build(deps): bump @babel/preset-env from 7.16.4 to 7.16.5
2021-12-28 11:49:14 -05:00
dependabot[bot] a7e3976556 build(deps): bump amplitude-js from 8.13.1 to 8.14.1 in /website/client
Bumps [amplitude-js](https://github.com/amplitude/amplitude-javascript) from 8.13.1 to 8.14.1.
- [Release notes](https://github.com/amplitude/amplitude-javascript/releases)
- [Changelog](https://github.com/amplitude/Amplitude-JavaScript/blob/main/CHANGELOG.md)
- [Commits](https://github.com/amplitude/amplitude-javascript/compare/v8.13.1...v8.14.1)

---
updated-dependencies:
- dependency-name: amplitude-js
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-27 05:11:24 +00:00
dependabot[bot] d6517bdd4c build(deps): bump apidoc from 0.50.2 to 0.50.3
Bumps [apidoc](https://github.com/apidoc/apidoc) from 0.50.2 to 0.50.3.
- [Release notes](https://github.com/apidoc/apidoc/releases)
- [Changelog](https://github.com/apidoc/apidoc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/apidoc/apidoc/compare/0.50.2...0.50.3)

---
updated-dependencies:
- dependency-name: apidoc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-27 05:02:32 +00:00
dependabot[bot] 887c21e4b5 build(deps): bump @babel/preset-env from 7.16.4 to 7.16.5
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.16.4 to 7.16.5.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.5/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-24 16:31:31 +00:00
Natalie L 326ef89ede Merge pull request #13703 from HabitRPG/dependabot/npm_and_yarn/express-4.17.2
build(deps): bump express from 4.17.1 to 4.17.2
2021-12-24 11:29:35 -05:00
Natalie L 0dd115998f Merge pull request #13702 from HabitRPG/dependabot/npm_and_yarn/babel/register-7.16.5
build(deps): bump @babel/register from 7.16.0 to 7.16.5
2021-12-24 11:29:06 -05:00
Natalie L 97c66779f7 Merge pull request #13715 from HabitRPG/dependabot/npm_and_yarn/stripe-8.195.0
build(deps): bump stripe from 8.193.0 to 8.195.0
2021-12-24 11:28:17 -05:00
dependabot[bot] 966a2a3dd1 build(deps): bump express from 4.17.1 to 4.17.2
Bumps [express](https://github.com/expressjs/express) from 4.17.1 to 4.17.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.17.1...4.17.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-23 21:50:19 +00:00
dependabot[bot] 52c32ab63d build(deps): bump @babel/register from 7.16.0 to 7.16.5
Bumps [@babel/register](https://github.com/babel/babel/tree/HEAD/packages/babel-register) from 7.16.0 to 7.16.5.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.5/packages/babel-register)

---
updated-dependencies:
- dependency-name: "@babel/register"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-23 21:50:17 +00:00
dependabot[bot] f4f575c9b9 build(deps): bump stripe from 8.193.0 to 8.195.0
Bumps [stripe](https://github.com/stripe/stripe-node) from 8.193.0 to 8.195.0.
- [Release notes](https://github.com/stripe/stripe-node/releases)
- [Changelog](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stripe/stripe-node/compare/v8.193.0...v8.195.0)

---
updated-dependencies:
- dependency-name: stripe
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-23 21:49:52 +00:00
Natalie L 2d44bdae5b Merge pull request #13707 from HabitRPG/dependabot/npm_and_yarn/babel/core-7.16.5
build(deps): bump @babel/core from 7.16.0 to 7.16.5
2021-12-23 16:48:10 -05:00
Natalie L bc23380535 Merge pull request #13714 from HabitRPG/dependabot/npm_and_yarn/universal-analytics-0.5.3
build(deps): bump universal-analytics from 0.5.2 to 0.5.3
2021-12-23 16:47:27 -05:00
dependabot[bot] 4581302ba2 build(deps): bump @babel/core from 7.16.0 to 7.16.5
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.16.0 to 7.16.5.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.5/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-23 21:35:45 +00:00
dependabot[bot] ef71a51598 build(deps): bump universal-analytics from 0.5.2 to 0.5.3
Bumps [universal-analytics](https://github.com/peaksandpies/universal-analytics) from 0.5.2 to 0.5.3.
- [Release notes](https://github.com/peaksandpies/universal-analytics/releases)
- [Changelog](https://github.com/peaksandpies/universal-analytics/blob/master/HISTORY.md)
- [Commits](https://github.com/peaksandpies/universal-analytics/compare/0.5.2...0.5.3)

---
updated-dependencies:
- dependency-name: universal-analytics
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-23 21:33:42 +00:00
SabreCat a301186432 Merge branch 'release' into develop 2021-12-23 15:29:26 -06:00
SabreCat 3b8a9d59b1 4.215.1 2021-12-22 15:00:01 -06:00
SabreCat f2cfc2744d fix(Slack): improve subscription notif logic 2021-12-22 14:58:15 -06:00
SabreCat 7d90317e31 fix(test): correct stub restore 2021-12-21 16:25:41 -06:00
SabreCat e2fd6a72c2 fix(test): correct stub restore 2021-12-21 16:25:29 -06:00
SabreCat 2698251bd2 Merge branch 'release' into develop 2021-12-21 16:03:39 -06:00
SabreCat 60ea8e48a8 fix(test): return empty event list for no promo 2021-12-21 16:01:27 -06:00
SabreCat e74a3f84f5 fix(string): missing token 2021-12-21 15:49:55 -06:00
Weblate 1c23f05deb Merge branch 'origin/develop' into Weblate. 2021-12-21 22:34:57 +01:00
SabreCat aee8e2e905 Merge branch 'release' into develop 2021-12-21 15:34:24 -06:00
SabreCat fbc0ccfab1 4.215.0 2021-12-21 15:33:58 -06:00
SabreCat c299e2e4d3 chore(sprites): compile 2021-12-21 15:32:20 -06:00
SabreCat 685ba1286e feat(content): Winter Wonderland 2021-22 2021-12-21 15:32:11 -06:00
Weblate 7b4a8bb292 Translated using Weblate (Vietnamese)
Currently translated at 84.2% (107 of 127 strings)

Translated using Weblate (Czech)

Currently translated at 85.6% (107 of 125 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (365 of 365 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Vietnamese)

Currently translated at 78.4% (98 of 125 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (365 of 365 strings)

Translated using Weblate (German)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (46 of 46 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (661 of 661 strings)

Translated using Weblate (Vietnamese)

Currently translated at 83.1% (620 of 746 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (134 of 134 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 98.9% (184 of 186 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 34.4% (43 of 125 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 12.0% (15 of 125 strings)

Translated using Weblate (Korean)

Currently translated at 96.4% (54 of 56 strings)

Translated using Weblate (Korean)

Currently translated at 89.5% (120 of 134 strings)

Translated using Weblate (Japanese)

Currently translated at 96.2% (206 of 214 strings)

Translated using Weblate (Korean)

Currently translated at 96.4% (54 of 56 strings)

Translated using Weblate (Japanese)

Currently translated at 95.7% (205 of 214 strings)

Co-authored-by: Aleš Dvořák <mail@alesdvorak.cz>
Co-authored-by: An Nguyen <nguyen.thienan.business@gmail.com>
Co-authored-by: Chap <chalda82+nogravatar@gmail.com>
Co-authored-by: Jiyoun Namkoong <slovesk00@gmail.com>
Co-authored-by: Jon Austdal <doffen1719@hotmail.com>
Co-authored-by: Mara Dolichotis <marascherzer@gmail.com>
Co-authored-by: Sciuridae <sweetvshoney@163.com>
Co-authored-by: Võ Trần Nhã Linh <vtrnnhlinh@outlook.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: mattya 226 <worldworld1114@gmail.com>
Co-authored-by: そら <comi4work@gmail.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/cs/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/nb_NO/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/it/
Translate-URL: https://translate.habitica.com/projects/habitica/character/nb_NO/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/de/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/it/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/overview/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/spells/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/zh_Hans/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Contrib
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Overview
Translation: Habitica/Questscontent
Translation: Habitica/Spells
Translation: Habitica/Tasks
2021-12-21 19:20:17 +01:00
SabreCat 741ddd9006 4.214.6 2021-12-17 14:01:06 -06:00
SabreCat 5986d0ea02 fix(g1g1): correct availability window 2021-12-17 14:00:59 -06:00
Weblate c92d3cc374 Merge branch 'origin/develop' into Weblate. 2021-12-15 23:48:50 +01:00
Weblate e5a35528b7 Translated using Weblate (Vietnamese)
Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Vietnamese)

Currently translated at 99.5% (213 of 214 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2481 of 2481 strings)

Translated using Weblate (Japanese)

Currently translated at 95.3% (204 of 214 strings)

Translated using Weblate (Korean)

Currently translated at 32.0% (57 of 178 strings)

Translated using Weblate (Korean)

Currently translated at 86.8% (317 of 365 strings)

Translated using Weblate (Korean)

Currently translated at 95.0% (193 of 203 strings)

Translated using Weblate (Korean)

Currently translated at 68.9% (1711 of 2481 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (203 of 203 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Vietnamese)

Currently translated at 60.7% (34 of 56 strings)

Translated using Weblate (Vietnamese)

Currently translated at 81.9% (172 of 210 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (13 of 13 strings)

Translated using Weblate (Ukrainian)

Currently translated at 82.9% (107 of 129 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (61 of 61 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (22 of 22 strings)

Translated using Weblate (Ukrainian)

Currently translated at 86.3% (315 of 365 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Ukrainian)

Currently translated at 82.0% (2035 of 2481 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (203 of 203 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (15 of 15 strings)

Translated using Weblate (Ukrainian)

Currently translated at 73.2% (93 of 127 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (372 of 372 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (46 of 46 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (657 of 657 strings)

Translated using Weblate (German)

Currently translated at 100.0% (661 of 661 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (657 of 657 strings)

Translated using Weblate (Ukrainian)

Currently translated at 98.9% (368 of 372 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (657 of 657 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (657 of 657 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (657 of 657 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (365 of 365 strings)

Translated using Weblate (Ukrainian)

Currently translated at 97.1% (638 of 657 strings)

Translated using Weblate (Vietnamese)

Currently translated at 88.0% (170 of 193 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (202 of 202 strings)

Translated using Weblate (Latvian)

Currently translated at 12.0% (15 of 125 strings)

Translated using Weblate (French)

Currently translated at 100.0% (193 of 193 strings)

Translated using Weblate (Ukrainian)

Currently translated at 90.1% (592 of 657 strings)

Translated using Weblate (French)

Currently translated at 100.0% (661 of 661 strings)

Translated using Weblate (Ukrainian)

Currently translated at 74.0% (143 of 193 strings)

Translated using Weblate (Ukrainian)

Currently translated at 82.9% (107 of 129 strings)

Translated using Weblate (Ukrainian)

Currently translated at 89.6% (589 of 657 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (661 of 661 strings)

Translated using Weblate (Ukrainian)

Currently translated at 87.2% (577 of 661 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (134 of 134 strings)

Translated using Weblate (Polish)

Currently translated at 70.2% (1744 of 2481 strings)

Translated using Weblate (Polish)

Currently translated at 70.2% (1744 of 2481 strings)

Translated using Weblate (German)

Currently translated at 100.0% (2481 of 2481 strings)

Translated using Weblate (Ukrainian)

Currently translated at 83.3% (622 of 746 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (98 of 98 strings)

Translated using Weblate (Polish)

Currently translated at 99.2% (124 of 125 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Korean)

Currently translated at 80.8% (76 of 94 strings)

Translated using Weblate (Korean)

Currently translated at 100.0% (46 of 46 strings)

Translated using Weblate (Korean)

Currently translated at 100.0% (372 of 372 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (134 of 134 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (134 of 134 strings)

Translated using Weblate (German)

Currently translated at 99.6% (2472 of 2481 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 75.0% (6 of 8 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (98 of 98 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (193 of 193 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (2481 of 2481 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (2481 of 2481 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (661 of 661 strings)

Translated using Weblate (Korean)

Currently translated at 100.0% (111 of 111 strings)

Translated using Weblate (Korean)

Currently translated at 100.0% (98 of 98 strings)

Translated using Weblate (Korean)

Currently translated at 84.1% (556 of 661 strings)

Translated using Weblate (Korean)

Currently translated at 86.5% (116 of 134 strings)

Translated using Weblate (Korean)

Currently translated at 100.0% (15 of 15 strings)

Translated using Weblate (Korean)

Currently translated at 95.9% (357 of 372 strings)

Translated using Weblate (Vietnamese)

Currently translated at 96.9% (354 of 365 strings)

Translated using Weblate (Japanese)

Currently translated at 99.9% (2479 of 2481 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (661 of 661 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Hungarian)

Currently translated at 24.8% (31 of 125 strings)

Translated using Weblate (Hungarian)

Currently translated at 24.0% (30 of 125 strings)

Translated using Weblate (Hungarian)

Currently translated at 23.2% (29 of 125 strings)

Co-authored-by: An Nguyen <nguyen.thienan.business@gmail.com>
Co-authored-by: Andris Zaguzovs <zaguzovs.andris@gmail.com>
Co-authored-by: Benoit Hetru <me+hbtc@gahanka.net>
Co-authored-by: Izabela Piskulla <ipiskulla@gmail.com>
Co-authored-by: Jiyoun Namkoong <slovesk00@gmail.com>
Co-authored-by: KanI <twinklingnerd@gmail.com>
Co-authored-by: Leonardo Nunes <starlotri@gmail.com>
Co-authored-by: Mara Dolichotis <marascherzer@gmail.com>
Co-authored-by: Márton Csibrik <csibrikmarton@gmail.com>
Co-authored-by: Nazar Paruna <nazarparuna@gmail.com>
Co-authored-by: Võ Trần Nhã Linh <vtrnnhlinh@outlook.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: konhi <hello.konhi@gmail.com>
Co-authored-by: mattya 226 <worldworld1114@gmail.com>
Co-authored-by: Естай <akseleu@yahoo.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/hu/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/lv/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/de/
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/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/ko/
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/communityguidelines/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/content/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/content/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/death/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/death/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/front/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/de/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pl/
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/generic/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/inventory/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/overview/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/quests/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/rebirth/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/spells/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/vi/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Challenge
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Contrib
Translation: Habitica/Death
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/Messages
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
2021-12-15 23:48:44 +01:00
SabreCat 831cce65e2 4.214.5 2021-12-15 16:42:34 -06:00
SabreCat 64c732e991 fix(test): stub event list not singleton 2021-12-15 16:32:58 -06:00
SabreCat 391a9bd91b feat(promo): G1G1 2021
Also refactors a number of places on web client to start using event 
list from world state instead of singular currentEvent
2021-12-15 16:20:43 -06:00
Lyqst fd4115ffcf Remove date from News title, add posting time in EST 2021-12-15 11:48:57 -03:00
negue a1cddcaf17 Feature: new "report a bug" modal (#13530)
* WIP: report a bug api/ui

* fix lint

* add USER_USERNAME

* extend sendTxn tests / checks + fix bug report email

* fix lint

* add more checks to sendTxn - fix bug-report variables

* fix lint / ci

* fix test: reset email config url

* fix test stub

* fix tests

* refactor the variables checks

* lint.

* move bug-report page as a modal

* send user_email to the email

* show true/false instead 1/0

* fix issues

* fix footer report bug email if not logged in

* fix styles/margins

* prefill user's email

* show facebook email if local email not existing

* bugReportSuccessModal.vue

* add BROWSER_UA to mail properties

* extract bugReportLogic to its own lib file for unit test

* test api validators

* fix lint
2021-12-14 19:16:50 -06:00
negue c37dac5568 FIX: refactor notifications position based on different promo banners (#13679) 2021-12-14 19:14:38 -06:00
Natalie L 9e0e805d35 Fix: Updated challenge.js to allow shortName to be editable by party leader (#13654)
* updated challenge.js to allow shortName to be editable

* fix api-v3 integration test error
2021-12-14 15:54:57 -06:00
SabreCat a174b218bd chore(heroku): remove unbuilt sprites 2021-12-14 14:28:58 -06:00
SabreCat 67fdb4dcb3 Merge branch 'release' into develop 2021-12-14 14:23:07 -06:00
SabreCat ecc04c6a69 chore(TOS): update terms 2021-12-14 14:22:25 -06:00
dependabot[bot] 21367f418e build(deps): bump @storybook/addon-actions in /website/client (#13695)
Bumps [@storybook/addon-actions](https://github.com/storybookjs/storybook/tree/HEAD/addons/actions) from 6.3.12 to 6.4.9.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.9/addons/actions)

---
updated-dependencies:
- dependency-name: "@storybook/addon-actions"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-13 16:09:11 -06:00
dependabot[bot] 16508f934b build(deps): bump universal-analytics from 0.4.23 to 0.5.2 (#13697)
Bumps [universal-analytics](https://github.com/peaksandpies/universal-analytics) from 0.4.23 to 0.5.2.
- [Release notes](https://github.com/peaksandpies/universal-analytics/releases)
- [Changelog](https://github.com/peaksandpies/universal-analytics/blob/master/HISTORY.md)
- [Commits](https://github.com/peaksandpies/universal-analytics/commits/0.5.2)

---
updated-dependencies:
- dependency-name: universal-analytics
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-13 15:55:02 -06:00
dependabot[bot] e387f2f782 build(deps): bump @storybook/addons in /website/client (#13693)
Bumps [@storybook/addons](https://github.com/storybookjs/storybook/tree/HEAD/lib/addons) from 6.3.12 to 6.4.9.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.9/lib/addons)

---
updated-dependencies:
- dependency-name: "@storybook/addons"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-13 15:54:45 -06:00
dependabot[bot] 429810f50f build(deps): bump @babel/preset-env from 7.16.0 to 7.16.4 (#13640)
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.16.0 to 7.16.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.4/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-13 15:52:43 -06:00
dependabot[bot] fcd5c38460 build(deps): bump @google-cloud/trace-agent from 5.1.5 to 5.1.6 (#13638)
Bumps [@google-cloud/trace-agent](https://github.com/googleapis/cloud-trace-nodejs) from 5.1.5 to 5.1.6.
- [Release notes](https://github.com/googleapis/cloud-trace-nodejs/releases)
- [Changelog](https://github.com/googleapis/cloud-trace-nodejs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/googleapis/cloud-trace-nodejs/compare/v5.1.5...v5.1.6)

---
updated-dependencies:
- dependency-name: "@google-cloud/trace-agent"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-13 15:52:31 -06:00
Natalie L 042ae6e228 Merge pull request #13694 from HabitRPG/dependabot/npm_and_yarn/website/client/core-js-3.19.3
build(deps): bump core-js from 3.19.2 to 3.19.3 in /website/client
2021-12-13 16:33:15 -05:00
Natalie L a21e914f86 Merge pull request #13692 from HabitRPG/dependabot/npm_and_yarn/website/client/storybook/addon-links-6.4.9
build(deps): bump @storybook/addon-links from 6.3.12 to 6.4.9 in /website/client
2021-12-13 16:32:28 -05:00
Natalie L d46e7f8aff Merge pull request #13691 from HabitRPG/dependabot/npm_and_yarn/stripe-8.193.0
build(deps): bump stripe from 8.191.0 to 8.193.0
2021-12-13 16:29:52 -05:00
Natalie L 6e9cf80079 Merge pull request #13686 from HabitRPG/dependabot/npm_and_yarn/express-basic-auth-1.2.1
build(deps): bump express-basic-auth from 1.2.0 to 1.2.1
2021-12-13 16:14:39 -05:00
Natalie L 60843e6afa Merge pull request #13684 from HabitRPG/dependabot/npm_and_yarn/body-parser-1.19.1
build(deps): bump body-parser from 1.19.0 to 1.19.1
2021-12-13 16:14:10 -05:00
dependabot[bot] 9c281b8010 build(deps): bump core-js from 3.19.2 to 3.19.3 in /website/client
Bumps [core-js](https://github.com/zloirock/core-js) from 3.19.2 to 3.19.3.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/compare/v3.19.2...v3.19.3)

---
updated-dependencies:
- dependency-name: core-js
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-13 05:11:38 +00:00
dependabot[bot] 775730ff02 build(deps): bump @storybook/addon-links in /website/client
Bumps [@storybook/addon-links](https://github.com/storybookjs/storybook/tree/HEAD/addons/links) from 6.3.12 to 6.4.9.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.9/addons/links)

---
updated-dependencies:
- dependency-name: "@storybook/addon-links"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-13 05:07:21 +00:00
dependabot[bot] 409f3bfa27 build(deps): bump stripe from 8.191.0 to 8.193.0
Bumps [stripe](https://github.com/stripe/stripe-node) from 8.191.0 to 8.193.0.
- [Release notes](https://github.com/stripe/stripe-node/releases)
- [Changelog](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stripe/stripe-node/compare/v8.191.0...v8.193.0)

---
updated-dependencies:
- dependency-name: stripe
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-13 05:06:24 +00:00
dependabot[bot] c425f85378 build(deps): bump express-basic-auth from 1.2.0 to 1.2.1
Bumps [express-basic-auth](https://github.com/LionC/express-basic-auth) from 1.2.0 to 1.2.1.
- [Release notes](https://github.com/LionC/express-basic-auth/releases)
- [Commits](https://github.com/LionC/express-basic-auth/compare/v1.2.0...v1.2.1)

---
updated-dependencies:
- dependency-name: express-basic-auth
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-13 05:03:12 +00:00
dependabot[bot] 59fa547e20 build(deps): bump body-parser from 1.19.0 to 1.19.1
Bumps [body-parser](https://github.com/expressjs/body-parser) from 1.19.0 to 1.19.1.
- [Release notes](https://github.com/expressjs/body-parser/releases)
- [Changelog](https://github.com/expressjs/body-parser/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/body-parser/compare/1.19.0...1.19.1)

---
updated-dependencies:
- dependency-name: body-parser
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-13 05:02:38 +00:00
SabreCat 389768d9e3 4.214.4 2021-12-10 14:11:38 -06:00
SabreCat 938cda1fcf fix(privacy): fussy wording 2021-12-10 14:11:27 -06:00
SabreCat 495b34124d 4.214.3 2021-12-10 09:58:48 -06:00
Craig Inches af9a12bb20 Alter naming to match expected elsewhere (#13682) 2021-12-10 09:58:36 -06:00
Craig Inches 9e1e4248a5 Alter naming to match expected elsewhere (#13682) 2021-12-10 09:43:34 -06:00
SabreCat 8b4074015f 4.214.2 2021-12-09 16:45:03 -06:00
SabreCat 94d666e8b9 Merge branch 'develop' into release 2021-12-09 16:44:55 -06:00
SabreCat 1e8222af15 Revert "Revert "chore(legal): updates to Privacy Policy""
This reverts commit d995a7484b.
2021-12-09 16:43:31 -06:00
SabreCat de89032491 fix(privacy): line edits 2021-12-09 16:25:01 -06:00
SabreCat 7a67d87ce1 4.214.1 2021-12-08 10:02:51 -06:00
SabreCat 90a1fabcdf Merge branch 'develop' into release 2021-12-08 10:02:44 -06:00
Weblate caac438858 Translated using Weblate (German)
Currently translated at 100.0% (193 of 193 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (661 of 661 strings)

Translated using Weblate (Japanese)

Currently translated at 99.6% (659 of 661 strings)

Translated using Weblate (German)

Currently translated at 100.0% (661 of 661 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (2481 of 2481 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (661 of 661 strings)

Translated using Weblate (Vietnamese)

Currently translated at 96.2% (179 of 186 strings)

Translated using Weblate (French)

Currently translated at 100.0% (193 of 193 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.6% (2473 of 2481 strings)

Translated using Weblate (French)

Currently translated at 100.0% (2481 of 2481 strings)

Translated using Weblate (French)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (French)

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (French)

Currently translated at 100.0% (372 of 372 strings)

Translated using Weblate (French)

Currently translated at 100.0% (661 of 661 strings)

Co-authored-by: Benoit Hetru <me+hbtc@gahanka.net>
Co-authored-by: Chap <chalda82+nogravatar@gmail.com>
Co-authored-by: Dmitriy Pleshevskiy <dmitriy@ideascup.me>
Co-authored-by: Mara Dolichotis <marascherzer@gmail.com>
Co-authored-by: Sciuridae <sweetvshoney@163.com>
Co-authored-by: Võ Trần Nhã Linh <vtrnnhlinh@outlook.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: mattya 226 <worldworld1114@gmail.com>
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/de/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/it/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/content/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/it/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/de/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/fr/
Translation: Habitica/Backgrounds
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Gear
Translation: Habitica/Questscontent
Translation: Habitica/Settings
Translation: Habitica/Subscriber
2021-12-08 16:59:54 +01:00
Vanathi G a193bd4b7a Fix show more button behaviour in Stable (#13655) 2021-12-07 15:42:09 -06:00
SabreCat d995a7484b Revert "chore(legal): updates to Privacy Policy"
This reverts commit e22eef993b.
2021-12-07 15:37:27 -06:00
Weblate 445f0cc117 Merge branch 'origin/develop' into Weblate. 2021-12-07 18:00:02 +01:00
Weblate 5f3336f3d5 Translated using Weblate (Japanese)
Currently translated at 100.0% (2477 of 2477 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (129 of 129 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (13 of 13 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (134 of 134 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (193 of 193 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (193 of 193 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (210 of 210 strings)

Translated using Weblate (Japanese)

Currently translated at 99.9% (2475 of 2477 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (2477 of 2477 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (203 of 203 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (178 of 178 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (372 of 372 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (98 of 98 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (654 of 654 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (125 of 125 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (2477 of 2477 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (178 of 178 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Hindi)

Currently translated at 98.9% (184 of 186 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (46 of 46 strings)

Translated using Weblate (Japanese)

Currently translated at 99.7% (2471 of 2477 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 98.7% (737 of 746 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (46 of 46 strings)

Translated using Weblate (German)

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (61 of 61 strings)

Translated using Weblate (Ukrainian)

Currently translated at 88.2% (98 of 111 strings)

Translated using Weblate (Japanese)

Currently translated at 99.5% (2465 of 2477 strings)

Translated using Weblate (Dutch)

Currently translated at 98.7% (646 of 654 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Dutch)

Currently translated at 98.3% (643 of 654 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (46 of 46 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Turkish)

Currently translated at 88.0% (110 of 125 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Russian)

Currently translated at 94.6% (53 of 56 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (372 of 372 strings)

Translated using Weblate (Vietnamese)

Currently translated at 98.3% (60 of 61 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (372 of 372 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Czech)

Currently translated at 96.4% (54 of 56 strings)

Translated using Weblate (Czech)

Currently translated at 93.7% (121 of 129 strings)

Translated using Weblate (Japanese)

Currently translated at 99.4% (2463 of 2477 strings)

Translated using Weblate (German)

Currently translated at 99.1% (2456 of 2477 strings)

Translated using Weblate (German)

Currently translated at 100.0% (746 of 746 strings)

Translated using Weblate (German)

Currently translated at 100.0% (372 of 372 strings)

Translated using Weblate (Japanese)

Currently translated at 99.3% (2461 of 2477 strings)

Translated using Weblate (Japanese)

Currently translated at 99.5% (743 of 746 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (372 of 372 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (654 of 654 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2473 of 2473 strings)

Translated using Weblate (Dutch)

Currently translated at 97.0% (635 of 654 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.8% (745 of 746 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (372 of 372 strings)

Translated using Weblate (Vietnamese)

Currently translated at 76.3% (97 of 127 strings)

Translated using Weblate (Hebrew)

Currently translated at 90.2% (121 of 134 strings)

Translated using Weblate (Hebrew)

Currently translated at 61.9% (119 of 192 strings)

Translated using Weblate (Hebrew)

Currently translated at 65.9% (62 of 94 strings)

Translated using Weblate (Hebrew)

Currently translated at 85.2% (52 of 61 strings)

Translated using Weblate (Hebrew)

Currently translated at 50.9% (107 of 210 strings)

Translated using Weblate (Hebrew)

Currently translated at 100.0% (22 of 22 strings)

Translated using Weblate (Hebrew)

Currently translated at 68.7% (1700 of 2473 strings)

Translated using Weblate (Hebrew)

Currently translated at 50.0% (28 of 56 strings)

Translated using Weblate (Hebrew)

Currently translated at 93.3% (14 of 15 strings)

Translated using Weblate (Hebrew)

Currently translated at 76.4% (570 of 746 strings)

Translated using Weblate (Hebrew)

Currently translated at 95.6% (178 of 186 strings)

Translated using Weblate (Hebrew)

Currently translated at 59.2% (74 of 125 strings)

Translated using Weblate (Hebrew)

Currently translated at 89.2% (166 of 186 strings)

Co-authored-by: Arnav Singhal <arnavsinghalyt@gmail.com>
Co-authored-by: Chap <chalda82+nogravatar@gmail.com>
Co-authored-by: Dmitriy Pleshevskiy <dmitriy@ideascup.me>
Co-authored-by: Ele Kho <elena.chochlova@seznam.cz>
Co-authored-by: Jerry Chen <minecjraft@qq.com>
Co-authored-by: John Collins <munmedia9865@gmail.com>
Co-authored-by: KanI <twinklingnerd@gmail.com>
Co-authored-by: Maikel Roelofs <maikel_roelofs@live.nl>
Co-authored-by: Mara Dolichotis <marascherzer@gmail.com>
Co-authored-by: Michael Purkert <Tevollogins123@gmail.com>
Co-authored-by: Nazar Paruna <nazarparuna@gmail.com>
Co-authored-by: Omer I.S <omeritzicschwartz@gmail.com>
Co-authored-by: Otto Spaude <ottospaude2@gmail.com>
Co-authored-by: Raithe <RaitheOfDureya@gmail.com>
Co-authored-by: Sciuridae <sweetvshoney@163.com>
Co-authored-by: Võ Trần Nhã Linh <vtrnnhlinh@outlook.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: mattya 226 <worldworld1114@gmail.com>
Co-authored-by: Естай <akseleu@yahoo.com>
Co-authored-by: そら <comi4work@gmail.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/he/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/it/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/it/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/nl/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/it/
Translate-URL: https://translate.habitica.com/projects/habitica/character/he/
Translate-URL: https://translate.habitica.com/projects/habitica/character/hi/
Translate-URL: https://translate.habitica.com/projects/habitica/character/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/de/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/it/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/content/de/
Translate-URL: https://translate.habitica.com/projects/habitica/content/it/
Translate-URL: https://translate.habitica.com/projects/habitica/content/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/content/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/content/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/content/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/death/he/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/he/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/it/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/front/it/
Translate-URL: https://translate.habitica.com/projects/habitica/front/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/de/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/he/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/it/
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/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/it/
Translate-URL: https://translate.habitica.com/projects/habitica/inventory/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/he/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/he/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/he/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/cs/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/overview/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/quests/he/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/de/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/he/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/it/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/rebirth/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/he/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/it/
Translate-URL: https://translate.habitica.com/projects/habitica/spells/cs/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/he/
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/tasks/he/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/it/
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/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Inventory
Translation: Habitica/Limited
Translation: Habitica/Loginincentives
Translation: Habitica/Messages
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
2021-12-07 17:59:42 +01:00
SabreCat 1a58e3f8a1 Merge branch 'release' into develop 2021-12-07 10:58:06 -06:00
Natalie L 4c657f43de Update: Dec 2021 Background and Armoire Items (#13667) 2021-12-07 10:45:36 -06:00
Natalie L f752f7a80d Merge pull request #13673 from HabitRPG/dependabot/npm_and_yarn/website/client/smartbanner.js-1.17.0
build(deps): bump smartbanner.js from 1.16.0 to 1.17.0 in /website/client
2021-12-06 12:10:15 -05:00
Natalie L 07c906c557 Merge pull request #13672 from HabitRPG/dependabot/npm_and_yarn/website/client/amplitude-js-8.13.1
build(deps): bump amplitude-js from 8.12.0 to 8.13.1 in /website/client
2021-12-06 12:09:12 -05:00
Natalie L b2f7d994f0 Merge pull request #13669 from HabitRPG/dependabot/npm_and_yarn/website/client/core-js-3.19.2
build(deps): bump core-js from 3.19.1 to 3.19.2 in /website/client
2021-12-06 12:04:07 -05:00
Natalie L a814fe8581 Merge pull request #13668 from HabitRPG/dependabot/npm_and_yarn/rate-limiter-flexible-2.3.6
build(deps): bump rate-limiter-flexible from 2.3.5 to 2.3.6
2021-12-06 12:03:41 -05:00
dependabot[bot] 2e41576fa2 build(deps): bump smartbanner.js in /website/client
Bumps [smartbanner.js](https://github.com/ain/smartbanner.js) from 1.16.0 to 1.17.0.
- [Release notes](https://github.com/ain/smartbanner.js/releases)
- [Commits](https://github.com/ain/smartbanner.js/compare/v1.16.0...v1.17.0)

---
updated-dependencies:
- dependency-name: smartbanner.js
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-06 05:10:00 +00:00
dependabot[bot] f7db8fc721 build(deps): bump amplitude-js from 8.12.0 to 8.13.1 in /website/client
Bumps [amplitude-js](https://github.com/amplitude/amplitude-javascript) from 8.12.0 to 8.13.1.
- [Release notes](https://github.com/amplitude/amplitude-javascript/releases)
- [Changelog](https://github.com/amplitude/Amplitude-JavaScript/blob/main/CHANGELOG.md)
- [Commits](https://github.com/amplitude/amplitude-javascript/compare/v8.12.0...v8.13.1)

---
updated-dependencies:
- dependency-name: amplitude-js
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-06 05:07:56 +00:00
dependabot[bot] 75b6d6e11a build(deps): bump core-js from 3.19.1 to 3.19.2 in /website/client
Bumps [core-js](https://github.com/zloirock/core-js) from 3.19.1 to 3.19.2.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/compare/v3.19.1...v3.19.2)

---
updated-dependencies:
- dependency-name: core-js
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-06 05:03:41 +00:00
dependabot[bot] a294b404ac build(deps): bump rate-limiter-flexible from 2.3.5 to 2.3.6
Bumps [rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) from 2.3.5 to 2.3.6.
- [Release notes](https://github.com/animir/node-rate-limiter-flexible/releases)
- [Commits](https://github.com/animir/node-rate-limiter-flexible/commits)

---
updated-dependencies:
- dependency-name: rate-limiter-flexible
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-06 05:03:02 +00:00
9984 changed files with 65425 additions and 72851 deletions
+3
View File
@@ -0,0 +1,3 @@
[submodule "habitica-images"]
path = habitica-images
url = https://github.com/HabitRPG/habitica-images
+3
View File
@@ -0,0 +1,3 @@
# Files not included in deployments to Heroku, to save on file size.
/habitica-images
+14 -111
View File
@@ -1,16 +1,8 @@
import gulp from 'gulp';
import imagemin from 'gulp-imagemin';
import spritesmith from 'gulp.spritesmith';
import clean from 'rimraf';
import sizeOf from 'image-size';
import mergeStream from 'merge-stream';
import { basename } from 'path';
import { sync } from 'glob';
import { each } from 'lodash';
import vinylBuffer from 'vinyl-buffer';
// https://github.com/Ensighten/grunt-spritesmith/issues/67#issuecomment-34786248
const MAX_SPRITESHEET_SIZE = 1024 * 1024 * 3;
const IMG_DIST_PATH = 'website/client/src/assets/images/sprites/';
const CSS_DIST_PATH = 'website/client/src/assets/css/sprites/';
@@ -20,49 +12,6 @@ function checkForSpecialTreatment (name) {
return name.match(regex) || name === 'head_0';
}
function calculateImgDimensions (img, addPadding) {
let dims = sizeOf(img);
const requiresSpecialTreatment = checkForSpecialTreatment(img);
if (requiresSpecialTreatment) {
const newWidth = dims.width < 90 ? 90 : dims.width;
const newHeight = dims.height < 90 ? 90 : dims.height;
dims = {
width: newWidth,
height: newHeight,
};
}
let padding = 0;
if (addPadding) {
padding = dims.width * 8 + dims.height * 8;
}
if (!dims.width || !dims.height) console.error('MISSING DIMENSIONS:', dims); // eslint-disable-line no-console
const totalPixelSize = dims.width * dims.height + padding;
return totalPixelSize;
}
function calculateSpritesheetsSrcIndicies (src) {
let totalPixels = 0;
const slices = [0];
each(src, (img, index) => {
const imageSize = calculateImgDimensions(img, true);
totalPixels += imageSize;
if (totalPixels > MAX_SPRITESHEET_SIZE) {
slices.push(index - 1);
totalPixels = imageSize;
}
});
return slices;
}
function cssVarMap (sprite) {
// For hair, skins, beards, etc. we want to output a '.customize-options.WHATEVER' class,
// which works as a 60x60 image pointing at the proper part of the 90x90 sprite.
@@ -86,79 +35,33 @@ function cssVarMap (sprite) {
}
function createSpritesStream (name, src) {
const spritesheetSliceIndicies = calculateSpritesheetsSrcIndicies(src);
const stream = mergeStream();
each(spritesheetSliceIndicies, (start, index) => {
const slicedSrc = src.slice(start, spritesheetSliceIndicies[index + 1]);
const spriteData = gulp.src(src)
.pipe(spritesmith({
imgName: `spritesmith-${name}.png`,
cssName: `spritesmith-${name}.css`,
algorithm: 'binary-tree',
padding: 1,
cssTemplate: 'website/raw_sprites/css/css.template.handlebars',
cssVarMap,
}));
const spriteData = gulp.src(slicedSrc)
.pipe(spritesmith({
imgName: `spritesmith-${name}-${index}.png`,
cssName: `spritesmith-${name}-${index}.css`,
algorithm: 'binary-tree',
padding: 1,
cssTemplate: 'website/raw_sprites/css/css.template.handlebars',
cssVarMap,
}));
const cssStream = spriteData.css
.pipe(gulp.dest(CSS_DIST_PATH));
const imgStream = spriteData.img
.pipe(vinylBuffer())
.pipe(imagemin())
.pipe(gulp.dest(IMG_DIST_PATH));
const cssStream = spriteData.css
.pipe(gulp.dest(CSS_DIST_PATH));
stream.add(imgStream);
stream.add(cssStream);
});
stream.add(cssStream);
return stream;
}
gulp.task('sprites:main', () => {
const mainSrc = sync('website/raw_sprites/spritesmith/**/*.png');
const mainSrc = sync('habitica-images/**/*.png');
return createSpritesStream('main', mainSrc);
});
gulp.task('sprites:largeSprites', () => {
const largeSrc = sync('website/raw_sprites/spritesmith_large/**/*.png');
return createSpritesStream('largeSprites', largeSrc);
});
gulp.task('sprites:clean', done => {
clean(`${IMG_DIST_PATH}spritesmith*,${CSS_DIST_PATH}spritesmith*}`, done);
});
gulp.task('sprites:checkCompiledDimensions', gulp.series('sprites:main', 'sprites:largeSprites', done => {
console.log('Verifiying that images do not exceed max dimensions'); // eslint-disable-line no-console
let numberOfSheetsThatAreTooBig = 0;
const distSpritesheets = sync(`${IMG_DIST_PATH}*.png`);
each(distSpritesheets, img => {
const spriteSize = calculateImgDimensions(img);
if (spriteSize > MAX_SPRITESHEET_SIZE) {
numberOfSheetsThatAreTooBig += 1;
const name = basename(img, '.png');
console.error(`WARNING: ${name} might be too big - ${spriteSize} > ${MAX_SPRITESHEET_SIZE}`); // eslint-disable-line no-console
}
});
if (numberOfSheetsThatAreTooBig > 0) {
// https://github.com/HabitRPG/habitica/pull/6683#issuecomment-185462180
console.error( // eslint-disable-line no-console
`${numberOfSheetsThatAreTooBig} sheets might too big for mobile Safari to be able to handle
them, but there is a margin of error in these calculations so it is probably okay. Mention
this to an admin so they can test a staging site on mobile Safari after your PR is merged.`,
);
} else {
console.log('All images are within the correct dimensions'); // eslint-disable-line no-console
}
done();
}));
gulp.task('sprites:compile', gulp.series('sprites:clean', 'sprites:checkCompiledDimensions', done => done()));
gulp.task('sprites:compile', gulp.series('sprites:clean', 'sprites:main', done => done()));
+1
Submodule habitica-images added at 8d7fa3c3da
+135
View File
@@ -0,0 +1,135 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20211230_nye';
import { model as User } from '../../../website/server/models/user';
import { v4 as uuid } from 'uuid';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count++;
const set = { migration: MIGRATION_NAME };
let push;
if (typeof user.items.gear.owned.head_special_nye2020 !== 'undefined') {
set['items.gear.owned.head_special_nye2021'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2021',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2019 !== 'undefined') {
set['items.gear.owned.head_special_nye2020'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2020',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2018 !== 'undefined') {
set['items.gear.owned.head_special_nye2019'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2019',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2017 !== 'undefined') {
set['items.gear.owned.head_special_nye2018'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2018',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2016 !== 'undefined') {
set['items.gear.owned.head_special_nye2017'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2017',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2015 !== 'undefined') {
set['items.gear.owned.head_special_nye2016'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2016',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2014 !== 'undefined') {
set['items.gear.owned.head_special_nye2015'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2015',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye !== 'undefined') {
set['items.gear.owned.head_special_nye2014'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2014',
_id: uuid(),
},
];
} else {
set['items.gear.owned.head_special_nye'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye',
_id: uuid(),
},
];
}
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await User.update({_id: user._id}, {$set: set, $push: {pinnedItems: {$each: push}}}).exec();
}
export default async function processUsers () {
let query = {
'auth.timestamps.loggedin': {$gt: new Date('2021-12-01')},
migration: {$ne: MIGRATION_NAME},
};
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
}
};
@@ -0,0 +1,97 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20220131_habit_birthday';
import { v4 as uuid } from 'uuid';
import { model as User } from '../../../website/server/models/user';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count++;
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 = {};
let push;
set.migration = MIGRATION_NAME;
if (typeof user.items.gear.owned.armor_special_birthday2021 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2022'] = false;
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2022', _id: uuid()}};
} else if (typeof user.items.gear.owned.armor_special_birthday2020 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2021'] = false;
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2021', _id: uuid()}};
} else if (typeof user.items.gear.owned.armor_special_birthday2019 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2020'] = false;
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2020', _id: uuid()}};
} else if (typeof user.items.gear.owned.armor_special_birthday2018 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2019'] = false;
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2019', _id: uuid()}};
} else if (typeof user.items.gear.owned.armor_special_birthday2017 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2018'] = false;
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2018', _id: uuid()}};
} else if (typeof user.items.gear.owned.armor_special_birthday2016 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2017'] = false;
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2017', _id: uuid()}};
} else if (typeof user.items.gear.owned.armor_special_birthday2015 !== 'undefined') {
set['items.gear.owned.armor_special_birthday2016'] = false;
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2016', _id: uuid()}};
} else if (typeof user.items.gear.owned.armor_special_birthday !== 'undefined') {
set['items.gear.owned.armor_special_birthday2015'] = false;
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2015', _id: uuid()}};
} else {
set['items.gear.owned.armor_special_birthday'] = false;
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday', _id: uuid()}};
}
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await User.update({_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('2022-01-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],
};
}
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
}
};
@@ -0,0 +1,178 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20220201_pet_group_achievements';
import { model as User } from '../../../website/server/models/user';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count++;
const set = {
migration: MIGRATION_NAME,
};
if (user && user.items && user.items.pets) {
const pets = user.items.pets;
if (pets['FlyingPig-Base']
&& pets['FlyingPig-CottonCandyBlue']
&& pets['FlyingPig-CottonCandyPink']
&& pets['FlyingPig-Desert']
&& pets['FlyingPig-Golden']
&& pets['FlyingPig-Red']
&& pets['FlyingPig-Shade']
&& pets['FlyingPig-Skeleton']
&& pets['FlyingPig-White']
&& pets['FlyingPig-Zombie']
&& pets['Snake-Base']
&& pets['Snake-CottonCandyBlue']
&& pets['Snake-CottonCandyPink']
&& pets['Snake-Desert']
&& pets['Snake-Golden']
&& pets['Snake-Red']
&& pets['Snake-Shade']
&& pets['Snake-Skeleton']
&& pets['Snake-White']
&& pets['Snake-Zombie']
&& pets['Sheep-Base']
&& pets['Sheep-CottonCandyBlue']
&& pets['Sheep-CottonCandyPink']
&& pets['Sheep-Desert']
&& pets['Sheep-Golden']
&& pets['Sheep-Red']
&& pets['Sheep-Shade']
&& pets['Sheep-Skeleton']
&& pets['Sheep-White']
&& pets['Sheep-Zombie']
&& pets['Rooster-Base']
&& pets['Rooster-CottonCandyBlue']
&& pets['Rooster-CottonCandyPink']
&& pets['Rooster-Desert']
&& pets['Rooster-Golden']
&& pets['Rooster-Red']
&& pets['Rooster-Shade']
&& pets['Rooster-Skeleton']
&& pets['Rooster-White']
&& pets['Rooster-Zombie']
&& pets['Rat-Base']
&& pets['Rat-CottonCandyBlue']
&& pets['Rat-CottonCandyPink']
&& pets['Rat-Desert']
&& pets['Rat-Golden']
&& pets['Rat-Red']
&& pets['Rat-Shade']
&& pets['Rat-Skeleton']
&& pets['Rat-White']
&& pets['Rat-Zombie']
&& pets['Bunny-Base']
&& pets['Bunny-CottonCandyBlue']
&& pets['Bunny-CottonCandyPink']
&& pets['Bunny-Desert']
&& pets['Bunny-Golden']
&& pets['Bunny-Red']
&& pets['Bunny-Shade']
&& pets['Bunny-Skeleton']
&& pets['Bunny-White']
&& pets['Bunny-Zombie']
&& pets['Horse-Base']
&& pets['Horse-CottonCandyBlue']
&& pets['Horse-CottonCandyPink']
&& pets['Horse-Desert']
&& pets['Horse-Golden']
&& pets['Horse-Red']
&& pets['Horse-Shade']
&& pets['Horse-Skeleton']
&& pets['Horse-White']
&& pets['Horse-Zombie']
&& pets['Cow-Base']
&& pets['Cow-CottonCandyBlue']
&& pets['Cow-CottonCandyPink']
&& pets['Cow-Desert']
&& pets['Cow-Golden']
&& pets['Cow-Red']
&& pets['Cow-Shade']
&& pets['Cow-Skeleton']
&& pets['Cow-White']
&& pets['Cow-Zombie']
&& pets['Monkey-Base']
&& pets['Monkey-CottonCandyBlue']
&& pets['Monkey-CottonCandyPink']
&& pets['Monkey-Desert']
&& pets['Monkey-Golden']
&& pets['Monkey-Red']
&& pets['Monkey-Shade']
&& pets['Monkey-Skeleton']
&& pets['Monkey-White']
&& pets['Monkey-Zombie']
&& pets['Wolf-Base']
&& pets['Wolf-CottonCandyBlue']
&& pets['Wolf-CottonCandyPink']
&& pets['Wolf-Desert']
&& pets['Wolf-Golden']
&& pets['Wolf-Red']
&& pets['Wolf-Shade']
&& pets['Wolf-Skeleton']
&& pets['Wolf-White']
&& pets['Wolf-Zombie']
&& pets['Tiger-Base']
&& pets['Tiger-CottonCandyBlue']
&& pets['Tiger-CottonCandyPink']
&& pets['Tiger-Desert']
&& pets['Tiger-Golden']
&& pets['Tiger-Red']
&& pets['Tiger-Shade']
&& pets['Tiger-Skeleton']
&& pets['Tiger-White']
&& pets['Tiger-Zombie']
&& pets['Dragon-Base']
&& pets['Dragon-CottonCandyBlue']
&& pets['Dragon-CottonCandyPink']
&& pets['Dragon-Desert']
&& pets['Dragon-Golden']
&& pets['Dragon-Red']
&& pets['Dragon-Shade']
&& pets['Dragon-Skeleton']
&& pets['Dragon-White']
&& pets['Dragon-Zombie']) {
set['achievements.zodiacZookeeper'] = true;
}
}
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await User.update({ _id: user._id }, { $set: set }).exec();
}
export default async function processUsers () {
let query = {
// migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: new Date('2021-08-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
}
};
@@ -0,0 +1,138 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20220309_pet_group_achievements';
import { model as User } from '../../../website/server/models/user';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count++;
const set = {
migration: MIGRATION_NAME,
};
if (user && user.items && user.items.pets) {
const pets = user.items.pets;
if (pets['FlyingPig-Base']
&& pets['FlyingPig-CottonCandyBlue']
&& pets['FlyingPig-CottonCandyPink']
&& pets['FlyingPig-Desert']
&& pets['FlyingPig-Golden']
&& pets['FlyingPig-Red']
&& pets['FlyingPig-Shade']
&& pets['FlyingPig-Skeleton']
&& pets['FlyingPig-White']
&& pets['FlyingPig-Zombie']
&& pets['Owl-Base']
&& pets['Owl-CottonCandyBlue']
&& pets['Owl-CottonCandyPink']
&& pets['Owl-Desert']
&& pets['Owl-Golden']
&& pets['Owl-Red']
&& pets['Owl-Shade']
&& pets['Owl-Skeleton']
&& pets['Owl-White']
&& pets['Owl-Zombie']
&& pets['Parrot-Base']
&& pets['Parrot-CottonCandyBlue']
&& pets['Parrot-CottonCandyPink']
&& pets['Parrot-Desert']
&& pets['Parrot-Golden']
&& pets['Parrot-Red']
&& pets['Parrot-Shade']
&& pets['Parrot-Skeleton']
&& pets['Parrot-White']
&& pets['Parrot-Zombie']
&& pets['Rooster-Base']
&& pets['Rooster-CottonCandyBlue']
&& pets['Rooster-CottonCandyPink']
&& pets['Rooster-Desert']
&& pets['Rooster-Golden']
&& pets['Rooster-Red']
&& pets['Rooster-Shade']
&& pets['Rooster-Skeleton']
&& pets['Rooster-White']
&& pets['Rooster-Zombie']
&& pets['Pterodactyl-Base']
&& pets['Pterodactyl-CottonCandyBlue']
&& pets['Pterodactyl-CottonCandyPink']
&& pets['Pterodactyl-Desert']
&& pets['Pterodactyl-Golden']
&& pets['Pterodactyl-Red']
&& pets['Pterodactyl-Shade']
&& pets['Pterodactyl-Skeleton']
&& pets['Pterodactyl-White']
&& pets['Pterodactyl-Zombie']
&& pets['Gryphon-Base']
&& pets['Gryphon-CottonCandyBlue']
&& pets['Gryphon-CottonCandyPink']
&& pets['Gryphon-Desert']
&& pets['Gryphon-Golden']
&& pets['Gryphon-Red']
&& pets['Gryphon-Shade']
&& pets['Gryphon-Skeleton']
&& pets['Gryphon-White']
&& pets['Gryphon-Zombie']
&& pets['Falcon-Base']
&& pets['Falcon-CottonCandyBlue']
&& pets['Falcon-CottonCandyPink']
&& pets['Falcon-Desert']
&& pets['Falcon-Golden']
&& pets['Falcon-Red']
&& pets['Falcon-Shade']
&& pets['Falcon-Skeleton']
&& pets['Falcon-White']
&& pets['Falcon-Zombie']
&& pets['Peacock-Base']
&& pets['Peacock-CottonCandyBlue']
&& pets['Peacock-CottonCandyPink']
&& pets['Peacock-Desert']
&& pets['Peacock-Golden']
&& pets['Peacock-Red']
&& pets['Peacock-Shade']
&& pets['Peacock-Skeleton']
&& pets['Peacock-White']
&& pets['Peacock-Zombie']) {
set['achievements.birdsOfAFeather'] = true;
}
}
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await User.update({ _id: user._id }, { $set: set }).exec();
}
export default async function processUsers () {
let query = {
// migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: new Date('2021-08-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
}
};
+3 -3
View File
@@ -3,13 +3,13 @@ import { v4 as uuid } from 'uuid';
import { model as User } from '../../website/server/models/user';
const MIGRATION_NAME = '20210314_pi_day';
const MIGRATION_NAME = '20220314_pi_day';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count *= 1;
count += 1;
const inc = {
'items.food.Pie_Skeleton': 1,
@@ -54,7 +54,7 @@ async function updateUser (user) {
export default async function processUsers () {
const query = {
migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: new Date('2021-02-15') },
'auth.timestamps.loggedin': { $gt: new Date('2022-02-15') },
};
const fields = {
+1195 -1267
View File
File diff suppressed because it is too large Load Diff
+21 -21
View File
@@ -1,25 +1,25 @@
{
"name": "habitica",
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
"version": "4.214.0",
"version": "4.224.3",
"main": "./website/server/index.js",
"dependencies": {
"@babel/core": "^7.16.0",
"@babel/preset-env": "^7.16.0",
"@babel/register": "^7.16.0",
"@google-cloud/trace-agent": "^5.1.5",
"@babel/core": "^7.16.12",
"@babel/preset-env": "^7.16.11",
"@babel/register": "^7.17.0",
"@google-cloud/trace-agent": "^5.1.6",
"@parse/node-apn": "^5.1.0",
"@slack/webhook": "^6.0.0",
"accepts": "^1.3.5",
"@slack/webhook": "^6.1.0",
"accepts": "^1.3.8",
"amazon-payments": "^0.2.9",
"amplitude": "^5.2.0",
"apidoc": "^0.50.2",
"apidoc": "^0.50.3",
"apple-auth": "^1.0.7",
"bcrypt": "^5.0.1",
"body-parser": "^1.18.3",
"body-parser": "^1.19.1",
"bootstrap": "^4.6.0",
"compression": "^1.7.4",
"cookie-session": "^1.4.0",
"cookie-session": "^2.0.0",
"coupon-code": "^0.4.5",
"csv-stringify": "^5.6.5",
"cwait": "^1.1.1",
@@ -27,8 +27,8 @@
"eslint": "^6.8.0",
"eslint-config-habitrpg": "^6.2.0",
"eslint-plugin-mocha": "^5.0.0",
"express": "^4.16.3",
"express-basic-auth": "^1.1.5",
"express": "^4.17.2",
"express-basic-auth": "^1.2.1",
"express-validator": "^5.2.0",
"glob": "^7.2.0",
"got": "^11.8.3",
@@ -39,7 +39,7 @@
"gulp.spritesmith": "^6.12.1",
"habitica-markdown": "^3.0.0",
"helmet": "^4.6.0",
"image-size": "^1.0.0",
"image-size": "^1.0.1",
"in-app-purchase": "^1.11.3",
"js2xmlparser": "^4.0.2",
"jsonwebtoken": "^8.5.1",
@@ -61,20 +61,20 @@
"paypal-rest-sdk": "^1.8.1",
"pp-ipn": "^1.1.0",
"ps-tree": "^1.0.0",
"rate-limiter-flexible": "^2.3.5",
"rate-limiter-flexible": "^2.3.6",
"redis": "^3.1.2",
"regenerator-runtime": "^0.13.9",
"remove-markdown": "^0.3.0",
"rimraf": "^3.0.2",
"short-uuid": "^4.2.0",
"stripe": "^8.191.0",
"superagent": "^6.1.0",
"universal-analytics": "^0.4.23",
"stripe": "^8.202.0",
"superagent": "^7.1.1",
"universal-analytics": "^0.5.3",
"useragent": "^2.1.9",
"uuid": "^8.3.2",
"validator": "^13.7.0",
"vinyl-buffer": "^1.0.1",
"winston": "^3.3.3",
"winston": "^3.5.1",
"winston-loggly-bulk": "^3.2.1",
"xml2js": "^0.4.23"
},
@@ -110,8 +110,8 @@
"apidoc": "gulp apidoc"
},
"devDependencies": {
"axios": "^0.24.0",
"chai": "^4.3.4",
"axios": "^0.25.0",
"chai": "^4.3.6",
"chai-as-promised": "^7.1.1",
"chai-moment": "^0.1.0",
"chalk": "^4.1.2",
@@ -121,7 +121,7 @@
"mocha": "^5.1.1",
"monk": "^7.3.4",
"require-again": "^2.0.0",
"run-rs": "^0.7.5",
"run-rs": "^0.7.6",
"sinon": "^12.0.1",
"sinon-chai": "^3.7.0",
"sinon-stub-promise": "^4.0.0"
+57
View File
@@ -0,0 +1,57 @@
/* eslint-disable global-require */
import nconf from 'nconf';
import { generateUser } from '../../../helpers/api-unit.helper';
import * as emailLib from '../../../../website/server/libs/email';
import { bugReportLogic } from '../../../../website/server/libs/bug-report';
describe('bug-report', () => {
beforeEach(() => {
sandbox.stub(emailLib, 'sendTxn').returns(Promise.resolve());
const nconfGetStub = sandbox.stub(nconf, 'get');
nconfGetStub.withArgs('ADMIN_EMAIL').returns('true');
});
afterEach(() => {
sandbox.restore();
});
it('sends a mail using sendTxn', async () => {
const userId = '2b58daeb-bc50-4a83-b5d3-4ac52c7c0608';
const userMail = 'me@me.com';
const userMessage = 'The power is over 9000, please fix it';
const userAgent = 'The UserAgent with a bunch of weird browser engine levels';
const user = generateUser({
_id: userId,
});
const result = await bugReportLogic(
user, userMail, userMessage, userAgent,
);
expect(emailLib.sendTxn).to.be.called;
expect(result).to.deep.equal({
sendMailResult: undefined,
emailData: {
BROWSER_UA: userAgent,
REPORT_MSG: userMessage,
USER_CLASS: 'warrior',
USER_CONSECUTIVE_MONTHS: 0,
USER_COSTUME: 'false',
USER_CUSTOMER_ID: undefined,
USER_CUSTOM_DAY: 0,
USER_DAILIES_PAUSED: 'false',
USER_EMAIL: userMail,
USER_HOURGLASSES: 0,
USER_ID: userId,
USER_LEVEL: 1,
USER_OFFSET_MONTHS: 0,
USER_PAYMENT_PLATFORM: undefined,
USER_SUBSCRIPTION: undefined,
USER_TIMEZONE_OFFSET: 0,
USER_USERNAME: undefined,
},
});
});
});
File diff suppressed because it is too large Load Diff
+73 -18
View File
@@ -148,9 +148,18 @@ describe('emails', () => {
});
});
describe('sendTxnEmail', () => {
describe('sendTxn', () => {
let sendTxn = null;
beforeEach(() => {
sandbox.stub(got, 'post').returns(defer().promise);
const nconfGetStub = sandbox.stub(nconf, 'get');
nconfGetStub.withArgs('IS_PROD').returns(true);
nconfGetStub.withArgs('BASE_URL').returns('BASE_URL');
const attachEmail = requireAgain(pathToEmailLib);
sendTxn = attachEmail.sendTxn;
});
afterEach(() => {
@@ -158,16 +167,14 @@ describe('emails', () => {
});
it('can send a txn email to one recipient', () => {
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
const attachEmail = requireAgain(pathToEmailLib);
const sendTxnEmail = attachEmail.sendTxn;
const emailType = 'an email type';
const mailingInfo = {
name: 'my name',
email: 'my@email',
};
sendTxnEmail(mailingInfo, emailType);
sendTxn(mailingInfo, emailType);
expect(got.post).to.be.called;
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
json: {
data: {
@@ -179,27 +186,77 @@ describe('emails', () => {
});
it('does not send email if address is missing', () => {
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
const attachEmail = requireAgain(pathToEmailLib);
const sendTxnEmail = attachEmail.sendTxn;
const emailType = 'an email type';
const mailingInfo = {
name: 'my name',
// email: 'my@email',
};
sendTxnEmail(mailingInfo, emailType);
sendTxn(mailingInfo, emailType);
expect(got.post).not.to.be.called;
});
it('throws error when mail target is only a string', () => {
const emailType = 'an email type';
const mailingInfo = 'my email';
expect(sendTxn(mailingInfo, emailType)).to.throw;
});
it('throws error when mail target has no _id or email', () => {
const emailType = 'an email type';
const mailingInfo = {
};
expect(sendTxn(mailingInfo, emailType)).to.throw;
});
it('throws error when variables not an array', () => {
const emailType = 'an email type';
const mailingInfo = {
name: 'my name',
email: 'my@email',
};
const variables = {};
expect(sendTxn(mailingInfo, emailType, variables)).to.throw;
});
it('throws error when variables array not contain name/content', () => {
const emailType = 'an email type';
const mailingInfo = {
name: 'my name',
email: 'my@email',
};
const variables = [
{
},
];
expect(sendTxn(mailingInfo, emailType, variables)).to.throw;
});
it('throws no error when variables array contain name but no content', () => {
const emailType = 'an email type';
const mailingInfo = {
name: 'my name',
email: 'my@email',
};
const variables = [
{
name: 'MY_VAR',
},
];
expect(sendTxn(mailingInfo, emailType, variables)).to.not.throw;
});
it('uses getUserInfo in case of user data', () => {
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
const attachEmail = requireAgain(pathToEmailLib);
const sendTxnEmail = attachEmail.sendTxn;
const emailType = 'an email type';
const mailingInfo = getUser();
sendTxnEmail(mailingInfo, emailType);
sendTxn(mailingInfo, emailType);
expect(got.post).to.be.called;
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
json: {
data: {
@@ -211,17 +268,15 @@ describe('emails', () => {
});
it('sends email with some default variables', () => {
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
const attachEmail = requireAgain(pathToEmailLib);
const sendTxnEmail = attachEmail.sendTxn;
const emailType = 'an email type';
const mailingInfo = {
name: 'my name',
email: 'my@email',
};
const variables = [1, 2, 3];
const variables = [];
sendTxnEmail(mailingInfo, emailType, variables);
sendTxn(mailingInfo, emailType, variables);
expect(got.post).to.be.called;
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
json: {
data: {
+22 -1
View File
@@ -256,7 +256,7 @@ describe('Google Payments', () => {
expirationDate,
});
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
.returns([{ expirationDate: expirationDate.toDate() }]);
.returns([{ expirationDate: expirationDate.toDate(), autoRenewing: false }]);
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
.returns(true);
@@ -325,5 +325,26 @@ describe('Google Payments', () => {
headers,
});
});
it('should not cancel a user subscription with autorenew', async () => {
iap.getPurchaseData.restore();
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
.returns([{ autoRenewing: true }]);
await googlePayments.cancelSubscribe(user, headers);
expect(iapSetupStub).to.be.calledOnce;
expect(iapValidateStub).to.be.calledOnce;
expect(iapValidateStub).to.be.calledWith(iap.GOOGLE, {
data: receipt,
signature,
});
expect(iapIsValidatedStub).to.be.calledOnce;
expect(iapIsValidatedStub).to.be.calledWith({
expirationDate,
});
expect(iapGetPurchaseDataStub).to.be.calledOnce;
expect(paymentCancelSubscriptionSpy).to.not.be.called;
});
});
});
+5 -5
View File
@@ -247,11 +247,11 @@ describe('payments/index', () => {
context('No Active Promotion', () => {
beforeEach(() => {
sinon.stub(worldState, 'getCurrentEvent').returns(null);
sinon.stub(worldState, 'getCurrentEventList').returns([]);
});
afterEach(() => {
worldState.getCurrentEvent.restore();
worldState.getCurrentEventList.restore();
});
it('sends a private message about the gift', async () => {
@@ -268,14 +268,14 @@ describe('payments/index', () => {
context('Active Promotion', () => {
beforeEach(() => {
sinon.stub(worldState, 'getCurrentEvent').returns({
sinon.stub(worldState, 'getCurrentEventList').returns([{
...common.content.events.winter2021Promo,
event: 'winter2021',
});
}]);
});
afterEach(() => {
worldState.getCurrentEvent.restore();
worldState.getCurrentEventList.restore();
});
it('creates a gift subscription for purchaser and recipient if none exist', async () => {
@@ -74,7 +74,6 @@ describe('PUT /challenges/:challengeId', () => {
expect(res.memberCount).to.equal(2);
expect(res.tasksOrder).not.to.equal('new order');
expect(res.official).to.equal(false);
expect(res.shortName).not.to.equal('new short name');
expect(res.leader).to.eql({
_id: user._id,
+49
View File
@@ -0,0 +1,49 @@
import {
generateUser,
} from '../../helpers/api-integration/v4';
describe('POST /bug-report', () => {
let user;
beforeEach(async () => {
user = await generateUser();
});
it('returns an error when message is not added', async () => {
await expect(user.post('/bug-report', {
message: '',
}))
.to.eventually.be.rejected.and.to.eql({
code: 400,
error: 'BadRequest',
// seems it is not possible to get the real error message
message: 'Invalid request parameters.',
});
});
it('returns an error when email is not added', async () => {
await expect(user.post('/bug-report', {
message: 'message',
email: '',
}))
.to.eventually.be.rejected.and.to.eql({
code: 400,
error: 'BadRequest',
// seems it is not possible to get the real error message
message: 'Invalid request parameters.',
});
});
it('returns an error when email is not valid', async () => {
await expect(user.post('/bug-report', {
message: 'message',
email: 'notamail',
}))
.to.eventually.be.rejected.and.to.eql({
code: 400,
error: 'BadRequest',
// seems it is not possible to get the real error message
message: 'Invalid request parameters.',
});
});
});
@@ -0,0 +1,38 @@
import {
generateUser,
translate as t,
} from '../../../helpers/api-integration/v4';
describe('GET /members/:memberId/purchase-history', () => {
let user;
before(async () => {
user = await generateUser({
contributor: { admin: true },
});
});
it('validates req.params.memberId', async () => {
await expect(user.get('/members/invalidUUID/purchase-history')).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: t('invalidReqParams'),
});
});
it('returns error if user is not admin', async () => {
const member = await generateUser();
const nonAdmin = await generateUser();
await expect(nonAdmin.get(`/members/${member._id}/purchase-history`)).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('noAdminAccess'),
});
});
it('returns purchase history based on given user', async () => {
const member = await generateUser();
const response = await user.get(`/members/${member._id}/purchase-history`);
expect(response.length).to.equal(0);
});
});
+20 -24
View File
@@ -40,28 +40,27 @@ describe('shared.ops.buy', () => {
analytics.track.restore();
});
it('returns error when key is not provided', done => {
it('returns error when key is not provided', async () => {
try {
buy(user);
await buy(user);
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(errorMessage('missingKeyParam'));
done();
}
});
it('recovers 15 hp', () => {
it('recovers 15 hp', async () => {
user.stats.hp = 30;
buy(user, { params: { key: 'potion' } }, analytics);
await buy(user, { params: { key: 'potion' } }, analytics);
expect(user.stats.hp).to.eql(45);
expect(analytics.track).to.be.calledOnce;
});
it('adds equipment to inventory', () => {
it('adds equipment to inventory', async () => {
user.stats.gp = 31;
buy(user, { params: { key: 'armor_warrior_1' } });
await buy(user, { params: { key: 'armor_warrior_1' } });
expect(user.items.gear.owned).to.eql({
weapon_warrior_0: true,
@@ -90,10 +89,10 @@ describe('shared.ops.buy', () => {
});
});
it('buys Steampunk Accessories Set', () => {
it('buys Steampunk Accessories Set', async () => {
user.purchased.plan.consecutive.trinkets = 1;
buy(user, {
await buy(user, {
params: {
key: '301404',
},
@@ -108,10 +107,10 @@ describe('shared.ops.buy', () => {
expect(user.items.gear.owned).to.have.property('eyewear_mystery_301404', true);
});
it('buys a Quest scroll', () => {
it('buys a Quest scroll', async () => {
user.stats.gp = 205;
buy(user, {
await buy(user, {
params: {
key: 'dilatoryDistress1',
},
@@ -122,11 +121,11 @@ describe('shared.ops.buy', () => {
expect(user.stats.gp).to.equal(5);
});
it('buys a special item', () => {
it('buys a special item', async () => {
user.stats.gp = 11;
const item = content.special.thankyou;
const [data, message] = buy(user, {
const [data, message] = await buy(user, {
params: {
key: 'thankyou',
},
@@ -144,15 +143,15 @@ describe('shared.ops.buy', () => {
}));
});
it('allows for bulk purchases', () => {
it('allows for bulk purchases', async () => {
user.stats.hp = 30;
buy(user, { params: { key: 'potion' }, quantity: 2 });
await buy(user, { params: { key: 'potion' }, quantity: 2 });
expect(user.stats.hp).to.eql(50);
});
it('errors if user supplies a non-numeric quantity', done => {
it('errors if user supplies a non-numeric quantity', async () => {
try {
buy(user, {
await buy(user, {
params: {
key: 'dilatoryDistress1',
},
@@ -162,13 +161,12 @@ describe('shared.ops.buy', () => {
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(errorMessage('invalidQuantity'));
done();
}
});
it('errors if user supplies a negative quantity', done => {
it('errors if user supplies a negative quantity', async () => {
try {
buy(user, {
await buy(user, {
params: {
key: 'dilatoryDistress1',
},
@@ -178,13 +176,12 @@ describe('shared.ops.buy', () => {
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(errorMessage('invalidQuantity'));
done();
}
});
it('errors if user supplies a decimal quantity', done => {
it('errors if user supplies a decimal quantity', async () => {
try {
buy(user, {
await buy(user, {
params: {
key: 'dilatoryDistress1',
},
@@ -194,7 +191,6 @@ describe('shared.ops.buy', () => {
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(errorMessage('invalidQuantity'));
done();
}
});
});
+13 -14
View File
@@ -33,7 +33,7 @@ describe('shared.ops.buyArmoire', () => {
const YIELD_EXP = 0.9;
const analytics = { track () {} };
function buyArmoire (_user, _req, _analytics) {
async function buyArmoire (_user, _req, _analytics) {
const buyOp = new BuyArmoireOperation(_user, _req, _analytics);
return buyOp.purchase();
@@ -61,11 +61,11 @@ describe('shared.ops.buyArmoire', () => {
});
context('failure conditions', () => {
it('does not open if user does not have enough gold', done => {
it('does not open if user does not have enough gold', async () => {
user.stats.gp = 50;
try {
buyArmoire(user);
await buyArmoire(user);
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('messageNotEnoughGold'));
@@ -74,17 +74,16 @@ describe('shared.ops.buyArmoire', () => {
});
expect(user.items.food).to.be.empty;
expect(user.stats.exp).to.eql(0);
done();
}
});
});
context('non-gear awards', () => {
it('gives Experience', () => {
it('gives Experience', async () => {
const previousExp = user.stats.exp;
randomValFns.trueRandom.returns(YIELD_EXP);
buyArmoire(user);
await buyArmoire(user);
expect(user.items.gear.owned).to.eql({ weapon_warrior_0: true });
expect(user.items.food).to.be.empty;
@@ -92,12 +91,12 @@ describe('shared.ops.buyArmoire', () => {
expect(user.stats.gp).to.equal(100);
});
it('gives food', () => {
it('gives food', async () => {
const previousExp = user.stats.exp;
randomValFns.trueRandom.returns(YIELD_FOOD);
buyArmoire(user);
await buyArmoire(user);
expect(user.items.gear.owned).to.eql({ weapon_warrior_0: true });
expect(user.items.food).to.not.be.empty;
@@ -105,12 +104,12 @@ describe('shared.ops.buyArmoire', () => {
expect(user.stats.gp).to.equal(100);
});
it('does not give equipment if all equipment has been found', () => {
it('does not give equipment if all equipment has been found', async () => {
randomValFns.trueRandom.returns(YIELD_EQUIPMENT);
user.items.gear.owned = getFullArmoire();
user.stats.gp = 150;
buyArmoire(user);
await buyArmoire(user);
expect(user.items.gear.owned).to.eql(getFullArmoire());
const armoireCount = count.remainingGearInSet(user.items.gear.owned, 'armoire');
@@ -122,13 +121,13 @@ describe('shared.ops.buyArmoire', () => {
});
context('gear awards', () => {
it('always drops equipment the first time', () => {
it('always drops equipment the first time', async () => {
delete user.flags.armoireOpened;
randomValFns.trueRandom.returns(YIELD_EXP);
expect(_.size(user.items.gear.owned)).to.equal(1);
buyArmoire(user);
await buyArmoire(user);
expect(_.size(user.items.gear.owned)).to.equal(2);
@@ -140,7 +139,7 @@ describe('shared.ops.buyArmoire', () => {
expect(user.stats.gp).to.equal(100);
});
it('gives more equipment', () => {
it('gives more equipment', async () => {
randomValFns.trueRandom.returns(YIELD_EQUIPMENT);
user.items.gear.owned = {
weapon_warrior_0: true,
@@ -150,7 +149,7 @@ describe('shared.ops.buyArmoire', () => {
expect(_.size(user.items.gear.owned)).to.equal(2);
buyArmoire(user, {}, analytics);
await buyArmoire(user, {}, analytics);
expect(_.size(user.items.gear.owned)).to.equal(3);
+17 -22
View File
@@ -11,7 +11,7 @@ import i18n from '../../../../website/common/script/i18n';
import { BuyGemOperation } from '../../../../website/common/script/ops/buy/buyGem';
import planGemLimits from '../../../../website/common/script/libs/planGemLimits';
function buyGem (user, req, analytics) {
async function buyGem (user, req, analytics) {
const buyOp = new BuyGemOperation(user, req, analytics);
return buyOp.purchase();
@@ -44,8 +44,8 @@ describe('shared.ops.buyGem', () => {
});
context('Gems', () => {
it('purchases gems', () => {
const [, message] = buyGem(user, { params: { type: 'gems', key: 'gem' } }, analytics);
it('purchases gems', async () => {
const [, message] = await buyGem(user, { params: { type: 'gems', key: 'gem' } }, analytics);
expect(message).to.equal(i18n.t('plusGem', { count: 1 }));
expect(user.balance).to.equal(userGemAmount + 0.25);
@@ -54,8 +54,8 @@ describe('shared.ops.buyGem', () => {
expect(analytics.track).to.be.calledOnce;
});
it('purchases gems with a different language than the default', () => {
const [, message] = buyGem(user, { params: { type: 'gems', key: 'gem' }, language: 'de' });
it('purchases gems with a different language than the default', async () => {
const [, message] = await buyGem(user, { params: { type: 'gems', key: 'gem' }, language: 'de' });
expect(message).to.equal(i18n.t('plusGem', { count: 1 }, 'de'));
expect(user.balance).to.equal(userGemAmount + 0.25);
@@ -63,8 +63,8 @@ describe('shared.ops.buyGem', () => {
expect(user.stats.gp).to.equal(goldPoints - planGemLimits.convRate);
});
it('makes bulk purchases of gems', () => {
const [, message] = buyGem(user, {
it('makes bulk purchases of gems', async () => {
const [, message] = await buyGem(user, {
params: { type: 'gems', key: 'gem' },
quantity: 2,
});
@@ -76,63 +76,58 @@ describe('shared.ops.buyGem', () => {
});
context('Failure conditions', () => {
it('returns an error when key is not provided', done => {
it('returns an error when key is not provided', async () => {
try {
buyGem(user, { params: { type: 'gems' } });
await buyGem(user, { params: { type: 'gems' } });
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('missingKeyParam'));
done();
}
});
it('prevents unsubscribed user from buying gems', done => {
it('prevents unsubscribed user from buying gems', async () => {
delete user.purchased.plan.customerId;
try {
buyGem(user, { params: { type: 'gems', key: 'gem' } });
await buyGem(user, { params: { type: 'gems', key: 'gem' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('mustSubscribeToPurchaseGems'));
done();
}
});
it('prevents user with not enough gold from buying gems', done => {
it('prevents user with not enough gold from buying gems', async () => {
user.stats.gp = 15;
try {
buyGem(user, { params: { type: 'gems', key: 'gem' } });
await buyGem(user, { params: { type: 'gems', key: 'gem' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('messageNotEnoughGold'));
done();
}
});
it('prevents user that have reached the conversion cap from buying gems', done => {
it('prevents user that have reached the conversion cap from buying gems', async () => {
user.stats.gp = goldPoints;
user.purchased.plan.gemsBought = gemsBought;
try {
buyGem(user, { params: { type: 'gems', key: 'gem' } });
await buyGem(user, { params: { type: 'gems', key: 'gem' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('maxBuyGems', { convCap: planGemLimits.convCap }));
done();
}
});
it('prevents user from buying an invalid quantity', done => {
it('prevents user from buying an invalid quantity', async () => {
user.stats.gp = goldPoints;
user.purchased.plan.gemsBought = gemsBought;
try {
buyGem(user, { params: { type: 'gems', key: 'gem' }, quantity: 'a' });
await buyGem(user, { params: { type: 'gems', key: 'gem' }, quantity: 'a' });
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('invalidQuantity'));
done();
}
});
});
+15 -23
View File
@@ -12,7 +12,7 @@ describe('shared.ops.buyHealthPotion', () => {
let user;
const analytics = { track () {} };
function buyHealthPotion (_user, _req, _analytics) {
async function buyHealthPotion (_user, _req, _analytics) {
const buyOp = new BuyHealthPotionOperation(_user, _req, _analytics);
return buyOp.purchase();
@@ -40,83 +40,75 @@ describe('shared.ops.buyHealthPotion', () => {
});
context('Potion', () => {
it('recovers 15 hp', () => {
it('recovers 15 hp', async () => {
user.stats.hp = 30;
buyHealthPotion(user, {}, analytics);
await buyHealthPotion(user, {}, analytics);
expect(user.stats.hp).to.eql(45);
expect(analytics.track).to.be.calledOnce;
});
it('does not increase hp above 50', () => {
it('does not increase hp above 50', async () => {
user.stats.hp = 45;
buyHealthPotion(user);
await buyHealthPotion(user);
expect(user.stats.hp).to.eql(50);
});
it('deducts 25 gp', () => {
it('deducts 25 gp', async () => {
user.stats.hp = 45;
buyHealthPotion(user);
await buyHealthPotion(user);
expect(user.stats.gp).to.eql(175);
});
it('does not purchase if not enough gp', done => {
it('does not purchase if not enough gp', async () => {
user.stats.hp = 45;
user.stats.gp = 5;
try {
buyHealthPotion(user);
await buyHealthPotion(user);
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('messageNotEnoughGold'));
expect(user.stats.hp).to.eql(45);
expect(user.stats.gp).to.eql(5);
done();
}
});
it('does not purchase if hp is full', done => {
it('does not purchase if hp is full', async () => {
user.stats.hp = 50;
user.stats.gp = 40;
try {
buyHealthPotion(user);
await buyHealthPotion(user);
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('messageHealthAlreadyMax'));
expect(user.stats.hp).to.eql(50);
expect(user.stats.gp).to.eql(40);
done();
}
});
it('does not allow potion purchases when hp is zero', done => {
it('does not allow potion purchases when hp is zero', async () => {
user.stats.hp = 0;
user.stats.gp = 40;
try {
buyHealthPotion(user);
await buyHealthPotion(user);
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('messageHealthAlreadyMin'));
expect(user.stats.hp).to.eql(0);
expect(user.stats.gp).to.eql(40);
done();
}
});
it('does not allow potion purchases when hp is negative', done => {
it('does not allow potion purchases when hp is negative', async () => {
user.stats.hp = -8;
user.stats.gp = 40;
try {
buyHealthPotion(user);
await buyHealthPotion(user);
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('messageHealthAlreadyMin'));
expect(user.stats.hp).to.eql(-8);
expect(user.stats.gp).to.eql(40);
done();
}
});
});
+44 -52
View File
@@ -13,7 +13,7 @@ import {
import i18n from '../../../../website/common/script/i18n';
import errorMessage from '../../../../website/common/script/libs/errorMessage';
function buyGear (user, req, analytics) {
async function buyGear (user, req, analytics) {
const buyOp = new BuyMarketGearOperation(user, req, analytics);
return buyOp.purchase();
@@ -57,10 +57,10 @@ describe('shared.ops.buyMarketGear', () => {
});
context('Gear', () => {
it('adds equipment to inventory', () => {
it('adds equipment to inventory', async () => {
user.stats.gp = 31;
buyGear(user, { params: { key: 'armor_warrior_1' } }, analytics);
await buyGear(user, { params: { key: 'armor_warrior_1' } }, analytics);
expect(user.items.gear.owned).to.eql({
weapon_warrior_0: true,
@@ -90,10 +90,10 @@ describe('shared.ops.buyMarketGear', () => {
expect(analytics.track).to.be.calledOnce;
});
it('adds the onboarding achievement to the user and checks the onboarding status', () => {
it('adds the onboarding achievement to the user and checks the onboarding status', async () => {
user.stats.gp = 31;
buyGear(user, { params: { key: 'armor_warrior_1' } }, analytics);
await buyGear(user, { params: { key: 'armor_warrior_1' } }, analytics);
expect(user.addAchievement).to.be.calledOnce;
expect(user.addAchievement).to.be.calledWith('purchasedEquipment');
@@ -102,36 +102,36 @@ describe('shared.ops.buyMarketGear', () => {
expect(shared.onboarding.checkOnboardingStatus).to.be.calledWith(user);
});
it('does not add the onboarding achievement to the user if it\'s already been awarded', () => {
it('does not add the onboarding achievement to the user if it\'s already been awarded', async () => {
user.stats.gp = 31;
user.achievements.purchasedEquipment = true;
buyGear(user, { params: { key: 'armor_warrior_1' } }, analytics);
await buyGear(user, { params: { key: 'armor_warrior_1' } }, analytics);
expect(user.addAchievement).to.not.be.called;
});
it('deducts gold from user', () => {
it('deducts gold from user', async () => {
user.stats.gp = 31;
buyGear(user, { params: { key: 'armor_warrior_1' } });
await buyGear(user, { params: { key: 'armor_warrior_1' } });
expect(user.stats.gp).to.eql(1);
});
it('auto equips equipment if user has auto-equip preference turned on', () => {
it('auto equips equipment if user has auto-equip preference turned on', async () => {
user.stats.gp = 31;
user.preferences.autoEquip = true;
buyGear(user, { params: { key: 'armor_warrior_1' } });
await buyGear(user, { params: { key: 'armor_warrior_1' } });
expect(user.items.gear.equipped).to.have.property('armor', 'armor_warrior_1');
});
it('updates the pinnedItems to the next item in the set if one exists', () => {
it('updates the pinnedItems to the next item in the set if one exists', async () => {
user.stats.gp = 31;
buyGear(user, { params: { key: 'armor_warrior_1' } });
await buyGear(user, { params: { key: 'armor_warrior_1' } });
expect(user.pinnedItems).to.deep.include({
type: 'marketGear',
@@ -139,155 +139,147 @@ describe('shared.ops.buyMarketGear', () => {
});
});
it('buyGears equipment but does not auto-equip', () => {
it('buyGears equipment but does not auto-equip', async () => {
user.stats.gp = 31;
user.preferences.autoEquip = false;
buyGear(user, { params: { key: 'armor_warrior_1' } });
await buyGear(user, { params: { key: 'armor_warrior_1' } });
expect(user.items.gear.equipped.property).to.not.equal('armor_warrior_1');
});
it('does not buyGear equipment twice', done => {
it('does not buyGear equipment twice', async () => {
user.stats.gp = 62;
buyGear(user, { params: { key: 'armor_warrior_1' } });
await buyGear(user, { params: { key: 'armor_warrior_1' } });
try {
buyGear(user, { params: { key: 'armor_warrior_1' } });
await buyGear(user, { params: { key: 'armor_warrior_1' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('equipmentAlreadyOwned'));
done();
}
});
it('does not buy equipment of different class', done => {
it('does not buy equipment of different class', async () => {
user.stats.gp = 82;
user.stats.class = 'warrior';
try {
buyGear(user, { params: { key: 'weapon_special_winter2018Rogue' } });
await buyGear(user, { params: { key: 'weapon_special_winter2018Rogue' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('cannotBuyItem'));
done();
}
});
it('does not buy equipment in bulk', done => {
it('does not buy equipment in bulk', async () => {
user.stats.gp = 82;
try {
buyGear(user, { params: { key: 'armor_warrior_1' }, quantity: 3 });
await buyGear(user, { params: { key: 'armor_warrior_1' }, quantity: 3 });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('messageNotAbleToBuyInBulk'));
done();
}
});
// TODO after user.ops.equip is done
xit('removes one-handed weapon and shield if auto-equip is on and a two-hander is bought', () => {
xit('removes one-handed weapon and shield if auto-equip is on and a two-hander is bought', async () => {
user.stats.gp = 100;
user.preferences.autoEquip = true;
buyGear(user, { params: { key: 'shield_warrior_1' } });
await buyGear(user, { params: { key: 'shield_warrior_1' } });
user.ops.equip({ params: { key: 'shield_warrior_1' } });
buyGear(user, { params: { key: 'weapon_warrior_1' } });
await buyGear(user, { params: { key: 'weapon_warrior_1' } });
user.ops.equip({ params: { key: 'weapon_warrior_1' } });
buyGear(user, { params: { key: 'weapon_wizard_1' } });
await buyGear(user, { params: { key: 'weapon_wizard_1' } });
expect(user.items.gear.equipped).to.have.property('shield', 'shield_base_0');
expect(user.items.gear.equipped).to.have.property('weapon', 'weapon_wizard_1');
});
// TODO after user.ops.equip is done
xit('buyGears two-handed equipment but does not automatically remove sword or shield', () => {
xit('buyGears two-handed equipment but does not automatically remove sword or shield', async () => {
user.stats.gp = 100;
user.preferences.autoEquip = false;
buyGear(user, { params: { key: 'shield_warrior_1' } });
await buyGear(user, { params: { key: 'shield_warrior_1' } });
user.ops.equip({ params: { key: 'shield_warrior_1' } });
buyGear(user, { params: { key: 'weapon_warrior_1' } });
await buyGear(user, { params: { key: 'weapon_warrior_1' } });
user.ops.equip({ params: { key: 'weapon_warrior_1' } });
buyGear(user, { params: { key: 'weapon_wizard_1' } });
await buyGear(user, { params: { key: 'weapon_wizard_1' } });
expect(user.items.gear.equipped).to.have.property('shield', 'shield_warrior_1');
expect(user.items.gear.equipped).to.have.property('weapon', 'weapon_warrior_1');
});
it('does not buyGear equipment without enough Gold', done => {
it('does not buyGear equipment without enough Gold', async () => {
user.stats.gp = 20;
try {
buyGear(user, { params: { key: 'armor_warrior_1' } });
await buyGear(user, { params: { key: 'armor_warrior_1' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('messageNotEnoughGold'));
expect(user.items.gear.owned).to.not.have.property('armor_warrior_1');
done();
}
});
it('returns error when key is not provided', done => {
it('returns error when key is not provided', async () => {
try {
buyGear(user);
await buyGear(user);
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(errorMessage('missingKeyParam'));
done();
}
});
it('returns error when item is not found', done => {
it('returns error when item is not found', async () => {
const params = { key: 'armor_warrior_notExisting' };
try {
buyGear(user, { params });
await buyGear(user, { params });
} catch (err) {
expect(err).to.be.an.instanceof(NotFound);
expect(err.message).to.equal(errorMessage('itemNotFound', params));
done();
}
});
it('does not buyGear equipment without the previous equipment', done => {
it('does not buyGear equipment without the previous equipment', async () => {
try {
buyGear(user, { params: { key: 'armor_warrior_2' } });
await buyGear(user, { params: { key: 'armor_warrior_2' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('previousGearNotOwned'));
done();
}
});
it('does not buyGear equipment if user does not own prior item in sequence', done => {
it('does not buyGear equipment if user does not own prior item in sequence', async () => {
user.stats.gp = 200;
try {
buyGear(user, { params: { key: 'armor_warrior_2' } });
await buyGear(user, { params: { key: 'armor_warrior_2' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('previousGearNotOwned'));
expect(user.items.gear.owned).to.not.have.property('armor_warrior_2');
done();
}
});
it('does buyGear equipment if item is a numbered special item user qualifies for', () => {
it('does buyGear equipment if item is a numbered special item user qualifies for', async () => {
user.stats.gp = 200;
user.items.gear.owned.head_special_2 = false;
buyGear(user, { params: { key: 'head_special_2' } });
await buyGear(user, { params: { key: 'head_special_2' } });
expect(user.items.gear.owned).to.have.property('head_special_2', true);
});
it('does buyGear equipment if it is an armoire item that an user previously lost', () => {
it('does buyGear equipment if it is an armoire item that an user previously lost', async () => {
user.stats.gp = 200;
user.items.gear.owned.shield_armoire_ramHornShield = false;
buyGear(user, { params: { key: 'shield_armoire_ramHornShield' } });
await buyGear(user, { params: { key: 'shield_armoire_ramHornShield' } });
expect(user.items.gear.owned).to.have.property('shield_armoire_ramHornShield', true);
});
+8 -11
View File
@@ -35,18 +35,17 @@ describe('shared.ops.buyMysterySet', () => {
context('Mystery Sets', () => {
context('failure conditions', () => {
it('does not grant mystery sets without Mystic Hourglasses', done => {
it('does not grant mystery sets without Mystic Hourglasses', async () => {
try {
buyMysterySet(user, { params: { key: '201501' } });
await buyMysterySet(user, { params: { key: '201501' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.eql(i18n.t('notEnoughHourglasses'));
expect(user.items.gear.owned).to.have.property('weapon_warrior_0', true);
done();
}
});
it('does not grant mystery set that has already been purchased', done => {
it('does not grant mystery set that has already been purchased', async () => {
user.purchased.plan.consecutive.trinkets = 1;
user.items.gear.owned = {
weapon_warrior_0: true,
@@ -57,30 +56,28 @@ describe('shared.ops.buyMysterySet', () => {
};
try {
buyMysterySet(user, { params: { key: '301404' } });
await buyMysterySet(user, { params: { key: '301404' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotFound);
expect(err.message).to.eql(i18n.t('mysterySetNotFound'));
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
done();
}
});
it('returns error when key is not provided', done => {
it('returns error when key is not provided', async () => {
try {
buyMysterySet(user);
await buyMysterySet(user);
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(errorMessage('missingKeyParam'));
done();
}
});
});
context('successful purchases', () => {
it('buys Steampunk Accessories Set', () => {
it('buys Steampunk Accessories Set', async () => {
user.purchased.plan.consecutive.trinkets = 1;
buyMysterySet(user, { params: { key: '301404' } }, analytics);
await buyMysterySet(user, { params: { key: '301404' } }, analytics);
expect(user.purchased.plan.consecutive.trinkets).to.eql(0);
expect(user.items.gear.owned).to.have.property('weapon_warrior_0', true);
+9 -10
View File
@@ -13,7 +13,7 @@ describe('shared.ops.buyQuestGems', () => {
const goldPoints = 40;
const analytics = { track () {} };
function buyQuest (_user, _req, _analytics) {
async function buyQuest (_user, _req, _analytics) {
const buyOp = new BuyQuestWithGemOperation(_user, _req, _analytics);
return buyOp.purchase();
@@ -44,19 +44,19 @@ describe('shared.ops.buyQuestGems', () => {
user.pinnedItems.push({ type: 'quests', key: 'gryphon' });
});
it('purchases quests', () => {
it('purchases quests', async () => {
const key = 'gryphon';
buyQuest(user, { params: { key } });
await buyQuest(user, { params: { key } });
expect(user.items.quests[key]).to.equal(1);
expect(pinnedGearUtils.removeItemByPath.notCalled).to.equal(true);
});
it('if a user\'s count of a quest scroll is negative, it will be reset to 0 before incrementing when they buy a new one.', () => {
it('if a user\'s count of a quest scroll is negative, it will be reset to 0 before incrementing when they buy a new one.', async () => {
const key = 'dustbunnies';
user.items.quests[key] = -1;
buyQuest(user, { params: { key } });
await buyQuest(user, { params: { key } });
expect(user.items.quests[key]).to.equal(1);
expect(pinnedGearUtils.removeItemByPath.notCalled).to.equal(true);
@@ -73,26 +73,25 @@ describe('shared.ops.buyQuestGems', () => {
user.purchased.plan.customerId = 'customer-id';
});
it('errors when user does not have enough gems', done => {
it('errors when user does not have enough gems', async () => {
user.balance = 1;
const key = 'gryphon';
try {
buyQuest(user, {
await buyQuest(user, {
params: { key },
quantity: 2,
});
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('notEnoughGems'));
done();
}
});
it('makes bulk purchases of quests', () => {
it('makes bulk purchases of quests', async () => {
const key = 'gryphon';
buyQuest(user, {
await buyQuest(user, {
params: { key },
quantity: 3,
});
+22 -29
View File
@@ -14,7 +14,7 @@ describe('shared.ops.buyQuest', () => {
let user;
const analytics = { track () {} };
function buyQuest (_user, _req, _analytics) {
async function buyQuest (_user, _req, _analytics) {
const buyOp = new BuyQuestWithGoldOperation(_user, _req, _analytics);
return buyOp.purchase();
@@ -29,9 +29,9 @@ describe('shared.ops.buyQuest', () => {
analytics.track.restore();
});
it('buys a Quest scroll', () => {
it('buys a Quest scroll', async () => {
user.stats.gp = 205;
buyQuest(user, {
await buyQuest(user, {
params: {
key: 'dilatoryDistress1',
},
@@ -43,11 +43,11 @@ describe('shared.ops.buyQuest', () => {
expect(analytics.track).to.be.calledOnce;
});
it('if a user\'s count of a quest scroll is negative, it will be reset to 0 before incrementing when they buy a new one.', () => {
it('if a user\'s count of a quest scroll is negative, it will be reset to 0 before incrementing when they buy a new one.', async () => {
user.stats.gp = 205;
const key = 'dilatoryDistress1';
user.items.quests[key] = -1;
buyQuest(user, {
await buyQuest(user, {
params: { key },
}, analytics);
expect(user.items.quests[key]).to.equal(1);
@@ -55,14 +55,14 @@ describe('shared.ops.buyQuest', () => {
expect(analytics.track).to.be.calledOnce;
});
it('buys a Quest scroll with the right quantity if a string is passed for quantity', () => {
it('buys a Quest scroll with the right quantity if a string is passed for quantity', async () => {
user.stats.gp = 1000;
buyQuest(user, {
await buyQuest(user, {
params: {
key: 'dilatoryDistress1',
},
}, analytics);
buyQuest(user, {
await buyQuest(user, {
params: {
key: 'dilatoryDistress1',
},
@@ -74,10 +74,10 @@ describe('shared.ops.buyQuest', () => {
});
});
it('does not buy a Quest scroll when an invalid quantity is passed', done => {
it('does not buy a Quest scroll when an invalid quantity is passed', async () => {
user.stats.gp = 1000;
try {
buyQuest(user, {
await buyQuest(user, {
params: {
key: 'dilatoryDistress1',
},
@@ -88,14 +88,13 @@ describe('shared.ops.buyQuest', () => {
expect(err.message).to.equal(i18n.t('invalidQuantity'));
expect(user.items.quests).to.eql({});
expect(user.stats.gp).to.equal(1000);
done();
}
});
it('does not buy Quests without enough Gold', done => {
it('does not buy Quests without enough Gold', async () => {
user.stats.gp = 1;
try {
buyQuest(user, {
await buyQuest(user, {
params: {
key: 'dilatoryDistress1',
},
@@ -105,14 +104,13 @@ describe('shared.ops.buyQuest', () => {
expect(err.message).to.equal(i18n.t('messageNotEnoughGold'));
expect(user.items.quests).to.eql({});
expect(user.stats.gp).to.equal(1);
done();
}
});
it('does not buy nonexistent Quests', done => {
it('does not buy nonexistent Quests', async () => {
user.stats.gp = 9999;
try {
buyQuest(user, {
await buyQuest(user, {
params: {
key: 'snarfblatter',
},
@@ -122,13 +120,12 @@ describe('shared.ops.buyQuest', () => {
expect(err.message).to.equal(errorMessage('questNotFound', { key: 'snarfblatter' }));
expect(user.items.quests).to.eql({});
expect(user.stats.gp).to.equal(9999);
done();
}
});
it('does not buy the Mystery of the Masterclassers', done => {
it('does not buy the Mystery of the Masterclassers', async () => {
try {
buyQuest(user, {
await buyQuest(user, {
params: {
key: 'lostMasterclasser1',
},
@@ -137,14 +134,13 @@ describe('shared.ops.buyQuest', () => {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('questUnlockLostMasterclasser'));
expect(user.items.quests).to.eql({});
done();
}
});
it('does not buy Gem-premium Quests', done => {
it('does not buy Gem-premium Quests', async () => {
user.stats.gp = 9999;
try {
buyQuest(user, {
await buyQuest(user, {
params: {
key: 'kraken',
},
@@ -154,23 +150,21 @@ describe('shared.ops.buyQuest', () => {
expect(err.message).to.equal(i18n.t('questNotGoldPurchasable', { key: 'kraken' }));
expect(user.items.quests).to.eql({});
expect(user.stats.gp).to.equal(9999);
done();
}
});
it('returns error when key is not provided', done => {
it('returns error when key is not provided', async () => {
try {
buyQuest(user);
await buyQuest(user);
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(errorMessage('missingKeyParam'));
done();
}
});
it('does not buy a quest without completing previous quests', done => {
it('does not buy a quest without completing previous quests', async () => {
try {
buyQuest(user, {
await buyQuest(user, {
params: {
key: 'dilatoryDistress3',
},
@@ -179,7 +173,6 @@ describe('shared.ops.buyQuest', () => {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('mustComplete', { quest: 'dilatoryDistress2' }));
expect(user.items.quests).to.eql({});
done();
}
});
});
+9 -12
View File
@@ -15,7 +15,7 @@ describe('shared.ops.buySpecialSpell', () => {
let user;
const analytics = { track () {} };
function buySpecialSpell (_user, _req, _analytics) {
async function buySpecialSpell (_user, _req, _analytics) {
const buyOp = new BuySpellOperation(_user, _req, _analytics);
return buyOp.purchase();
@@ -29,19 +29,18 @@ describe('shared.ops.buySpecialSpell', () => {
analytics.track.restore();
});
it('throws an error if params.key is missing', done => {
it('throws an error if params.key is missing', async () => {
try {
buySpecialSpell(user);
await buySpecialSpell(user);
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(errorMessage('missingKeyParam'));
done();
}
});
it('throws an error if the spell doesn\'t exists', done => {
it('throws an error if the spell doesn\'t exists', async () => {
try {
buySpecialSpell(user, {
await buySpecialSpell(user, {
params: {
key: 'notExisting',
},
@@ -49,14 +48,13 @@ describe('shared.ops.buySpecialSpell', () => {
} catch (err) {
expect(err).to.be.an.instanceof(NotFound);
expect(err.message).to.equal(errorMessage('spellNotFound', { spellId: 'notExisting' }));
done();
}
});
it('throws an error if the user doesn\'t have enough gold', done => {
it('throws an error if the user doesn\'t have enough gold', async () => {
user.stats.gp = 1;
try {
buySpecialSpell(user, {
await buySpecialSpell(user, {
params: {
key: 'thankyou',
},
@@ -64,15 +62,14 @@ describe('shared.ops.buySpecialSpell', () => {
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('messageNotEnoughGold'));
done();
}
});
it('buys an item', () => {
it('buys an item', async () => {
user.stats.gp = 11;
const item = content.special.thankyou;
const [data, message] = buySpecialSpell(user, {
const [data, message] = await buySpecialSpell(user, {
params: {
key: 'thankyou',
},
+23 -32
View File
@@ -15,7 +15,7 @@ describe('common.ops.hourglassPurchase', () => {
let user;
const analytics = { track () {} };
function buyMount (_user, _req, _analytics) {
async function buyMount (_user, _req, _analytics) {
const buyOp = new BuyHourglassMountOperation(_user, _req, _analytics);
return buyOp.purchase();
@@ -31,116 +31,107 @@ describe('common.ops.hourglassPurchase', () => {
});
context('failure conditions', () => {
it('return error when key is not provided', done => {
it('return error when key is not provided', async () => {
try {
hourglassPurchase(user, { params: {} });
await hourglassPurchase(user, { params: {} });
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.eql(errorMessage('missingKeyParam'));
done();
}
});
it('returns error when type is not provided', done => {
it('returns error when type is not provided', async () => {
try {
hourglassPurchase(user, { params: { key: 'Base' } });
await hourglassPurchase(user, { params: { key: 'Base' } });
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.eql(errorMessage('missingTypeParam'));
done();
}
});
it('returns error when inccorect type is provided', done => {
it('returns error when inccorect type is provided', async () => {
try {
hourglassPurchase(user, { params: { type: 'notAType', key: 'MantisShrimp-Base' } });
await hourglassPurchase(user, { params: { type: 'notAType', key: 'MantisShrimp-Base' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.eql(i18n.t('typeNotAllowedHourglass', { allowedTypes: _.keys(content.timeTravelStable).toString() }));
done();
}
});
it('does not grant to pets without Mystic Hourglasses', done => {
it('does not grant to pets without Mystic Hourglasses', async () => {
try {
hourglassPurchase(user, { params: { type: 'pets', key: 'MantisShrimp-Base' } });
await hourglassPurchase(user, { params: { type: 'pets', key: 'MantisShrimp-Base' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.eql(i18n.t('notEnoughHourglasses'));
done();
}
});
it('does not grant to mounts without Mystic Hourglasses', done => {
it('does not grant to mounts without Mystic Hourglasses', async () => {
try {
buyMount(user, { params: { key: 'MantisShrimp-Base' } });
await buyMount(user, { params: { key: 'MantisShrimp-Base' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.eql(i18n.t('notEnoughHourglasses'));
done();
}
});
it('does not grant pet that is not part of the Time Travel Stable', done => {
it('does not grant pet that is not part of the Time Travel Stable', async () => {
user.purchased.plan.consecutive.trinkets = 1;
try {
hourglassPurchase(user, { params: { type: 'pets', key: 'Wolf-Veteran' } });
await hourglassPurchase(user, { params: { type: 'pets', key: 'Wolf-Veteran' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.eql(i18n.t('notAllowedHourglass'));
done();
}
});
it('does not grant mount that is not part of the Time Travel Stable', done => {
it('does not grant mount that is not part of the Time Travel Stable', async () => {
user.purchased.plan.consecutive.trinkets = 1;
try {
buyMount(user, { params: { key: 'Orca-Base' } });
await buyMount(user, { params: { key: 'Orca-Base' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.eql(i18n.t('notAllowedHourglass'));
done();
}
});
it('does not grant pet that has already been purchased', done => {
it('does not grant pet that has already been purchased', async () => {
user.purchased.plan.consecutive.trinkets = 1;
user.items.pets = {
'MantisShrimp-Base': true,
};
try {
hourglassPurchase(user, { params: { type: 'pets', key: 'MantisShrimp-Base' } });
await hourglassPurchase(user, { params: { type: 'pets', key: 'MantisShrimp-Base' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.eql(i18n.t('petsAlreadyOwned'));
done();
}
});
it('does not grant mount that has already been purchased', done => {
it('does not grant mount that has already been purchased', async () => {
user.purchased.plan.consecutive.trinkets = 1;
user.items.mounts = {
'MantisShrimp-Base': true,
};
try {
buyMount(user, { params: { key: 'MantisShrimp-Base' } });
await buyMount(user, { params: { key: 'MantisShrimp-Base' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.eql(i18n.t('mountsAlreadyOwned'));
done();
}
});
});
context('successful purchases', () => {
it('buys a pet', () => {
it('buys a pet', async () => {
user.purchased.plan.consecutive.trinkets = 2;
const [, message] = hourglassPurchase(user, { params: { type: 'pets', key: 'MantisShrimp-Base' } }, analytics);
const [, message] = await hourglassPurchase(user, { params: { type: 'pets', key: 'MantisShrimp-Base' } }, analytics);
expect(message).to.eql(i18n.t('hourglassPurchase'));
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
@@ -148,10 +139,10 @@ describe('common.ops.hourglassPurchase', () => {
expect(analytics.track).to.be.calledOnce;
});
it('buys a mount', () => {
it('buys a mount', async () => {
user.purchased.plan.consecutive.trinkets = 2;
const [, message] = buyMount(user, { params: { key: 'MantisShrimp-Base' } });
const [, message] = await buyMount(user, { params: { key: 'MantisShrimp-Base' } });
expect(message).to.eql(i18n.t('hourglassPurchase'));
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
expect(user.items.mounts).to.eql({ 'MantisShrimp-Base': true });
+34 -45
View File
@@ -33,118 +33,108 @@ describe('shared.ops.purchase', () => {
});
context('failure conditions', () => {
it('returns an error when type is not provided', done => {
it('returns an error when type is not provided', async () => {
try {
purchase(user, { params: {} });
await purchase(user, { params: {} });
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('typeRequired'));
done();
}
});
it('returns error when unknown type is provided', done => {
it('returns error when unknown type is provided', async () => {
try {
purchase(user, { params: { type: 'randomType', key: 'gem' } });
await purchase(user, { params: { type: 'randomType', key: 'gem' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotFound);
expect(err.message).to.equal(i18n.t('notAccteptedType'));
done();
}
});
it('returns error when user attempts to purchase a piece of gear they own', done => {
it('returns error when user attempts to purchase a piece of gear they own', async () => {
user.items.gear.owned['shield_rogue_1'] = true; // eslint-disable-line dot-notation
try {
purchase(user, { params: { type: 'gear', key: 'shield_rogue_1' } });
await purchase(user, { params: { type: 'gear', key: 'shield_rogue_1' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('alreadyHave'));
done();
}
});
it('returns error when unknown item is requested', done => {
it('returns error when unknown item is requested', async () => {
try {
purchase(user, { params: { type: 'gear', key: 'randomKey' } });
await purchase(user, { params: { type: 'gear', key: 'randomKey' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotFound);
expect(err.message).to.equal(i18n.t('contentKeyNotFound', { type: 'gear' }));
done();
}
});
it('returns error when user does not have permission to buy an item', done => {
it('returns error when user does not have permission to buy an item', async () => {
try {
purchase(user, { params: { type: 'gear', key: 'eyewear_mystery_301405' } });
await purchase(user, { params: { type: 'gear', key: 'eyewear_mystery_301405' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('messageNotAvailable'));
done();
}
});
it('returns error when user does not have enough gems to buy an item', done => {
it('returns error when user does not have enough gems to buy an item', async () => {
try {
purchase(user, { params: { type: 'gear', key: 'headAccessory_special_wolfEars' } });
await purchase(user, { params: { type: 'gear', key: 'headAccessory_special_wolfEars' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('notEnoughGems'));
done();
}
});
it('returns error when item is not found', done => {
it('returns error when item is not found', async () => {
const params = { key: 'notExisting', type: 'food' };
try {
purchase(user, { params });
await purchase(user, { params });
} catch (err) {
expect(err).to.be.an.instanceof(NotFound);
expect(err.message).to.equal(i18n.t('contentKeyNotFound', params));
done();
}
});
it('returns error when user supplies a non-numeric quantity', done => {
it('returns error when user supplies a non-numeric quantity', async () => {
const type = 'eggs';
const key = 'Wolf';
try {
purchase(user, { params: { type, key }, quantity: 'jamboree' }, analytics);
await purchase(user, { params: { type, key }, quantity: 'jamboree' }, analytics);
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('invalidQuantity'));
done();
}
});
it('returns error when user supplies a negative quantity', done => {
it('returns error when user supplies a negative quantity', async () => {
const type = 'eggs';
const key = 'Wolf';
user.balance = 10;
try {
purchase(user, { params: { type, key }, quantity: -2 }, analytics);
await purchase(user, { params: { type, key }, quantity: -2 }, analytics);
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('invalidQuantity'));
done();
}
});
it('returns error when user supplies a decimal quantity', done => {
it('returns error when user supplies a decimal quantity', async () => {
const type = 'eggs';
const key = 'Wolf';
user.balance = 10;
try {
purchase(user, { params: { type, key }, quantity: 2.9 }, analytics);
await purchase(user, { params: { type, key }, quantity: 2.9 }, analytics);
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('invalidQuantity'));
done();
}
});
});
@@ -164,48 +154,48 @@ describe('shared.ops.purchase', () => {
user.pinnedItems.push({ type: 'bundles', key: 'featheredFriends' });
});
it('purchases eggs', () => {
it('purchases eggs', async () => {
const type = 'eggs';
const key = 'Wolf';
purchase(user, { params: { type, key } }, analytics);
await purchase(user, { params: { type, key } }, analytics);
expect(user.items[type][key]).to.equal(1);
expect(pinnedGearUtils.removeItemByPath.notCalled).to.equal(true);
expect(analytics.track).to.be.calledOnce;
});
it('purchases hatchingPotions', () => {
it('purchases hatchingPotions', async () => {
const type = 'hatchingPotions';
const key = 'Base';
purchase(user, { params: { type, key } });
await purchase(user, { params: { type, key } });
expect(user.items[type][key]).to.equal(1);
expect(pinnedGearUtils.removeItemByPath.notCalled).to.equal(true);
});
it('purchases food', () => {
it('purchases food', async () => {
const type = 'food';
const key = SEASONAL_FOOD;
purchase(user, { params: { type, key } });
await purchase(user, { params: { type, key } });
expect(user.items[type][key]).to.equal(1);
expect(pinnedGearUtils.removeItemByPath.notCalled).to.equal(true);
});
it('purchases gear', () => {
it('purchases gear', async () => {
const type = 'gear';
const key = 'headAccessory_special_tigerEars';
purchase(user, { params: { type, key } });
await purchase(user, { params: { type, key } });
expect(user.items.gear.owned[key]).to.be.true;
expect(pinnedGearUtils.removeItemByPath.calledOnce).to.equal(true);
});
it('purchases quest bundles', () => {
it('purchases quest bundles', async () => {
const startingBalance = user.balance;
const clock = sandbox.useFakeTimers(moment('2019-05-20').valueOf());
const type = 'bundles';
@@ -217,7 +207,7 @@ describe('shared.ops.purchase', () => {
'owl',
];
purchase(user, { params: { type, key } });
await purchase(user, { params: { type, key } });
forEach(questList, bundledKey => {
expect(user.items.quests[bundledKey]).to.equal(1);
@@ -240,28 +230,27 @@ describe('shared.ops.purchase', () => {
user.purchased.plan.customerId = 'customer-id';
});
it('errors when user does not have enough gems', done => {
it('errors when user does not have enough gems', async () => {
user.balance = 1;
const type = 'eggs';
const key = 'TigerCub';
try {
purchase(user, {
await purchase(user, {
params: { type, key },
quantity: 2,
});
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('notEnoughGems'));
done();
}
});
it('makes bulk purchases of eggs', () => {
it('makes bulk purchases of eggs', async () => {
const type = 'eggs';
const key = 'TigerCub';
purchase(user, {
await purchase(user, {
params: { type, key },
quantity: 2,
});
+14 -18
View File
@@ -19,51 +19,48 @@ describe('shared.ops.changeClass', () => {
user.stats.flagSelected = false;
});
it('user is not level 10', done => {
it('user is not level 10', async () => {
user.stats.lvl = 9;
try {
changeClass(user, { query: { class: 'rogue' } });
await await changeClass(user, { query: { class: 'rogue' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('lvl10ChangeClass'));
done();
}
});
it('req.query.class is an invalid class', done => {
it('req.query.class is an invalid class', async () => {
user.flags.classSelected = false;
user.preferences.disableClasses = false;
try {
changeClass(user, { query: { class: 'cellist' } });
await changeClass(user, { query: { class: 'cellist' } });
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('invalidClass'));
done();
}
});
context('req.query.class is a valid class', () => {
it('errors if user.stats.flagSelected is true and user.balance < 0.75', done => {
it('errors if user.stats.flagSelected is true and user.balance < 0.75', async () => {
user.flags.classSelected = true;
user.preferences.disableClasses = false;
user.balance = 0;
try {
changeClass(user, { query: { class: 'rogue' } });
await changeClass(user, { query: { class: 'rogue' } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('notEnoughGems'));
done();
}
});
it('changes class', () => {
it('changes class', async () => {
user.stats.class = 'healer';
user.items.gear.owned.weapon_healer_3 = true;
user.items.gear.equipped.weapon = 'weapon_healer_3';
const [data] = changeClass(user, { query: { class: 'rogue' } });
const [data] = await changeClass(user, { query: { class: 'rogue' } });
expect(data).to.eql({
preferences: user.preferences,
stats: user.stats,
@@ -81,7 +78,7 @@ describe('shared.ops.changeClass', () => {
});
context('req.query.class is missing or user.stats.flagSelected is true', () => {
it('has user.preferences.disableClasses === true', () => {
it('has user.preferences.disableClasses === true', async () => {
user.balance = 1;
user.preferences.disableClasses = true;
user.preferences.autoAllocate = true;
@@ -92,7 +89,7 @@ describe('shared.ops.changeClass', () => {
user.stats.int = 4;
user.flags.classSelected = true;
const [data] = changeClass(user);
const [data] = await changeClass(user);
expect(data).to.eql({
preferences: user.preferences,
stats: user.stats,
@@ -112,18 +109,17 @@ describe('shared.ops.changeClass', () => {
});
context('has user.preferences.disableClasses !== true', () => {
it('and less than 3 gems', done => {
it('and less than 3 gems', async () => {
user.balance = 0.5;
try {
changeClass(user);
await changeClass(user);
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('notEnoughGems'));
done();
}
});
it('and at least 3 gems', () => {
it('and at least 3 gems', async () => {
user.balance = 1;
user.stats.points = 45;
user.stats.str = 1;
@@ -132,7 +128,7 @@ describe('shared.ops.changeClass', () => {
user.stats.int = 4;
user.flags.classSelected = true;
const [data] = changeClass(user);
const [data] = await changeClass(user);
expect(data).to.eql({
preferences: user.preferences,
stats: user.stats,
+48 -49
View File
@@ -24,60 +24,59 @@ describe('shared.ops.rebirth', () => {
tasks = [generateHabit(), generateDaily(), generateTodo(), generateReward()];
});
it('returns an error when user balance is too low and user is less than max level', done => {
it('returns an error when user balance is too low and user is less than max level', async () => {
user.balance = 0;
try {
rebirth(user);
await rebirth(user);
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('notEnoughGems'));
done();
}
});
it('rebirths a user with enough gems', () => {
const [, message] = rebirth(user);
it('rebirths a user with enough gems', async () => {
const [, message] = await rebirth(user);
expect(message).to.equal(i18n.t('rebirthComplete'));
});
it('rebirths a user with not enough gems but max level', () => {
it('rebirths a user with not enough gems but max level', async () => {
user.balance = 0;
user.stats.lvl = MAX_LEVEL;
const [, message] = rebirth(user);
const [, message] = await rebirth(user);
expect(message).to.equal(i18n.t('rebirthComplete'));
expect(user.flags.lastFreeRebirth).to.exist;
});
it('rebirths a user with not enough gems but more than max level', () => {
it('rebirths a user with not enough gems but more than max level', async () => {
user.balance = 0;
user.stats.lvl = MAX_LEVEL + 1;
const [, message] = rebirth(user);
const [, message] = await rebirth(user);
expect(message).to.equal(i18n.t('rebirthComplete'));
});
it('rebirths a user using gems if over max level but rebirthed recently', () => {
it('rebirths a user using gems if over max level but rebirthed recently', async () => {
user.stats.lvl = MAX_LEVEL + 1;
user.flags.lastFreeRebirth = new Date();
const [, message] = rebirth(user);
const [, message] = await rebirth(user);
expect(message).to.equal(i18n.t('rebirthComplete'));
expect(user.balance).to.equal(0);
});
it('resets user\'s tasks values except for rewards to 0', () => {
it('resets user\'s tasks values except for rewards to 0', async () => {
tasks[0].value = 1;
tasks[1].value = 1;
tasks[2].value = 1;
tasks[3].value = 1; // Reward
rebirth(user, tasks);
await rebirth(user, tasks);
expect(tasks[0].value).to.equal(0);
expect(tasks[1].value).to.equal(0);
@@ -85,99 +84,99 @@ describe('shared.ops.rebirth', () => {
expect(tasks[3].value).to.equal(1); // Reward
});
it('resets user\'s daily streaks to 0', () => {
it('resets user\'s daily streaks to 0', async () => {
tasks[0].counterDown = 1; // Habit
tasks[0].counterUp = 1; // Habit
tasks[1].streak = 1; // Daily
rebirth(user, tasks);
await rebirth(user, tasks);
expect(tasks[0].counterDown).to.equal(0);
expect(tasks[0].counterUp).to.equal(0);
expect(tasks[1].streak).to.equal(0);
});
it('resets a user\'s buffs', () => {
it('resets a user\'s buffs', async () => {
user.stats.buffs = { test: 'test' };
rebirth(user);
await rebirth(user);
expect(user.stats.buffs).to.be.empty;
});
it('resets a user\'s health points', () => {
it('resets a user\'s health points', async () => {
user.stats.hp = 40;
rebirth(user);
await rebirth(user);
expect(user.stats.hp).to.equal(50);
});
it('resets a user\'s class', () => {
it('resets a user\'s class', async () => {
user.stats.class = 'rouge';
rebirth(user);
await rebirth(user);
expect(user.stats.class).to.equal('warrior');
});
it('resets a user\'s stats', () => {
it('resets a user\'s stats', async () => {
user.stats.class = 'rouge';
_.each(userStats, value => {
user.stats[value] = 10;
});
rebirth(user);
await rebirth(user);
_.each(userStats, value => {
user.stats[value] = 0;
});
});
it('retains a user\'s gear', () => {
it('retains a user\'s gear', async () => {
const prevGearEquipped = user.items.gear.equipped;
const prevGearCostume = user.items.gear.costume;
const prevPrefCostume = user.preferences.costume;
rebirth(user);
await rebirth(user);
expect(user.items.gear.equipped).to.deep.equal(prevGearEquipped);
expect(user.items.gear.costume).to.deep.equal(prevGearCostume);
expect(user.preferences.costume).to.equal(prevPrefCostume);
});
it('retains a user\'s gear owned', () => {
it('retains a user\'s gear owned', async () => {
user.items.gear.owned.weapon_warrior_1 = true; // eslint-disable-line camelcase
const prevGearOwned = user.items.gear.owned;
rebirth(user);
await rebirth(user);
expect(user.items.gear.owned).to.equal(prevGearOwned);
});
it('resets a user\'s current pet', () => {
it('resets a user\'s current pet', async () => {
user.items.pets[animal] = true;
user.items.currentPet = animal;
rebirth(user);
await rebirth(user);
expect(user.items.currentPet).to.be.empty;
});
it('resets a user\'s current mount', () => {
it('resets a user\'s current mount', async () => {
user.items.mounts[animal] = true;
user.items.currentMount = animal;
rebirth(user);
await rebirth(user);
expect(user.items.currentMount).to.be.empty;
});
it('resets a user\'s flags', () => {
it('resets a user\'s flags', async () => {
user.flags.itemsEnabled = true;
user.flags.classSelected = true;
user.flags.rebirthEnabled = true;
user.flags.levelDrops = { test: 'test' };
rebirth(user);
await rebirth(user);
expect(user.flags.itemsEnabled).to.be.false;
expect(user.flags.classSelected).to.be.false;
@@ -185,80 +184,80 @@ describe('shared.ops.rebirth', () => {
expect(user.flags.levelDrops).to.be.empty;
});
it('reset rebirthEnabled even if user has beastMaster', () => {
it('reset rebirthEnabled even if user has beastMaster', async () => {
user.achievements.beastMaster = 1;
user.flags.rebirthEnabled = true;
rebirth(user);
await rebirth(user);
expect(user.flags.rebirthEnabled).to.be.false;
});
it('sets rebirth achievement', () => {
rebirth(user);
it('sets rebirth achievement', async () => {
await rebirth(user);
expect(user.achievements.rebirths).to.equal(1);
expect(user.achievements.rebirthLevel).to.equal(user.stats.lvl);
});
it('increments rebirth achievements', () => {
it('increments rebirth achievements', async () => {
user.stats.lvl = 2;
user.achievements.rebirths = 1;
user.achievements.rebirthLevel = 1;
rebirth(user);
await rebirth(user);
expect(user.achievements.rebirths).to.equal(2);
expect(user.achievements.rebirthLevel).to.equal(2);
});
it('does not increment rebirth achievements when level is lower than previous', () => {
it('does not increment rebirth achievements when level is lower than previous', async () => {
user.stats.lvl = 2;
user.achievements.rebirths = 1;
user.achievements.rebirthLevel = 3;
rebirth(user);
await rebirth(user);
expect(user.achievements.rebirths).to.equal(1);
expect(user.achievements.rebirthLevel).to.equal(3);
});
it('always increments rebirth achievements when level is MAX_LEVEL', () => {
it('always increments rebirth achievements when level is MAX_LEVEL', async () => {
user.stats.lvl = MAX_LEVEL;
user.achievements.rebirths = 1;
// this value is not actually possible (actually capped at MAX_LEVEL) but makes a good test
user.achievements.rebirthLevel = MAX_LEVEL + 1;
rebirth(user);
await rebirth(user);
expect(user.achievements.rebirths).to.equal(2);
expect(user.achievements.rebirthLevel).to.equal(MAX_LEVEL);
});
it('always increments rebirth achievements when level is greater than MAX_LEVEL', () => {
it('always increments rebirth achievements when level is greater than MAX_LEVEL', async () => {
user.stats.lvl = MAX_LEVEL + 1;
user.achievements.rebirths = 1;
// this value is not actually possible (actually capped at MAX_LEVEL) but makes a good test
user.achievements.rebirthLevel = MAX_LEVEL + 2;
rebirth(user);
await rebirth(user);
expect(user.achievements.rebirths).to.equal(2);
expect(user.achievements.rebirthLevel).to.equal(MAX_LEVEL);
});
it('keeps automaticAllocation false', () => {
it('keeps automaticAllocation false', async () => {
user.preferences.automaticAllocation = false;
rebirth(user);
await rebirth(user);
expect(user.preferences.automaticAllocation).to.be.false;
});
it('sets automaticAllocation to false when true', () => {
it('sets automaticAllocation to false when true', async () => {
user.preferences.automaticAllocation = true;
rebirth(user);
await rebirth(user);
expect(user.preferences.automaticAllocation).to.be.false;
});
+19 -21
View File
@@ -23,87 +23,85 @@ describe('shared.ops.releaseMounts', () => {
user.balance = 1;
});
it('returns an error when user balance is too low', done => {
it('returns an error when user balance is too low', async () => {
user.balance = 0;
try {
releaseMounts(user);
await releaseMounts(user);
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('notEnoughGems'));
done();
}
});
it('returns an error when user does not have all pets', done => {
it('returns an error when user does not have all pets', async () => {
const mountsKeys = Object.keys(user.items.mounts);
delete user.items.mounts[mountsKeys[0]];
try {
releaseMounts(user);
await releaseMounts(user);
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('notEnoughMounts'));
done();
}
});
it('releases mounts', () => {
const message = releaseMounts(user)[1];
it('releases mounts', async () => {
const result = await releaseMounts(user);
expect(message).to.equal(i18n.t('mountsReleased'));
expect(result[1]).to.equal(i18n.t('mountsReleased'));
expect(user.items.mounts[animal]).to.equal(null);
});
it('removes drop currentMount', () => {
it('removes drop currentMount', async () => {
const mountInfo = content.mountInfo[user.items.currentMount];
expect(mountInfo.type).to.equal('drop');
releaseMounts(user);
await releaseMounts(user);
expect(user.items.currentMount).to.be.empty;
});
it('leaves non-drop mount equipped', () => {
it('leaves non-drop mount equipped', async () => {
const questAnimal = 'Gryphon-Base';
user.items.currentMount = questAnimal;
user.items.mounts[questAnimal] = true;
const mountInfo = content.mountInfo[user.items.currentMount];
expect(mountInfo.type).to.not.equal('drop');
releaseMounts(user);
await releaseMounts(user);
expect(user.items.currentMount).to.equal(questAnimal);
});
it('increases mountMasterCount achievement', () => {
releaseMounts(user);
it('increases mountMasterCount achievement', async () => {
await releaseMounts(user);
expect(user.achievements.mountMasterCount).to.equal(1);
});
it('does not increase mountMasterCount achievement if mount is missing (null)', () => {
it('does not increase mountMasterCount achievement if mount is missing (null)', async () => {
const mountMasterCountBeforeRelease = user.achievements.mountMasterCount;
user.items.mounts[animal] = null;
try {
releaseMounts(user);
await releaseMounts(user);
} catch (e) {
expect(user.achievements.mountMasterCount).to.equal(mountMasterCountBeforeRelease);
}
});
it('does not increase mountMasterCount achievement if mount is missing (undefined)', () => {
it('does not increase mountMasterCount achievement if mount is missing (undefined)', async () => {
const mountMasterCountBeforeRelease = user.achievements.mountMasterCount;
delete user.items.mounts[animal];
try {
releaseMounts(user);
await releaseMounts(user);
} catch (e) {
expect(user.achievements.mountMasterCount).to.equal(mountMasterCountBeforeRelease);
}
});
it('subtracts gems from balance', () => {
releaseMounts(user);
it('subtracts gems from balance', async () => {
await releaseMounts(user);
expect(user.balance).to.equal(0);
});
+20 -22
View File
@@ -23,98 +23,96 @@ describe('shared.ops.releasePets', () => {
user.balance = 1;
});
it('returns an error when user balance is too low', done => {
it('returns an error when user balance is too low', async () => {
user.balance = 0;
try {
releasePets(user);
await releasePets(user);
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('notEnoughGems'));
done();
}
});
it('returns an error when user does not have all pets', done => {
it('returns an error when user does not have all pets', async () => {
const petKeys = Object.keys(user.items.pets);
delete user.items.pets[petKeys[0]];
try {
releasePets(user);
await releasePets(user);
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('notEnoughPets'));
done();
}
});
it('releases pets', () => {
const message = releasePets(user)[1];
it('releases pets', async () => {
const message = await releasePets(user)[1];
expect(message).to.equal(i18n.t('petsReleased'));
expect(user.items.pets[animal]).to.equal(0);
});
it('removes drop currentPet', () => {
it('removes drop currentPet', async () => {
const petInfo = content.petInfo[user.items.currentPet];
expect(petInfo.type).to.equal('drop');
releasePets(user);
await releasePets(user);
expect(user.items.currentPet).to.be.empty;
});
it('leaves non-drop pets equipped', () => {
it('leaves non-drop pets equipped', async () => {
const questAnimal = 'Gryphon-Base';
user.items.currentPet = questAnimal;
user.items.pets[questAnimal] = 5;
const petInfo = content.petInfo[user.items.currentPet];
expect(petInfo.type).to.not.equal('drop');
releasePets(user);
await releasePets(user);
expect(user.items.currentPet).to.equal(questAnimal);
});
it('decreases user\'s balance', () => {
releasePets(user);
it('decreases user\'s balance', async () => {
await releasePets(user);
expect(user.balance).to.equal(0);
});
it('incremenets beastMasterCount', () => {
releasePets(user);
it('incremenets beastMasterCount', async () => {
await releasePets(user);
expect(user.achievements.beastMasterCount).to.equal(1);
});
it('does not increment beastMasterCount if any pet is level 0 (released)', () => {
it('does not increment beastMasterCount if any pet is level 0 (released)', async () => {
const beastMasterCountBeforeRelease = user.achievements.beastMasterCount;
user.items.pets[animal] = 0;
try {
releasePets(user);
await releasePets(user);
} catch (e) {
expect(user.achievements.beastMasterCount).to.equal(beastMasterCountBeforeRelease);
}
});
it('does not increment beastMasterCount if any pet is missing (null)', () => {
it('does not increment beastMasterCount if any pet is missing (null)', async () => {
const beastMasterCountBeforeRelease = user.achievements.beastMasterCount;
user.items.pets[animal] = null;
try {
releasePets(user);
await releasePets(user);
} catch (e) {
expect(user.achievements.beastMasterCount).to.equal(beastMasterCountBeforeRelease);
}
});
it('does not increment beastMasterCount if any pet is missing (undefined)', () => {
it('does not increment beastMasterCount if any pet is missing (undefined)', async () => {
const beastMasterCountBeforeRelease = user.achievements.beastMasterCount;
delete user.items.pets[animal];
try {
releasePets(user);
await releasePets(user);
} catch (e) {
expect(user.achievements.beastMasterCount).to.equal(beastMasterCountBeforeRelease);
}
+10 -11
View File
@@ -19,43 +19,42 @@ describe('shared.ops.reroll', () => {
tasks = [generateDaily(), generateReward()];
});
it('returns an error when user balance is too low', done => {
it('returns an error when user balance is too low', async () => {
user.balance = 0;
try {
reroll(user);
await reroll(user);
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('notEnoughGems'));
done();
}
});
it('rerolls a user with enough gems', () => {
const [, message] = reroll(user);
it('rerolls a user with enough gems', async () => {
const [, message] = await reroll(user);
expect(message).to.equal(i18n.t('fortifyComplete'));
});
it('reduces a user\'s balance', () => {
reroll(user);
it('reduces a user\'s balance', async () => {
await reroll(user);
expect(user.balance).to.equal(0);
});
it('resets a user\'s health points', () => {
it('resets a user\'s health points', async () => {
user.stats.hp = 40;
reroll(user);
await reroll(user);
expect(user.stats.hp).to.equal(50);
});
it('resets user\'s taks values except for rewards to 0', () => {
it('resets user\'s taks values except for rewards to 0', async () => {
tasks[0].value = 1;
tasks[1].value = 1;
reroll(user, tasks);
await reroll(user, tasks);
expect(tasks[0].value).to.equal(0);
expect(tasks[1].value).to.equal(1);
+70 -81
View File
@@ -19,184 +19,173 @@ describe('shared.ops.unlock', () => {
user.balance = usersStartingGems;
});
it('returns an error when path is not provided', done => {
it('returns an error when path is not provided', async () => {
try {
unlock(user);
await unlock(user);
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('pathRequired'));
done();
}
});
it('does not unlock lost gear', done => {
it('does not unlock lost gear', async () => {
user.items.gear.owned.headAccessory_special_bearEars = false;
unlock(user, { query: { path: 'items.gear.owned.headAccessory_special_bearEars' } });
await unlock(user, { query: { path: 'items.gear.owned.headAccessory_special_bearEars' } });
expect(user.balance).to.equal(usersStartingGems);
done();
});
it('returns an error when user balance is too low', done => {
it('returns an error when user balance is too low', async () => {
user.balance = 0;
try {
unlock(user, { query: { path: unlockPath } });
await unlock(user, { query: { path: unlockPath } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('notEnoughGems'));
done();
}
});
it('returns an error when user already owns a full set', done => {
it('returns an error when user already owns a full set', async () => {
let expectedBalance;
try {
unlock(user, { query: { path: unlockPath } });
await unlock(user, { query: { path: unlockPath } });
expectedBalance = user.balance;
unlock(user, { query: { path: unlockPath } });
await unlock(user, { query: { path: unlockPath } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('alreadyUnlocked'));
expect(user.balance).to.equal(expectedBalance);
done();
}
});
it('returns an error when user already owns a full set of gear', done => {
it('returns an error when user already owns a full set of gear', async () => {
let expectedBalance;
try {
unlock(user, { query: { path: unlockGearSetPath } });
await unlock(user, { query: { path: unlockGearSetPath } });
expectedBalance = user.balance;
unlock(user, { query: { path: unlockGearSetPath } });
await unlock(user, { query: { path: unlockGearSetPath } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('alreadyUnlocked'));
expect(user.balance).to.equal(expectedBalance);
done();
}
});
it('returns an error if an item does not exists', done => {
it('returns an error if an item does not exists', async () => {
try {
unlock(user, { query: { path: 'background.invalid_background' } });
await unlock(user, { query: { path: 'background.invalid_background' } });
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('invalidUnlockSet'));
done();
}
});
it('returns an error if there are items from multiple sets', done => {
it('returns an error if there are items from multiple sets', async () => {
try {
unlock(user, { query: { path: 'shirt.convict,skin.0ff591' } });
await unlock(user, { query: { path: 'shirt.convict,skin.0ff591' } });
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('invalidUnlockSet'));
done();
}
});
it('returns an error if gear is not from the animal set', done => {
it('returns an error if gear is not from the animal set', async () => {
try {
unlock(user, { query: { path: 'items.gear.owned.back_mystery_202004' } });
await unlock(user, { query: { path: 'items.gear.owned.back_mystery_202004' } });
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('invalidUnlockSet'));
done();
}
});
it('returns an error if the item is free', done => {
it('returns an error if the item is free', async () => {
try {
unlock(user, { query: { path: 'shirt.black' } });
await unlock(user, { query: { path: 'shirt.black' } });
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('invalidUnlockSet'));
done();
}
});
it('returns an error if an item does not belong to a set (appearances)', done => {
it('returns an error if an item does not belong to a set (appearances)', async () => {
try {
unlock(user, { query: { path: 'shirt.pink' } });
await unlock(user, { query: { path: 'shirt.pink' } });
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('invalidUnlockSet'));
done();
}
});
it('returns an error when user already owns items in a full set and it would be more expensive to buy the entire set', done => {
it('returns an error when user already owns items in a full set and it would be more expensive to buy the entire set', async () => {
try {
// There are 11 shirts in the set, each cost 2 gems, the full set 5 gems
// In order for the full purchase not to be worth, we must own 9
const partialUnlockPaths = unlockPath.split(',');
unlock(user, { query: { path: partialUnlockPaths[0] } });
unlock(user, { query: { path: partialUnlockPaths[1] } });
unlock(user, { query: { path: partialUnlockPaths[2] } });
unlock(user, { query: { path: partialUnlockPaths[3] } });
unlock(user, { query: { path: partialUnlockPaths[4] } });
unlock(user, { query: { path: partialUnlockPaths[5] } });
unlock(user, { query: { path: partialUnlockPaths[6] } });
unlock(user, { query: { path: partialUnlockPaths[7] } });
unlock(user, { query: { path: partialUnlockPaths[8] } });
await unlock(user, { query: { path: partialUnlockPaths[0] } });
await unlock(user, { query: { path: partialUnlockPaths[1] } });
await unlock(user, { query: { path: partialUnlockPaths[2] } });
await unlock(user, { query: { path: partialUnlockPaths[3] } });
await unlock(user, { query: { path: partialUnlockPaths[4] } });
await unlock(user, { query: { path: partialUnlockPaths[5] } });
await unlock(user, { query: { path: partialUnlockPaths[6] } });
await unlock(user, { query: { path: partialUnlockPaths[7] } });
await unlock(user, { query: { path: partialUnlockPaths[8] } });
unlock(user, { query: { path: unlockPath } });
await unlock(user, { query: { path: unlockPath } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('alreadyUnlockedPart'));
done();
}
});
it('does not return an error when user already owns items in a full set and it would not be more expensive to buy the entire set', () => {
it('does not return an error when user already owns items in a full set and it would not be more expensive to buy the entire set', async () => {
// There are 11 shirts in the set, each cost 2 gems, the full set 5 gems
// In order for the full purchase to be worth, we can own already 8
const partialUnlockPaths = unlockPath.split(',');
unlock(user, { query: { path: partialUnlockPaths[0] } });
unlock(user, { query: { path: partialUnlockPaths[1] } });
unlock(user, { query: { path: partialUnlockPaths[2] } });
unlock(user, { query: { path: partialUnlockPaths[3] } });
unlock(user, { query: { path: partialUnlockPaths[4] } });
unlock(user, { query: { path: partialUnlockPaths[5] } });
unlock(user, { query: { path: partialUnlockPaths[6] } });
unlock(user, { query: { path: partialUnlockPaths[7] } });
await unlock(user, { query: { path: partialUnlockPaths[0] } });
await unlock(user, { query: { path: partialUnlockPaths[1] } });
await unlock(user, { query: { path: partialUnlockPaths[2] } });
await unlock(user, { query: { path: partialUnlockPaths[3] } });
await unlock(user, { query: { path: partialUnlockPaths[4] } });
await unlock(user, { query: { path: partialUnlockPaths[5] } });
await unlock(user, { query: { path: partialUnlockPaths[6] } });
await unlock(user, { query: { path: partialUnlockPaths[7] } });
unlock(user, { query: { path: unlockPath } });
await unlock(user, { query: { path: unlockPath } });
});
it('equips an item already owned', () => {
it('equips an item already owned', async () => {
expect(user.purchased.background.giant_florals).to.not.exist;
unlock(user, { query: { path: backgroundUnlockPath } });
await unlock(user, { query: { path: backgroundUnlockPath } });
const afterBalance = user.balance;
const response = unlock(user, { query: { path: backgroundUnlockPath } });
const response = await unlock(user, { query: { path: backgroundUnlockPath } });
expect(user.balance).to.equal(afterBalance); // do not bill twice
expect(response.message).to.not.exist;
expect(user.preferences.background).to.equal('giant_florals');
});
it('un-equips a background already equipped', () => {
it('un-equips a background already equipped', async () => {
expect(user.purchased.background.giant_florals).to.not.exist;
unlock(user, { query: { path: backgroundUnlockPath } }); // unlock
await unlock(user, { query: { path: backgroundUnlockPath } }); // unlock
const afterBalance = user.balance;
unlock(user, { query: { path: backgroundUnlockPath } }); // equip
const response = unlock(user, { query: { path: backgroundUnlockPath } });
await unlock(user, { query: { path: backgroundUnlockPath } }); // equip
const response = await unlock(user, { query: { path: backgroundUnlockPath } });
expect(user.balance).to.equal(afterBalance); // do not bill twice
expect(response.message).to.not.exist;
expect(user.preferences.background).to.equal('');
});
it('unlocks a full set of appearance items', () => {
it('unlocks a full set of appearance items', async () => {
const initialShirts = Object.keys(user.purchased.shirt).length;
const [, message] = unlock(user, { query: { path: unlockPath } });
const [, message] = await unlock(user, { query: { path: unlockPath } });
expect(message).to.equal(i18n.t('unlocked'));
const individualPaths = unlockPath.split(',');
@@ -208,11 +197,11 @@ describe('shared.ops.unlock', () => {
expect(user.balance).to.equal(usersStartingGems - 1.25);
});
it('unlocks a full set of hair items', () => {
it('unlocks a full set of hair items', async () => {
user.purchased.hair.color = {};
const initialHairColors = Object.keys(user.purchased.hair.color).length;
const [, message] = unlock(user, { query: { path: hairUnlockPath } });
const [, message] = await unlock(user, { query: { path: hairUnlockPath } });
expect(message).to.equal(i18n.t('unlocked'));
const individualPaths = hairUnlockPath.split(',');
@@ -224,13 +213,13 @@ describe('shared.ops.unlock', () => {
expect(user.balance).to.equal(usersStartingGems - 1.25);
});
it('unlocks the facial hair set', () => {
it('unlocks the facial hair set', async () => {
user.purchased.hair.mustache = {};
user.purchased.hair.beard = {};
const initialMustache = Object.keys(user.purchased.hair.mustache).length;
const initialBeard = Object.keys(user.purchased.hair.mustache).length;
const [, message] = unlock(user, { query: { path: facialHairUnlockPath } });
const [, message] = await unlock(user, { query: { path: facialHairUnlockPath } });
expect(message).to.equal(i18n.t('unlocked'));
const individualPaths = facialHairUnlockPath.split(',');
@@ -242,9 +231,9 @@ describe('shared.ops.unlock', () => {
expect(user.balance).to.equal(usersStartingGems - 1.25);
});
it('unlocks a full set of gear', () => {
it('unlocks a full set of gear', async () => {
const initialGear = Object.keys(user.items.gear.owned).length;
const [, message] = unlock(user, { query: { path: unlockGearSetPath } });
const [, message] = await unlock(user, { query: { path: unlockGearSetPath } });
expect(message).to.equal(i18n.t('unlocked'));
@@ -257,9 +246,9 @@ describe('shared.ops.unlock', () => {
expect(user.balance).to.equal(usersStartingGems - 1.25);
});
it('unlocks a full set of backgrounds', () => {
it('unlocks a full set of backgrounds', async () => {
const initialBackgrounds = Object.keys(user.purchased.background).length;
const [, message] = unlock(user, { query: { path: backgroundSetUnlockPath } });
const [, message] = await unlock(user, { query: { path: backgroundSetUnlockPath } });
expect(message).to.equal(i18n.t('unlocked'));
const individualPaths = backgroundSetUnlockPath.split(',');
@@ -271,10 +260,10 @@ describe('shared.ops.unlock', () => {
expect(user.balance).to.equal(usersStartingGems - 3.75);
});
it('unlocks an item (appearance)', () => {
it('unlocks an item (appearance)', async () => {
const path = unlockPath.split(',')[0];
const initialShirts = Object.keys(user.purchased.shirt).length;
const [, message] = unlock(user, { query: { path } });
const [, message] = await unlock(user, { query: { path } });
expect(message).to.equal(i18n.t('unlocked'));
expect(Object.keys(user.purchased.shirt).length).to.equal(initialShirts + 1);
@@ -282,12 +271,12 @@ describe('shared.ops.unlock', () => {
expect(user.balance).to.equal(usersStartingGems - 0.5);
});
it('unlocks an item (hair color)', () => {
it('unlocks an item (hair color)', async () => {
user.purchased.hair.color = {};
const path = hairUnlockPath.split(',')[0];
const initialColorHair = Object.keys(user.purchased.hair.color).length;
const [, message] = unlock(user, { query: { path } });
const [, message] = await unlock(user, { query: { path } });
expect(message).to.equal(i18n.t('unlocked'));
expect(Object.keys(user.purchased.hair.color).length).to.equal(initialColorHair + 1);
@@ -295,14 +284,14 @@ describe('shared.ops.unlock', () => {
expect(user.balance).to.equal(usersStartingGems - 0.5);
});
it('unlocks an item (facial hair)', () => {
it('unlocks an item (facial hair)', async () => {
user.purchased.hair.mustache = {};
user.purchased.hair.beard = {};
const path = facialHairUnlockPath.split(',')[0];
const initialMustache = Object.keys(user.purchased.hair.mustache).length;
const initialBeard = Object.keys(user.purchased.hair.beard).length;
const [, message] = unlock(user, { query: { path } });
const [, message] = await unlock(user, { query: { path } });
expect(message).to.equal(i18n.t('unlocked'));
@@ -313,10 +302,10 @@ describe('shared.ops.unlock', () => {
expect(user.balance).to.equal(usersStartingGems - 0.5);
});
it('unlocks an item (gear)', () => {
it('unlocks an item (gear)', async () => {
const path = unlockGearSetPath.split(',')[0];
const initialGear = Object.keys(user.items.gear.owned).length;
const [, message] = unlock(user, { query: { path } });
const [, message] = await unlock(user, { query: { path } });
expect(message).to.equal(i18n.t('unlocked'));
expect(Object.keys(user.items.gear.owned).length).to.equal(initialGear + 1);
@@ -324,9 +313,9 @@ describe('shared.ops.unlock', () => {
expect(user.balance).to.equal(usersStartingGems - 0.5);
});
it('unlocks an item (background)', () => {
it('unlocks an item (background)', async () => {
const initialBackgrounds = Object.keys(user.purchased.background).length;
const [, message] = unlock(user, { query: { path: backgroundUnlockPath } });
const [, message] = await unlock(user, { query: { path: backgroundUnlockPath } });
expect(message).to.equal(i18n.t('unlocked'));
expect(Object.keys(user.purchased.background).length).to.equal(initialBackgrounds + 1);
+12
View File
@@ -40,6 +40,18 @@ store.state.user.data = {
preferences: {
},
auth: {
local: {
// email: 'example@example.com',
},
facebook: {
emails: [
{
value: 'test@test.de',
},
],
},
},
};
Vue.prototype.$store = store;
+2255 -1975
View File
File diff suppressed because it is too large Load Diff
+10 -10
View File
@@ -13,26 +13,26 @@
"storybook:serve": "vue-cli-service storybook:serve -p 6006 -c config/storybook"
},
"dependencies": {
"@storybook/addons": "6.3.12",
"@storybook/addon-actions": "6.3.12",
"@storybook/addon-actions": "6.4.18",
"@storybook/addon-knobs": "6.2.9",
"@storybook/addon-links": "6.3.12",
"@storybook/addon-links": "6.4.17",
"@storybook/addon-notes": "5.3.21",
"@storybook/vue": "6.3.12",
"@storybook/addons": "6.4.18",
"@storybook/vue": "6.3.13",
"@vue/cli-plugin-babel": "^4.5.15",
"@vue/cli-plugin-eslint": "^4.5.15",
"@vue/cli-plugin-router": "^4.5.15",
"@vue/cli-plugin-unit-mocha": "^4.5.15",
"@vue/cli-service": "^4.5.15",
"@vue/test-utils": "1.0.0-beta.29",
"amplitude-js": "^8.12.0",
"axios": "^0.24.0",
"amplitude-js": "^8.16.1",
"axios": "^0.25.0",
"axios-progress-bar": "^1.2.0",
"babel-eslint": "^10.1.0",
"bootstrap": "^4.6.0",
"bootstrap-vue": "^2.21.2",
"chai": "^4.3.4",
"core-js": "^3.19.1",
"chai": "^4.3.6",
"core-js": "^3.20.3",
"eslint": "^6.8.0",
"eslint-config-habitrpg": "^6.2.0",
"eslint-plugin-mocha": "^5.3.0",
@@ -47,7 +47,7 @@
"nconf": "^0.11.3",
"sass": "^1.34.0",
"sass-loader": "^8.0.2",
"smartbanner.js": "^1.16.0",
"smartbanner.js": "^1.17.0",
"svg-inline-loader": "^0.8.2",
"svg-url-loader": "^7.1.1",
"svgo": "^1.3.2",
@@ -64,6 +64,6 @@
"webpack": "^4.46.0"
},
"devDependencies": {
"@babel/plugin-proposal-optional-chaining": "^7.16.0"
"@babel/plugin-proposal-optional-chaining": "^7.16.7"
}
}
+8 -1
View File
@@ -33,6 +33,8 @@
<payments-success-modal />
<sub-cancel-modal-confirm v-if="isUserLoaded" />
<sub-canceled-modal v-if="isUserLoaded" />
<bug-report-modal v-if="isUserLoaded" />
<bug-report-success-modal v-if="isUserLoaded" />
<snackbars />
<router-view v-if="!isUserLoggedIn || isStaticPage" />
<template v-else>
@@ -177,6 +179,10 @@ import {
removeLocalSetting,
} from '@/libs/userlocalManager';
const bugReportModal = () => import(/* webpackChunkName: "bug-report-modal" */'@/components/bugReportModal');
const bugReportSuccessModal = () => import(/* webpackChunkName: "bug-report-success-modal" */'@/components/bugReportSuccessModal');
const COMMUNITY_MANAGER_EMAIL = process.env.EMAILS_COMMUNITY_MANAGER_EMAIL; // eslint-disable-line
export default {
@@ -196,6 +202,8 @@ export default {
paymentsSuccessModal,
subCancelModalConfirm,
subCanceledModal,
bugReportModal,
bugReportSuccessModal,
},
mixins: [notifications, spellsMixin],
data () {
@@ -522,6 +530,5 @@ export default {
<style src="intro.js/minified/introjs.min.css"></style>
<style src="axios-progress-bar/dist/nprogress.css"></style>
<style src="@/assets/scss/index.scss" lang="scss"></style>
<style src="@/assets/css/sprites/spritesmith-largeSprites-0.css"></style>
<style src="@/assets/scss/sprites.scss" lang="scss"></style>
<style src="smartbanner.js/dist/smartbanner.min.css"></style>
@@ -1,84 +0,0 @@
.promo_armoire_backgrounds_202010 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -639px;
width: 423px;
height: 147px;
}
.promo_fall_customizations {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -532px 0px;
width: 336px;
height: 207px;
}
.promo_fall_festival_2019 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -449px;
width: 360px;
height: 189px;
}
.promo_fall_festival_2020 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -361px -449px;
width: 360px;
height: 174px;
}
.promo_mystery_202009 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -869px -296px;
width: 282px;
height: 147px;
}
.promo_mystery_202010 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -869px -444px;
width: 282px;
height: 147px;
}
.promo_sandy_sidekicks_bundle {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -869px -148px;
width: 420px;
height: 147px;
}
.promo_skeleton_achievements {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -244px;
width: 366px;
height: 204px;
}
.promo_spooky_sparkles {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -424px -639px;
width: 423px;
height: 147px;
}
.promo_take_this {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -1152px -296px;
width: 96px;
height: 69px;
}
.promo_vampire_potions {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -869px 0px;
width: 423px;
height: 147px;
}
.scene_positivity {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px 0px;
width: 531px;
height: 243px;
}
.scene_squall {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -532px -208px;
width: 141px;
height: 169px;
}
.scene_strength {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -869px -592px;
width: 192px;
height: 129px;
}
File diff suppressed because it is too large Load Diff
@@ -1,816 +0,0 @@
.background_halflings_house {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: 0px 0px;
width: 141px;
height: 147px;
}
.background_hall_of_heroes {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -142px 0px;
width: 141px;
height: 147px;
}
.background_harvest_feast {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -284px 0px;
width: 141px;
height: 147px;
}
.background_harvest_fields {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: 0px -148px;
width: 141px;
height: 147px;
}
.background_harvest_moon {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -142px -148px;
width: 141px;
height: 147px;
}
.background_haunted_forest {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -284px -148px;
width: 141px;
height: 147px;
}
.background_haunted_house {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -426px 0px;
width: 141px;
height: 147px;
}
.background_haunted_photo {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -426px -148px;
width: 141px;
height: 147px;
}
.background_heart_shaped_bubbles {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: 0px -296px;
width: 141px;
height: 147px;
}
.background_heather_field {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -142px -296px;
width: 141px;
height: 147px;
}
.background_herding_sheep_in_autumn {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -284px -296px;
width: 141px;
height: 147px;
}
.background_holiday_hearth {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -426px -296px;
width: 141px;
height: 147px;
}
.background_holiday_market {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -568px 0px;
width: 141px;
height: 147px;
}
.background_holiday_wreath {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -568px -148px;
width: 141px;
height: 147px;
}
.background_hot_air_balloon {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -568px -296px;
width: 141px;
height: 147px;
}
.background_hot_spring {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: 0px -444px;
width: 141px;
height: 147px;
}
.background_ice_cave {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -142px -444px;
width: 141px;
height: 147px;
}
.background_ice_palace {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -284px -444px;
width: 141px;
height: 147px;
}
.background_iceberg {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -426px -444px;
width: 141px;
height: 147px;
}
.background_icicle_bridge {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -568px -444px;
width: 141px;
height: 147px;
}
.background_idyllic_cabin {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -710px 0px;
width: 141px;
height: 147px;
}
.background_in_a_classroom {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -710px -148px;
width: 141px;
height: 147px;
}
.background_in_an_ancient_tomb {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -710px -296px;
width: 141px;
height: 147px;
}
.background_in_the_armory {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -710px -444px;
width: 141px;
height: 147px;
}
.background_inside_a_potion_bottle {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: 0px -592px;
width: 141px;
height: 147px;
}
.background_inside_an_ornament {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -142px -592px;
width: 141px;
height: 147px;
}
.background_island_waterfalls {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -284px -592px;
width: 141px;
height: 147px;
}
.background_jungle_canopy {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -426px -592px;
width: 141px;
height: 147px;
}
.background_kelp_forest {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -568px -592px;
width: 141px;
height: 147px;
}
.background_lake_with_floating_lanterns {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -710px -592px;
width: 141px;
height: 147px;
}
.background_lighthouse_shore {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -852px 0px;
width: 141px;
height: 147px;
}
.background_lilypad {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -852px -148px;
width: 141px;
height: 147px;
}
.background_magic_beanstalk {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -852px -296px;
width: 141px;
height: 147px;
}
.background_magical_candles {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -852px -444px;
width: 141px;
height: 147px;
}
.background_magical_museum {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -852px -592px;
width: 141px;
height: 147px;
}
.background_marble_temple {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: 0px -740px;
width: 141px;
height: 147px;
}
.background_market {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -142px -740px;
width: 141px;
height: 147px;
}
.background_meandering_cave {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -284px -740px;
width: 141px;
height: 147px;
}
.background_medieval_kitchen {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -426px -740px;
width: 141px;
height: 147px;
}
.background_midnight_castle {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -568px -740px;
width: 141px;
height: 147px;
}
.background_midnight_clouds {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -710px -740px;
width: 141px;
height: 147px;
}
.background_midnight_lake {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -852px -740px;
width: 141px;
height: 147px;
}
.background_mist_shrouded_mountain {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -994px 0px;
width: 141px;
height: 147px;
}
.background_mistiflying_circus {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -994px -148px;
width: 141px;
height: 147px;
}
.background_monster_makers_workshop {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -994px -296px;
width: 141px;
height: 147px;
}
.background_mountain_lake {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -994px -444px;
width: 141px;
height: 147px;
}
.background_mountain_pyramid {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -994px -592px;
width: 141px;
height: 147px;
}
.background_mystical_observatory {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -994px -740px;
width: 141px;
height: 147px;
}
.background_night_dunes {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: 0px -888px;
width: 141px;
height: 147px;
}
.background_ocean_sunrise {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -142px -888px;
width: 141px;
height: 147px;
}
.background_old_fashioned_bakery {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -284px -888px;
width: 141px;
height: 147px;
}
.background_on_tree_branch {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -426px -888px;
width: 141px;
height: 147px;
}
.background_open_waters {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -568px -888px;
width: 141px;
height: 147px;
}
.background_orchard {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -710px -888px;
width: 141px;
height: 147px;
}
.background_pagodas {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -852px -888px;
width: 141px;
height: 147px;
}
.background_park_with_statue {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -994px -888px;
width: 141px;
height: 147px;
}
.background_pirate_flag {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1136px 0px;
width: 141px;
height: 147px;
}
.background_pixelists_workshop {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1136px -148px;
width: 141px;
height: 147px;
}
.background_potion_shop {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1136px -296px;
width: 141px;
height: 147px;
}
.background_productivity_plaza {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1136px -444px;
width: 141px;
height: 147px;
}
.background_pumpkin_carriage {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1136px -592px;
width: 141px;
height: 147px;
}
.background_pumpkin_patch {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1136px -740px;
width: 141px;
height: 147px;
}
.background_purple {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1136px -888px;
width: 141px;
height: 147px;
}
.background_pyramids {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: 0px -1036px;
width: 141px;
height: 147px;
}
.background_raging_river {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -142px -1036px;
width: 141px;
height: 147px;
}
.background_rainbow_meadow {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -284px -1036px;
width: 141px;
height: 147px;
}
.background_rainbows_end {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -426px -1036px;
width: 141px;
height: 147px;
}
.background_rainforest {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -568px -1036px;
width: 141px;
height: 147px;
}
.background_rainy_barnyard {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -710px -1036px;
width: 141px;
height: 147px;
}
.background_rainy_city {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -852px -1036px;
width: 141px;
height: 147px;
}
.background_red {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -994px -1036px;
width: 141px;
height: 147px;
}
.background_relaxation_river {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1136px -1036px;
width: 141px;
height: 147px;
}
.background_resting_in_the_inn {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1278px 0px;
width: 141px;
height: 147px;
}
.background_river_of_lava {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1278px -148px;
width: 141px;
height: 147px;
}
.background_rolling_hills {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1278px -296px;
width: 141px;
height: 147px;
}
.background_rope_bridge {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1278px -444px;
width: 141px;
height: 147px;
}
.background_rose_garden {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1278px -592px;
width: 141px;
height: 147px;
}
.background_rowboat {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1278px -740px;
width: 141px;
height: 147px;
}
.background_salt_lake {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1278px -888px;
width: 141px;
height: 147px;
}
.background_sandcastle {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1278px -1036px;
width: 141px;
height: 147px;
}
.background_school_of_fish {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: 0px -1184px;
width: 141px;
height: 147px;
}
.background_scribes_workshop {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -142px -1184px;
width: 141px;
height: 147px;
}
.background_seafarer_ship {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -284px -1184px;
width: 141px;
height: 147px;
}
.background_seaside_cliffs {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -426px -1184px;
width: 141px;
height: 147px;
}
.background_shimmering_ice_prism {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -568px -1184px;
width: 141px;
height: 147px;
}
.background_shimmery_bubbles {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -710px -1184px;
width: 141px;
height: 147px;
}
.background_slimy_swamp {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -852px -1184px;
width: 141px;
height: 147px;
}
.background_snowglobe {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -994px -1184px;
width: 141px;
height: 147px;
}
.background_snowman_army {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1136px -1184px;
width: 141px;
height: 147px;
}
.background_snowy_day_fireplace {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1278px -1184px;
width: 141px;
height: 147px;
}
.background_snowy_pines {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1420px 0px;
width: 141px;
height: 147px;
}
.background_snowy_sunrise {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1420px -148px;
width: 141px;
height: 147px;
}
.background_south_pole {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1420px -296px;
width: 141px;
height: 147px;
}
.background_sparkling_snowflake {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1420px -444px;
width: 141px;
height: 147px;
}
.background_spider_web {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1420px -592px;
width: 141px;
height: 147px;
}
.background_spiral_staircase {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1420px -740px;
width: 141px;
height: 147px;
}
.background_splash_in_a_puddle {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1420px -888px;
width: 141px;
height: 147px;
}
.background_spooky_hotel {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1420px -1036px;
width: 141px;
height: 147px;
}
.background_spooky_scarecrow_field {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1420px -1184px;
width: 141px;
height: 147px;
}
.background_spring_rain {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: 0px -1332px;
width: 141px;
height: 147px;
}
.background_spring_thaw {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -142px -1332px;
width: 141px;
height: 147px;
}
.background_stable {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -284px -1332px;
width: 141px;
height: 147px;
}
.background_stained_glass {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -426px -1332px;
width: 141px;
height: 147px;
}
.background_starry_skies {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -568px -1332px;
width: 141px;
height: 147px;
}
.background_starry_winter_night {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -710px -1332px;
width: 141px;
height: 147px;
}
.background_stoikalm_volcanoes {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -852px -1332px;
width: 141px;
height: 147px;
}
.background_stone_circle {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -994px -1332px;
width: 141px;
height: 147px;
}
.background_stone_tower {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1136px -1332px;
width: 141px;
height: 147px;
}
.background_stormy_rooftops {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1278px -1332px;
width: 141px;
height: 147px;
}
.background_stormy_ship {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1420px -1332px;
width: 141px;
height: 147px;
}
.background_strange_sewers {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1562px 0px;
width: 141px;
height: 147px;
}
.background_strawberry_patch {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1562px -148px;
width: 141px;
height: 147px;
}
.background_succulent_garden {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1562px -296px;
width: 141px;
height: 147px;
}
.background_summer_fireworks {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1562px -444px;
width: 141px;
height: 147px;
}
.background_sunken_ship {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1562px -592px;
width: 141px;
height: 147px;
}
.background_sunset_meadow {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1562px -740px;
width: 141px;
height: 147px;
}
.background_sunset_oasis {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1562px -888px;
width: 141px;
height: 147px;
}
.background_sunset_savannah {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1562px -1036px;
width: 141px;
height: 147px;
}
.background_swarming_darkness {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1562px -1184px;
width: 141px;
height: 147px;
}
.background_swimming_among_jellyfish {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1562px -1332px;
width: 141px;
height: 147px;
}
.background_tar_pits {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: 0px -1480px;
width: 141px;
height: 147px;
}
.background_tavern {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -142px -1480px;
width: 141px;
height: 147px;
}
.background_tea_party {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -284px -1480px;
width: 141px;
height: 147px;
}
.background_terraced_rice_field {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -426px -1480px;
width: 141px;
height: 147px;
}
.background_throne_room {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -568px -1480px;
width: 141px;
height: 147px;
}
.background_thunderstorm {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -710px -1480px;
width: 141px;
height: 147px;
}
.background_tide_pool {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -852px -1480px;
width: 141px;
height: 147px;
}
.background_tornado {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -994px -1480px;
width: 141px;
height: 147px;
}
.background_toymakers_workshop {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1136px -1480px;
width: 141px;
height: 147px;
}
.background_training_grounds {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1278px -1480px;
width: 141px;
height: 147px;
}
.background_treasure_room {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1420px -1480px;
width: 141px;
height: 147px;
}
.background_tree_roots {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1562px -1480px;
width: 141px;
height: 147px;
}
.background_treehouse {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1704px 0px;
width: 141px;
height: 147px;
}
.background_tulip_garden {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1704px -148px;
width: 141px;
height: 147px;
}
.background_twinkly_lights {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1704px -296px;
width: 141px;
height: 147px;
}
.background_twinkly_party_lights {
background-image: url('~@/assets/images/sprites/spritesmith-main-1.png');
background-position: -1704px -444px;
width: 141px;
height: 147px;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,390 +0,0 @@
.quest_bunny {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: 0px -1546px;
width: 210px;
height: 186px;
}
.quest_butterfly {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -220px 0px;
width: 219px;
height: 219px;
}
.quest_cheetah {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -440px 0px;
width: 219px;
height: 219px;
}
.quest_cow {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1760px 0px;
width: 174px;
height: 213px;
}
.quest_dilatory {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -220px -232px;
width: 219px;
height: 219px;
}
.quest_dilatoryDistress1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -222px -1332px;
width: 210px;
height: 210px;
}
.quest_dilatoryDistress2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1760px -422px;
width: 150px;
height: 150px;
}
.quest_dilatoryDistress3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -440px -232px;
width: 219px;
height: 219px;
}
.quest_dilatory_derby {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: 0px -232px;
width: 219px;
height: 219px;
}
.quest_dolphin {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -660px 0px;
width: 219px;
height: 219px;
}
.quest_dustbunnies {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -660px -220px;
width: 219px;
height: 219px;
}
.quest_egg {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1760px -214px;
width: 165px;
height: 207px;
}
.quest_evilsanta {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1760px -724px;
width: 118px;
height: 131px;
}
.quest_evilsanta2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: 0px -452px;
width: 219px;
height: 219px;
}
.quest_falcon {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -220px -452px;
width: 219px;
height: 219px;
}
.quest_ferret {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -440px -452px;
width: 219px;
height: 219px;
}
.quest_fluorite {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -660px -452px;
width: 219px;
height: 219px;
}
.quest_frog {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: 0px -1332px;
width: 221px;
height: 213px;
}
.quest_ghost_stag {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -880px 0px;
width: 219px;
height: 219px;
}
.quest_goldenknight1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -880px -220px;
width: 219px;
height: 219px;
}
.quest_goldenknight2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -211px -1546px;
width: 250px;
height: 150px;
}
.quest_goldenknight3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: 0px 0px;
width: 219px;
height: 231px;
}
.quest_gryphon {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -876px -1332px;
width: 216px;
height: 177px;
}
.quest_guineapig {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -880px -440px;
width: 219px;
height: 219px;
}
.quest_harpy {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: 0px -672px;
width: 219px;
height: 219px;
}
.quest_hedgehog {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -433px -1332px;
width: 219px;
height: 186px;
}
.quest_hippo {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -220px -672px;
width: 219px;
height: 219px;
}
.quest_horse {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -440px -672px;
width: 219px;
height: 219px;
}
.quest_kangaroo {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -660px -672px;
width: 219px;
height: 219px;
}
.quest_kraken {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1093px -1332px;
width: 216px;
height: 177px;
}
.quest_lostMasterclasser1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -880px -672px;
width: 219px;
height: 219px;
}
.quest_lostMasterclasser2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1100px 0px;
width: 219px;
height: 219px;
}
.quest_lostMasterclasser3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1100px -220px;
width: 219px;
height: 219px;
}
.quest_mayhemMistiflying1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1760px -573px;
width: 150px;
height: 150px;
}
.quest_mayhemMistiflying2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1100px -440px;
width: 219px;
height: 219px;
}
.quest_mayhemMistiflying3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1100px -660px;
width: 219px;
height: 219px;
}
.quest_monkey {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: 0px -892px;
width: 219px;
height: 219px;
}
.quest_moon1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1540px -220px;
width: 216px;
height: 216px;
}
.quest_moon2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -220px -892px;
width: 219px;
height: 219px;
}
.quest_moon3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -440px -892px;
width: 219px;
height: 219px;
}
.quest_moonstone1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -660px -892px;
width: 219px;
height: 219px;
}
.quest_moonstone2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -880px -892px;
width: 219px;
height: 219px;
}
.quest_moonstone3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1100px -892px;
width: 219px;
height: 219px;
}
.quest_nudibranch {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1540px -437px;
width: 216px;
height: 216px;
}
.quest_octopus {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -653px -1332px;
width: 222px;
height: 177px;
}
.quest_onyx {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1320px 0px;
width: 219px;
height: 219px;
}
.quest_owl {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1320px -220px;
width: 219px;
height: 219px;
}
.quest_peacock {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1540px -654px;
width: 216px;
height: 216px;
}
.quest_penguin {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: 0px -1733px;
width: 190px;
height: 183px;
}
.quest_pterodactyl {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1320px -440px;
width: 219px;
height: 219px;
}
.quest_rat {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1320px -660px;
width: 219px;
height: 219px;
}
.quest_robot {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1320px -880px;
width: 219px;
height: 219px;
}
.quest_rock {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1540px -871px;
width: 216px;
height: 216px;
}
.quest_rooster {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1527px -1332px;
width: 213px;
height: 174px;
}
.quest_ruby {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: 0px -1112px;
width: 219px;
height: 219px;
}
.quest_sabretooth {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -220px -1112px;
width: 219px;
height: 219px;
}
.quest_seaserpent {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -440px -1112px;
width: 219px;
height: 219px;
}
.quest_sheep {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -660px -1112px;
width: 219px;
height: 219px;
}
.quest_silver {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -880px -1112px;
width: 219px;
height: 219px;
}
.quest_slime {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1100px -1112px;
width: 219px;
height: 219px;
}
.quest_sloth {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1320px -1112px;
width: 219px;
height: 219px;
}
.quest_snail {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1540px -1088px;
width: 219px;
height: 213px;
}
.quest_snake {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1310px -1332px;
width: 216px;
height: 177px;
}
.quest_spider {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -462px -1546px;
width: 250px;
height: 150px;
}
.quest_squirrel {
background-image: url('~@/assets/images/sprites/spritesmith-main-15.png');
background-position: -1540px 0px;
width: 219px;
height: 219px;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 465 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 465 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 414 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 588 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

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