Merge remote-tracking branch 'upstream/develop' into bugfix-npc-style

This commit is contained in:
osiris
2020-01-15 12:41:26 +08:00
158 changed files with 10624 additions and 3586 deletions

3
.gitignore vendored
View File

@@ -37,3 +37,6 @@ yarn.lock
.elasticbeanstalk/*
!.elasticbeanstalk/*.cfg.yml
!.elasticbeanstalk/*.global.yml
# webstorm fake webpack for path intellisense
webpack.webstorm.config

View File

@@ -3,9 +3,12 @@ FROM node:12
# Install global packages
RUN npm install -g gulp-cli mocha
# Copy Habitica code into container and install dependencies
# Copy package.json and package-lock.json into image, then install
# dependencies.
WORKDIR /usr/src/habitica
COPY . /usr/src/habitica
COPY ["package.json", "package-lock.json", "./"]
RUN npm install
# Copy the remaining source files in.
COPY . /usr/src/habitica
RUN npm run postinstall

View File

@@ -15,8 +15,9 @@ services:
ports:
- "8080:8080"
volumes:
- .:/code
- /code/node_modules
- .:/usr/src/habitica
- /usr/src/habitica/node_modules
- /usr/src/habitica/website/client/node_modules
server:
build:
context: .
@@ -32,8 +33,8 @@ services:
ports:
- "3000:3000"
volumes:
- .:/code
- /code/node_modules
- .:/usr/src/habitica
- /usr/src/habitica/node_modules
mongo:
image: mongo:3.6
networks:

1404
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,24 +1,24 @@
{
"name": "habitica",
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
"version": "4.129.0",
"version": "4.129.3",
"main": "./website/server/index.js",
"dependencies": {
"@babel/core": "^7.7.7",
"@babel/preset-env": "^7.7.7",
"@babel/register": "^7.7.7",
"@google-cloud/trace-agent": "^4.2.4",
"@babel/core": "^7.8.0",
"@babel/preset-env": "^7.8.2",
"@babel/register": "^7.8.0",
"@google-cloud/trace-agent": "^4.2.5",
"@slack/client": "^3.8.1",
"accepts": "^1.3.5",
"amazon-payments": "^0.2.7",
"amazon-payments": "^0.2.8",
"amplitude": "^3.5.0",
"apidoc": "^0.17.5",
"apn": "^2.2.0",
"aws-sdk": "^2.597.0",
"aws-sdk": "^2.601.0",
"bcrypt": "^3.0.7",
"body-parser": "^1.18.3",
"compression": "^1.7.4",
"cookie-session": "^1.3.3",
"cookie-session": "^1.4.0",
"coupon-code": "^0.4.5",
"csv-stringify": "^5.3.6",
"cwait": "^1.1.1",
@@ -46,7 +46,7 @@
"method-override": "^3.0.0",
"moment": "^2.24.0",
"moment-recur": "^1.0.7",
"mongoose": "^5.8.4",
"mongoose": "^5.8.7",
"morgan": "^1.7.0",
"nconf": "^0.10.0",
"node-gcm": "^1.0.2",
@@ -63,7 +63,7 @@
"rimraf": "^3.0.0",
"short-uuid": "^3.0.0",
"stripe": "^7.15.0",
"superagent": "^5.1.3",
"superagent": "^5.2.1",
"universal-analytics": "^0.4.17",
"useragent": "^2.1.9",
"uuid": "^3.3.3",
@@ -103,14 +103,14 @@
"apidoc": "gulp apidoc"
},
"devDependencies": {
"axios": "^0.19.0",
"axios": "^0.19.1",
"chai": "^4.1.2",
"chai-as-promised": "^7.1.1",
"chalk": "^2.4.1",
"expect.js": "^0.3.1",
"istanbul": "^1.1.0-alpha.1",
"mocha": "^5.1.1",
"monk": "^7.1.1",
"monk": "^7.1.2",
"require-again": "^2.0.0",
"sinon": "^7.2.4",
"sinon-chai": "^3.4.0",

View File

@@ -43,6 +43,7 @@ describe('webhooks', () => {
options: {
questStarted: true,
questFinised: true,
questInvited: true,
},
}, {
id: 'userActivity',
@@ -576,7 +577,7 @@ describe('webhooks', () => {
};
});
['questStarted', 'questFinised'].forEach(type => {
['questStarted', 'questFinised', 'questInvited'].forEach(type => {
it(`sends ${type} webhooks`, () => {
data.type = type;

View File

@@ -183,6 +183,7 @@ describe('Webhook Model', () => {
options: {
questStarted: true,
questFinished: true,
questInvited: true,
},
};
});
@@ -197,6 +198,7 @@ describe('Webhook Model', () => {
expect(wh.options).to.eql({
questStarted: false,
questFinished: false,
questInvited: false,
});
});
@@ -210,6 +212,7 @@ describe('Webhook Model', () => {
expect(wh.options).to.eql({
questStarted: false,
questFinished: true,
questInvited: true,
});
});
@@ -224,6 +227,7 @@ describe('Webhook Model', () => {
expect(wh.options).to.eql({
questStarted: true,
questFinished: true,
questInvited: true,
});
});

View File

@@ -66,7 +66,7 @@ describe('POST /members/send-private-message', () => {
})).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('notAuthorizedToSendMessageToThisUser'),
message: t('blockedToSendToThisUser'),
});
});

View File

@@ -89,7 +89,7 @@ describe('POST /members/transfer-gems', () => {
})).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('notAuthorizedToSendMessageToThisUser'),
message: t('blockedToSendToThisUser'),
});
});

View File

@@ -2,6 +2,7 @@ import { v4 as generateUUID } from 'uuid';
import {
createAndPopulateGroup,
translate as t,
server,
sleep,
} from '../../../../helpers/api-integration/v3';
import { quests as questScrolls } from '../../../../../website/common/script/content/quests';
@@ -210,5 +211,39 @@ describe('POST /groups/:groupId/quests/invite/:questKey', () => {
const returnedGroup = await groupLeader.get(`/groups/${group._id}`);
expect(returnedGroup.chat[0]._meta).to.be.undefined;
});
context('sending quest activity webhooks', () => {
before(async () => {
await server.start();
});
after(async () => {
await server.close();
});
it('sends quest invited webhook', async () => {
const uuid = generateUUID();
await member.post('/user/webhook', {
url: `http://localhost:${server.port}/webhooks/${uuid}`,
type: 'questActivity',
enabled: true,
options: {
questInvited: true,
},
});
await leader.post(`/groups/${questingGroup._id}/quests/invite/${PET_QUEST}`);
await sleep();
const body = server.getWebhookData(uuid);
expect(body.type).to.eql('questInvited');
expect(body.group.id).to.eql(questingGroup.id);
expect(body.group.name).to.eql(questingGroup.name);
expect(body.quest.key).to.eql(PET_QUEST);
});
});
});
});

View File

@@ -226,6 +226,69 @@ describe('POST /user/webhook', () => {
});
});
it('defaults questActivity options', async () => {
body.type = 'questActivity';
const webhook = await user.post('/user/webhook', body);
expect(webhook.options).to.eql({
questStarted: false,
questFinished: false,
questInvited: false,
});
});
it('can set questActivity options', async () => {
body.type = 'questActivity';
body.options = {
questStarted: true,
questFinished: true,
questInvited: true,
};
const webhook = await user.post('/user/webhook', body);
expect(webhook.options).to.eql({
questStarted: true,
questFinished: true,
questInvited: true,
});
});
it('discards extra properties in questActivity options', async () => {
body.type = 'questActivity';
body.options = {
questStarted: false,
questFinished: true,
questInvited: true,
foo: 'bar',
};
const webhook = await user.post('/user/webhook', body);
expect(webhook.options.foo).to.not.exist;
expect(webhook.options).to.eql({
questStarted: false,
questFinished: true,
questInvited: true,
});
});
['questStarted', 'questFinished', 'questInvited'].forEach(option => {
it(`requires questActivity option ${option} to be a boolean`, async () => {
body.type = 'questActivity';
body.options = {
[option]: 'not a boolean',
};
await expect(user.post('/user/webhook', body)).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: t('webhookBooleanOption', { option }),
});
});
});
it('discards extra properties in globalActivity options', async () => {
body.type = 'globalActivity';
body.options = {

View File

@@ -1,6 +1,37 @@
/* eslint-disable import/no-extraneous-dependencies */
import { configure } from '@storybook/vue';
import '../../src/assets/scss/index.scss';
import '../../src/assets/css/sprites.css';
import '../../src/assets/css/sprites/spritesmith-main-0.css';
import '../../src/assets/css/sprites/spritesmith-main-1.css';
import '../../src/assets/css/sprites/spritesmith-main-2.css';
import '../../src/assets/css/sprites/spritesmith-main-3.css';
import '../../src/assets/css/sprites/spritesmith-main-4.css';
import '../../src/assets/css/sprites/spritesmith-main-5.css';
import '../../src/assets/css/sprites/spritesmith-main-6.css';
import '../../src/assets/css/sprites/spritesmith-main-7.css';
import '../../src/assets/css/sprites/spritesmith-main-8.css';
import '../../src/assets/css/sprites/spritesmith-main-9.css';
import '../../src/assets/css/sprites/spritesmith-main-10.css';
import '../../src/assets/css/sprites/spritesmith-main-11.css';
import '../../src/assets/css/sprites/spritesmith-main-12.css';
import '../../src/assets/css/sprites/spritesmith-main-13.css';
import '../../src/assets/css/sprites/spritesmith-main-14.css';
import '../../src/assets/css/sprites/spritesmith-main-15.css';
import '../../src/assets/css/sprites/spritesmith-main-16.css';
import '../../src/assets/css/sprites/spritesmith-main-17.css';
import '../../src/assets/css/sprites/spritesmith-main-18.css';
import '../../src/assets/css/sprites/spritesmith-main-19.css';
import '../../src/assets/css/sprites/spritesmith-main-20.css';
import '../../src/assets/css/sprites/spritesmith-main-21.css';
import '../../src/assets/css/sprites/spritesmith-main-22.css';
import '../../src/assets/css/sprites/spritesmith-main-23.css';
import '../../src/assets/css/sprites/spritesmith-main-24.css';
import '../../src/assets/css/sprites/spritesmith-main-25.css';
import '../../src/assets/css/sprites/spritesmith-main-26.css';
import Vue from 'vue';
import StoreModule from '@/libs/store';
const req = require.context('../../src', true, /.stories.js$/);
@@ -8,4 +39,6 @@ function loadStories () {
req.keys().forEach(filename => req(filename));
}
Vue.use(StoreModule);
configure(loadStories, module);

View File

@@ -0,0 +1,75 @@
export const userStyles = {
contributor: {
admin: true,
level: 9,
text: '',
},
items: {
gear: {
equipped: {
armor: 'armor_special_2',
head: 'head_special_2',
shield: 'shield_special_goldenknight',
headAccessory: 'headAccessory_base_0',
eyewear: 'eyewear_base_0',
weapon: 'weapon_special_1',
back: 'back_base_0',
},
costume: {
armor: 'armor_special_fallRogue',
head: 'head_special_fallRogue',
shield: 'shield_armoire_shieldOfDiamonds',
body: 'body_mystery_201706',
eyewear: 'eyewear_special_blackHalfMoon',
back: 'back_base_0',
headAccessory: 'headAccessory_special_wolfEars',
weapon: 'weapon_armoire_lamplighter',
},
},
},
preferences: {
hair: {
color: 'black', base: 0, bangs: 3, beard: 0, mustache: 0, flower: 0,
},
tasks: { groupByChallenge: false, confirmScoreNotes: false },
size: 'broad',
skin: 'wolf',
shirt: 'zombie',
chair: 'none',
sleep: true,
disableClasses: false,
background: 'midnight_castle',
costume: true,
},
stats: {
buffs: {
str: 0,
int: 0,
per: 0,
con: 0,
stealth: 0,
streaks: false,
snowball: false,
spookySparkles: false,
shinySeed: false,
seafoam: false,
},
training: {
int: 0, per: 0, str: 0, con: 0,
},
hp: 50,
mp: 158,
exp: 227,
gp: 464.31937261345155,
lvl: 17,
class: 'rogue',
points: 17,
str: 0,
con: 0,
int: 0,
per: 0,
toNextLevel: 380,
maxHealth: 50,
maxMP: 158,
},
};

File diff suppressed because it is too large Load Diff

View File

@@ -18,34 +18,34 @@
"@vue/cli-plugin-router": "^4.1.2",
"@vue/cli-plugin-unit-mocha": "^4.1.2",
"@vue/cli-service": "^4.1.2",
"@storybook/addon-actions": "^5.0.0",
"@storybook/addon-knobs": "^5.0.0",
"@storybook/addon-links": "^5.0.0",
"@storybook/addon-notes": "^5.0.0",
"@storybook/vue": "^5.2.5",
"@storybook/addon-actions": "^5.3.1",
"@storybook/addon-knobs": "^5.3.1",
"@storybook/addon-links": "^5.3.1",
"@storybook/addon-notes": "^5.3.1",
"@storybook/vue": "^5.3.1",
"@vue/test-utils": "1.0.0-beta.29",
"amplitude-js": "^5.8.0",
"axios": "^0.19.0",
"axios": "^0.19.1",
"axios-progress-bar": "^1.2.0",
"babel-eslint": "^10.0.1",
"bootstrap": "^4.4.1",
"bootstrap-vue": "^2.1.0",
"bootstrap-vue": "^2.2.0",
"chai": "^4.1.2",
"core-js": "^3.6.1",
"core-js": "^3.6.3",
"eslint": "^6.8.0",
"eslint-config-habitrpg": "^6.2.0",
"eslint-plugin-mocha": "^5.3.0",
"eslint-plugin-vue": "^6.1.2",
"habitica-markdown": "^1.3.2",
"hellojs": "^1.18.1",
"hellojs": "^1.18.4",
"inspectpack": "^4.3.0",
"intro.js": "^2.9.3",
"jquery": "^3.4.1",
"lodash": "^4.17.15",
"moment": "^2.24.0",
"nconf": "^0.10.0",
"sass": "^1.24.2",
"sass-loader": "^8.0.0",
"sass": "^1.24.4",
"sass-loader": "^8.0.1",
"smartbanner.js": "^1.15.0",
"svg-inline-loader": "^0.8.0",
"svg-url-loader": "^3.0.3",
@@ -58,6 +58,7 @@
"vue-mugen-scroll": "^0.2.6",
"vue-router": "^3.0.6",
"vue-template-compiler": "^2.6.11",
"vue2-perfect-scrollbar": "^1.3.0",
"vuedraggable": "^2.23.1",
"vuejs-datepicker": "git://github.com/habitrpg/vuejs-datepicker.git#5d237615463a84a23dd6f3f77c6ab577d68593ec",
"webpack": "^4.41.5"

View File

@@ -28,7 +28,10 @@
</div>
<div
id="app"
:class="{'casting-spell': castingSpell}"
:class="{
'casting-spell': castingSpell,
'resting': showRestingBanner
}"
>
<banned-account-modal />
<amazon-payments-modal v-if="!isStaticPage" />
@@ -66,7 +69,10 @@
</div>
<notifications-display />
<app-menu />
<div class="container-fluid">
<div
class="container-fluid"
:class="{'no-margin': noMargin}"
>
<app-header />
<buyModal
:item="selectedItemToBuy || {}"
@@ -83,7 +89,7 @@
<router-view />
</div>
</div>
<app-footer />
<app-footer v-if="!hideFooter" />
<audio
id="sound"
ref="sound"
@@ -97,13 +103,20 @@
<style lang='scss' scoped>
@import '~@/assets/scss/colors.scss';
@import '~@/assets/scss/variables.scss';
#app {
height: calc(100% - 56px); /* 56px is the menu */
display: flex;
flex-direction: column;
min-height: 100vh;
overflow-x: hidden;
&.resting {
--banner-resting-height: #{$restingToolbarHeight};
}
&.giftingBanner {
--banner-gifting-height: 2.5rem;
}
}
#loading-screen-inapp {
@@ -148,6 +161,13 @@
flex: 1 0 auto;
}
.no-margin {
margin-left: 0;
margin-right: 0;
padding-left: 0;
padding-right: 0;
}
.notification {
border-radius: 1000px;
background-color: $green-10;
@@ -160,7 +180,7 @@
.resting-banner {
width: 100%;
min-height: 40px;
height: $restingToolbarHeight;
background-color: $blue-10;
top: 0;
z-index: 1300;
@@ -302,7 +322,13 @@ export default {
return this.$t(`tip${tipNumber}`);
},
showRestingBanner () {
return !this.bannerHidden && this.user.preferences.sleep;
return !this.bannerHidden && this.user && this.user.preferences.sleep;
},
noMargin () {
return ['privateMessages'].includes(this.$route.name);
},
hideFooter () {
return ['privateMessages'].includes(this.$route.name);
},
},
created () {

View File

@@ -1,18 +1,18 @@
.promo_armoire_backgrounds_202001 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -175px;
background-position: -424px -175px;
width: 423px;
height: 147px;
}
.promo_g1g1_2019 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -471px;
background-position: -403px -471px;
width: 357px;
height: 144px;
}
.promo_mystery_202001 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -241px -616px;
background-position: -241px -619px;
width: 279px;
height: 147px;
}
@@ -24,25 +24,25 @@
}
.promo_take_this {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -358px -471px;
background-position: -761px -471px;
width: 96px;
height: 69px;
}
.promo_winter_potions_2020 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -424px -175px;
background-position: 0px -323px;
width: 423px;
height: 147px;
}
.promo_winter_quests_bundle {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -323px;
background-position: 0px -175px;
width: 423px;
height: 147px;
}
.promo_winter_wonderland_2019 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -424px -323px;
background-position: 0px -471px;
width: 402px;
height: 147px;
}
@@ -52,9 +52,27 @@
width: 468px;
height: 147px;
}
.promo_wintery_hair {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -521px -619px;
width: 152px;
height: 75px;
}
.promo_wintery_skins {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -424px -323px;
width: 420px;
height: 147px;
}
.customize-option.promo_wintery_skins {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -449px -338px;
width: 60px;
height: 60px;
}
.scene_list {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -616px;
background-position: 0px -619px;
width: 240px;
height: 195px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 92 KiB

View File

@@ -7,3 +7,6 @@ $npc_quests_flavor: 'nye';
$npc_seasonal_flavor: 'nye';
$npc_timetravelers_flavor: 'winter';
$npc_tavern_flavor: 'nye';
$restingToolbarHeight: 40px;
$menuToolbarHeight: 56px;

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="#A5A1AC" fill-rule="evenodd" d="M15.7 14.3l-4.8-4.8c.7-1 1.1-2.2 1.1-3.5 0-3.3-2.7-6-6-6S0 2.7 0 6s2.7 6 6 6c1.3 0 2.5-.4 3.5-1.1l4.8 4.8c.4.4 1 .4 1.4 0 .4-.4.4-1 0-1.4zM6 10c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4z"/>
</svg>

After

Width:  |  Height:  |  Size: 334 B

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="24" viewBox="0 0 32 24">
<g fill="none" fill-rule="evenodd">
<path fill="#9A62FF" d="M28 0H4C1.79 0 0 1.79 0 4v16c0 2.21 1.79 4 4 4h24c2.21 0 4-1.79 4-4V4c0-2.21-1.79-4-4-4z"/>
<path fill="#BDA8FF" d="M28 20H4V4l12 10L28 4z"/>
<path fill="#D5C8FF" d="M28 20H4V7l12 10L28 7z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 380 B

View File

@@ -1,5 +1,21 @@
<template>
<div class="form-wrapper">
<div
v-if="forgotPassword && preOutage"
class="warning-banner d-flex"
>
<div class="warning-box ml-auto my-auto mr-2 d-flex">
<div
class="svg-icon exclamation m-auto"
v-html="icons.exclamation"
>
</div>
</div>
<div class="mr-auto my-auto">
Habitica emails will be temporarily unavailable on <strong>January 11, 2020</strong> from
<strong>1:00 - 7:00 AM EST</strong>.
</div>
</div>
<div id="top-background">
<div class="seamless_stars_varied_opacity_repeat"></div>
</div>
@@ -546,15 +562,36 @@
font-size: 90%;
width: 100%;
}
.warning-banner {
color: $white;
background-color: $maroon-100;
height: 2.5rem;
width: 100%;
}
.warning-box {
font-weight: bold;
width: 1rem;
height: 1rem;
border: 2px solid;
border-radius: 2px;
}
.exclamation {
width: 2px;
}
</style>
<script>
import axios from 'axios';
import hello from 'hellojs';
import moment from 'moment';
import debounce from 'lodash/debounce';
import isEmail from 'validator/lib/isEmail';
import { MINIMUM_PASSWORD_LENGTH } from '@/../../common/script/constants';
import exclamation from '@/assets/svg/exclamation.svg';
import gryphon from '@/assets/svg/gryphon.svg';
import habiticaIcon from '@/assets/svg/habitica-logo.svg';
import facebookSquareIcon from '@/assets/svg/facebook-square.svg';
@@ -576,6 +613,7 @@ export default {
};
data.icons = Object.freeze({
exclamation,
gryphon,
habiticaIcon,
facebookIcon: facebookSquareIcon,
@@ -635,6 +673,9 @@ export default {
|| this.passwordInvalid
|| this.passwordConfirmInvalid;
},
preOutage () {
return moment.utc().isBefore('2020-01-12');
},
},
watch: {
$route: {

View File

@@ -101,7 +101,7 @@
</div>
</div>
<div
v-if="showCategorySelect && creating"
v-if="showCategorySelect"
class="category-box"
>
<!-- eslint-disable vue/no-use-v-if-with-v-for -->

View File

@@ -5,7 +5,7 @@
class="mentioned-icon"
></div>
<div
v-if="!inbox && user.contributor.admin && msg.flagCount"
v-if="user.contributor.admin && msg.flagCount"
class="message-hidden"
>
{{ flagCountDescription }}
@@ -27,8 +27,7 @@
class="mr-1"
></span>
<span
v-b-tooltip
:title="msg.timestamp | date"
v-b-tooltip.hover="messageDate"
>{{ msg.timestamp | timeAgo }}&nbsp;</span>
<span v-if="msg.client && user.contributor.level >= 4">({{ msg.client }})</span>
</p>
@@ -37,21 +36,12 @@
class="text"
v-html="atHighlight(parseMarkdown(msg.text))"
></div>
<div
v-if="isMessageReported && (inbox === true)"
class="reported"
>
<span v-once>{{ $t('reportedMessage') }}</span>
<br>
<span v-once>{{ $t('canDeleteNow') }}</span>
</div>
<hr>
<div
v-if="msg.id"
class="d-flex"
>
<div
v-if="!inbox"
class="action d-flex align-items-center"
@click="copyAsTodo(msg)"
>
@@ -62,7 +52,7 @@
<div>{{ $t('copyAsTodo') }}</div>
</div>
<div
v-if="(inbox || (user.flags.communityGuidelinesAccepted && msg.uuid !== 'system'))
v-if="(user.flags.communityGuidelinesAccepted && msg.uuid !== 'system')
&& (!isMessageReported || user.contributor.admin)"
class="action d-flex align-items-center"
@click="report(msg)"
@@ -77,7 +67,7 @@
</div>
</div>
<div
v-if="msg.uuid === user._id || inbox || user.contributor.admin"
v-if="msg.uuid === user._id || user.contributor.admin"
class="action d-flex align-items-center"
@click="remove()"
>
@@ -91,7 +81,6 @@
</div>
</div>
<div
v-if="!inbox"
v-b-tooltip="{title: likeTooltip(msg.likes[user._id])}"
class="ml-auto d-flex"
>
@@ -121,7 +110,7 @@
></div>
</div>
</div>
<span v-if="!msg.likes[user._id] && !inbox">{{ $t('like') }}</span>
<span v-if="!msg.likes[user._id]">{{ $t('like') }}</span>
</div>
</div>
</div>
@@ -205,15 +194,9 @@
color: $purple-400;
}
}
.reported {
margin-top: 18px;
color: $red-50;
}
</style>
<script>
import axios from 'axios';
import moment from 'moment';
import cloneDeep from 'lodash/cloneDeep';
import escapeRegExp from 'lodash/escapeRegExp';
@@ -244,10 +227,6 @@ export default {
},
props: {
msg: {},
inbox: {
type: Boolean,
default: false,
},
groupId: {},
},
data () {
@@ -311,6 +290,10 @@ export default {
if (this.msg.flagCount < CHAT_FLAG_FROM_SHADOW_MUTE) return 'Message hidden';
return 'Message hidden (shadow-muted)';
},
messageDate () {
const date = moment(this.msg.timestamp).toDate();
return date.toString();
},
},
mounted () {
const links = this.$refs.markdownContainer.getElementsByTagName('a');
@@ -372,11 +355,6 @@ export default {
const message = this.msg;
this.$emit('message-removed', message);
if (this.inbox) {
await axios.delete(`/api/v4/inbox/messages/${message.id}`);
return;
}
await this.$store.dispatch('chat:deleteChat', {
groupId: this.groupId,
chatId: message.id,

View File

@@ -35,13 +35,11 @@
v-for="msg in messages"
v-if="chat && canViewFlag(msg)"
:key="msg.id"
:class="{row: inbox}"
>
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
<div
v-if="user._id !== msg.uuid"
class="d-flex"
:class="{'flex-grow-1': inbox}"
>
<avatar
v-if="msg.userStyles
@@ -51,16 +49,13 @@
:avatar-only="true"
:override-top-padding="'14px'"
:hide-class-badge="true"
:class="{'inbox-avatar-left': inbox}"
@click.native="showMemberModal(msg.uuid)"
/>
<div
class="card"
:class="{'col-10': inbox}"
>
<chat-card
:msg="msg"
:inbox="inbox"
:group-id="groupId"
@message-liked="messageLiked"
@message-removed="messageRemoved"
@@ -72,15 +67,12 @@
<div
v-if="user._id === msg.uuid"
class="d-flex"
:class="{'flex-grow-1': inbox}"
>
<div
class="card"
:class="{'col-10': inbox}"
>
<chat-card
:msg="msg"
:inbox="inbox"
:group-id="groupId"
@message-liked="messageLiked"
@message-removed="messageRemoved"
@@ -95,7 +87,6 @@
:avatar-only="true"
:hide-class-badge="true"
:override-top-padding="'14px'"
:class="{'inbox-avatar-right': inbox}"
@click.native="showMemberModal(msg.uuid)"
/>
</div>
@@ -144,16 +135,6 @@
margin-right: 2rem;
}
.inbox-avatar-left {
margin-left: -1rem;
margin-right: 2.5rem;
min-width: 5rem;
}
.inbox-avatar-right {
margin-left: -3.5rem;
}
.hr {
width: 100%;
height: 20px;
@@ -209,10 +190,6 @@ export default {
},
props: {
chat: {},
inbox: {
type: Boolean,
default: false,
},
groupType: {},
groupId: {},
groupName: {},
@@ -260,12 +237,6 @@ export default {
this.lastOffset = container.scrollTop - (container.scrollHeight - container.clientHeight);
// disable scroll
container.style.overflowY = 'hidden';
const canLoadMore = this.inbox && !this.isLoading && this.canLoadMore;
if (canLoadMore) {
await this.$emit('triggerLoad');
this.handleScrollBack = true;
}
},
canViewFlag (message) {
if (message.uuid === this.user._id) return true;
@@ -380,11 +351,6 @@ export default {
this.chat.splice(chatIndex, 1, message);
},
messageRemoved (message) {
if (this.inbox) {
this.$emit('message-removed', message);
return;
}
const chatIndex = findIndex(this.chat, chatMessage => chatMessage.id === message.id);
this.chat.splice(chatIndex, 1);
},

View File

@@ -23,7 +23,7 @@
</div>
<div class="footer text-center">
<button
v-if="user.contributor.admin && abuseObject.flagCount > 0"
v-if="user.contributor.admin"
class="pull-left btn btn-danger"
@click="clearFlagCount()"
>

View File

@@ -0,0 +1,47 @@
/* eslint-disable import/no-extraneous-dependencies */
import { storiesOf } from '@storybook/vue';
import FaceAvatar from './faceAvatar.vue';
import Avatar from './avatar.vue';
import { userStyles } from '../../config/storybook/mock.data';
import content from '../../../common/script/content/index';
import getters from '@/store/getters';
storiesOf('Face Avatar', module)
.add('simple', () => ({
components: { FaceAvatar },
template: `
<div style="position: absolute; margin: 20px">
<face-avatar :member="user"></face-avatar>
</div>
`,
data () {
return {
user: userStyles,
};
},
}))
.add('compare', () => ({
components: { FaceAvatar, Avatar },
template: `
<div style="position: absolute; margin: 20px">
<face-avatar :member="user"></face-avatar>
<avatar :member="user"></avatar>
</div>
`,
data () {
return {
user: userStyles,
};
},
state: {
content,
},
store: {
getters,
state: {
content,
},
},
}));

View File

@@ -0,0 +1,154 @@
<template>
<div
class="face-avatar"
:style="{width, height}"
>
<div class="character-sprites">
<!-- Buffs that cause visual changes to avatar: Snowman, Ghost, Flower, etc-->
<template v-for="(klass, item) in visualBuffs">
<span
v-if="member.stats.buffs[item] && showVisualBuffs"
:key="klass"
:class="klass"
></span>
</template>
<!-- Show flower ALL THE TIME!!!-->
<!-- See https://github.com/HabitRPG/habitica/issues/7133-->
<span :class="'hair_flower_' + member.preferences.hair.flower"></span>
<!-- Show avatar only if not currently affected by visual buff-->
<template v-if="showAvatar()">
<span :class="[skinClass]"></span><span :class="['head_0']"></span>
<template v-for="type in ['bangs', 'base', 'mustache', 'beard']">
<span
:key="type"
:class="[getHairClass(type)]"
></span>
</template>
<span :class="[getGearClass('body')]"></span>
<span :class="[getGearClass('eyewear')]"></span>
<span :class="[getGearClass('head')]"></span>
<span :class="[getGearClass('headAccessory')]"></span>
<span :class="['hair_flower_' + member.preferences.hair.flower]"></span>
</template>
<!-- Resting--><span
v-if="member.preferences.sleep"
class="zzz"
></span>
</div>
</div>
</template>
<style lang="scss" scoped>
@import '~@/assets/scss/colors.scss';
.face-avatar {
width: 36px;
height: 36px;
border: solid 2px currentColor;
border-radius: 18px;
image-rendering: pixelated;
position: relative;
overflow: hidden;
}
.character-sprites {
width: 90px;
height: 90px;
margin: -25px -41px;
}
.character-sprites span {
position: absolute;
}
</style>
<script>
import { mapState } from '@/libs/store';
export default {
components: {
},
props: {
member: {
type: Object,
required: true,
},
avatarOnly: {
type: Boolean,
default: false,
},
hideClassBadge: {
type: Boolean,
default: false,
},
withBackground: {
type: Boolean,
},
overrideAvatarGear: {
type: Object,
},
width: {
type: Number,
default: 140,
},
height: {
type: Number,
default: 147,
},
showVisualBuffs: {
type: Boolean,
default: true,
},
},
computed: {
...mapState({
flatGear: 'content.gear.flat',
}),
hasClass () {
return this.$store.getters['members:hasClass'](this.member);
},
isBuffed () {
return this.$store.getters['members:isBuffed'](this.member);
},
visualBuffs () {
return {
snowball: 'snowman',
spookySparkles: 'ghost',
shinySeed: `avatar_floral_${this.member.stats.class}`,
seafoam: 'seafoam_star',
};
},
skinClass () {
const baseClass = `skin_${this.member.preferences.skin}`;
return `${baseClass}${this.member.preferences.sleep ? '_sleep' : ''}`;
},
costumeClass () {
return this.member.preferences.costume ? 'costume' : 'equipped';
},
},
methods: {
getGearClass (gearType) {
let result = this.member.items.gear[this.costumeClass][gearType];
if (this.overrideAvatarGear && this.overrideAvatarGear[gearType]) {
result = this.overrideAvatarGear[gearType];
}
return result;
},
showAvatar () {
if (!this.showVisualBuffs) return true;
const { buffs } = this.member.stats;
return !buffs.snowball && !buffs.spookySparkles && !buffs.shinySeed && !buffs.seafoam;
},
getHairClass (type) {
const hairPref = this.member.preferences.hair;
return `hair_${type}_${hairPref[type]}_${hairPref.color}`;
},
},
};
</script>

View File

@@ -536,13 +536,12 @@ export default {
},
methods: {
sendMessage (member) {
this.$root.$emit('habitica::new-inbox-message', {
userIdToMessage: member._id,
displayName: member.profile.name,
username: member.auth.local.username,
backer: member.backer,
contributor: member.contributor,
this.$store.dispatch('user:newPrivateMessageTo', {
member,
});
this.$root.$emit('bv::hide::modal', 'members-modal');
this.$router.push('/private-messages');
},
async searchMembers (searchTerm = '') {
this.members = await this.$store.state.memberModalOptions.fetchMoreMembers({

View File

@@ -8,7 +8,7 @@
<div
id="app-header"
class="row"
:class="{'hide-header': $route.name === 'groupPlan'}"
:class="{'hide-header': hideHeader}"
>
<members-modal :hide-badge="true" />
<member-details
@@ -171,6 +171,9 @@ export default {
sortedPartyMembers () {
return orderBy(this.partyMembers, [this.user.party.order], [this.user.party.orderAscending]);
},
hideHeader () {
return ['groupPlan', 'privateMessages'].includes(this.$route.name);
},
},
created () {
if (this.user.party && this.user.party._id) {

View File

@@ -1,6 +1,5 @@
<template>
<div>
<inbox-modal />
<creator-intro />
<profileModal />
<report-flag-modal />
@@ -408,6 +407,7 @@
<style lang="scss" scoped>
@import '~@/assets/scss/colors.scss';
@import '~@/assets/scss/utils.scss';
@import '~@/assets/scss/variables.scss';
@media only screen and (max-width: 1200px) {
.chevron {
@@ -438,7 +438,7 @@
}
.topbar {
max-height: 56px;
max-height: $menuToolbarHeight;
.currency-tray {
margin-left: auto;
@@ -721,7 +721,6 @@ import chevronDownIcon from '@/assets/svg/chevron-down.svg';
import logo from '@/assets/svg/logo.svg';
import creatorIntro from '../creatorIntro';
import InboxModal from '../userMenu/inbox.vue';
import notificationMenu from './notificationsDropdown';
import profileModal from '../userMenu/profileModal';
import reportFlagModal from '../chat/reportFlagModal';
@@ -733,7 +732,6 @@ import userDropdown from './userDropdown';
export default {
components: {
creatorIntro,
InboxModal,
notificationMenu,
profileModal,
reportFlagModal,

View File

@@ -3,7 +3,7 @@
:can-remove="canRemove"
:has-icon="true"
:notification="notification"
:read-after-click="true"
:read-after-click="false"
@click="action"
>
<div

View File

@@ -25,7 +25,7 @@ export default {
props: ['notification', 'canRemove'],
methods: {
action () {
this.$root.$emit('bv::show::modal', 'inbox-modal');
this.$router.push('/private-messages');
},
},
};

View File

@@ -139,7 +139,7 @@ import GROUP_TASK_CLAIMED from './notifications/groupTaskClaimed';
import UNALLOCATED_STATS_POINTS from './notifications/unallocatedStatsPoints';
import NEW_MYSTERY_ITEMS from './notifications/newMysteryItems';
import CARD_RECEIVED from './notifications/cardReceived';
import NEW_INBOX_MESSAGE from './notifications/newInboxMessage';
import NEW_INBOX_MESSAGE from './notifications/newPrivateMessage';
import NEW_CHAT_MESSAGE from './notifications/newChatMessage';
import WORLD_BOSS from './notifications/worldBoss';
import VERIFY_USERNAME from './notifications/verifyUsername';

View File

@@ -33,7 +33,7 @@
<a
class="nav-link dropdown-item
dropdown-separated d-flex justify-content-between align-items-center"
@click.prevent="showInbox()"
@click.prevent="showPrivateMessages()"
>
<div>{{ $t('messages') }}</div>
<message-count
@@ -43,7 +43,7 @@
</a>
<a
class="dropdown-item"
@click="showAvatar('backgrounds', '2019')"
@click="showAvatar('backgrounds', '2020')"
>{{ $t('backgrounds') }}</a>
<a
class="dropdown-item"
@@ -163,10 +163,15 @@ export default {
this.$store.state.avatarEditorOptions.subpage = subpage;
this.$root.$emit('bv::show::modal', 'avatar-modal');
},
showInbox () {
showPrivateMessages () {
markPMSRead(this.user);
axios.post('/api/v4/user/mark-pms-read');
this.$root.$emit('bv::show::modal', 'inbox-modal');
if (this.$router.history.current.name === 'privateMessages') {
this.$root.$emit('pm::refresh');
} else {
this.$router.push('/private-messages');
}
},
showProfile (startingPage) {
this.$router.push({ name: startingPage });

View File

@@ -0,0 +1,235 @@
<template>
<div
class="conversation"
:class="{active: activeKey === uuid}"
@click="$emit('click', {})"
@mouseleave="hideDropDown()"
>
<div class="user">
<user-label
:backer="backer"
:contributor="contributor"
:name="displayName"
/><span
v-if="username"
class="username"
>@{{ username }}</span>
<div
v-if="lastMessageDate"
class="time"
>
{{ lastMessageDate | timeAgo }}
</div>
</div>
<div class="preview-row">
<div class="messagePreview">
{{ lastMessageText }}
</div>
<div
v-if="userLoggedIn.id !== uuid"
class="actions"
>
<b-dropdown
ref="dropdown"
class="action-dropdown"
right
toggle-class="btn-flat action-padding"
no-caret
variant="link"
size="lg"
>
<template slot="button-content">
<div
class="svg-icon inline dots"
v-html="icons.dots"
></div>
</template>
<b-dropdown-item @click="block()">
<span class="dropdown-icon-item">
<div
class="svg-icon inline"
v-html="icons.remove"
></div><span class="text">{{ $t('block') }}</span></span>
</b-dropdown-item>
</b-dropdown>
</div>
</div>
</div>
</template>
<script>
import moment from 'moment';
import userLabel from '../userLabel';
import dots from '@/assets/svg/dots.svg';
import remove from '@/assets/svg/remove.svg';
import { mapState } from '@/libs/store';
export default {
components: {
userLabel,
},
props: [
'activeKey', 'uuid', 'backer', 'displayName',
'username', 'contributor', 'lastMessageText',
'lastMessageDate',
],
computed: {
...mapState({
userLoggedIn: 'user.data',
}),
},
data () {
return {
icons: Object.freeze({
dots,
remove,
}),
};
},
filters: {
timeAgo (value) {
return moment(value).fromNow();
},
},
methods: {
hideDropDown () {
const { dropdown } = this.$refs;
if (dropdown) {
dropdown.hide();
}
},
block () {
this.$store.dispatch('user:block', {
uuid: this.uuid,
});
},
},
};
</script>
<style lang="scss">
@import '~@/assets/scss/colors.scss';
.action-padding {
height: 24px !important;
width: 24px;
padding: 0 !important;
}
.action-dropdown {
.dropdown-item {
padding: 12px 16px;
.svg-icon {
width: 16px;
height: 16px;
}
}
.dots {
height: 16px;
width: 4px;
svg path {
fill: $purple-300
}
}
}
</style>
<style lang="scss" scoped>
@import '~@/assets/scss/colors.scss';
.conversation {
padding: 1.5rem;
border-bottom: 1px solid $gray-500;
&:hover {
cursor: pointer;
background: #EEE;
.actions {
display: block;
}
}
&.active {
background-color: #f1edff;
}
.user {
display: flex;
flex-direction: row;
height: 20px;
.user-label {
flex: 1;
flex-grow: 0;
margin-right: 0.5rem;
white-space: nowrap;
}
.username {
flex: 1;
flex-grow: 0;
}
.time {
flex: 2;
text-align: end;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-left: 1rem;
}
}
.messagePreview {
//width: 100%;
height: 30px;
margin-right: 40px;
margin-top: 4px;
font-size: 12px;
font-weight: normal;
font-style: normal;
font-stretch: normal;
line-height: 1.33;
letter-spacing: normal;
color: $gray-100;
overflow: hidden;
// text-overflow: ellipsis;
}
}
.preview-row {
display: flex;
flex-direction: row;
position: relative;
.messagePreview {
flex: 1;
width: calc(100% - 16px);
}
}
.actions {
position: absolute;
right: 0;
display: none;
width: 16px;
margin-top: 4px;
.dots {
height: 16px;
width: 4px;
}
.action-icon {
margin-right: 1em;
}
}
</style>

View File

@@ -0,0 +1,216 @@
<template>
<div class="card-body">
<user-link
:user-id="msg.uuid"
:name="msg.user"
:backer="msg.backer"
:contributor="msg.contributor"
/>
<p class="time">
<span
v-if="msg.username"
class="mr-1"
>@{{ msg.username }}</span><span
v-if="msg.username"
class="mr-1"
></span>
<span
v-b-tooltip.hover="messageDate"
>{{ msg.timestamp | timeAgo }}&nbsp;</span>
<span v-if="msg.client && user.contributor.level >= 4"> ({{ msg.client }})</span>
</p>
<div
class="text"
v-html="atHighlight(parseMarkdown(msg.text))"
></div>
<div
v-if="isMessageReported"
class="reported"
>
<span v-once>{{ $t('reportedMessage') }}</span><br>
<span v-once>{{ $t('canDeleteNow') }}</span>
</div>
<hr>
<div
v-if="msg.id"
class="d-flex"
>
<div
v-if="!isMessageReported"
class="action d-flex align-items-center"
@click="report(msg)"
>
<div
v-once
class="svg-icon"
v-html="icons.report"
></div>
<div v-once>
{{ $t('report') }}
</div>
</div>
<div
class="action d-flex align-items-center"
@click="remove()"
>
<div
v-once
class="svg-icon"
v-html="icons.delete"
></div>
<div v-once>
{{ $t('delete') }}
</div>
</div>
</div>
</div>
</template>
<style lang="scss">
.at-highlight {
background-color: rgba(213, 200, 255, 0.32);
padding: 0.1rem;
}
.at-text {
color: #6133b4;
}
</style>
<style lang="scss" scoped>
@import '~@/assets/scss/colors.scss';
@import '~@/assets/scss/tiers.scss';
.action {
display: inline-block;
color: $gray-200;
margin-right: 1em;
font-size: 12px;
:hover {
cursor: pointer;
}
.svg-icon {
color: $gray-300;
margin-right: .2em;
width: 16px;
}
}
.active {
color: $purple-300;
.svg-icon {
color: $purple-400;
}
}
.card-body {
padding: 0.75rem 1.25rem 0.75rem 1.25rem;
.time {
font-size: 12px;
color: $gray-200;
margin-bottom: 0.5rem;
}
.text {
font-size: 14px;
color: $gray-50;
text-align: left !important;
min-height: 0rem;
margin-bottom: -0.5rem;
}
}
hr {
margin-bottom: 0.5rem;
margin-top: 0.5rem;
}
.reported {
margin-top: 18px;
color: $red-50;
}
</style>
<script>
import axios from 'axios';
import moment from 'moment';
import habiticaMarkdown from 'habitica-markdown';
import { mapState } from '@/libs/store';
import userLink from '../userLink';
import deleteIcon from '@/assets/svg/delete.svg';
import reportIcon from '@/assets/svg/report.svg';
import { highlightUsers } from '../../libs/highlightUsers';
export default {
components: {
userLink,
},
filters: {
timeAgo (value) {
return moment(value).fromNow();
},
},
props: {
msg: {},
},
data () {
return {
icons: Object.freeze({
delete: deleteIcon,
report: reportIcon,
}),
reported: false,
};
},
computed: {
...mapState({ user: 'user.data' }),
isMessageReported () {
return (this.msg.flags && this.msg.flags[this.user.id]) || this.reported;
},
messageDate () {
const date = moment(this.msg.timestamp).toDate();
return date.toString();
},
},
mounted () {
this.$emit('message-card-mounted');
},
methods: {
report () {
this.$root.$on('habitica:report-result', data => {
if (data.ok) {
this.reported = true;
}
this.$root.$off('habitica:report-result');
});
this.$root.$emit('habitica::report-chat', {
message: this.msg,
groupId: 'privateMessage',
});
},
async remove () {
if (!window.confirm(this.$t('areYouSureDeleteMessage'))) return;
const message = this.msg;
this.$emit('message-removed', message);
await axios.delete(`/api/v4/inbox/messages/${message.id}`);
},
atHighlight (text) {
return highlightUsers(text, this.user.auth.local.username, this.user.profile.name);
},
parseMarkdown (text) {
if (!text) return null;
return habiticaMarkdown.render(String(text));
},
},
};
</script>

View File

@@ -0,0 +1,400 @@
<template>
<perfect-scrollbar
ref="container"
class="container-fluid"
:class="{'disable-perfect-scroll': disablePerfectScroll}"
:options="psOptions"
>
<div class="row loadmore">
<div v-if="canLoadMore && !isLoading">
<div class="loadmore-divider"></div>
<button
class="btn btn-secondary"
@click="triggerLoad()"
>
{{ $t('loadEarlierMessages') }}
</button>
<div class="loadmore-divider"></div>
</div>
<h2
v-show="isLoading"
class="col-12 loading"
>
{{ $t('loading') }}
</h2>
</div>
<div
v-for="(msg) in messages"
:key="msg.id"
class="row message-row"
:class="{ 'margin-right': user._id !== msg.uuid}"
>
<div
v-if="user._id !== msg.uuid"
class="d-flex flex-grow-1"
>
<avatar
v-if="msg.userStyles || (cachedProfileData[msg.uuid]
&& !cachedProfileData[msg.uuid].rejected)"
class="avatar-left"
:member="msg.userStyles || cachedProfileData[msg.uuid]"
:avatar-only="true"
:override-top-padding="'14px'"
:hide-class-badge="true"
@click.native="showMemberModal(msg.uuid)"
/>
<div class="card card-right">
<message-card
:msg="msg"
@message-removed="messageRemoved"
@show-member-modal="showMemberModal"
@message-card-mounted="itemWasMounted"
/>
</div>
</div>
<div
v-if="user._id === msg.uuid"
class="d-flex flex-grow-1"
>
<div class="card card-left">
<message-card
:msg="msg"
@message-removed="messageRemoved"
@show-member-modal="showMemberModal"
@message-card-mounted="itemWasMounted"
/>
</div>
<avatar
v-if="msg.userStyles
|| (cachedProfileData[msg.uuid] && !cachedProfileData[msg.uuid].rejected)"
class="avatar-right"
:member="msg.userStyles || cachedProfileData[msg.uuid]"
:avatar-only="true"
:hide-class-badge="true"
:override-top-padding="'14px'"
@click.native="showMemberModal(msg.uuid)"
/>
</div>
</div>
</perfect-scrollbar>
</template>
<style lang="scss" scoped>
@import '~@/assets/scss/colors.scss';
@import '~vue2-perfect-scrollbar/dist/vue2-perfect-scrollbar.css';
.disable-perfect-scroll {
overflow-y: inherit !important;
}
.avatar {
width: 15%;
min-width: 8rem;
height: 120px;
padding-top: 0 !important;
}
.avatar-left {
margin-left: -1rem;
}
.avatar-right {
margin-left: -1rem;
}
.card {
border: 0px;
margin-bottom: 1rem;
padding: 0rem;
width: 684px;
}
.message-row {
margin-left: 12px;
margin-right: 12px;
&:not(.margin-right) {
.d-flex {
justify-content: flex-end;
}
}
}
@media only screen and (max-width: 1200px) {
.card {
width: 100%;
}
}
@media only screen and (min-width: 1400px) {
.message-row {
margin-left: -15px;
margin-right: -30px;
}
}
.card-left {
border: 1px solid $purple-500;
}
.card-right {
border: 1px solid $gray-500;
}
.hr {
width: 100%;
height: 20px;
border-bottom: 1px solid $gray-500;
text-align: center;
margin: 2em 0;
}
.hr-middle {
font-size: 16px;
font-weight: bold;
font-family: 'Roboto Condensed';
line-height: 1.5;
text-align: center;
color: $gray-200;
background-color: $gray-700;
padding: .2em;
margin-top: .2em;
display: inline-block;
width: 100px;
}
.loadmore {
justify-content: center;
margin-right: 12px;
> div {
display: flex;
width: 100%;
align-items: center;
button {
text-align: center;
color: $gray-50;
margin-top: 12px;
margin-bottom: 24px;
}
}
}
.loadmore-divider {
height: 1px;
background-color: $gray-500;
flex: 1;
margin-left: 24px;
margin-right: 24px;
&:last-of-type {
margin-right: 0;
}
}
.loading {
padding-left: 1.5rem;
margin-bottom: 1rem;
}
</style>
<script>
import moment from 'moment';
import axios from 'axios';
import debounce from 'lodash/debounce';
import { PerfectScrollbar } from 'vue2-perfect-scrollbar';
import { mapState } from '@/libs/store';
import Avatar from '../avatar';
import messageCard from './messageCard';
export default {
components: {
Avatar,
messageCard,
PerfectScrollbar,
},
props: {
chat: {},
isLoading: Boolean,
canLoadMore: Boolean,
},
data () {
return {
currentDayDividerDisplay: moment().day(),
cachedProfileData: {},
currentProfileLoadedCount: 0,
currentProfileLoadedEnd: 10,
loading: false,
handleScrollBack: false,
lastOffset: -1,
disablePerfectScroll: false,
};
},
mounted () {
this.loadProfileCache();
this.$el.addEventListener('selectstart', () => this.handleSelectStart());
this.$el.addEventListener('mouseup', () => this.handleSelectChange());
},
created () {
window.addEventListener('scroll', this.handleScroll);
},
beforeDestroy () {
this.$el.removeEventListener('selectstart', () => this.handleSelectStart());
this.$el.removeEventListener('mouseup', () => this.handleSelectChange());
},
destroyed () {
window.removeEventListener('scroll', this.handleScroll);
},
computed: {
...mapState({ user: 'user.data' }),
// @TODO: We need a different lazy load mechnism.
// But honestly, adding a paging route to chat would solve this
messages () {
this.loadProfileCache();
return this.chat;
},
psOptions () {
return {
suppressScrollX: true,
};
},
},
methods: {
handleScroll () {
this.loadProfileCache(window.scrollY / 1000);
},
async triggerLoad () {
const container = this.$refs.container.$el;
// get current offset
this.lastOffset = container.scrollTop - (container.scrollHeight - container.clientHeight);
// disable scroll
// container.style.overflowY = 'hidden';
const canLoadMore = !this.isLoading && this.canLoadMore;
if (canLoadMore) {
const triggerLoadResult = this.$emit('triggerLoad');
await triggerLoadResult;
this.handleScrollBack = true;
}
},
loadProfileCache: debounce(function loadProfileCache (screenPosition) {
this._loadProfileCache(screenPosition);
}, 1000),
async _loadProfileCache (screenPosition) {
if (this.loading) return;
this.loading = true;
const promises = [];
const noProfilesLoaded = Object.keys(this.cachedProfileData).length === 0;
// @TODO: write an explination
// @TODO: Remove this after enough messages are cached
if (!noProfilesLoaded && screenPosition
&& Math.floor(screenPosition) + 1 > this.currentProfileLoadedEnd / 10) {
this.currentProfileLoadedEnd = 10 * (Math.floor(screenPosition) + 1);
} else if (!noProfilesLoaded && screenPosition) {
return;
}
const aboutToCache = {};
this.messages.forEach(message => {
const { uuid } = message;
if (message.userStyles) {
this.$set(this.cachedProfileData, uuid, message.userStyles);
}
if (Boolean(uuid) && !this.cachedProfileData[uuid] && !aboutToCache[uuid]) {
if (uuid === 'system' || this.currentProfileLoadedCount === this.currentProfileLoadedEnd) return;
aboutToCache[uuid] = {};
promises.push(axios.get(`/api/v4/members/${uuid}`));
this.currentProfileLoadedCount += 1;
}
});
const results = await Promise.all(promises);
results.forEach(result => {
// We could not load the user. Maybe they were deleted.
// So, let's cache empty so we don't try again
if (!result || !result.data || result.status >= 400) {
return;
}
const userData = result.data.data;
this.$set(this.cachedProfileData, userData._id, userData);
});
// Merge in any attempts that were rejected so we don't attempt again
for (const uuid in aboutToCache) {
if (!this.cachedProfileData[uuid]) {
this.$set(this.cachedProfileData, uuid, { rejected: true });
}
}
this.loading = false;
},
displayDivider (message) {
if (this.currentDayDividerDisplay !== moment(message.timestamp).day()) {
this.currentDayDividerDisplay = moment(message.timestamp).day();
return true;
}
return false;
},
async showMemberModal (memberId) {
let profile = this.cachedProfileData[memberId];
if (!profile._id) {
const result = await this.$store.dispatch('members:fetchMember', { memberId });
if (result.response && result.response.status === 404) {
return this.$store.dispatch('snackbars:add', {
title: 'Habitica',
text: this.$t('messageDeletedUser'),
type: 'error',
timeout: false,
});
}
this.cachedProfileData[memberId] = result.data.data;
profile = result.data.data;
}
// Open the modal only if the data is available
if (profile && !profile.rejected) {
this.$router.push({ name: 'userProfile', params: { userId: profile._id } });
}
return null;
},
itemWasMounted: debounce(function itemWasMounted () {
if (this.handleScrollBack) {
this.handleScrollBack = false;
const container = this.$refs.container.$el;
const offset = container.scrollHeight - container.clientHeight;
const newOffset = offset + this.lastOffset;
container.scrollTo(0, newOffset);
// enable scroll again
// container.style.overflowY = 'scroll';
}
}, 50),
messageRemoved (message) {
this.$emit('message-removed', message);
},
handleSelectStart () {
this.disablePerfectScroll = true;
},
handleSelectChange () {
this.disablePerfectScroll = false;
},
},
};
</script>

View File

@@ -266,25 +266,9 @@
color: $white;
}
.banner-g1g1 {
height: 5.75rem;
background-color: $teal-50;
color: $white;
}
.gifts-right {
filter: flipH;
transform: scaleX(-1);
}
.subscribe-pay {
margin-top: 1em;
}
.svg-gifts {
width: 55px;
height: 65px;
}
</style>
<script>
@@ -301,7 +285,6 @@ import notificationsMixin from '../../mixins/notifications';
import amazonButton from '@/components/payments/amazonButton';
import creditCardIcon from '@/assets/svg/credit-card-icon.svg';
import giftsVertical from '@/assets/svg/gifts-vertical.svg';
export default {
components: {
@@ -330,7 +313,6 @@ export default {
},
icons: Object.freeze({
creditCardIcon,
giftsVertical,
}),
};
},

View File

@@ -1,8 +1,8 @@
<template>
<b-modal
id="task-modal"
:no-close-on-esc="showTagsSelect"
:no-close-on-backdrop="showTagsSelect"
:no-close-on-esc="true"
:no-close-on-backdrop="true"
size="sm"
@hidden="onClose()"
@show="handleOpen()"

View File

@@ -1,9 +1,14 @@
/* eslint-disable import/no-extraneous-dependencies */
import { storiesOf } from '@storybook/vue';
import { withKnobs, number } from '@storybook/addon-knobs';
import CountBadge from './countBadge.vue';
storiesOf('Count Badge', module)
const stories = storiesOf('Count Badge', module);
stories.addDecorator(withKnobs);
stories
.add('simple', () => ({
components: { CountBadge },
template: `
@@ -19,9 +24,9 @@ storiesOf('Count Badge', module)
<count-badge :count="count" :show="true"></count-badge>
</div>
`,
data () {
return {
count: 3,
};
props: {
count: {
default: number('Count', 3),
},
},
}));

View File

@@ -2,14 +2,14 @@
<div class="popover-box">
<div
:id="containerId"
class="clearfix"
class="clearfix toggle-switch-outer"
>
<div
v-if="label"
class="float-left toggle-switch-description"
:class="hoverText ? 'hasPopOver' : ''"
>
{{ label }}
<span>{{ label }}</span>
</div>
<div class="toggle-switch float-left">
<input
@@ -53,9 +53,7 @@
}
.toggle-switch-description {
height: 20px;
&.hasPopOver {
&.hasPopOver span {
border-bottom: 1px dashed $gray-200;
}
}

View File

@@ -0,0 +1,115 @@
<template>
<div
v-if="displayName"
v-b-tooltip.hover.top="tierTitle"
class="user-label"
:class="levelStyle()"
>
{{ displayName }}
<div
class="svg-icon"
v-html="tierIcon()"
></div>
</div>
</template>
<style scoped lang="scss">
@import '~@/assets/scss/colors.scss';
.user-label.no-tier {
color: $gray-50;
}
.user-label {
font-weight: bold;
margin-bottom: 0;
display: inline-block;
font-size: 16px;
.svg-icon {
width: 10px;
display: inline-block;
margin-left: .5em;
}
}
</style>
<script>
import achievementsLib from '@/../../common/script/libs/achievements';
import styleHelper from '@/mixins/styleHelper';
import tier1 from '@/assets/svg/tier-1.svg';
import tier2 from '@/assets/svg/tier-2.svg';
import tier3 from '@/assets/svg/tier-3.svg';
import tier4 from '@/assets/svg/tier-4.svg';
import tier5 from '@/assets/svg/tier-5.svg';
import tier6 from '@/assets/svg/tier-6.svg';
import tier7 from '@/assets/svg/tier-7.svg';
import tier8 from '@/assets/svg/tier-mod.svg';
import tier9 from '@/assets/svg/tier-staff.svg';
import tierNPC from '@/assets/svg/tier-npc.svg';
export default {
mixins: [styleHelper],
props: ['user', 'name', 'backer', 'contributor', 'hideTooltip'],
data () {
return {
icons: Object.freeze({
tier1,
tier2,
tier3,
tier4,
tier5,
tier6,
tier7,
tier8,
tier9,
tierNPC,
}),
};
},
computed: {
displayName () {
if (this.name) {
return this.name;
}
if (this.user && this.user.profile) {
return this.user.profile.name;
}
return null;
},
level () {
if (this.contributor) {
return this.contributor.level;
} if (this.user && this.user.contributor) {
return this.user.contributor.level;
}
return 0;
},
isNPC () {
if (this.backer) {
return this.backer.level;
} if (this.user && this.user.backer) {
return this.user.backer.level;
}
return false;
},
},
methods: {
tierIcon () {
if (this.isNPC) {
return this.icons.tierNPC;
}
return this.icons[`tier${this.level}`];
},
tierTitle () {
return this.hideTooltip ? '' : achievementsLib.getContribText(this.contributor, this.isNPC) || '';
},
levelStyle () {
return this.userLevelStyleFromLevel(this.level, this.isNPC);
},
},
};
</script>

View File

@@ -1,700 +0,0 @@
<template>
<b-modal
id="inbox-modal"
title
:hide-footer="true"
size="lg"
@shown="onModalShown"
@hide="onModalHide"
>
<div
slot="modal-header"
class="header-wrap container align-items-center"
>
<div class="row align-items-center">
<div class="col-4">
<div class="row align-items-center">
<div class="col-2">
<div
class="svg-icon envelope"
v-html="icons.messageIcon"
></div>
</div>
<div class="col-6">
<h2
v-once
class="text-center"
>
{{ $t('messages') }}
</h2>
</div>
</div>
</div>
<div class="col-4 offset-3">
<toggle-switch
class="float-right"
:label="optTextSet.switchDescription"
:checked="!user.inbox.optOut"
:hover-text="optTextSet.popoverText"
@change="toggleOpt()"
/>
</div>
<div class="col-1">
<div class="close">
<span
class="svg-icon inline icon-10"
aria-hidden="true"
@click="close()"
v-html="icons.svgClose"
></span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-4 sidebar">
<div class="search-section">
<b-form-input
v-model="search"
:placeholder="$t('search')"
/>
</div>
<div
v-if="filtersConversations.length === 0"
class="empty-messages text-center"
>
<div
class="svg-icon envelope"
v-html="icons.messageIcon"
></div>
<h4 v-once>
{{ $t('emptyMessagesLine1') }}
</h4>
<p v-if="!user.flags.chatRevoked">
{{ $t('emptyMessagesLine2') }}
</p>
</div>
<div
v-if="filtersConversations.length > 0"
class="conversations"
>
<div
v-for="conversation in filtersConversations"
:key="conversation.key"
class="conversation"
:class="{active: selectedConversation.key === conversation.key}"
@click="selectConversation(conversation.key)"
>
<div>
<h3 :class="userLevelStyle(conversation)">
{{ conversation.name }}
<div
class="svg-icon"
v-html="tierIcon(conversation)"
></div>
</h3>
</div>
<div class="time">
<span
v-if="conversation.username"
class="mr-1"
>@{{ conversation.username }} </span>
<span v-if="conversation.date">{{ conversation.date | timeAgo }}</span>
</div>
<div
class="messagePreview"
>
{{ conversation.lastMessageText
? removeTags(parseMarkdown(conversation.lastMessageText)) : '' }}
</div>
</div>
</div>
</div>
<div class="col-8 messages d-flex flex-column justify-content-between">
<div
v-if="!selectedConversation.key"
class="empty-messages text-center"
>
<div
class="svg-icon envelope"
v-html="icons.messageIcon"
></div>
<h4>{{ placeholderTexts.title }}</h4>
<p v-html="placeholderTexts.description"></p>
</div>
<div
v-if="selectedConversation && selectedConversationMessages.length === 0"
class="empty-messages text-center"
>
<p>{{ $t('beginningOfConversation', {userName: selectedConversation.name}) }}</p>
</div>
<chat-messages
v-if="selectedConversation && selectedConversationMessages.length > 0"
ref="chatscroll"
class="message-scroll"
:chat="selectedConversationMessages"
:inbox="true"
:can-load-more="canLoadMore"
:is-loading="messagesLoading"
@message-removed="messageRemoved"
@triggerLoad="infiniteScrollTrigger"
/>
<div
v-if="user.inbox.optOut && selectedConversation.key"
class="pm-disabled-caption text-center"
>
<h4>{{ $t('PMDisabledCaptionTitle') }}</h4>
<p>{{ $t('PMDisabledCaptionText') }}</p>
</div>
<div
v-if="selectedConversation.key && !user.flags.chatRevoked"
class="new-message-row"
>
<textarea
v-model="newMessage"
maxlength="3000"
@keyup.ctrl.enter="sendPrivateMessage()"
></textarea>
<button
class="btn btn-secondary"
@click="sendPrivateMessage()"
>
{{ $t('send') }}
</button>
<div class="row">
<span class="ml-3">{{ currentLength }} / 3000</span>
</div>
</div>
</div>
</div>
</b-modal>
</template>
<style lang="scss">
#inbox-modal .modal-body {
padding-top: 0px;
}
</style>
<style lang="scss" scoped>
@import '~@/assets/scss/colors.scss';
.header-wrap {
padding: 0.5em;
h2 {
margin: 0;
line-height: 1;
}
}
h3 {
margin: 0rem;
.svg-icon {
width: 10px;
display: inline-block;
margin-left: .5em;
}
}
.envelope {
color: $gray-400 !important;
margin: 0;
}
.sidebar {
background-color: $gray-700;
min-height: 540px;
padding: 0;
.search-section {
padding: 1em;
box-shadow: 0 1px 2px 0 rgba(26, 24, 29, 0.24);
}
}
.messages {
position: relative;
padding-left: 0;
padding-bottom: 6em;
height: 540px;
}
.message-scroll {
max-height: 500px;
overflow-x: scroll;
@media (min-width: 992px) {
overflow-x: hidden;
overflow-y: scroll;
}
}
.to-form input {
width: 60%;
display: inline-block;
margin-left: 1em;
}
.empty-messages {
margin-top: 10em;
color: $gray-400;
padding: 1em;
h4 {
color: $gray-400;
margin-top: 1em;
}
.envelope {
width: 30px;
margin: 0 auto;
}
}
.pm-disabled-caption {
padding-top: 1em;
background-color: $gray-700;
z-index: 2;
h4, p {
color: $gray-300;
}
h4 {
margin-top: 0;
margin-bottom: 0.4em;
}
p {
font-size: 12px;
margin-bottom: 0;
}
}
.new-message-row {
background-color: $gray-700;
position: absolute;
bottom: 0;
height: 88px;
width: 100%;
padding: 1em;
textarea {
height: 80%;
display: inline-block;
vertical-align: bottom;
width: 80%;
}
button {
vertical-align: bottom;
display: inline-block;
box-shadow: none;
margin-left: 1em;
}
}
.conversations {
max-height: 400px;
overflow-x: hidden;
overflow-y: scroll;
}
.conversation {
padding: 1.5em;
background: $white;
}
.conversation.active {
border: 1px solid $purple-400;
}
.conversation:hover {
cursor: pointer;
}
.time {
font-size: 12px;
color: $gray-200;
margin-bottom: 0.5rem;
}
.messagePreview {
display: block;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-word;
}
</style>
<script>
import Vue from 'vue';
import moment from 'moment';
import filter from 'lodash/filter';
import groupBy from 'lodash/groupBy';
import orderBy from 'lodash/orderBy';
import habiticaMarkdown from 'habitica-markdown';
import axios from 'axios';
import { mapState } from '@/libs/store';
import styleHelper from '@/mixins/styleHelper';
import toggleSwitch from '@/components/ui/toggleSwitch';
import chatMessages from '../chat/chatMessages';
import messageIcon from '@/assets/svg/message.svg';
import svgClose from '@/assets/svg/close.svg';
import tier1 from '@/assets/svg/tier-1.svg';
import tier2 from '@/assets/svg/tier-2.svg';
import tier3 from '@/assets/svg/tier-3.svg';
import tier4 from '@/assets/svg/tier-4.svg';
import tier5 from '@/assets/svg/tier-5.svg';
import tier6 from '@/assets/svg/tier-6.svg';
import tier7 from '@/assets/svg/tier-7.svg';
import tier8 from '@/assets/svg/tier-mod.svg';
import tier9 from '@/assets/svg/tier-staff.svg';
import tierNPC from '@/assets/svg/tier-npc.svg';
export default {
components: {
chatMessages,
toggleSwitch,
},
filters: {
timeAgo (value) {
return moment(new Date(value)).fromNow();
},
},
mixins: [styleHelper],
data () {
return {
icons: Object.freeze({
messageIcon,
svgClose,
tier1,
tier2,
tier3,
tier4,
tier5,
tier6,
tier7,
tier8,
tier9,
tierNPC,
}),
displayCreate: true,
selectedConversation: {},
search: '',
newMessage: '',
showPopover: false,
messages: [],
messagesByConversation: {}, // cache {uuid: []}
loadedConversations: [],
loaded: false,
messagesLoading: false,
initiatedConversation: null,
updateConversionsCounter: 0,
};
},
computed: {
...mapState({ user: 'user.data' }),
canLoadMore () {
return this.selectedConversation && this.selectedConversation.canLoadMore;
},
conversations () {
const inboxGroup = groupBy(this.loadedConversations, 'uuid');
// Add placeholder for new conversations
if (this.initiatedConversation && this.initiatedConversation.uuid) {
inboxGroup[this.initiatedConversation.uuid] = [{
uuid: this.initiatedConversation.uuid,
user: this.initiatedConversation.user,
username: this.initiatedConversation.username,
contributor: this.initiatedConversation.contributor,
id: '',
text: '',
timestamp: new Date(),
backer: this.initiatedConversation.backer,
}];
}
// Create conversation objects
const convos = [];
for (const key of Object.keys(inboxGroup)) {
const recentMessage = inboxGroup[key][0];
const convoModel = {
key: recentMessage.uuid,
// Handles case where from user sent
// the only message or the to user sent the only message
name: recentMessage.user,
username: !recentMessage.text ? recentMessage.username : recentMessage.toUserName,
date: recentMessage.timestamp,
lastMessageText: recentMessage.text,
canLoadMore: true,
page: 0,
backer: recentMessage.backer,
};
convos.push(convoModel);
}
return convos;
},
// Separate from selectedConversation which
// is not computed so messages don't update automatically
selectedConversationMessages () {
// Vue-subscribe to changes
const subScribeToUpdate = this.messagesLoading || this.updateConversionsCounter > -1;
const selectedConversationKey = this.selectedConversation.key;
const selectedConversation = this.messagesByConversation[selectedConversationKey];
this.messages = selectedConversation || []; // eslint-disable-line vue/no-side-effects-in-computed-properties, max-len
const ordered = orderBy(this.messages, [m => m.timestamp], ['asc']);
if (subScribeToUpdate) {
return ordered;
}
return [];
},
filtersConversations () {
// Vue-subscribe to changes
const subScribeToUpdate = this.updateConversionsCounter > -1;
const filtered = subScribeToUpdate && !this.search
? this.conversations
: filter(
this.conversations,
conversation => conversation.name.toLowerCase().indexOf(this.search.toLowerCase()) !== -1,
);
const ordered = orderBy(filtered, [o => moment(o.date).toDate()], ['desc']);
return ordered;
},
currentLength () {
return this.newMessage.length;
},
placeholderTexts () {
if (this.user.flags.chatRevoked) {
return {
title: this.$t('PMPlaceholderTitleRevoked'),
description: this.$t('chatPrivilegesRevoked'),
};
}
return {
title: this.$t('PMPlaceholderTitle'),
description: this.$t('PMPlaceholderDescription'),
};
},
optTextSet () {
if (!this.user.inbox.optOut) {
return {
switchDescription: this.$t('PMReceive'),
popoverText: this.$t('PMEnabledOptPopoverText'),
};
}
return {
switchDescription: this.$t('PMReceive'),
popoverText: this.$t('PMDisabledOptPopoverText'),
};
},
},
mounted () {
this.$root.$on('habitica::new-inbox-message', data => {
this.$root.$emit('bv::show::modal', 'inbox-modal');
// Wait for messages to be loaded
const unwatchLoaded = this.$watch('loaded', loaded => {
if (!loaded) return;
const conversation = this.conversations.find(convo => convo.key === data.userIdToMessage);
if (loaded) setImmediate(() => unwatchLoaded());
if (conversation) {
this.selectConversation(data.userIdToMessage);
return;
}
this.initiatedConversation = {
uuid: data.userIdToMessage,
user: data.displayName,
username: data.username,
backer: data.backer,
contributor: data.contributor,
};
this.selectConversation(data.userIdToMessage);
}, { immediate: true });
});
},
destroyed () {
this.$root.$off('habitica::new-inbox-message');
},
methods: {
async onModalShown () {
this.loaded = false;
const conversationRes = await axios.get('/api/v4/inbox/conversations');
this.loadedConversations = conversationRes.data.data;
this.loaded = true;
},
onModalHide () {
// reset everything
this.loadedConversations = [];
this.loaded = false;
this.initiatedConversation = null;
this.messagesByConversation = {};
this.selectedConversation = {};
},
messageRemoved (message) {
const messages = this.messagesByConversation[this.selectedConversation.key];
const messageIndex = messages.findIndex(msg => msg.id === message.id);
if (messageIndex !== -1) messages.splice(messageIndex, 1);
if (this.selectedConversationMessages.length === 0) {
this.initiatedConversation = {
uuid: this.selectedConversation.key,
user: this.selectedConversation.name,
username: this.selectedConversation.username,
backer: this.selectedConversation.backer,
contributor: this.selectedConversation.contributor,
};
}
},
toggleClick () {
this.displayCreate = !this.displayCreate;
},
toggleOpt () {
this.$store.dispatch('user:togglePrivateMessagesOpt');
},
async selectConversation (key) {
const convoFound = this.conversations.find(conversation => conversation.key === key);
this.selectedConversation = convoFound || {};
if (!this.messagesByConversation[this.selectedConversation.key]) {
await this.loadMessages();
}
Vue.nextTick(() => {
if (!this.$refs.chatscroll) return;
const chatscroll = this.$refs.chatscroll.$el;
chatscroll.scrollTop = chatscroll.scrollHeight;
});
},
sendPrivateMessage () {
if (!this.newMessage) return;
const messages = this.messagesByConversation[this.selectedConversation.key];
messages.push({
sent: true,
text: this.newMessage,
timestamp: new Date(),
toUser: this.selectedConversation.name,
toUserName: this.selectedConversation.username,
toUserContributor: this.selectedConversation.contributor,
toUserBacker: this.selectedConversation.backer,
toUUID: this.selectedConversation.uuid,
id: '-1', // will be updated once the result is back
likes: {},
ownerId: this.user._id,
uuid: this.user._id,
fromUUID: this.user._id,
user: this.user.profile.name,
username: this.user.auth.local.username,
contributor: this.user.contributor,
backer: this.user.backer,
});
// Remove the placeholder message
if (
this.initiatedConversation
&& this.initiatedConversation.uuid === this.selectedConversation.key
) {
this.loadedConversations.unshift(this.initiatedConversation);
this.initiatedConversation = null;
}
this.selectedConversation.lastMessageText = this.newMessage;
this.selectedConversation.date = new Date();
Vue.nextTick(() => {
if (!this.$refs.chatscroll) return;
const chatscroll = this.$refs.chatscroll.$el;
chatscroll.scrollTop = chatscroll.scrollHeight;
});
this.$store.dispatch('members:sendPrivateMessage', {
toUserId: this.selectedConversation.key,
message: this.newMessage,
}).then(response => {
const newMessage = response.data.data.message;
const messageToReset = messages[messages.length - 1];
messageToReset.id = newMessage.id; // just set the id, all other infos already set
Object.assign(messages[messages.length - 1], messageToReset);
this.updateConversionsCounter += 1;
});
this.newMessage = '';
},
close () {
this.$root.$emit('bv::hide::modal', 'inbox-modal');
},
tierIcon (message) {
const isNPC = Boolean(message.backer && message.backer.npc);
if (isNPC) {
return this.icons.tierNPC;
}
if (!message.contributor) return null;
return this.icons[`tier${message.contributor.level}`];
},
removeTags (html) {
const tmp = document.createElement('DIV');
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || '';
},
parseMarkdown (text) {
if (!text) return null;
return habiticaMarkdown.render(String(text));
},
infiniteScrollTrigger () {
// show loading and wait until the loadMore debounced
// or else it would trigger on every scrolling-pixel (while not loading)
if (this.canLoadMore) {
this.messagesLoading = true;
}
return this.loadMore();
},
loadMore () {
this.selectedConversation.page += 1;
return this.loadMessages();
},
async loadMessages () {
this.messagesLoading = true;
const requestUrl = `/api/v4/inbox/paged-messages?conversation=${this.selectedConversation.key}&page=${this.selectedConversation.page}`;
const res = await axios.get(requestUrl);
const loadedMessages = res.data.data;
this.messagesByConversation[this.selectedConversation.key] = this.messagesByConversation[this.selectedConversation.key] || []; // eslint-disable-line max-len
const loadedMessagesToAdd = loadedMessages
.filter(m => this.messagesByConversation[this.selectedConversation.key].findIndex(mI => mI.id === m.id) === -1); // eslint-disable-line max-len
this.messagesByConversation[this.selectedConversation.key].push(...loadedMessagesToAdd);
// only show the load more Button if the max count was returned
this.selectedConversation.canLoadMore = loadedMessages.length === 10;
this.messagesLoading = false;
},
},
};
</script>

View File

@@ -859,13 +859,12 @@ export default {
window.history.replaceState(null, null, '');
},
sendMessage () {
this.$root.$emit('habitica::new-inbox-message', {
userIdToMessage: this.user._id,
displayName: this.user.profile.name,
username: this.user.auth.local.username,
backer: this.user.backer,
contributor: this.user.contributor,
this.$store.dispatch('user:newPrivateMessageTo', {
member: this.user,
});
this.$router.push('/private-messages');
this.$root.$emit('bv::hide::modal', 'profile');
},
getProgressDisplay () {
// let currentLoginDay = Content.loginIncentives[this.user.loginIncentives];

View File

@@ -0,0 +1,867 @@
<template>
<div id="private-message">
<div class="floating-header-shadow"></div>
<div class="header-bar d-flex w-100">
<!-- changing w-25 would also need changes in .left-header.w-25 -->
<div class="d-flex w-25 left-header">
<div
v-once
class="mail-icon svg-icon"
v-html="icons.mail"
></div>
<h2
v-once
class="flex-fill text-center mail-icon-label"
>
{{ $t('messages') }}
</h2>
<div class="placeholder svg-icon">
<!-- placeholder -->
</div>
</div>
<div class="d-flex w-75 selected-conversion">
<face-avatar
v-if="selectedConversation.userStyles"
:member="selectedConversation.userStyles"
:class="selectedConversationFaceAvatarClass"
/>
<user-label
:backer="selectedConversation.backer"
:contributor="selectedConversation.contributor"
:name="selectedConversation.name"
:hide-tooltip="true"
/>
</div>
</div>
<div class="d-flex content">
<div class="w-25 sidebar d-flex flex-column">
<div class="disable-background">
<toggle-switch
:label="optTextSet.switchDescription"
:checked="this.user.inbox.optOut"
:hover-text="optTextSet.popoverText"
@change="toggleOpt()"
/>
</div>
<div class="search-section">
<b-form-input
v-model="search"
class="input-search"
:placeholder="$t('search')"
/>
</div>
<div
v-if="filtersConversations.length === 0"
class="empty-messages m-auto text-center empty-sidebar"
>
<div>
<div
v-once
class="svg-icon envelope"
v-html="icons.messageIcon"
></div>
<h4 v-once>
{{ $t('emptyMessagesLine1') }}
</h4>
<p v-if="!user.flags.chatRevoked">
{{ $t('emptyMessagesLine2') }}
</p>
</div>
</div>
<div
v-if="filtersConversations.length > 0"
class="conversations"
>
<conversation-item
v-for="conversation in filtersConversations"
:key="conversation.key"
:active-key="selectedConversation.key"
:contributor="conversation.contributor"
:backer="conversation.backer"
:uuid="conversation.key"
:display-name="conversation.name"
:username="conversation.username"
:last-message-date="conversation.date"
:last-message-text="conversation.lastMessageText
? removeTags(parseMarkdown(conversation.lastMessageText)) : ''"
@click="selectConversation(conversation.key)"
/>
</div>
</div>
<div class="w-75 messages-column d-flex flex-column align-items-center">
<div
v-if="!selectedConversation.key"
class="empty-messages full-height m-auto text-center"
>
<div
v-once
class="svg-icon envelope"
v-html="icons.messageIcon"
></div>
<h4>{{ placeholderTexts.title }}</h4>
<p v-html="placeholderTexts.description"></p>
</div>
<div
v-if="selectedConversation.key && selectedConversationMessages.length === 0"
class="empty-messages full-height mt-auto text-center"
>
<avatar
v-if="selectedConversation.userStyles"
:member="selectedConversation.userStyles"
:avatar-only="true"
sprites-margin="0 0 0 -45px"
class="center-avatar"
/>
<h3>{{ $t('beginningOfConversation', {userName: selectedConversation.name}) }}</h3>
<p>{{ $t('beginningOfConversationReminder') }}</p>
</div>
<messageList
v-if="selectedConversation && selectedConversationMessages.length > 0"
ref="chatscroll"
class="message-scroll"
:chat="selectedConversationMessages"
:can-load-more="canLoadMore"
:is-loading="messagesLoading"
@message-removed="messageRemoved"
@triggerLoad="infiniteScrollTrigger"
/>
<div
v-if="user.inbox.optOut"
class="pm-disabled-caption text-center"
>
<h4>{{ $t('PMDisabledCaptionTitle') }}</h4>
<p>{{ $t('PMDisabledCaptionText') }}</p>
</div>
<div>
<div
v-if="selectedConversation.key && !user.flags.chatRevoked"
class="new-message-row d-flex align-items-center"
>
<textarea
v-model="newMessage"
class="flex-fill"
:placeholder="$t('needsTextPlaceholder')"
maxlength="3000"
:class="{'has-content': newMessage !== ''}"
@keyup.ctrl.enter="sendPrivateMessage()"
></textarea>
</div>
<div
v-if="selectedConversation.key && !user.flags.chatRevoked"
class="sub-new-message-row d-flex"
>
<div
v-once
class="guidelines flex-fill"
v-html="$t('communityGuidelinesIntro')"
></div>
<button
class="btn btn-primary"
:class="{'disabled':newMessage === ''}"
@click="sendPrivateMessage()"
>
{{ $t('send') }}
</button>
</div>
</div>
</div>
</div>
</div>
</template>
<style lang="scss">
@import '~@/assets/scss/colors.scss';
@import '~@/assets/scss/variables.scss';
$pmHeaderHeight: 56px;
// Content of Private Message should be always full-size (minus the toolbar/resting banner)
#private-message {
height: calc(100vh - #{$menuToolbarHeight} -
var(--banner-gifting-height, 0px) -
var(--banner-resting-height, 0px)); // css variable magic :), must be 0px, 0 alone won't work
.content {
flex: 1;
height: calc(100vh - #{$menuToolbarHeight} - #{$pmHeaderHeight} -
var(--banner-gifting-height, 0px) -
var(--banner-resting-height, 0px)
);
}
.disable-background {
.toggle-switch-description {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
flex: 1;
}
.toggle-switch-outer {
display: flex;
}
}
.modal-body {
padding: 0rem;
}
.modal-content {
width: 66vw;
}
.modal-dialog {
margin: 10vh 15vw 0rem;
}
.modal-header {
padding: 1rem 0rem;
.close {
cursor: pointer;
margin: 0rem 1.5rem;
min-width: 0.75rem;
padding: 0rem;
width: 0.75rem;
}
}
.toggle-switch-description {
font-size: 14px;
font-weight: bold;
font-style: normal;
font-stretch: normal;
line-height: 1.43;
letter-spacing: normal;
color: $gray-50;
}
}
</style>
<style lang="scss" scoped>
@import '~@/assets/scss/colors.scss';
@import '~@/assets/scss/tiers.scss';
@import '~@/assets/scss/variables.scss';
$pmHeaderHeight: 56px;
$background: $white;
.header-bar {
height: 56px;
background-color: $white;
padding-left: 1.5rem;
padding-right: 1.5rem;
align-items: center;
.mail-icon {
width: 32px;
height: 24px;
object-fit: contain;
}
.mail-icon-label {
margin-bottom: 0;
}
.placeholder.svg-icon {
width: 32px;
}
.left-header.w-25 {
width: calc(25% - 2rem) !important;
}
}
.full-height {
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
}
.user-label {
margin-left: 12px;
}
.input-search {
background-repeat: no-repeat;
background-position: center left 16px;
background-size: 16px 16px;
background-image: url(~@/assets/svg/for-css/search_gray.svg) !important;
padding-left: 40px;
color: $gray-200 !important;
height: 40px;
}
.selected-conversion {
justify-content: center;
align-items: center;
}
#private-message {
background-color: $background;
position: relative;
}
.disable-background {
height: 44px;
background-color: $gray-600;
padding: 0.75rem 1.5rem;
}
.conversations {
max-height: 35rem;
overflow-x: hidden;
overflow-y: auto;
height: 100%;
}
.empty-messages {
h3, h4, p {
color: $gray-400;
margin: 0rem;
}
p {
font-size: 12px;
}
.envelope {
width: 30px;
margin: 0 auto 0.5rem;
}
}
.envelope {
color: $gray-500 !important;
margin: 0rem;
max-width: 2rem;
}
h3 {
margin: 0rem;
.svg-icon {
width: 10px;
display: inline-block;
margin-left: .5em;
}
}
.header-wrap {
padding: 0.5em;
h2 {
margin: 0;
line-height: 1;
}
}
.messagePreview {
display: block;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-word;
}
.messages-column {
padding: 0rem;
display: flex;
flex-direction: column;
.empty-messages, .message-scroll {
flex: 1;
}
}
.message-scroll {
overflow-x: hidden;
padding-top: 0.5rem;
@media (min-width: 992px) {
overflow-x: hidden;
overflow-y: scroll;
}
}
.new-message-row {
width: 100%;
padding-left: 1.5rem;
padding-top: 1.5rem;
padding-right: 1.5rem;
textarea {
height: 5.5rem;
display: inline-block;
vertical-align: bottom;
border-radius: 2px;
z-index: 5;
border: solid 1px $gray-400;
opacity: 0.64;
background-color: $gray-500;
&:focus, &.has-content {
opacity: 1;
background-color: $white;
}
}
}
.sub-new-message-row {
padding: 1rem 1.5rem 1.5rem;
.guidelines {
height: 32px;
font-size: 12px;
font-weight: normal;
font-style: normal;
font-stretch: normal;
line-height: 1.33;
letter-spacing: normal;
color: $gray-200;
margin-top: 0.25rem;
margin-bottom: 0.25rem;
}
button {
height: 40px;
border-radius: 2px;
margin-left: 1.5rem;
&.disabled {
cursor: default;
pointer-events: none;
opacity: 0.64;
background-color: $gray-500;
}
}
}
.pm-disabled-caption {
padding-top: 1em;
background-color: $gray-700;
z-index: 2;
h4, p {
color: $gray-300;
}
h4 {
margin-top: 0;
margin-bottom: 0.4em;
}
p {
font-size: 12px;
margin-bottom: 0;
}
}
.sidebar {
background-color: $gray-700;
min-height: 540px;
max-width: 330px;
padding: 0;
border-bottom-left-radius: 8px;
.search-section {
padding: 1rem 1.5rem;
border-bottom: 1px solid $gray-500;
}
}
.time {
font-size: 12px;
color: $gray-200;
margin-bottom: 0.5rem;
}
.to-form input {
width: 60%;
display: inline-block;
margin-left: 1em;
}
.empty-sidebar {
display: flex;
align-items: center;
}
.floating-message-input {
background: $background;
position: fixed;
bottom: 0;
}
.floating-header-shadow {
position: absolute;
top: 0;
width: 100%;
height: 56px;
right: 0;
z-index: 1;
pointer-events: none;
box-shadow: 0 3px 12px 0 rgba(26, 24, 29, 0.24);
}
.center-avatar {
margin: 0 auto;
}
</style>
<script>
import Vue from 'vue';
import moment from 'moment';
import filter from 'lodash/filter';
import groupBy from 'lodash/groupBy';
import orderBy from 'lodash/orderBy';
import habiticaMarkdown from 'habitica-markdown';
import axios from 'axios';
import { mapState } from '@/libs/store';
import styleHelper from '@/mixins/styleHelper';
import toggleSwitch from '@/components/ui/toggleSwitch';
import userLabel from '@/components/userLabel';
import messageList from '@/components/messages/messageList';
import messageIcon from '@/assets/svg/message.svg';
import mail from '@/assets/svg/mail.svg';
import conversationItem from '@/components/messages/conversationItem';
import faceAvatar from '@/components/faceAvatar';
import Avatar from '@/components/avatar';
export default {
components: {
Avatar,
messageList,
toggleSwitch,
conversationItem,
userLabel,
faceAvatar,
},
filters: {
timeAgo (value) {
return moment(new Date(value)).fromNow();
},
},
mixins: [styleHelper],
data () {
return {
icons: Object.freeze({
messageIcon,
mail,
}),
displayCreate: true,
selectedConversation: {},
search: '',
newMessage: '',
showPopover: false,
messages: [],
messagesByConversation: {}, // cache {uuid: []}
loadedConversations: [],
loaded: false,
messagesLoading: false,
initiatedConversation: null,
updateConversationsCounter: 0,
};
},
async mounted () {
this.$root.$on('pm::refresh', async () => {
await this.reload();
this.selectConversation(this.loadedConversations[0].uuid, true);
});
await this.reload();
const data = this.$store.state.privateMessageOptions;
if (data && data.userIdToMessage) {
this.initiatedConversation = {
uuid: data.userIdToMessage,
user: data.displayName,
username: data.username,
backer: data.backer,
contributor: data.contributor,
userStyles: data.userStyles,
};
this.$store.state.privateMessageOptions = {};
this.selectConversation(this.initiatedConversation.uuid);
}
},
destroyed () {
this.$root.$off('habitica::new-private-message');
},
computed: {
...mapState({ user: 'user.data' }),
canLoadMore () {
return this.selectedConversation && this.selectedConversation.canLoadMore;
},
conversations () {
const inboxGroup = groupBy(this.loadedConversations, 'uuid');
// Add placeholder for new conversations
if (this.initiatedConversation && this.initiatedConversation.uuid) {
inboxGroup[this.initiatedConversation.uuid] = [{
uuid: this.initiatedConversation.uuid,
user: this.initiatedConversation.user,
username: this.initiatedConversation.username,
contributor: this.initiatedConversation.contributor,
backer: this.initiatedConversation.backer,
userStyles: this.initiatedConversation.userStyles,
id: '',
text: '',
timestamp: new Date(),
}];
}
// Create conversation objects
const convos = [];
for (const key in inboxGroup) {
if (Object.prototype.hasOwnProperty.call(inboxGroup, key)) {
const recentMessage = inboxGroup[key][0];
const convoModel = {
key: recentMessage.uuid,
name: recentMessage.user,
// Handles case where from user sent the only message
// or the to user sent the only message
username: recentMessage.username,
date: recentMessage.timestamp,
lastMessageText: recentMessage.text,
contributor: recentMessage.contributor,
userStyles: recentMessage.userStyles,
backer: recentMessage.backer,
canLoadMore: false,
page: 0,
};
convos.push(convoModel);
}
}
return convos;
},
// Separate from selectedConversation which is not computed
// so messages don't update automatically
/* eslint-disable vue/no-side-effects-in-computed-properties */
selectedConversationMessages () {
// Vue-subscribe to changes
const subscribeToUpdate = this.messagesLoading || this.updateConversationsCounter > -1;
const selectedConversationKey = this.selectedConversation.key;
const selectedConversation = this.messagesByConversation[selectedConversationKey];
this.messages = selectedConversation || [];
const ordered = orderBy(this.messages, [m => m.timestamp], ['asc']);
if (subscribeToUpdate) {
return ordered;
}
return [];
},
filtersConversations () {
// Vue-subscribe to changes
const subscribeToUpdate = this.updateConversationsCounter > -1;
const filtered = subscribeToUpdate && !this.search
? this.conversations
/* eslint-disable max-len */
: filter(this.conversations, conversation => conversation.name.toLowerCase().indexOf(this.search.toLowerCase()) !== -1);
const ordered = orderBy(filtered, [o => moment(o.date).toDate()], ['desc']);
return ordered;
},
currentLength () {
return this.newMessage.length;
},
placeholderTexts () {
if (this.user.flags.chatRevoked) {
return {
title: this.$t('PMPlaceholderTitleRevoked'),
description: this.$t('chatPrivilegesRevoked'),
};
}
return {
title: this.$t('PMPlaceholderTitle'),
description: this.$t('PMPlaceholderDescription'),
};
},
optTextSet () {
if (!this.user.inbox.optOut) {
return {
switchDescription: this.$t('PMDisabled'),
popoverText: this.$t('PMEnabledOptPopoverText'),
};
}
return {
switchDescription: this.$t('PMDisabled'),
popoverText: this.$t('PMDisabledOptPopoverText'),
};
},
selectedConversationFaceAvatarClass () {
if (this.selectedConversation && this.selectedConversation.contributor) {
return `tier${this.selectedConversation.contributor.level}`;
}
return '';
},
},
methods: {
async reload () {
this.loaded = false;
const conversationRes = await axios.get('/api/v4/inbox/conversations');
this.loadedConversations = conversationRes.data.data;
this.selectedConversation = {};
this.loaded = true;
},
messageRemoved (message) {
const messages = this.messagesByConversation[this.selectedConversation.key];
const messageIndex = messages.findIndex(msg => msg.id === message.id);
if (messageIndex !== -1) messages.splice(messageIndex, 1);
if (this.selectedConversationMessages.length === 0) {
this.initiatedConversation = {
uuid: this.selectedConversation.key,
user: this.selectedConversation.name,
username: this.selectedConversation.username,
backer: this.selectedConversation.backer,
contributor: this.selectedConversation.contributor,
};
}
},
toggleClick () {
this.displayCreate = !this.displayCreate;
},
toggleOpt () {
this.$store.dispatch('user:togglePrivateMessagesOpt');
},
async selectConversation (key, forceLoadMessage = false) {
const convoFound = this.conversations.find(conversation => conversation.key === key);
this.selectedConversation = convoFound || {};
if (!this.messagesByConversation[this.selectedConversation.key] || forceLoadMessage) {
await this.loadMessages();
}
Vue.nextTick(() => {
if (!this.$refs.chatscroll) return;
const chatscroll = this.$refs.chatscroll.$el;
chatscroll.scrollTop = chatscroll.scrollHeight;
});
},
sendPrivateMessage () {
if (!this.newMessage) return;
const messages = this.messagesByConversation[this.selectedConversation.key];
messages.push({
sent: true,
text: this.newMessage,
timestamp: new Date(),
toUser: this.selectedConversation.name,
toUserName: this.selectedConversation.username,
toUserContributor: this.selectedConversation.contributor,
toUserBacker: this.selectedConversation.backer,
toUUID: this.selectedConversation.uuid,
id: '-1', // will be updated once the result is back
likes: {},
ownerId: this.user._id,
uuid: this.user._id,
fromUUID: this.user._id,
user: this.user.profile.name,
username: this.user.auth.local.username,
contributor: this.user.contributor,
backer: this.user.backer,
});
// Remove the placeholder message
if (this.initiatedConversation
&& this.initiatedConversation.uuid === this.selectedConversation.key) {
this.loadedConversations.unshift(this.initiatedConversation);
this.initiatedConversation = null;
}
this.selectedConversation.lastMessageText = this.newMessage;
this.selectedConversation.date = new Date();
Vue.nextTick(() => {
if (!this.$refs.chatscroll) return;
const chatscroll = this.$refs.chatscroll.$el;
chatscroll.scrollTop = chatscroll.scrollHeight;
});
this.$store.dispatch('members:sendPrivateMessage', {
toUserId: this.selectedConversation.key,
message: this.newMessage,
}).then(response => {
const newMessage = response.data.data.message;
const messageToReset = messages[messages.length - 1];
messageToReset.id = newMessage.id; // just set the id, all other infos already set
Object.assign(messages[messages.length - 1], messageToReset);
this.updateConversationsCounter += 1;
});
this.newMessage = '';
},
removeTags (html) {
const tmp = document.createElement('DIV');
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || '';
},
parseMarkdown (text) {
if (!text) return null;
return habiticaMarkdown.render(String(text));
},
infiniteScrollTrigger () {
// show loading and wait until the loadMore debounced
// or else it would trigger on every scrolling-pixel (while not loading)
if (this.canLoadMore) {
this.messagesLoading = true;
}
return this.loadMore();
},
loadMore () {
this.selectedConversation.page += 1;
return this.loadMessages();
},
async loadMessages () {
this.messagesLoading = true;
// use local vars if the loading takes longer
// and the user switches the conversation while loading
const conversationKey = this.selectedConversation.key;
const requestUrl = `/api/v4/inbox/paged-messages?conversation=${conversationKey}&page=${this.selectedConversation.page}`;
const res = await axios.get(requestUrl);
const loadedMessages = res.data.data;
this.messagesByConversation[conversationKey] = this.messagesByConversation[conversationKey] || [];
const loadedMessagesToAdd = loadedMessages
.filter(m => this.messagesByConversation[conversationKey].findIndex(mI => mI.id === m.id) === -1);
this.messagesByConversation[conversationKey].push(...loadedMessagesToAdd);
// only show the load more Button if the max count was returned
this.selectedConversation.canLoadMore = loadedMessages.length === 10;
this.messagesLoading = false;
},
},
};
</script>

View File

@@ -75,6 +75,8 @@ const GroupPlanIndex = () => import(/* webpackChunkName: "group-plans" */ '@/com
const GroupPlanTaskInformation = () => import(/* webpackChunkName: "group-plans" */ '@/components/group-plans/taskInformation');
const GroupPlanBilling = () => import(/* webpackChunkName: "group-plans" */ '@/components/group-plans/billing');
const MessagesIndex = () => import(/* webpackChunkName: "private-messages" */ '@/pages/private-messages');
// Challenges
const ChallengeIndex = () => import(/* webpackChunkName: "challenges" */ '@/components/challenges/index');
const MyChallenges = () => import(/* webpackChunkName: "challenges" */ '@/components/challenges/myChallenges');
@@ -193,6 +195,7 @@ const router = new VueRouter({
},
],
},
{ path: '/private-messages', name: 'privateMessages', component: MessagesIndex },
{
name: 'challenges',
path: '/challenges',

View File

@@ -60,7 +60,10 @@ async function buyArmoire (store, params) {
const isExperience = item.type === 'experience';
if (item.type === 'gear') {
store.state.user.data.items.gear.owned[item.dropKey] = true;
store.state.user.data.items.gear.owned = {
...store.state.user.data.items.gear.owned,
[item.dropKey]: true,
};
}
if (item.type === 'food') {

View File

@@ -160,3 +160,65 @@ export async function userLookup (store, params) {
}
return response;
}
export function block (store, params) {
store.state.user.data.inbox.blocks.push(params.uuid);
return axios.post(`/api/v4/user/block/${params.uuid}`);
}
export function unblock (store, params) {
const index = store.state.user.data.inbox.blocks.indexOf(params.uuid);
store.state.user.data.inbox.blocks.splice(index, 1);
return axios.post(`/api/v4/user/block/${params.uuid}`);
}
export function newPrivateMessageTo (store, params) {
const { member } = params;
const userStyles = {};
userStyles.items = { gear: {} };
if (member.items) {
userStyles.items.gear = {};
userStyles.items.gear.costume = { ...member.items.gear.costume };
userStyles.items.gear.equipped = { ...member.items.gear.equipped };
userStyles.items.currentMount = member.items.currentMount;
userStyles.items.currentPet = member.items.currentPet;
}
if (member.preferences) {
userStyles.preferences = {};
if (member.preferences.style) userStyles.preferences.style = member.preferences.style;
userStyles.preferences.hair = member.preferences.hair;
userStyles.preferences.skin = member.preferences.skin;
userStyles.preferences.shirt = member.preferences.shirt;
userStyles.preferences.chair = member.preferences.chair;
userStyles.preferences.size = member.preferences.size;
userStyles.preferences.chair = member.preferences.chair;
userStyles.preferences.background = member.preferences.background;
userStyles.preferences.costume = member.preferences.costume;
}
if (member.stats) {
userStyles.stats = {};
userStyles.stats.class = member.stats.class;
if (member.stats.buffs) {
userStyles.stats.buffs = {
seafoam: member.stats.buffs.seafoam,
shinySeed: member.stats.buffs.shinySeed,
spookySparkles: member.stats.buffs.spookySparkles,
snowball: member.stats.buffs.snowball,
};
}
}
store.state.privateMessageOptions = {
userIdToMessage: member._id,
displayName: member.profile.name,
username: member.auth.local.username,
backer: member.backer,
contributor: member.contributor,
userStyles,
};
}

View File

@@ -127,6 +127,13 @@ export default function () {
equipmentDrawerOpen: true,
groupPlans: [],
isRunningYesterdailies: false,
privateMessageOptions: {
userIdToMessage: '',
displayName: '',
username: '',
backer: {},
contributor: {},
},
},
});

View File

@@ -116,6 +116,7 @@ module.exports = {
},
devServer: {
disableHostCheck: true,
proxy: {
// proxy all requests to the server at IP:PORT as specified in the top-level config
'^/api/v3': {

View File

@@ -0,0 +1,9 @@
const path = require('path');
module.exports = {
resolve: {
alias: {
'@': path.join(__dirname, 'src'),
}
},
};

View File

@@ -2,29 +2,66 @@
"achievement": "Præstation",
"share": "Del",
"onwards": "Fremad!",
"levelup": "Ved at opnå dine mål fra den virkelige verden er du steget i level, og er nu fuldt helet igen!",
"reachedLevel": "Du har nået level <%= level %>",
"achievementLostMasterclasser": "Quest færdiggører: Mesterklasse-rækken",
"achievementLostMasterclasserText": "Færdiggjorde alle 16 quests i Mesterklasse quest-rækken og løste alle mysterier fra \"the Lost Masterclasser\"!",
"achievementLostMasterclasserModalText": "Du har klaret alle seksten quests i Mesterklasser-serien og løst mysteriet om den forsvundne Mesterklasser!",
"levelup": "Ved at opnå dine mål fra den virkelige verden er du steget i niveau, og er nu fuldt helet igen!",
"reachedLevel": "Du har nået niveau <%= level %>",
"achievementLostMasterclasser": "Quest-knuser: Mesterklasse-serien",
"achievementLostMasterclasserText": "Færdiggjorde alle 16 quests i Mesterklasse-questrækken, og løste mysteriet om den Forsvundne Mesterklasser!",
"achievementLostMasterclasserModalText": "Du har klaret alle seksten quests i Mesterklasse-serien og løst mysteriet om den Forsvundne Mesterklasser!",
"achievementMindOverMatterText": "Har fuldført sten-, slim- og garn-kæledyrsquests.",
"achievementMindOverMatterModalText": "Du har klaret sten-, slim-, og garn-kæledyrsquestene!",
"achievementJustAddWater": "Tilføj kun vand",
"achievementJustAddWaterText": "Har klaret blæksprutte-, søheste-, tiarmet blæksprutte-, hval-, skildpadde-, nøgensnegle-, søslange- og delfin-kæledyrsquestene.",
"achievementJustAddWaterModalText": "Du har klaret blæksprutte-, søheste-, tiarmet blæksprutte-, hval-, skildpadde-, nøgensnegle-, søslange- og delfin-kæledyrsquestene!",
"achievementBackToBasics": "Almindeligt udbredt",
"achievementBackToBasicsText": "Har samlet alle Almindelige kæledyr.",
"achievementBackToBasicsModalText": "Du har samlet alle Almindelige kæledyr!",
"achievementBackToBasicsText": "Har samlet alle almindelige kæledyr.",
"achievementBackToBasicsModalText": "Du har samlet alle almindelige kæledyr!",
"achievementAllYourBase": "Alle almindelige",
"achievementAllYourBaseText": "Har tæmmet alle Almindelige ridedyr.",
"achievementAllYourBaseModalText": "Du har tæmmet alle Almindelige ridedyr!",
"achievementMonsterMagusModalText": "Du har samlet all zombie dyr!",
"achievementMonsterMagusText": "Har samlet all zombie dyr.",
"achievementPartyOn": "Dit hold vokset til 4 medlemmer!",
"achievementAridAuthorityModalText": "Du har tæmmet all ørken dyr!",
"achievementAridAuthorityText": "Har tæmmet all ørken dyr.",
"achievementDustDevilModalText": "Du har samlet alle ørken dyr!",
"achievementDustDevilText": "Har samlet alle ørken dyr.",
"achievementDustDevil": "Støv djævel",
"achievementMindOverMatter": "Hvor der er vilje..."
"achievementAllYourBaseText": "Har tæmmet alle almindelige ridedyr.",
"achievementAllYourBaseModalText": "Du har tæmmet alle almindelige ridedyr!",
"achievementMonsterMagusModalText": "Du har samlet all zombiekæledyr!",
"achievementMonsterMagusText": "Har samlet all zombiekæledyr.",
"achievementPartyOn": "Dit hold voksede til 4 medlemmer!",
"achievementAridAuthorityModalText": "Du har tæmmet all ørkenridedyr!",
"achievementAridAuthorityText": "Har tæmmet all ørkenridedyr.",
"achievementDustDevilModalText": "Du har samlet alle ørkenkæledyr!",
"achievementDustDevilText": "Har samlet alle ørkenkæledyr.",
"achievementDustDevil": "Støvdjævel",
"achievementMindOverMatter": "Stof til eftertanke",
"achievementPearlyProModalText": "Du har tæmmet alle de hvide ridedyr!",
"achievementPearlyProText": "Har tæmmet alle hvide ridedyr.",
"achievementPearlyPro": "Perleskinnende prof",
"achievementPrimedForPaintingModalText": "Du har samlet alle de hvide kæledyr!",
"achievementPrimedForPaintingText": "Har samlet all hvide kæledyr.",
"achievementPrimedForPainting": "Grundmalet gruppe",
"achievementPurchasedEquipmentModalText": "Udstyr er en måde at tilpasse din avatar og forbedre dine egenskaber",
"achievementPurchasedEquipmentText": "Købte deres første stykke udstyr.",
"achievementPurchasedEquipment": "Køb udstyr",
"achievementFedPetModalText": "Der er mange forskellige slags mad, men kæledyr kan være kræsne",
"achievementFedPetText": "Fodrede deres første kæledyr.",
"achievementFedPet": "Giv et kæledyr mad",
"achievementHatchedPetModalText": "Kig i dit inventar, og prøv at kombinere en udrugningseliksir og et æg",
"achievementHatchedPetText": "Udklækkede deres første kæledyr.",
"achievementHatchedPet": "Udklæk et kæledyr",
"achievementCompletedTaskModalText": "Marker enhver af dine opgaver som færdig for at få belønninger",
"achievementCompletedTaskText": "Udførte deres første opgave.",
"achievementCompletedTask": "Udfør en opgave",
"achievementCreatedTaskModalText": "Tilføj en opgave for noget, du gerne vil gøre i denne uge",
"achievementCreatedTaskText": "Oprettede deres første opgave.",
"achievementCreatedTask": "Opret en opgave",
"achievementUndeadUndertakerModalText": "Du har tæmmet alle zombieridedyr!",
"achievementUndeadUndertakerText": "Har tæmmet alle zombieridedyr.",
"achievementUndeadUndertaker": "Udød yndling",
"achievementMonsterMagus": "Monstrøs magiker",
"achievementKickstarter2019Text": "Sponsorerede Kickstarterprojektet for badges i 2019",
"achievementKickstarter2019": "Pin Kickstarter sponsor",
"achievementAridAuthority": "Knastør ekspert",
"achievementPartyUp": "Du dannede hold med en anden bruger!",
"hideAchievements": "Skjul <%= category %>",
"showAllAchievements": "Vis alle <%= category %>",
"onboardingCompleteDesc": "Du opnåede <strong>5 præstationer</strong> og <strong class=\"gold-amount\">100</strong> guld for at færdiggøre listen.",
"earnedAchievement": "Du opnåede en præstation!",
"viewAchievements": "Se præstationer",
"letsGetStarted": "Lad os komme i gang!",
"onboardingProgress": "<%= percentage %>% fremskridt",
"gettingStartedDesc": "Lad os lave en opgave, udføre den, og så se på din belønning. You vil få <strong>5 præstationer</strong> og <strong class=\"gold-amount\">100 guld</strong>, når du er færdig!"
}

View File

@@ -1,13 +1,13 @@
{
"defaultHabit1Text": "Produktivt arbejde (Klik på blyanten for at redigere)",
"defaultHabit1Notes": "Eksempler på Gode Vaner: +Spist en grønsag +15 minutters produktivt arbejde",
"defaultHabit1Notes": "Eksempler på gode vaner: + Spis en grønsag + 15 minutters produktivt arbejde",
"defaultHabit2Text": "Spis junk food (Klik på blyanten for at redigere)",
"defaultHabit2Notes": "Eksempler på Dårlige Vaner: -Ryge -Overspringshandling",
"defaultHabit3Text": "Tag trapperne/elevator (Klik på blyanten for at redigere)",
"defaultHabit3Notes": "Eksempel på God eller Dårlig Vane: +/- Tog Trapperne/Elevatoren; +/- Drak Vand/Sodavand",
"defaultHabit2Notes": "Eksempler på dårlige vaner: - Rygning - Lav overspringshandlinger",
"defaultHabit3Text": "Tag trapperne/elevatoren (Klik på blyanten for at redigere)",
"defaultHabit3Notes": "Eksempel på en god eller dårlig vane: +/- Tog trapperne/elevatoren; +/- Drak vand/sodavand",
"defaultHabit4Text": "Tilføj en opgave til Habitica",
"defaultHabit4Notes": "Enten en Vane, en Daglig eller en To-Do",
"defaultHabit5Text": "Tryk her for at gøre dette til en dårlig vane du gerne vil af med",
"defaultHabit5Text": "Tryk her, for at gøre dette til en dårlig vane, du gerne vil af med",
"defaultHabit5Notes": "Eller slet fra redigeringsskærmen",
"defaultDaily1Text": "Brug Habitica til at holde styr på dine opgaver",
"defaultTodo1Text": "Start med at spille Habitica (Markér mig som færdig!)",

View File

@@ -140,59 +140,59 @@
"subscriptionRateText": "Løbende $<%= price %> USD hver <%= months %>. måned",
"recurringText": "løbende",
"benefits": "Fordele",
"coupon": "Kupon",
"couponPlaceholder": "Indtast Kuponkode",
"couponText": "Nogle gange har vi events og giver kuponkoder til specielt udstyr. (f.eks. til dem, der svinger forbi vores stand på Wondercon)",
"coupon": "Rabat",
"couponPlaceholder": "Indtast rabatkode",
"couponText": "Nogle gange har vi events og giver rabatkoder til specielt udstyr (f.eks. til dem, der svinger indenom vores stand på Wondercon).",
"apply": "Udfør",
"resubscribe": "Genabonnér",
"promoCode": "Promo-kode",
"promoCodeApplied": "Promo-kode anvendt. Tjek dit inventar",
"promoPlaceholder": "Indtast Promo-kode",
"promoCodeApplied": "Promo-kode accepteret! Tjek dit inventar",
"promoPlaceholder": "Indtast promo-kode",
"displayInviteToPartyWhenPartyIs1": "Vis Invitér til Hold-knap når holdet har 1 medlem.",
"saveCustomDayStart": "Gem Brugerdefineret Dagstart",
"saveCustomDayStart": "Gem brugerdefineret starttidspunkt",
"registration": "Registrering",
"addLocalAuth": "Tilføj login med email og kodeord",
"generateCodes": "Generér Koder",
"generateCodes": "Generér koder",
"generate": "Generér",
"getCodes": "Hent Koder",
"getCodes": "Hent koder",
"webhooks": "Webhooks",
"webhooksInfo": "Habitica tilbyder webhooks, så information kan blive sendt til et script på en anden hjemmeside, når der sker bestemte ting med din konto. Du kan specificere disse scripts her. Vær forsigtig med denne funktion. En forkert URL kan forårsage fejl eller gøre Habitica langsomt. Se wiki-siden <a target=\"_blank\" href=\"https://habitica.fandom.com/wiki/Webhooks\">Webhooks</a> for mere information (engelsk).",
"webhooksInfo": "Habitica tilbyder webhooks, så information kan blive sendt til et script på en anden hjemmeside, når der sker bestemte ting med din konto. Du kan specificere disse scripts her. Vær forsigtig med denne funktion. En forkert URL kan forårsage fejl eller gøre Habitica langsom. Se wiki-siden <a target=\"_blank\" href=\"https://habitica.fandom.com/wiki/Webhooks\">Webhooks</a> (EN) for mere information.",
"enabled": "Aktiveret",
"webhookURL": "Webhook URL",
"invalidUrl": "ugyldig url",
"invalidEnabled": "Parametren \"aktiveret\" skal være en boolesk værdi.",
"invalidWebhookId": "Parametren \"id\" skal være et gyldigt Unikt Bruger-ID.",
"missingWebhookId": "Webhook-id påkrævet.",
"invalidWebhookType": "\"<%= type %>\" er ikke en gyldig værdi for parametren \"type\".",
"invalidEnabled": "Parametret \"aktiveret\" skal være en boolesk værdi.",
"invalidWebhookId": "Parametret \"id\" skal være et gyldigt unikt bruger-ID.",
"missingWebhookId": "Webhook-ID påkrævet.",
"invalidWebhookType": "\"<%= type %>\" er ikke en gyldig værdi for parametret \"type\".",
"webhookBooleanOption": "\"<%= option %>\" skal være en boolesk værdi.",
"webhookIdAlreadyTaken": "En webhook med id'et <%= id %> findes allerede.",
"noWebhookWithId": "Der er ingen webhook med id'et <%= id %>.",
"regIdRequired": "RegId påkrævet",
"invalidPushClient": "Ugyldig klient. Kun officielle Habitica-klienter kan modtage push notifikationer.",
"webhookIdAlreadyTaken": "En webhook med ID'et <%= id %> findes allerede.",
"noWebhookWithId": "Der er ingen webhook med ID'et <%= id %>.",
"regIdRequired": "RegID påkrævet",
"invalidPushClient": "Ugyldig klient. Kun officielle Habitica-klienter kan modtage pushnotifikationer.",
"pushDeviceAdded": "Push-enhed tilføjet",
"pushDeviceAlreadyAdded": "Denne bruger har allerede push-enheden",
"pushDeviceNotFound": "Brugeren har ingen push-enhed med dette ID.",
"pushDeviceRemoved": "Push-enhed fjernet.",
"buyGemsGoldCap": "Maksimum hævet til <%= amount %>",
"mysticHourglass": "<%= amount %> Mystiske Timeglas",
"mysticHourglassText": "Mystiske Timeglas giver dig adgang til at købe tidligere måneders Mystiske Gendstande-sæt.",
"mysticHourglass": "<%= amount %> mystiske timeglas",
"mysticHourglassText": "Mystiske timeglas giver dig adgang til at købe mystiske sæt fra tidligere måneder.",
"purchasedPlanId": "Løbende $<%= price %> USD hver <%= months %>. måned (<%= plan %>)",
"purchasedPlanExtraMonths": "Du har <%= months %> måneders overskydende abonnementkredit.",
"consecutiveSubscription": "Fortløbende Abonnement",
"consecutiveMonths": "Fortløbende Måneder:",
"gemCapExtra": "Ekstra Ædelstensmaksimum:",
"mysticHourglasses": "Mystiske Timeglas:",
"consecutiveSubscription": "Fortløbende abonnement",
"consecutiveMonths": "Fortløbende måneder:",
"gemCapExtra": "Ekstra ædelstensmaksimum:",
"mysticHourglasses": "Mystiske timeglas:",
"mysticHourglassesTooltip": "Mystiske timeglas",
"paypal": "PayPal",
"amazonPayments": "Amazon Payments",
"amazonPaymentsRecurring": "Det er nødvendigt at sætte hak i boksen nedenunder for at oprette dit abonnement. Det vil tillade at din Amazonkonto kan bruges til gentagne betalinger for <strong>dette</strong> abonnement. Det vil ikke få til Amazonkonto til at blive brugt automatisk ved fremtidige køb.",
"amazonPaymentsRecurring": "Det er nødvendigt at sætte hak i boksen nedenunder for at oprette dit abonnement. Det vil tillade, at din Amazonkonto kan bruges til gentagne betalinger for <strong>dette</strong> abonnement. Det vil ikke forårsage, at din Amazonkonto bliver brugt automatisk ved fremtidige køb.",
"timezone": "Tidszone",
"timezoneUTC": "Habitica bruger tidszonen sat på din PC, som er: <strong><%= utc %></strong>",
"timezoneInfo": "Hvis tidszonen er forkert, kan du først genindlæse denne side ved hjælp af din browsers knap til genindlæsning for at give Habitica de mest opdaterede informationer. Hvis den stadig er forkert, kan du justere din tidszone på din PC og derefter genindlæse siden igen.<br><br> <strong>Hvis du bruger Habitica på andre PC'er eller mobile enheder, skal tidszonen være den samme på dem alle.</strong> Hvis dine Daglige er blevet nulstellet på det forkerte tidspunkt. kan du gentage denne gennemgang alle andre PC'er og i en browser på dine mobile enheder.",
"timezoneUTC": "Habitica bruger tidszonen fra din PC, som er: <strong><%= utc %></strong>",
"timezoneInfo": "Hvis tidszonen er forkert, kan du først genindlæse denne side, ved hjælp af din browsers knap til genindlæsning, for at give Habitica de mest opdaterede informationer. Hvis den stadig er forkert, kan du justere din tidszone på din PC, og derefter genindlæse siden igen.<br><br> <strong>Hvis du bruger Habitica på andre PC'er eller mobile enheder, skal tidszonen være den samme på dem alle.</strong> Hvis dine Daglige er blevet nulstillet på det forkerte tidspunkt. gentag venligst denne gennemgang af alle PC'er og i en browser på alle mobile enheder.",
"push": "Push",
"about": "Om Habitica",
"setUsernameNotificationTitle": "Bekræft dit brugernavn!",
"setUsernameNotificationBody": "Vi vil skifte loginnavne til unikke, offentlige brugernavne snart. Dette brugernavn vil blive brugt til invitationer, @tags i chat og beskeder.",
"setUsernameNotificationBody": "Vi ændrer snart loginnavne til unikke, offentlige brugernavne. Dette brugernavn vil blive brugt til invitationer, @tags i chat og beskeder.",
"usernameIssueSlur": "Brugernavne må ikke indeholde upassende sprogbrug.",
"usernameIssueForbidden": "Brugernavne må ikke indeholde blokerede ord.",
"usernameIssueLength": "Brugernavne skal være mellem 1 og 20 tegn.",
@@ -200,9 +200,13 @@
"currentUsername": "Nuværende brugernavn:",
"displaynameIssueLength": "Displaynavne skal indeholde mellem 1 og 30 tegn.",
"displaynameIssueSlur": "Displaynavne må ikke indeholde upassende sprogbrug.",
"goToSettings": "Gå til Indstillinger",
"goToSettings": "Gå til indstillinger",
"usernameVerifiedConfirmation": "Dit brugernavn, <%= username %>, er blevet bekræftet!",
"usernameNotVerified": "Bekræft venligst dit brugernavn.",
"changeUsernameDisclaimer": "Vi vil lave loginnavne om til unikke, offentlige brugernavne snart. Dette brugernavn vil blive brugt til invitationer, @tags i chat og beskeder.",
"verifyUsernameVeteranPet": "Et af disse Veterankæledyr venter på dig når du er færdig med at bekræfte!"
"changeUsernameDisclaimer": "Dette brugernavn vil blive brugt til invitationer, @tags i chat og beskeder.",
"verifyUsernameVeteranPet": "Et af disse veterankæledyr venter på dig, når du er færdig med at bekræfte!",
"onlyPrivateSpaces": "Kun i private rum",
"everywhere": "Alle steder",
"suggestMyUsername": "Foreslå mit brugernavn",
"mentioning": "Tagging"
}

View File

@@ -485,5 +485,12 @@
"backgroundHolidayWreathText": "Adventskranz",
"backgroundHolidayMarketNotes": "Finde die perfekten Geschenke und Dekorationsartikel auf einem Weihnachtsmarkt.",
"backgroundHolidayMarketText": "Weihnachtsmarkt",
"backgrounds122019": "SET 67: Veröffentlicht im Dezember 2019"
"backgrounds122019": "Set 67: Veröffentlicht im Dezember 2019",
"backgroundSnowglobeNotes": "Schüttele eine Schneekugel und nimm Deinen Platz im Mikrokosmos einer Winterlandschaft ein.",
"backgroundSnowglobeText": "Schneekugel",
"backgroundDesertWithSnowNotes": "Erlebe die rare und stille Schönheit einer Verschneiten Wüste.",
"backgroundDesertWithSnowText": "Verschneite Wüste",
"backgroundBirthdayPartyNotes": "Feiere den Geburtstag Deines Lieblingsmitmenschen in Habitica.",
"backgroundBirthdayPartyText": "Geburtstagsfeier",
"backgrounds012020": "Set 68: Veröffentlicht im Januar 2020"
}

View File

@@ -2017,5 +2017,13 @@
"headMystery202001Text": "Fabelhafte Fuchsohren",
"headSpecialNye2019Notes": "Du hast einen Frevelhaften Fetenhut erhalten! Trage ihn mit Stolz während Du das neue Jahr einläutest! Gewährt keinen Attributbonus.",
"headSpecialNye2019Text": "Frevelhafter Fetenhut",
"armorSpecialWinter2020MageNotes": "Läute das neue Jahr in dieser warmen, gemütlichen Robe ein, die Dich gegen übermässige Erschütterungen puffert. Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe 2019-2020 Winterausrüstung."
"armorSpecialWinter2020MageNotes": "Läute das neue Jahr in dieser warmen, gemütlichen Robe ein, die Dich gegen übermässige Erschütterungen puffert. Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe 2019-2020 Winterausrüstung.",
"shieldArmoireBirthdayBannerNotes": "Feiere Deinen besonderen Tag, den besonderen Tag von jemandem, den Du liebst, oder trage es zum Geburtstag von Habitica am 31. Januar! Erhöht Stärke um <%= str %>. Verzauberter Schrank: Herzlichen Glückwunsch zum Geburtstag-Set (Gegenstand 4 von 4).",
"shieldArmoireBirthdayBannerText": "Geburtstagsgösch",
"headArmoireFrostedHelmNotes": "Der perfekte Kopfschutz für jede Feier! Erhöht Intelligenz um <%= int %>. Verzauberter Schrank: Herzlichen Glückwunsch zum Geburtstag-Set (Gegenstand 1 von 4).",
"headArmoireFrostedHelmText": "Glasierter Helm",
"armorArmoireLayerCakeArmorNotes": "Sie ist schützend und lecker! Erhöht Ausdauer um <%= con %>. Verzauberter Schrank: Herzlichen Glückwunsch zum Geburtstag-Set (Gegenstand 2 von 4).",
"armorArmoireLayerCakeArmorText": "Schichttortenrüstung",
"weaponArmoireHappyBannerNotes": "Steht das \"H\" für Herzlich oder für Habitica? Entscheide selbst! Erhöht Wahrnehmung um <%= per %>. Verzauberter Schrank: Herzlichen Glückwunsch zum Geburtstag-Set (Gegenstand 3 von 4).",
"weaponArmoireHappyBannerText": "Herzliche Gösch"
}

View File

@@ -3,7 +3,7 @@
"stringNotFound": "String '<%= string %>' nicht gefunden.",
"titleIndex": "Habitica | Dein Leben, das Rollenspiel",
"habitica": "Habitica",
"habiticaLink": "<a href='http://habitica.fandom.com/wiki/Habitica' target='_blank'>Habitica</a>",
"habiticaLink": "<a href='http://habitica.fandom.com/de/wiki/Habitica' target='_blank'>Habitica</a>",
"onward": "Vorwärts!",
"done": "Erledigt",
"gotIt": "Verstanden!",

View File

@@ -138,6 +138,7 @@
"PMPlaceholderDescription": "Select a conversation on the left",
"PMPlaceholderTitleRevoked": "Your chat privileges have been revoked",
"PMReceive": "Receive Private Messages",
"PMDisabled": "Disable Private Messages",
"PMEnabledOptPopoverText": "Private Messages are enabled. Users can contact you via your profile.",
"PMDisabledOptPopoverText": "Private Messages are disabled. Enable this option to allow users to contact you via your profile.",
"PMDisabledCaptionTitle": "Private Messages are disabled",
@@ -151,6 +152,7 @@
"toUserIDRequired": "A User ID is required",
"gemAmountRequired": "A number of gems is required",
"notAuthorizedToSendMessageToThisUser": "You can't send a message to this player because they have chosen to block messages.",
"blockedToSendToThisUser": "You can't send to this player because you have blocked this player.",
"privateMessageGiftGemsMessage": "Hello <%= receiverName %>, <%= senderName %> has sent you <%= gemAmount %> gems!",
"privateMessageGiftSubscriptionMessage": "<%= numberOfMonths %> months of subscription! ",
"cannotSendGemsToYourself": "Cannot send gems to yourself. Try a subscription instead.",

View File

@@ -68,7 +68,8 @@
"notificationsRequired": "Notification ids are required.",
"unallocatedStatsPoints": "You have <span class=\"notification-bold-blue\"><%= points %> unallocated Stat Points</span>",
"beginningOfConversation": "This is the beginning of your conversation with <%= userName %>. Remember to be kind, respectful, and follow the Community Guidelines!",
"beginningOfConversation": "This is the beginning of your conversation with <%= userName %>.",
"beginningOfConversationReminder": "Remember to be kind, respectful, and follow the Community Guidelines!",
"messageDeletedUser": "Sorry, this user has deleted their account.",
"messageMissingDisplayName": "Missing display name.",

View File

@@ -1793,5 +1793,25 @@
"weaponSpecialSpring2019RogueNotes": "These weapons contain th' power o' th' sky an' rain. We recommend that ye dinnae use 'em while in th' water. Raises yer Strength by <%= str %>. Limited Edition 2019 Spring Gear.",
"weaponSpecialSpring2019RogueText": "Lightnin' Bolt",
"weaponSpecialKS2019Notes": "Curved as a gryphon's beak an' talons, this fancy polearm reminds ye t' power through when th' task ahead feels o'erwhelmin'. Raises yer Strength by <%= str %>.",
"weaponSpecialKS2019Text": "yon Mythical Gryphon Glaive"
"weaponSpecialKS2019Text": "yon Mythical Gryphon Glaive",
"weaponArmoireMagnifyingGlassNotes": "Arrr!! A piece o' evidence! Examine it closely wi' this fine magnifier. Increases Perception by <%= per %>. Enchanted Armoire: Detective Set (Item 3 of 4).",
"weaponArmoireMagnifyingGlassText": "Magnifyin' Glass",
"weaponArmoireAstronomersTelescopeNotes": "An inster-mint that'll allow ye t' observe th' stars' ancient dance. Raises yer Perception by <%= per %>. Enchanted Armoire: Astronomer Mage Set (Item 3 of 3).",
"weaponArmoireAstronomersTelescopeText": "Astronomer's 'Scope",
"weaponArmoireBambooCaneNotes": "Perfick fer assistin' ye in a stroll, or fer dancin' the Charleston. Raises yer Intelligence, Perception, and Constitution by <%= attrs %> each. Enchanted Armoire: Boatin' Set (Item 3 of 3).",
"weaponArmoireBambooCaneText": "Cane o' Bamboo",
"weaponArmoireNephriteBowNotes": "This bow shoots special jade-tipped arrers that'll take down e'en yer most stubborn bad 'abits! Raises yer Intelligence by <%= int %> and Strength by <%= str %>. Enchanted Armoire: Nephrite Archer Set (Item 1 of 3).",
"weaponArmoireNephriteBowText": "Bow o' Nephrite",
"weaponArmoireSlingshotNotes": "Take aim atcher red Dailies! Raises yer Strength by <%= str %>. Enchanted Armoire: Independent Item.",
"weaponArmoireSlingshotText": "yon Slingshot",
"weaponArmoireJugglingBallsNotes": "Habiticans be masters at multi-taskin', so ye should 'ave no trouble keepin' all these balls in th' air! Raises yer Intelligence by <%= int %>. Enchanted Armoire: Independent Item.",
"weaponArmoireJugglingBallsText": "Jugglin' Balls",
"weaponMystery201911Notes": "Th' crystal ball atop yon staff kin show ye th' future, but beware! Usin' such dang'rous knowledge kin change a person in ways ye'd no' espect. Confers no benefit. November 2019 Subscriber Item.",
"weaponMystery201911Text": "Becharmed Crystal Staff",
"weaponSpecialWinter2020HealerNotes": "Wavin' it about'll waft th' aroma t' summon yer friends an' 'elpers ta begin cookin' an' bakin'! Raises yer Intelligence by <%= int %>. Limited Edition 2019-2020 Winter Gear.",
"weaponSpecialWinter2020HealerText": "Clove-Spice Scepter",
"weaponSpecialWinter2020MageNotes": "Wiv practice, ye kin perject this aural magic (in waves! Like th' sea!!) any way ye like: a thoughtful hum, a festive chime, er a RED TASK O'ERBOARD ALARM. Raises yer Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2019-2020 Winter Gear.",
"weaponSpecialWinter2020MageText": "Ripplin' Waves o' Sound",
"weaponSpecialWinter2020WarriorNotes": "Avast, squirrels! Ye'll get no piece o' this! ...But iffen ye wanna hang out an' 'ave cocoa, that be cool. Raises yer Strength by <%= str %>. Limited Edition 2019-2020 Winter Gear.",
"weaponSpecialWinter2020WarriorText": "Pointy Conny-fer Cone"
}

View File

@@ -18,5 +18,50 @@
"achievementJustAddWater": "Just Add Water",
"achievementMindOverMatterModalText": "You completed the Rock, Slime, and Yarn pet quests!",
"achievementMindOverMatterText": "Has completed Rock, Slime, and Yarn pet quests.",
"achievementMindOverMatter": "Mind Over Matter"
"achievementMindOverMatter": "Mind Over Matter",
"achievementPearlyProModalText": "You tamed all the White Mounts!",
"achievementPearlyProText": "Has tamed all White Mounts.",
"achievementPearlyPro": "Pearly Pro",
"achievementPrimedForPaintingModalText": "You collected all the White Pets!",
"achievementPrimedForPaintingText": "Has collected all White Pets.",
"achievementPrimedForPainting": "Primed for Painting",
"achievementPurchasedEquipmentModalText": "Equipment is a way to customise your avatar and improve your stats",
"achievementPurchasedEquipmentText": "Purchased their first piece of equipment.",
"achievementPurchasedEquipment": "Purchase Equipment",
"achievementFedPetModalText": "There are many different types of food, but pets can be picky",
"achievementFedPetText": "Fed their first pet.",
"achievementFedPet": "Feed a Pet",
"achievementHatchedPetModalText": "Head over to your inventory and try combining a hatching potion and an egg",
"achievementHatchedPetText": "Hatched their first pet.",
"achievementHatchedPet": "Hatch a Pet",
"achievementCompletedTaskModalText": "Check off any of your tasks to earn rewards",
"achievementCompletedTaskText": "Completed their first task.",
"achievementCompletedTask": "Complete a Task",
"achievementCreatedTaskModalText": "Add a task for something you would like to accomplish this week",
"achievementCreatedTaskText": "Created their first task.",
"achievementCreatedTask": "Create a Task",
"achievementUndeadUndertakerModalText": "You tamed all the Zombie Mounts!",
"achievementUndeadUndertakerText": "Has tamed all Zombie Mounts.",
"achievementUndeadUndertaker": "Undead Undertaker",
"achievementMonsterMagusModalText": "You collected all the Zombie Pets!",
"achievementMonsterMagusText": "Has collected all Zombie Pets.",
"achievementMonsterMagus": "Monster Magus",
"achievementPartyOn": "Your party grew to 4 members!",
"achievementKickstarter2019Text": "Backed the 2019 Pin Kickstarter Project",
"achievementKickstarter2019": "Pin Kickstarter Backer",
"achievementAridAuthorityModalText": "You tamed all the Desert Mounts!",
"achievementAridAuthorityText": "Has tamed all Desert Mounts.",
"achievementAridAuthority": "Arid Authority",
"achievementPartyUp": "You teamed up with a party member!",
"achievementDustDevilModalText": "You collected all the Desert Pets!",
"achievementDustDevilText": "Has collected all Desert Pets.",
"achievementDustDevil": "Dust Devil",
"hideAchievements": "Hide <%= category %>",
"showAllAchievements": "Show All <%= category %>",
"onboardingCompleteDesc": "You earned <strong>5 achievements</strong> and <strong class=\"gold-amount\">100</strong> gold for completing the list.",
"earnedAchievement": "You earned an achievement!",
"viewAchievements": "View Achievements",
"letsGetStarted": "Let's get started!",
"onboardingProgress": "<%= percentage %>% progress",
"gettingStartedDesc": "Lets create a task, complete it, then check out your rewards. Youll earn <strong>5 achievements</strong> and <strong class=\"gold-amount\">100 gold</strong> once youre done!"
}

View File

@@ -422,5 +422,75 @@
"backgroundFieldWithColoredEggsText": "Field with Coloured Eggs",
"backgroundFieldWithColoredEggsNotes": "Hunt for springtime treasure in a Field with Coloured Eggs.",
"backgroundFlowerMarketText": "Flower Market",
"backgroundFlowerMarketNotes": "Find the perfect colours for bouquet or garden in a Flower Market."
"backgroundFlowerMarketNotes": "Find the perfect colours for bouquet or garden in a Flower Market.",
"backgroundHolidayMarketText": "Holiday Market",
"backgroundHolidayMarketNotes": "Find the perfect gifts and decorations at a Holiday Market.",
"backgroundHolidayWreathText": "Holiday Wreath",
"backgroundHolidayWreathNotes": "Festoon your avatar with a fragrant Holiday Wreath.",
"backgroundWinterNocturneText": "Winter Nocturne",
"backgroundWinterNocturneNotes": "Bask in the starlight of a Winter Nocturne.",
"backgrounds012020": "SET 68: Released January 2020",
"backgroundBirthdayPartyText": "Birthday Party",
"backgroundBirthdayPartyNotes": "Celebrate the Birthday Party of your favourite Habitican.",
"backgroundDesertWithSnowText": "Snowy Desert",
"backgroundDesertWithSnowNotes": "Witness the rare and quiet beauty of a Snowy Desert.",
"backgroundSnowglobeText": "Snowglobe",
"backgroundSnowglobeNotes": "Shake up a Snowglobe and take your place in a microcosm of a winter landscape.",
"backgrounds122019": "SET 67: Released December 2019",
"backgroundPotionShopNotes": "Find an elixir for any ailment at a Potion Shop.",
"backgroundPotionShopText": "Potion Shop",
"backgroundFlyingInAThunderstormNotes": "Chase a Tumultuous Thunderstorm as closely as you dare.",
"backgroundFlyingInAThunderstormText": "Tumultuous Thunderstorm",
"backgroundFarmersMarketNotes": "Shop for the freshest of foods at a Farmer's Market.",
"backgroundFarmersMarketText": "Farmer's Market",
"backgrounds112019": "SET 66: Released November 2019",
"backgroundMonsterMakersWorkshopNotes": "Experiment with discredited sciences in a Monster Maker's Workshop.",
"backgroundMonsterMakersWorkshopText": "Monster Maker's Workshop",
"backgroundPumpkinCarriageNotes": "Ride in an enchanted Pumpkin Carriage before the clock strikes midnight.",
"backgroundPumpkinCarriageText": "Pumpkin Carriage",
"backgroundFoggyMoorNotes": "Watch your step traversing a Foggy Moor.",
"backgroundFoggyMoorText": "Foggy Moor",
"backgrounds102019": "SET 65: Released October 2019",
"backgroundInAClassroomNotes": "Absorb knowledge from your mentors in a Classroom.",
"backgroundInAClassroomText": "Classroom",
"backgroundInAnAncientTombNotes": "Brave the mysteries of an Ancient Tomb.",
"backgroundInAnAncientTombText": "Ancient Tomb",
"backgroundAutumnFlowerGardenNotes": "Take in the warmth of an Autumn Flower Garden.",
"backgroundAutumnFlowerGardenText": "Autumn Flower Garden",
"backgrounds092019": "SET 64: Released September 2019",
"backgroundTreehouseNotes": "Hang out in an arboreal hideaway all to yourself, in your very own Treehouse.",
"backgroundTreehouseText": "Treehouse",
"backgroundGiantDandelionsNotes": "Dally among Giant Dandelions.",
"backgroundGiantDandelionsText": "Giant Dandelions",
"backgroundAmidAncientRuinsNotes": "Stand in reverence of the mysterious past Amid Ancient Ruins.",
"backgroundAmidAncientRuinsText": "Amid Ancient Ruins",
"backgrounds082019": "SET 63: Released August 2019",
"backgroundAmongGiantAnemonesNotes": "Explore reef life, protected from predators Among Giant Anemones.",
"backgroundAmongGiantAnemonesText": "Among Giant Anemones",
"backgroundFlyingOverTropicalIslandsNotes": "Let the view take your breath away as you Fly over Tropical Islands.",
"backgroundFlyingOverTropicalIslandsText": "Flying over Tropical Islands",
"backgroundLakeWithFloatingLanternsNotes": "Stargaze from the festival atmosphere of a Lake with Floating Lanterns.",
"backgroundLakeWithFloatingLanternsText": "Lake with Floating Lanterns",
"backgrounds072019": "SET 62: Released July 2019",
"backgroundUnderwaterVentsNotes": "Take a deep dive down, down to the Underwater Vents.",
"backgroundUnderwaterVentsText": "Underwater Vents",
"backgroundSeasideCliffsNotes": "Stand on a beach with the beauty of Seaside Cliffs above.",
"backgroundSeasideCliffsText": "Seaside Cliffs",
"backgroundSchoolOfFishNotes": "Swim among a School of Fish.",
"backgroundSchoolOfFishText": "School of Fish",
"backgrounds062019": "SET 61: Released June 2019",
"backgroundRainbowMeadowNotes": "Find the pot of gold where a Rainbow ends in a Meadow.",
"backgroundRainbowMeadowText": "Rainbow Meadow",
"backgroundParkWithStatueNotes": "Follow a flower-lined path through a Park with a Statue.",
"backgroundParkWithStatueText": "Park with Statue",
"backgroundDojoNotes": "Learn new moves in a Dojo.",
"backgroundDojoText": "Dojo",
"backgrounds052019": "SET 60: Released May 2019",
"backgroundBlossomingDesertNotes": "Witness a rare superbloom in the Blossoming Desert.",
"backgroundBlossomingDesertText": "Blossoming Desert",
"backgroundHalflingsHouseNotes": "Visit a charming Halfling's House.",
"backgroundHalflingsHouseText": "Halfling's House",
"backgroundBirchForestNotes": "Dally in a peaceful Birch Forest.",
"backgroundBirchForestText": "Birch Forest",
"backgrounds042019": "SET 59: Released April 2019"
}

View File

@@ -104,7 +104,7 @@
"allocatePerPop": "Add a Point to Perception",
"allocateInt": "Points allocated to Intelligence:",
"allocateIntPop": "Add a Point to Intelligence",
"noMoreAllocate": "Now that you've hit level 100, you won't gain any more Stat Points. You can continue leveling up, or start a new adventure at level 1 by using the <a href='http://habitica.fandom.com/wiki/Orb_of_Rebirth' target='_blank'>Orb of Rebirth</a>, now available for free in the Market.",
"noMoreAllocate": "Now that you've hit level 100, you won't gain any more Stat Points. You can continue levelling up, or start a new adventure at level 1 by using the <a href='http://habitica.fandom.com/wiki/Orb_of_Rebirth' target='_blank'>Orb of Rebirth</a>!",
"stats": "Stats",
"achievs": "Achievements",
"strength": "Strength",
@@ -224,5 +224,9 @@
"mainHand": "Main-Hand",
"offHand": "Off-Hand",
"statPoints": "Stat Points",
"pts": "pts"
"pts": "pts",
"chatCastSpellUser": "<%= username %> casts <%= spell %> on <%= target %>.",
"chatCastSpellParty": "<%= username %> casts <%= spell %> for the party.",
"purchasePetItemConfirm": "This purchase would exceed the number of items you need to hatch all possible <%= itemText %> pets. Are you sure?",
"purchaseForGold": "Purchase for <%= cost %> Gold?"
}

View File

@@ -17,14 +17,14 @@
"commGuideList02E": "<strong>Avoid profanity. This includes milder, religious-based oaths that may be acceptable elsewhere</strong>. We have people from all religious and cultural backgrounds, and we want to make sure that all of them feel comfortable in public spaces. <strong>If a moderator or staff member tells you that a term is disallowed on Habitica, even if it is a term that you did not realize was problematic, that decision is final</strong>. Additionally, slurs will be dealt with very severely, as they are also a violation of the Terms of Service.",
"commGuideList02F": "<strong>Avoid extended discussions of divisive topics in the Tavern and where it would be off-topic</strong>. If you feel that someone has said something rude or hurtful, do not engage them. If someone mentions something that is allowed by the guidelines but which is hurtful to you, its okay to politely let someone know that. If it is against the guidelines or the Terms of Service, you should flag it and let a mod respond. When in doubt, flag the post.",
"commGuideList02G": "<strong>Comply immediately with any Mod request</strong>. This could include, but is not limited to, requesting you limit your posts in a particular space, editing your profile to remove unsuitable content, asking you to move your discussion to a more suitable space, etc.",
"commGuideList02H": "<strong>Take time to reflect instead of responding in anger</strong> if someone tells you that something you said or did made them uncomfortable. There is great strength in being able to sincerely apologize to someone. If you feel that the way they responded to you was inappropriate, contact a mod rather than calling them out on it publicly.",
"commGuideList02I": "<strong>Divisive/contentious conversations should be reported to mods</strong> by flagging the messages involved or using the <a href='http://contact.habitica.com/' target='_blank'>Moderator Contact Form</a>. If you feel that a conversation is getting heated, overly emotional, or hurtful, cease to engage. Instead, report the posts to let us know about it. Moderators will respond as quickly as possible. It's our job to keep you safe. If you feel that more context is required, you can report the problem using the <a href='http://contact.habitica.com/' target='_blank'>Moderator Contact Form</a>.",
"commGuideList02H": "<strong>Take time to reflect instead of responding in anger</strong> if someone tells you that something you said or did made them uncomfortable. There is great strength in being able to sincerely apologise to someone. If you feel that the way they responded to you was inappropriate, contact a mod rather than calling them out on it publicly.",
"commGuideList02I": "<strong>Divisive/contentious conversations should be reported to mods</strong> by flagging the messages involved or using the <a href='https://contact.habitica.com/' target='_blank'>Moderator Contact Form</a>. If you feel that a conversation is getting heated, overly emotional, or hurtful, cease to engage. Instead, report the posts to let us know about it. Moderators will respond as quickly as possible. It's our job to keep you safe. If you feel that more context is required, you can report the problem using the <a href='https://contact.habitica.com/' target='_blank'>Moderator Contact Form</a>.",
"commGuideList02J": "<strong>Do not spam</strong>. Spamming may include, but is not limited to: posting the same comment or query in multiple places, posting links without explanation or context, posting nonsensical messages, posting multiple promotional messages about a Guild, Party or Challenge, or posting many messages in a row. Asking for gems or a subscription in any of the chat spaces or via Private Message is also considered spamming. If people clicking on a link will result in any benefit to you, you need to disclose that in the text of your message or that will also be considered spam.<br/><br/>It is up to the mods to decide if something constitutes spam or might lead to spam, even if you dont feel that you have been spamming. For example, advertising a Guild is acceptable once or twice, but multiple posts in one day would probably constitute spam, no matter how useful the Guild is!",
"commGuideList02K": "<strong>Avoid posting large header text in the public chat spaces, particularly the Tavern</strong>. Much like ALL CAPS, it reads as if you were yelling, and interferes with the comfortable atmosphere.",
"commGuideList02L": "<strong>We highly discourage the exchange of personal information -- particularly information that can be used to identify you -- in public chat spaces</strong>. Identifying information can include but is not limited to: your address, your email address, and your API token/password. This is for your safety! Staff or moderators may remove such posts at their discretion. If you are asked for personal information in a private Guild, Party, or PM, we highly recommend that you politely refuse and alert the staff and moderators by either 1) flagging the message if it is in a Party or private Guild, or 2) filling out the <a href='http://contact.habitica.com/' target='_blank'>Moderator Contact Form</a> and including screenshots.",
"commGuideList02L": "<strong>We highly discourage the exchange of personal information -- particularly information that can be used to identify you -- in public chat spaces</strong>. Identifying information can include but is not limited to: your address, your email address, and your API token/password. This is for your safety! Staff or moderators may remove such posts at their discretion. If you are asked for personal information in a private Guild, Party, or PM, we highly recommend that you politely refuse and alert the staff and moderators by either 1) flagging the message if it is in a Party or private Guild, or 2) filling out the <a href='https://contact.habitica.com/' target='_blank'>Moderator Contact Form</a> and including screenshots.",
"commGuidePara019": "<strong>In private spaces</strong>, users have more freedom to discuss whatever topics they would like, but they still may not violate the Terms and Conditions, including posting slurs or any discriminatory, violent, or threatening content. Note that, because Challenge names appear in the winner's public profile, ALL Challenge names must obey the public space guidelines, even if they appear in a private space.",
"commGuidePara020": "<strong>Private Messages (PMs)</strong> have some additional guidelines. If someone has blocked you, do not contact them elsewhere to ask them to unblock you. Additionally, you should not send PMs to someone asking for support (since public answers to support questions are helpful to the community). Finally, do not send anyone PMs begging for a gift of gems or a subscription, as this can be considered spamming.",
"commGuidePara020A": "<strong>If you see a post that you believe is in violation of the public space guidelines outlined above, or if you see a post that concerns you or makes you uncomfortable, you can bring it to the attention of Moderators and Staff by clicking the flag icon to report it</strong>. A Staff member or Moderator will respond to the situation as soon as possible. Please note that intentionally reporting innocent posts is an infraction of these Guidelines (see below in “Infractions”). PMs cannot be flagged at this time, so if you need to report a PM, please contact the Mods via the form on the “Contact Us” page, which you can also access via the help menu by clicking “<a href='http://contact.habitica.com/' target='_blank'>Contact the Moderation Team</a>.” You may want to do this if there are multiple problematic posts by the same person in different Guilds, or if the situation requires some explanation. You may contact us in your native language if that is easier for you: we may have to use Google Translate, but we want you to feel comfortable about contacting us if you have a problem.",
"commGuidePara020A": "<strong>If you see a post that you believe is in violation of the public space guidelines outlined above, or if you see a post that concerns you or makes you uncomfortable, you can bring it to the attention of Moderators and Staff by clicking the flag icon to report it</strong>. A Staff member or Moderator will respond to the situation as soon as possible. Please note that intentionally reporting innocent posts is an infraction of these Guidelines (see below in “Infractions”). PMs cannot be flagged at this time, so if you need to report a PM, please contact the Mods via the form on the “Contact Us” page, which you can also access via the help menu by clicking “<a href='https://contact.habitica.com/' target='_blank'>Contact the Moderation Team</a>.” You may want to do this if there are multiple problematic posts by the same person in different Guilds, or if the situation requires some explanation. You may contact us in your native language if that is easier for you: we may have to use Google Translate, but we want you to feel comfortable about contacting us if you have a problem.",
"commGuidePara021": "Furthermore, some public spaces in Habitica have additional guidelines.",
"commGuideHeadingTavern": "The Tavern",
"commGuidePara022": "The Tavern is the main spot for Habiticans to mingle. Daniel the Innkeeper keeps the place spic-and-span, and Lemoness will happily conjure up some lemonade while you sit and chat. Just keep in mind…",
@@ -35,8 +35,8 @@
"commGuidePara029": "<strong>Public Guilds are much like the Tavern, except that instead of being centered around general conversation, they have a focused theme</strong>. Public Guild chat should focus on this theme. For example, members of the Wordsmiths Guild might be cross if the conversation is suddenly focusing on gardening instead of writing, and a Dragon-Fanciers Guild might not have any interest in deciphering ancient runes. Some Guilds are more lax about this than others, but in general, <strong>try to stay on topic</strong>!",
"commGuidePara031": "Some public Guilds will contain sensitive topics such as depression, religion, politics, etc. This is fine as long as the conversations therein do not violate any of the Terms and Conditions or Public Space Rules, and as long as they stay on topic.",
"commGuidePara033": "<strong>Public Guilds may NOT contain 18+ content. If they plan to regularly discuss sensitive content, they should say so in the Guild description</strong>. This is to keep Habitica safe and comfortable for everyone.",
"commGuidePara035": "<strong>If the Guild in question has different kinds of sensitive issues, it is respectful to your fellow Habiticans to place your comment behind a warning (ex. \"Warning: references self-harm\")</strong>. These may be characterized as trigger warnings and/or content notes, and Guilds may have their own rules in addition to those given here. If possible, please use <a href='http://habitica.fandom.com/wiki/Markdown_Cheat_Sheet' target='_blank'>markdown</a> to hide the potentially sensitive content below line breaks so that those who may wish to avoid reading it can scroll past it without seeing the content. Habitica staff and moderators may still remove this material at their discretion.",
"commGuidePara036": "Additionally, the sensitive material should be topical -- bringing up self-harm in a Guild focused on fighting depression may make sense, but is probably less appropriate in a music Guild. If you see someone who is repeatedly violating this guideline, especially after several requests, please flag the posts and notify the moderators via the <a href='http://contact.habitica.com/' target='_blank'>Moderator Contact Form</a>.",
"commGuidePara035": "<strong>If the Guild in question has different kinds of sensitive issues, it is respectful to your fellow Habiticans to place your comment behind a warning (ex. \"Warning: references self-harm\")</strong>. These may be characterised as trigger warnings and/or content notes, and Guilds may have their own rules in addition to those given here. If possible, please use <a href='http://habitica.fandom.com/wiki/Markdown_Cheat_Sheet' target='_blank'>markdown</a> to hide the potentially sensitive content below line breaks so that those who may wish to avoid reading it can scroll past it without seeing the content. Habitica staff and moderators may still remove this material at their discretion.",
"commGuidePara036": "Additionally, the sensitive material should be topical -- bringing up self-harm in a Guild focused on fighting depression may make sense, but is probably less appropriate in a music Guild. If you see someone who is repeatedly violating this guideline, especially after several requests, please flag the posts and notify the moderators via the <a href='https://contact.habitica.com/' target='_blank'>Moderator Contact Form</a>.",
"commGuidePara037": "<strong>No Guilds, Public or Private, should be created for the purpose of attacking any group or individual</strong>. Creating such a Guild is grounds for an instant ban. Fight bad habits, not your fellow adventurers!",
"commGuidePara038": "<strong>All Tavern Challenges and Public Guild Challenges must comply with these rules as well</strong>.",
"commGuideHeadingInfractionsEtc": "Infractions, Consequences, and Restoration",
@@ -65,7 +65,7 @@
"commGuidePara056": "Minor Infractions, while discouraged, still have minor consequences. If they continue to occur, they can lead to more severe consequences over time.",
"commGuidePara057": "The following are some examples of Minor Infractions. This is not a comprehensive list.",
"commGuideList07A": "First-time violation of Public Space Guidelines",
"commGuideList07B": "Any statements or actions that trigger a \"Please Don't\". When a Mod has to say \"Please don't do this\" to a user, it can count as a very minor infraction for that user. An example might be \"Please don't keep arguing in favor of this feature idea after we've told you several times that it isn't feasible.\" In many cases, the Please Don't will be the minor consequence as well, but if Mods have to say \"Please Don't\" to the same user enough times, the triggering Minor Infractions will start to count as Moderate Infractions.",
"commGuideList07B": "Any statements or actions that trigger a \"Please Don't\". When a Mod has to say \"Please don't do this\" to a user, it can count as a very minor infraction for that user. An example might be \"Please don't keep arguing in favour of this feature idea after we've told you several times that it isn't feasible.\" In many cases, the Please Don't will be the minor consequence as well, but if Mods have to say \"Please Don't\" to the same user enough times, the triggering Minor Infractions will start to count as Moderate Infractions.",
"commGuidePara057A": "Some posts may be hidden because they contain sensitive information or might give people the wrong idea. Typically this does not count as an infraction, particularly not the first time it happens!",
"commGuideHeadingConsequences": "Consequences",
"commGuidePara058": "In Habitica -- as in real life -- every action has a consequence, whether it is getting fit because you've been running, getting cavities because you've been eating too much sugar, or passing a class because you've been studying.",
@@ -75,7 +75,7 @@
"commGuideList08B": "what the consequence is",
"commGuideList08C": "what to do to correct the situation and restore your status, if possible.",
"commGuidePara060A": "If the situation calls for it, you may receive a PM or email as well as a post in the forum in which the infraction occurred. In some cases you may not be reprimanded in public at all.",
"commGuidePara060B": "If your account is banned (a severe consequence), you will not be able to log into Habitica and will receive an error message upon attempting to log in. <strong>If you wish to apologize or make a plea for reinstatement, please email the staff at <a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a> with your UUID</strong> (which will be given in the error message). It is <strong>your</strong> responsibility to reach out if you desire reconsideration or reinstatement.",
"commGuidePara060B": "If your account is banned (a severe consequence), you will not be able to log into Habitica and will receive an error message upon attempting to log in. <strong>If you wish to apologise or make a plea for reinstatement, please email the staff at <a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a> with your UUID</strong> (which will be given in the error message). It is <strong>your</strong> responsibility to reach out if you desire reconsideration or reinstatement.",
"commGuideHeadingSevereConsequences": "Examples of Severe Consequences",
"commGuideList09A": "Account bans (see above)",
"commGuideList09C": "Permanently disabling (\"freezing\") progression through Contributor Tiers",
@@ -94,7 +94,7 @@
"commGuideList11E": "Edits (Mods/Staff may edit problematic content)",
"commGuideHeadingRestoration": "Restoration",
"commGuidePara061": "Habitica is a land devoted to self-improvement, and we believe in second chances. <strong>If you commit an infraction and receive a consequence, view it as a chance to evaluate your actions and strive to be a better member of the community</strong>.",
"commGuidePara062": "The announcement, message, and/or email that you receive explaining the consequences of your actions is a good source of information. Cooperate with any restrictions which have been imposed, and endeavor to meet the requirements to have any penalties lifted.",
"commGuidePara062": "The announcement, message, and/or email that you receive explaining the consequences of your actions is a good source of information. Cooperate with any restrictions which have been imposed, and endeavour to meet the requirements to have any penalties lifted.",
"commGuidePara063": "If you do not understand your consequences, or the nature of your infraction, ask the Staff/Moderators for help so you can avoid committing infractions in the future. If you feel a particular decision was unfair, you can contact the staff to discuss it at <a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a>.",
"commGuideHeadingMeet": "Meet the Staff and Mods!",
"commGuidePara006": "Habitica has some tireless knights-errant who join forces with the staff members to keep the community calm, contented, and free of trolls. Each has a specific domain, but will sometimes be called to serve in other social spheres.",
@@ -111,10 +111,10 @@
"commGuidePara011c": "on Wikia",
"commGuidePara011d": "on GitHub",
"commGuidePara012": "If you have an issue or concern about a particular Mod, please send an email to our Staff (<a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a>).",
"commGuidePara013": "In a community as big as Habitica, users come and go, and sometimes a staff member or moderator needs to lay down their noble mantle and relax. The following are Staff and Moderators Emeritus. They no longer act with the power of a Staff member or Moderator, but we would still like to honor their work!",
"commGuidePara013": "In a community as big as Habitica, users come and go, and sometimes a staff member or moderator needs to lay down their noble mantle and relax. The following are Staff and Moderators Emeritus. They no longer act with the power of a Staff member or Moderator, but we would still like to honour their work!",
"commGuidePara014": "Staff and Moderators Emeritus:",
"commGuideHeadingFinal": "The Final Section",
"commGuidePara067": "So there you have it, brave Habitican -- the Community Guidelines! Wipe that sweat off of your brow and give yourself some XP for reading it all. If you have any questions or concerns about these Community Guidelines, please reach out to us via the <a href='http://contact.habitica.com/' target='_blank'>Moderator Contact Form</a> and we will be happy to help clarify things.",
"commGuidePara067": "So there you have it, brave Habitican -- the Community Guidelines! Wipe that sweat off of your brow and give yourself some XP for reading it all. If you have any questions or concerns about these Community Guidelines, please reach out to us via the <a href='https://contact.habitica.com/' target='_blank'>Moderator Contact Form</a> and we will be happy to help clarify things.",
"commGuidePara068": "Now go forth, brave adventurer, and slay some Dailies!",
"commGuideHeadingLinks": "Useful Links",
"commGuideLink01": "<a href='/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a' target='_blank'>Habitica Help: Ask a Question</a>: a Guild for users to ask questions!",

View File

@@ -212,7 +212,7 @@
"hatchingPotionFrost": "Frost",
"hatchingPotionIcySnow": "Icy Snow",
"hatchingPotionNotes": "Pour this on an egg, and it will hatch as a <%= potText(locale) %> pet.",
"premiumPotionAddlNotes": "Not usable on quest pet eggs.",
"premiumPotionAddlNotes": "Not usable on quest pet eggs. Available for purchase until <%= date(locale) %>.",
"foodMeat": "Meat",
"foodMeatThe": "the Meat",
"foodMeatA": "Meat",
@@ -339,5 +339,19 @@
"foodPieDesertA": "a slice of Desert Dessert Pie",
"foodPieRed": "Red Cherry Pie",
"foodPieRedThe": "the Red Cherry Pie",
"foodPieRedA": "a slice of Red Cherry Pie"
"foodPieRedA": "a slice of Red Cherry Pie",
"premiumPotionUnlimitedNotes": "Not usable on quest pet eggs.",
"hatchingPotionAurora": "Aurora",
"hatchingPotionAmber": "Amber",
"hatchingPotionShadow": "Shadow",
"hatchingPotionSilver": "Silver",
"hatchingPotionWatery": "Watery",
"hatchingPotionBronze": "Bronze",
"hatchingPotionSunshine": "Sunshine",
"questEggRobotAdjective": "a futuristic",
"questEggRobotMountText": "Robot",
"questEggRobotText": "Robot",
"questEggDolphinAdjective": "a chipper",
"questEggDolphinMountText": "Dolphin",
"questEggDolphinText": "Dolphin"
}

View File

@@ -1,5 +1,5 @@
{
"playerTiersDesc": "The colored usernames you see in chat represent a person's contributor tier. The higher the tier, the more the person has contributed to habitica through art, code, the community, or more!",
"playerTiersDesc": "The coloured usernames you see in chat represent a person's contributor tier. The higher the tier, the more the person has contributed to habitica through art, code, the community, or more!",
"tier1": "Tier 1 (Friend)",
"tier2": "Tier 2 (Friend)",
"tier3": "Tier 3 (Elite)",

View File

@@ -24,5 +24,42 @@
"defaultTag4": "School",
"defaultTag5": "Teams",
"defaultTag6": "Chores",
"defaultTag7": "Creativity"
"defaultTag7": "Creativity",
"defaultHabitNotes": "Or delete from the edit screen",
"defaultHabitText": "Click here to edit this into a bad habit you'd like to quit",
"creativityTodoNotes": "Tap to specify the name of your project",
"creativityTodoText": "Finish creative project",
"creativityDailyNotes": "Tap to specify the name of your current project + set the schedule!",
"creativityDailyText": "Work on creative project",
"creativityHabit": "Study a master of the craft >> + Practiced a new creative technique",
"choresTodoNotes": "Tap to specify the cluttered area!",
"choresTodoText": "Organise closet >> Organise clutter",
"choresDailyNotes": "Tap to choose your schedule!",
"choresDailyText": "Wash dishes",
"choresHabit": "10 minutes cleaning",
"selfCareTodoNotes": "Tap to specify what you plan to do!",
"selfCareTodoText": "Engage in a fun activity",
"selfCareDailyNotes": "Tap to choose your schedule!",
"selfCareDailyText": "5 minutes of quiet breathing",
"selfCareHabit": "Take a short break",
"schoolTodoNotes": "Tap to name the assignment and choose a due date!]",
"schoolTodoText": "Finish assignment for class",
"schoolDailyNotes": "Tap to choose your homework schedule!",
"schoolDailyText": "Finish homework",
"schoolHabit": "Study/Procrastinate",
"healthTodoNotes": "Tap to add checklists!",
"healthTodoText": "Schedule check-up >> Brainstorm a healthy change",
"healthDailyNotes": "Tap to make any changes!",
"healthDailyText": "Floss",
"healthHabit": "Eat Health/Junk Food",
"exerciseTodoNotes": "Tap to add a checklist!",
"exerciseTodoText": "Set up workout schedule",
"exerciseDailyNotes": "Tap to choose your schedule and specify exercises!",
"exerciseDailyText": "Stretching >> Daily workout routine",
"exerciseHabit": "10 min cardio >> + 10 minutes cardio",
"workTodoProjectNotes": "Tap to specify the name of your current project + set a due date!",
"workTodoProject": "Work project >> Complete work project",
"workDailyImportantTaskNotes": "Tap to specify your most important task",
"workDailyImportantTask": "Most important task >> Worked on todays most important task",
"workHabitMail": "Process email"
}

View File

@@ -27,7 +27,7 @@
"faqQuestion6": "How do I get a Pet or Mount?",
"iosFaqAnswer6": "At level 3, you will unlock the Drop System. Every time you complete a task, you'll have a random chance at receiving an egg, a hatching potion, or a piece of food. They will be stored in Menu > Items.\n\n To hatch a Pet, you'll need an egg and a hatching potion. Tap on the egg to determine the species you want to hatch, and select \"Hatch Egg.\" Then choose a hatching potion to determine its colour! Go to Menu > Pets to equip your new Pet to your avatar by clicking on it. \n\n You can also grow your Pets into Mounts by feeding them under Menu > Pets. Tap on a Pet, and then select \"Feed Pet\"! You'll have to feed a pet many times before it becomes a Mount, but if you can figure out its favourite food, it will grow more quickly. Use trial and error, or [see the spoilers here](http://habitica.fandom.com/wiki/Food#Food_Preferences). Once you have a Mount, go to Menu > Mounts and tap on it to equip it to your avatar.\n\n You can also get eggs for Quest Pets by completing certain Quests. (See below to learn more about Quests.)",
"androidFaqAnswer6": "At level 3, you will unlock the Drop System. Every time you complete a task, you'll have a random chance at receiving an egg, a hatching potion, or a piece of food. They will be stored in Menu > Items.\n\n To hatch a Pet, you'll need an egg and a hatching potion. Tap on the egg to determine the species you want to hatch, and select \"Hatch with potion.\" Then choose a hatching potion to determine its colour! To equip your new Pet, go to Menu > Stable > Pets, select a species, click on the desired Pet, and select \"Use\". (Your avatar doesn't update to reflect the change.) \n\n You can also grow your Pets into Mounts by feeding them under Menu > Stable [ > Pets ]. Tap on a Pet, and then select \"Feed\"! You'll have to feed a pet many times before it becomes a Mount, but if you can figure out its favourite food, it will grow more quickly. Use trial and error, or [see the spoilers here](http://habitica.fandom.com/wiki/Food#Food_Preferences). To equip your Mount, go to Menu > Stable > Mounts, select a species, click on the desired Mount, and select \"Use\". (Your avatar doesn't update to reflect the change.)\n\n You can also get eggs for Quest Pets by completing certain Quests. (See below to learn more about Quests.)",
"webFaqAnswer6": "At level 3, you will unlock the Drop System. Every time you complete a task, you'll have a random chance at receiving an egg, a hatching potion, or a piece of food. They will be stored under Inventory > Items. To hatch a Pet, you'll need an egg and a hatching potion. Once you have both an egg and a potion, go to Inventory > Stable to hatch your pet by clicking on its image. Once you've hatched a pet, you can equip it by clicking on it. You can also grow your Pets into Mounts by feeding them under Inventory > Stable. Drag a piece of food from the action bar at the bottom of the screen and drop it on a pet to feed it! You'll have to feed a Pet many times before it becomes a Mount, but if you can figure out its favorite food, it will grow more quickly. Use trial and error, or [see the spoilers here](http://habitica.fandom.com/wiki/Food#Food_Preferences). Once you have a Mount, click on it to equip it to your avatar. You can also get eggs for Quest Pets by completing certain Quests. (See below to learn more about Quests.)",
"webFaqAnswer6": "At level 3, you will unlock the Drop System. Every time you complete a task, you'll have a random chance at receiving an egg, a hatching potion, or a piece of food. They will be stored under Inventory > Items. To hatch a Pet, you'll need an egg and a hatching potion. Once you have both an egg and a potion, go to Inventory > Stable to hatch your pet by clicking on its image. Once you've hatched a pet, you can equip it by clicking on it. You can also grow your Pets into Mounts by feeding them under Inventory > Stable. Drag a piece of food from the action bar at the bottom of the screen and drop it on a pet to feed it! You'll have to feed a Pet many times before it becomes a Mount, but if you can figure out its favourite food, it will grow more quickly. Use trial and error, or [see the spoilers here](http://habitica.fandom.com/wiki/Food#Food_Preferences). Once you have a Mount, click on it to equip it to your avatar. You can also get eggs for Quest Pets by completing certain Quests. (See below to learn more about Quests.)",
"faqQuestion7": "How do I become a Warrior, Mage, Rogue, or Healer?",
"iosFaqAnswer7": "At level 10, you can choose to become a Warrior, Mage, Rogue, or Healer. (All players start as Warriors by default.) Each Class has different equipment options, different Skills that they can cast after level 11, and different advantages. Warriors can easily damage Bosses, withstand more damage from their tasks, and help make their Party tougher. Mages can also easily damage Bosses, as well as level up quickly and restore Mana for their party. Rogues earn the most gold and find the most item drops, and they can help their Party do the same. Finally, Healers can heal themselves and their Party members.\n\n If you don't want to choose a Class immediately -- for example, if you are still working to buy all the gear of your current class -- you can click “Decide Later” and choose later under Menu > Choose Class.",
"androidFaqAnswer7": "At level 10, you can choose to become a Warrior, Mage, Rogue, or Healer. (All players start as Warriors by default.) Each Class has different equipment options, different Skills that they can cast after level 11, and different advantages. Warriors can easily damage Bosses, withstand more damage from their tasks, and help make their Party tougher. Mages can also easily damage Bosses, as well as level up quickly and restore Mana for their party. Rogues earn the most gold and find the most item drops, and they can help their Party do the same. Finally, Healers can heal themselves and their Party members.\n\n If you don't want to choose a Class immediately -- for example, if you are still working to buy all the gear of your current class -- you can click “Opt Out” and choose later under Menu > Choose Class.",

View File

@@ -37,7 +37,7 @@
"companyVideos": "Videos",
"contribUse": "Habitica contributors use",
"dragonsilverQuote": "I can't tell you how many time and task tracking systems I've tried over the decades... [Habitica] is the only thing I've used that actually helps me get things done rather than just list them.",
"dreimQuote": "When I discovered [Habitica] last summer, I had just failed about half of my exams. Thanks to the Dailies... I was able to organize and discipline myself, and I actually passed all my exams with really good grades a month ago.",
"dreimQuote": "When I discovered [Habitica] last summer, I had just failed about half of my exams. Thanks to the Dailies... I was able to organise and discipline myself, and I actually passed all my exams with really good grades a month ago.",
"elmiQuote": "Every morning I'm looking forward to getting up so I can earn some gold!",
"forgotPassword": "Forgot Password?",
"emailNewPass": "Email a Password Reset Link",
@@ -85,7 +85,7 @@
"landingend": "Not convinced yet?",
"landingend2": "See a more detailed list of [our features](/static/overview). Are you looking for a more private approach? Check out our [administrative packages](/static/plans), which are perfect for families, teachers, support groups, and businesses.",
"landingp1": "The problem with most productivity apps on the market is that they provide no incentive to continue using them. Habitica fixes this by making habit building fun! By rewarding you for your successes and penalising you for slip-ups, Habitica provides external motivation for completing your day-to-day activities.",
"landingp2": "Whenever you reinforce a positive habit, complete a daily task, or take care of an old to-do, Habitica immediately rewards you with Experience points and Gold. As you gain experience, you can level up, increasing your Stats and unlocking more features, like classes and pets. Gold can be spent on in-game items that change your experience or personalized rewards you've created for motivation. When even the smallest successes provide you with an immediate reward, you're less likely to procrastinate.",
"landingp2": "Whenever you reinforce a positive habit, complete a daily task, or take care of an old to-do, Habitica immediately rewards you with Experience points and Gold. As you gain experience, you can level up, increasing your Stats and unlocking more features, like classes and pets. Gold can be spent on in-game items that change your experience or personalised rewards you've created for motivation. When even the smallest successes provide you with an immediate reward, you're less likely to procrastinate.",
"landingp2header": "Instant Gratification",
"landingp3": "Whenever you indulge in a bad habit or fail to complete one of your daily tasks, you lose health. If your health drops too low, you lose some of the progress you've made. By providing immediate consequences, Habitica can help break bad habits and procrastination cycles before they cause real-world problems.",
"landingp3header": "Consequences",
@@ -112,7 +112,7 @@
"marketing2Lead3Title": "Challenge Each Other",
"marketing2Lead3": "Challenges let you compete with friends and strangers. Whoever does the best at the end of a challenge wins special prizes.",
"marketing3Header": "Apps and Extensions",
"marketing3Lead1": "The **iPhone & Android** apps let you take care of business on the go. We realize that logging into the website to click buttons can be a drag.",
"marketing3Lead1": "The **iPhone & Android** apps let you take care of business on the go. We realise that logging into the website to click buttons can be a drag.",
"marketing3Lead2Title": "Integrations",
"marketing3Lead2": "Other **3rd Party Tools** tie Habitica into various aspects of your life. Our API provides easy integration for things like the [Chrome Extension](https://chrome.google.com/webstore/detail/habitica/pidkmpibnnnhneohdgjclfdjpijggmjj?hl=en-US), for which you lose points when browsing unproductive websites, and gain points when on productive ones. [See more here](http://habitica.fandom.com/wiki/Extensions,_Add-Ons,_and_Customizations).",
"marketing4Header": "Organisational Use",
@@ -313,16 +313,16 @@
"trackYourGoals": "Track Your Habits and Goals",
"trackYourGoalsDesc": "Stay accountable by tracking and managing your Habits, Daily goals, and To-Do list with Habiticas easy-to-use mobile apps and web interface.",
"earnRewards": "Earn Rewards for Your Goals",
"earnRewardsDesc": "Check off tasks to level up your Avatar and unlock in-game features such as battle armor, mysterious pets, magic skills, and even quests!",
"earnRewardsDesc": "Check off tasks to level up your Avatar and unlock in-game features such as battle armour, mysterious pets, magic skills, and even quests!",
"battleMonsters": "Battle Monsters with Friends",
"battleMonstersDesc": "Fight monsters with other Habiticans! Use the Gold that you earn to buy in-game or custom rewards, like watching an episode of your favorite TV show.",
"battleMonstersDesc": "Fight monsters with other Habiticans! Use the Gold that you earn to buy in-game or custom rewards, like watching an episode of your favourite TV show.",
"playersUseToImprove": "Players Use Habitica to Improve",
"healthAndFitness": "Health and Fitness",
"healthAndFitnessDesc": "Never motivated to floss? Can't seem to get to the gym? Habitica finally makes it fun to get healthy.",
"schoolAndWork": "School and Work",
"schoolAndWorkDesc": "Whether you're preparing a report for your teacher or your boss, it's easy to keep track of your progress as you tackle your toughest tasks.",
"muchmuchMore": "And much, much more!",
"muchmuchMoreDesc": "Our fully customizable task list means that you can shape Habitica to fit your personal goals. Work on creative projects, emphasize self-care, or pursue a different dream -- it's all up to you.",
"muchmuchMoreDesc": "Our fully customizable task list means that you can shape Habitica to fit your personal goals. Work on creative projects, emphasise self-care, or pursue a different dream -- it's all up to you.",
"levelUpAnywhere": "Level Up Anywhere",
"levelUpAnywhereDesc": "Our mobile apps make it simple to keep track of your tasks on-the-go. Accomplish your goals with a single tap, no matter where you are.",
"joinMany": "Join over 2,000,000 people having fun while accomplishing their goals!",
@@ -331,5 +331,6 @@
"getStarted": "Get Started!",
"mobileApps": "Mobile Apps",
"learnMore": "Learn More",
"communityInstagram": "Instagram"
"communityInstagram": "Instagram",
"minPasswordLength": "Password must be 8 characters or more."
}

View File

@@ -109,7 +109,7 @@
"weaponSpecialNomadsScimitarText": "Nomad's Scimitar",
"weaponSpecialNomadsScimitarNotes": "The curved blade of this Scimitar is perfect for attacking Tasks from the back of a mount! Increases Intelligence by <%= int %>.",
"weaponSpecialFencingFoilText": "Fencing Foil",
"weaponSpecialFencingFoilNotes": "Should anyone dare to impugn your honor, you'll be ready with this fine foil! Increases Strength by <%= str %>.",
"weaponSpecialFencingFoilNotes": "Should anyone dare to impugn your honour, you'll be ready with this fine foil! Increases Strength by <%= str %>.",
"weaponSpecialTachiText": "Tachi",
"weaponSpecialTachiNotes": "This light and curved sword will shred your tasks to ribbons! Increases Strength by <%= str %>.",
"weaponSpecialAetherCrystalsText": "Aether Crystals",
@@ -191,7 +191,7 @@
"weaponSpecialSpring2016WarriorText": "Cheese Mallet",
"weaponSpecialSpring2016WarriorNotes": "No one has as many friends as the mouse with tender cheeses. Increases Strength by <%= str %>. Limited Edition 2016 Spring Gear.",
"weaponSpecialSpring2016MageText": "Staff of Bells",
"weaponSpecialSpring2016MageNotes": "Abracadabra! So dazzling, you might mesmerize yourself! Ooh... it jingles... Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2016 Spring Gear.",
"weaponSpecialSpring2016MageNotes": "Abracadabra! So dazzling, you might mesmerise yourself! Ooh... it jingles... Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2016 Spring Gear.",
"weaponSpecialSpring2016HealerText": "Spring Flower Wand",
"weaponSpecialSpring2016HealerNotes": "With a wave and a wink, you bring the fields and forests into bloom! Or bop troublesome mice on the head. Increases Intelligence by <%= int %>. Limited Edition 2016 Spring Gear.",
"weaponSpecialSummer2016RogueText": "Electric Rod",
@@ -259,7 +259,7 @@
"weaponSpecialSpring2018HealerText": "Garnet Rod",
"weaponSpecialSpring2018HealerNotes": "The stones in this staff will focus your power when you cast healing spells! Increases Intelligence by <%= int %>. Limited Edition 2018 Spring Gear.",
"weaponSpecialSummer2018RogueText": "Fishing Rod",
"weaponSpecialSummer2018RogueNotes": "This lightweight, practically unbreakable rod and reel can be dual-wielded to maximize your DPS (Dragonfish Per Summer). Increases Strength by <%= str %>. Limited Edition 2018 Summer Gear.",
"weaponSpecialSummer2018RogueNotes": "This lightweight, practically unbreakable rod and reel can be dual-wielded to maximise your DPS (Dragonfish Per Summer). Increases Strength by <%= str %>. Limited Edition 2018 Summer Gear.",
"weaponSpecialSummer2018WarriorText": "Betta Fish Spear",
"weaponSpecialSummer2018WarriorNotes": "Mighty enough for battle, elegant enough for ceremony, this exquisitely crafted spear shows you will protect your home surf no matter what! Increases Strength by <%= str %>. Limited Edition 2018 Summer Gear.",
"weaponSpecialSummer2018MageText": "Lionfish Fin Rays",
@@ -279,7 +279,7 @@
"weaponSpecialWinter2019WarriorText": "Snowflake Halberd",
"weaponSpecialWinter2019WarriorNotes": "This snowflake was grown, ice crystal by ice crystal, into a diamond-hard blade! Increases Strength by <%= str %>. Limited Edition 2018-2019 Winter Gear.",
"weaponSpecialWinter2019MageText": "Fiery Dragon Staff",
"weaponSpecialWinter2019MageNotes": "Watch out! This explosive staff is ready to help you take on all comers. Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2018-2019 Winter Gear",
"weaponSpecialWinter2019MageNotes": "Watch out! This explosive staff is ready to help you take on all comers. Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2018-2019 Winter Gear.",
"weaponSpecialWinter2019HealerText": "Wand of Winter",
"weaponSpecialWinter2019HealerNotes": "Winter can be a time of rest and healing, and so this wand of winter magic can help to soothe the most grievous hurts. Increases Intelligence by <%= int %>. Limited Edition 2018-2019 Winter Gear.",
"weaponMystery201411Text": "Pitchfork of Feasting",
@@ -425,7 +425,7 @@
"armorSpecial2Text": "Jean Chalard's Noble Tunic",
"armorSpecial2Notes": "Makes you extra fluffy! Increases Constitution and Intelligence by <%= attrs %> each.",
"armorSpecialTakeThisText": "Take This Armour",
"armorSpecialTakeThisNotes": "This armor was earned by participating in a sponsored Challenge made by Take This. Congratulations! Increases all Stats by <%= attrs %>.",
"armorSpecialTakeThisNotes": "This armour was earned by participating in a sponsored Challenge made by Take This. Congratulations! Increases all Stats by <%= attrs %>.",
"armorSpecialFinnedOceanicArmorText": "Finned Oceanic Armour",
"armorSpecialFinnedOceanicArmorNotes": "Although delicate, this armour makes your skin as harmful to the touch as a fire coral. Increases Strength by <%= str %>.",
"armorSpecialPyromancersRobesText": "Pyromancer's Robes",
@@ -451,9 +451,9 @@
"armorSpecialSamuraiArmorText": "Samurai Armour",
"armorSpecialSamuraiArmorNotes": "This strong, scaled armour is held together by elegant silk cords. Increases Perception by <%= per %>.",
"armorSpecialTurkeyArmorBaseText": "Turkey Armor",
"armorSpecialTurkeyArmorBaseNotes": "Keep your drumsticks warm and cozy in this feathery armor! Confers no benefit.",
"armorSpecialTurkeyArmorGildedText": "Gilded Turkey Armor",
"armorSpecialTurkeyArmorGildedNotes": "Strut your stuff in this seasonally shiny armor! Confers no benefit.",
"armorSpecialTurkeyArmorBaseNotes": "Keep your drumsticks warm and cozy in this feathery armour! Confers no benefit.",
"armorSpecialTurkeyArmorGildedText": "Gilded Turkey Armour",
"armorSpecialTurkeyArmorGildedNotes": "Strut your stuff in this seasonally shiny armour! Confers no benefit.",
"armorSpecialYetiText": "Yeti-Tamer Robe",
"armorSpecialYetiNotes": "Fuzzy and fierce. Increases Constitution by <%= con %>. Limited Edition 2013-2014 Winter Gear.",
"armorSpecialSkiText": "Ski-sassin Parka",
@@ -501,7 +501,7 @@
"armorSpecialFallHealerText": "Gauzy Gear",
"armorSpecialFallHealerNotes": "Charge into battle pre-bandaged! Increases Constitution by <%= con %>. Limited Edition 2014 Autumn Gear.",
"armorSpecialWinter2015RogueText": "Icicle Drake Armour",
"armorSpecialWinter2015RogueNotes": "This armour is freezing cold, but it will definitely be worth it when you uncover the untold riches at the center of the Icicle Drake hives. Not that you are looking for any such untold riches, because you are truly, definitely, absolutely a genuine Icicle Drake, okay?! Stop asking questions! Increases Perception by <%= per %>. Limited Edition 2014-2015 Winter Gear.",
"armorSpecialWinter2015RogueNotes": "This armour is freezing cold, but it will definitely be worth it when you uncover the untold riches at the centre of the Icicle Drake hives. Not that you are looking for any such untold riches, because you are truly, definitely, absolutely a genuine Icicle Drake, okay?! Stop asking questions! Increases Perception by <%= per %>. Limited Edition 2014-2015 Winter Gear.",
"armorSpecialWinter2015WarriorText": "Gingerbread Armour",
"armorSpecialWinter2015WarriorNotes": "Cozy and warm, straight from the oven! Increases Constitution by <%= con %>. Limited Edition 2014-2015 Winter Gear.",
"armorSpecialWinter2015MageText": "Boreal Robe",
@@ -591,7 +591,7 @@
"armorSpecialFall2017RogueText": "Pumpkin Patch Robes",
"armorSpecialFall2017RogueNotes": "Need to hide out? Crouch among the Jack o' Lanterns and these robes will conceal you! Increases Perception by <%= per %>. Limited Edition 2017 Autumn Gear.",
"armorSpecialFall2017WarriorText": "Strong and Sweet Armor",
"armorSpecialFall2017WarriorNotes": "This armor will protect you like a delicious candy shell. Increases Constitution by <%= con %>. Limited Edition 2017 Autumn Gear.",
"armorSpecialFall2017WarriorNotes": "This armour will protect you like a delicious candy shell. Increases Constitution by <%= con %>. Limited Edition 2017 Autumn Gear.",
"armorSpecialFall2017MageText": "Masquerade Robes",
"armorSpecialFall2017MageNotes": "What masquerade ensemble would be complete without dramatic and sweeping robes? Increases Intelligence by <%= int %>. Limited Edition 2017 Autumn Gear.",
"armorSpecialFall2017HealerText": "Haunted House Armor",
@@ -599,7 +599,7 @@
"armorSpecialWinter2018RogueText": "Reindeer Costume",
"armorSpecialWinter2018RogueNotes": "You look so cute and fuzzy, who could suspect you are after holiday loot? Increases Perception by <%= per %>. Limited Edition 2017-2018 Winter Gear.",
"armorSpecialWinter2018WarriorText": "Wrapping Paper Armor",
"armorSpecialWinter2018WarriorNotes": "Don't let the papery feel of this armor fool you. It's nearly impossible to rip! Increases Constitution by <%= con %>. Limited Edition 2017-2018 Winter Gear.",
"armorSpecialWinter2018WarriorNotes": "Don't let the papery feel of this armour fool you. It's nearly impossible to rip! Increases Constitution by <%= con %>. Limited Edition 2017-2018 Winter Gear.",
"armorSpecialWinter2018MageText": "Sparkly Tuxedo",
"armorSpecialWinter2018MageNotes": "The ultimate in magical formalwear. Increases Intelligence by <%= int %>. Limited Edition 2017-2018 Winter Gear.",
"armorSpecialWinter2018HealerText": "Mistletoe Robes",
@@ -607,17 +607,17 @@
"armorSpecialSpring2018RogueText": "Feather Suit",
"armorSpecialSpring2018RogueNotes": "This fluffy yellow costume will trick your enemies into thinking you're just a harmless ducky! Increases Perception by <%= per %>. Limited Edition 2018 Spring Gear.",
"armorSpecialSpring2018WarriorText": "Armor of Dawn",
"armorSpecialSpring2018WarriorNotes": "This colorful plate is forged with the sunrise's fire. Increases Constitution by <%= con %>. Limited Edition 2018 Spring Gear.",
"armorSpecialSpring2018WarriorNotes": "This colourful plate is forged with the sunrise's fire. Increases Constitution by <%= con %>. Limited Edition 2018 Spring Gear.",
"armorSpecialSpring2018MageText": "Tulip Robe",
"armorSpecialSpring2018MageNotes": "Your spell casting can only improve while clad in these soft, silky petals. Increases Intelligence by <%= int %>. Limited Edition 2018 Spring Gear.",
"armorSpecialSpring2018HealerText": "Garnet Armor",
"armorSpecialSpring2018HealerNotes": "Let this bright armor infuse your heart with power for healing. Increases Constitution by <%= con %>. Limited Edition 2018 Spring Gear.",
"armorSpecialSpring2018HealerNotes": "Let this bright armour infuse your heart with power for healing. Increases Constitution by <%= con %>. Limited Edition 2018 Spring Gear.",
"armorSpecialSummer2018RogueText": "Pocket Fishing Vest",
"armorSpecialSummer2018RogueNotes": "Bobbers? Boxes of hooks? Spare line? Lockpicks? Smoke bombs? Whatever you need on hand for your summer fishing getaway, there's a pocket for it! Increases Perception by <%= per %>. Limited Edition 2018 Summer Gear.",
"armorSpecialSummer2018WarriorText": "Betta Tail Armor",
"armorSpecialSummer2018WarriorNotes": "Dazzle onlookers with whorls of magnificent color as you spin and dart through the water. How could any opponent dare strike at this beauty? Increases Constitution by <%= con %>. Limited Edition 2018 Summer Gear.",
"armorSpecialSummer2018WarriorNotes": "Dazzle onlookers with whorls of magnificent colour as you spin and dart through the water. How could any opponent dare strike at this beauty? Increases Constitution by <%= con %>. Limited Edition 2018 Summer Gear.",
"armorSpecialSummer2018MageText": "Lionfish Scale Hauberk",
"armorSpecialSummer2018MageNotes": "Venom magic has a reputation for subtlety. Not so this colorful armor, whose message is clear to beast and task alike: watch out! Increases Intelligence by <%= int %>. Limited Edition 2018 Summer Gear.",
"armorSpecialSummer2018MageNotes": "Venom magic has a reputation for subtlety. Not so this colourful armour, whose message is clear to beast and task alike: watch out! Increases Intelligence by <%= int %>. Limited Edition 2018 Summer Gear.",
"armorSpecialSummer2018HealerText": "Merfolk Monarch Robes",
"armorSpecialSummer2018HealerNotes": "These cerulean vestments reveal that you have land-walking feet... well. Not even a monarch can be expected to be perfect. Increases Constitution by <%= con %>. Limited Edition 2018 Summer Gear.",
"armorSpecialFall2018RogueText": "Alter Ego Frock Coat",
@@ -631,7 +631,7 @@
"armorSpecialWinter2019RogueText": "Poinsettia Armor",
"armorSpecialWinter2019RogueNotes": "With holiday greenery all about, no one will notice an extra shrubbery! You can move through seasonal gatherings with ease and stealth. Increases Perception by <%= per %>. Limited Edition 2018-2019 Winter Gear.",
"armorSpecialWinter2019WarriorText": "Glacial Armor",
"armorSpecialWinter2019WarriorNotes": "In the heat of battle, this armor will keep you ice cool and ready for action. Increases Constitution by <%= con %>. Limited Edition 2018-2019 Winter Gear.",
"armorSpecialWinter2019WarriorNotes": "In the heat of battle, this armour will keep you ice cool and ready for action. Increases Constitution by <%= con %>. Limited Edition 2018-2019 Winter Gear.",
"armorSpecialWinter2019MageText": "Robes of Burning Inspiration",
"armorSpecialWinter2019MageNotes": "This fireproof garb will help protect you if any of your flashes of brilliance should happen to backfire! Increases Intelligence by <%= int %>. Limited Edition 2018-2019 Winter Gear.",
"armorSpecialWinter2019HealerText": "Midnight Robe",
@@ -697,17 +697,17 @@
"armorMystery201711Text": "Carpet Rider Outfit",
"armorMystery201711Notes": "This cozy sweater set will help keep you warm as you ride through the sky! Confers no benefit. November 2017 Subscriber Item.",
"armorMystery201712Text": "Candlemancer Armor",
"armorMystery201712Notes": "The heat and light generated by this magic armor will warm your heart but never burn your skin! Confers no benefit. December 2017 Subscriber Item.",
"armorMystery201802Text": "Love Bug Armor",
"armorMystery201802Notes": "This shiny armor reflects your strength of heart and infuses it into any Habiticans nearby who may need encouragement! Confers no benefit. February 2018 Subscriber Item.",
"armorMystery201712Notes": "The heat and light generated by this magic armour will warm your heart but never burn your skin! Confers no benefit. December 2017 Subscriber Item.",
"armorMystery201802Text": "Love Bug Armour",
"armorMystery201802Notes": "This shiny armour reflects your strength of heart and infuses it into any Habiticans nearby who may need encouragement! Confers no benefit. February 2018 Subscriber Item.",
"armorMystery201806Text": "Alluring Anglerfish Tail",
"armorMystery201806Notes": "This sinuous tail features glowing spots to light your way through the deep. Confers no benefit. June 2018 Subscriber Item.",
"armorMystery201807Text": "Sea Serpent Tail",
"armorMystery201807Notes": "This powerful tail will propel you through the sea at incredible speeds! Confers no benefit. July 2018 Subscriber Item.",
"armorMystery201808Text": "Lava Dragon Armor",
"armorMystery201808Notes": "This armor is made from the shed scales of the elusive (and extremely warm) Lava Dragon. Confers no benefit. August 2018 Subscriber Item.",
"armorMystery201808Notes": "This armour is made from the shed scales of the elusive (and extremely warm) Lava Dragon. Confers no benefit. August 2018 Subscriber Item.",
"armorMystery201809Text": "Armor of Autumn Leaves",
"armorMystery201809Notes": "You are not only a small and fearsome leaf puff, you are sporting the most beautiful colors of the season! Confers no benefit. September 2018 Subscriber Item.",
"armorMystery201809Notes": "You are not only a small and fearsome leaf puff, you are sporting the most beautiful colours of the season! Confers no benefit. September 2018 Subscriber Item.",
"armorMystery201810Text": "Dark Forest Robes",
"armorMystery201810Notes": "These robes are extra warm to protect you from the ghastly cold of haunted realms. Confers no benefit. October 2018 Subscriber Item.",
"armorMystery301404Text": "Steampunk Suit",
@@ -777,7 +777,7 @@
"armorArmoireSwanDancerTutuText": "Swan Dancer Tutu",
"armorArmoireSwanDancerTutuNotes": "You just might fly away into the air as you spin in this gorgeous feathered tutu. Increases Intelligence and Strength by <%= attrs %> each. Enchanted Armoire: Swan Dancer Set (Item 2 of 3).",
"armorArmoireAntiProcrastinationArmorText": "Anti-Procrastination Armour",
"armorArmoireAntiProcrastinationArmorNotes": "Infused with ancient productivity spells, this steel armor will give you extra strength to battle your tasks. Increases Strength by <%= str %>. Enchanted Armoire: Anti-Procrastination Set (Item 2 of 3).",
"armorArmoireAntiProcrastinationArmorNotes": "Infused with ancient productivity spells, this steel armour will give you extra strength to battle your tasks. Increases Strength by <%= str %>. Enchanted Armoire: Anti-Procrastination Set (Item 2 of 3).",
"armorArmoireYellowPartyDressText": "Yellow Party Dress",
"armorArmoireYellowPartyDressNotes": "You're perceptive, strong, smart, and so fashionable! Increases Perception, Strength, and Intelligence by <%= attrs %> each. Enchanted Armoire: Yellow Hairbow Set (Item 2 of 2).",
"armorArmoireFarrierOutfitText": "Farrier Outfit",
@@ -785,7 +785,7 @@
"armorArmoireCandlestickMakerOutfitText": "Candlestick Maker Outfit",
"armorArmoireCandlestickMakerOutfitNotes": "This sturdy set of clothes will protect you from hot wax spills as you ply your craft! Increases Constitution by <%= con %>. Enchanted Armoire: Candlestick Maker Set (Item 1 of 3).",
"armorArmoireWovenRobesText": "Woven Robes",
"armorArmoireWovenRobesNotes": "Display your weaving work proudly by wearing this colorful robe! Increases Constitution by <%= con %> and Intelligence by <%= int %>. Enchanted Armoire: Weaver Set (Item 1 of 3).",
"armorArmoireWovenRobesNotes": "Display your weaving work proudly by wearing this colourful robe! Increases Constitution by <%= con %> and Intelligence by <%= int %>. Enchanted Armoire: Weaver Set (Item 1 of 3).",
"armorArmoireLamplightersGreatcoatText": "Lamplighter's Greatcoat",
"armorArmoireLamplightersGreatcoatNotes": "This heavy woolen coat can stand up to the harshest wintry night! Increases Perception by <%= per %>. Enchanted Armoire: Lamplighter's Set (Item 2 of 4).",
"armorArmoireCoachDriverLiveryText": "Coach Driver's Livery",
@@ -803,7 +803,7 @@
"armorArmoirePiraticalPrincessGownText": "Piratical Princess Gown",
"armorArmoirePiraticalPrincessGownNotes": "This luxuriant garment has many pockets for concealing weapons and loot! Increases Perception by <%= per %>. Enchanted Armoire: Piratical Princess Set (Item 2 of 4).",
"armorArmoireJeweledArcherArmorText": "Jeweled Archer Armor",
"armorArmoireJeweledArcherArmorNotes": "This finely crafted armor will protect you from projectiles or errant red Dailies! Increases Constitution by <%= con %>. Enchanted Armoire: Jeweled Archer Set (Item 2 of 3).",
"armorArmoireJeweledArcherArmorNotes": "This finely crafted armour will protect you from projectiles or errant red Dailies! Increases Constitution by <%= con %>. Enchanted Armoire: Jeweled Archer Set (Item 2 of 3).",
"armorArmoireCoverallsOfBookbindingText": "Coveralls of Bookbinding",
"armorArmoireCoverallsOfBookbindingNotes": "Everything you need in a set of coveralls, including pockets for everything. A pair of goggles, loose change, a golden ring... Increases Constitution by <%= con %> and Perception by <%= per %>. Enchanted Armoire: Bookbinder Set (Item 2 of 4).",
"armorArmoireRobeOfSpadesText": "Robe of Spades",
@@ -811,9 +811,9 @@
"armorArmoireSoftBlueSuitText": "Soft Blue Suit",
"armorArmoireSoftBlueSuitNotes": "Blue is a calming colour. So calming, some even wear this soft outfit to sleep... zZz. Increases Intelligence by <%= int %> and Perception by <%= per %>. Enchanted Armoire: Blue Loungewear Set (Item 2 of 3).",
"armorArmoireSoftGreenSuitText": "Soft Green Suit",
"armorArmoireSoftGreenSuitNotes": "Green is the most refreshing color! Ideal for resting those tired eyes... mmm, or even a nap... Increases Constitution and Intelligence by <%= attrs %> each. Enchanted Armoire: Green Loungewear Set (Item 2 of 3).",
"armorArmoireSoftGreenSuitNotes": "Green is the most refreshing colour! Ideal for resting those tired eyes... mmm, or even a nap... Increases Constitution and Intelligence by <%= attrs %> each. Enchanted Armoire: Green Loungewear Set (Item 2 of 3).",
"armorArmoireSoftRedSuitText": "Soft Red Suit",
"armorArmoireSoftRedSuitNotes": "Red is such an invigorating color. If you need to wake up bright and early, this suit could make the perfect pajamas... Increases Intelligence by <%= int %> and Strength by <%= str %>. Enchanted Armoire: Red Loungewear Set (Item 2 of 3).",
"armorArmoireSoftRedSuitNotes": "Red is such an invigorating colour. If you need to wake up bright and early, this suit could make the perfect pajamas... Increases Intelligence by <%= int %> and Strength by <%= str %>. Enchanted Armoire: Red Loungewear Set (Item 2 of 3).",
"armorArmoireScribesRobeText": "Scribe's Robes",
"armorArmoireScribesRobeNotes": "These velvety robes are woven with inspirational and motivational magic. Increases Perception and Intelligence by <%= attrs %> each. Enchanted Armoire: Scribe Set (Item 1 of 3).",
"headgear": "helm",
@@ -833,7 +833,7 @@
"headRogue1Text": "Leather Hood",
"headRogue1Notes": "Basic protective cowl. Increases Perception by <%= per %>.",
"headRogue2Text": "Black Leather Hood",
"headRogue2Notes": "Useful for both defense and disguise. Increases Perception by <%= per %>.",
"headRogue2Notes": "Useful for both defence and disguise. Increases Perception by <%= per %>.",
"headRogue3Text": "Camouflage Hood",
"headRogue3Notes": "Rugged, but doesn't impede hearing. Increases Perception by <%= per %>.",
"headRogue4Text": "Penumbral Hood",
@@ -863,7 +863,7 @@
"headSpecial0Text": "Shade Helm",
"headSpecial0Notes": "Blood and ash, lava and obsidian give this helm its imagery and power. Increases Intelligence by <%= int %>.",
"headSpecial1Text": "Crystal Helm",
"headSpecial1Notes": "The favored crown of those who lead by example. Increases all Stats by <%= attrs %>.",
"headSpecial1Notes": "The favoured crown of those who lead by example. Increases all Stats by <%= attrs %>.",
"headSpecial2Text": "Nameless Helm",
"headSpecial2Notes": "A testament to those who gave of themselves while asking nothing in return. Increases Intelligence and Strength by <%= attrs %> each.",
"headSpecialTakeThisText": "Take This Helm",
@@ -949,7 +949,7 @@
"headSpecialSpring2015MageText": "Stage Mage Hat",
"headSpecialSpring2015MageNotes": "Which came first, the bunny or the hat? Increases Perception by <%= per %>. Limited Edition 2015 Spring Gear.",
"headSpecialSpring2015HealerText": "Comforting Crown",
"headSpecialSpring2015HealerNotes": "The pearl at the center of this crown calms and comforts those around it. Increases Intelligence by <%= int %>. Limited Edition 2015 Spring Gear.",
"headSpecialSpring2015HealerNotes": "The pearl at the centre of this crown calms and comforts those around it. Increases Intelligence by <%= int %>. Limited Edition 2015 Spring Gear.",
"headSpecialSummer2015RogueText": "Renegade Hat",
"headSpecialSummer2015RogueNotes": "This pirate hat fell overboard and has been decorated with scraps of fire coral. Increases Perception by <%= per %>. Limited Edition 2015 Summer Gear.",
"headSpecialSummer2015WarriorText": "Jeweled Oceanic Helm",
@@ -1071,7 +1071,7 @@
"headSpecialNye2018Text": "Outlandish Party Hat",
"headSpecialNye2018Notes": "You've received an Outlandish Party Hat! Wear it with pride while ringing in the New Year! Confers no benefit.",
"headSpecialWinter2019RogueText": "Poinsettia Helm",
"headSpecialWinter2019RogueNotes": "This leafy helm will attain its brightest red color right around the darkest days of winter, helping you blend in with holiday decor! Increases Perception by <%= per %>. Limited Edition 2018-2019 Winter Gear.",
"headSpecialWinter2019RogueNotes": "This leafy helm will attain its brightest red colour right around the darkest days of winter, helping you blend in with holiday decor! Increases Perception by <%= per %>. Limited Edition 2018-2019 Winter Gear.",
"headSpecialWinter2019WarriorText": "Glacial Helm",
"headSpecialWinter2019WarriorNotes": "It's important to keep a cool head! This icy helm will protect you from any opponent's blows. Increases Strength by <%= str %>. Limited Edition 2018-2019 Winter Gear.",
"headSpecialWinter2019MageText": "Flaming Fireworks",
@@ -1139,7 +1139,7 @@
"headMystery201707Text": "Jellymancer Helm",
"headMystery201707Notes": "Need some extra hands for your tasks? This translucent jelly helm has quite a few tentacles to lend you help! Confers no benefit. July 2017 Subscriber Item.",
"headMystery201710Text": "Imperious Imp Helm",
"headMystery201710Notes": "This helm makes you look intimidating... but it won't do any favors for your depth perception! Confers no benefit. October 2017 Subscriber Item.",
"headMystery201710Notes": "This helm makes you look intimidating... but it won't do any favours for your depth perception! Confers no benefit. October 2017 Subscriber Item.",
"headMystery201712Text": "Candlemancer Crown",
"headMystery201712Notes": "This crown will bring light and warmth to even the darkest winter night. Confers no benefit. December 2017 Subscriber Item.",
"headMystery201802Text": "Love Bug Helm",
@@ -1157,7 +1157,7 @@
"headMystery201809Text": "Crown of Autumn Flowers",
"headMystery201809Notes": "The last flowers of autumn's warm days are a reminder of the beauty of the season. Confers no benefit. September 2018 Subscriber Item.",
"headMystery201810Text": "Dark Forest Helm",
"headMystery201810Notes": "If you find yourself traveling through a spooky place, the glowing red eyes of this helm will surely scare away any enemies in your path. Confers no benefit. October 2018 Subscriber Item.",
"headMystery201810Notes": "If you find yourself travelling through a spooky place, the glowing red eyes of this helm will surely scare away any enemies in your path. Confers no benefit. October 2018 Subscriber Item.",
"headMystery201811Text": "Splendid Sorcerer's Hat",
"headMystery201811Notes": "Wear this feathered hat to stand out at even the fanciest wizardly gatherings! Confers no benefit. November 2018 Subscriber Item.",
"headMystery201901Text": "Polaris Helm",
@@ -1181,7 +1181,7 @@
"headArmoireRancherHatText": "Rancher Hat",
"headArmoireRancherHatNotes": "Round up your pets and wrangle your mounts while wearing this magical Rancher Hat! Increases Strength by <%= str %>, Perception by <%= per %>, and Intelligence by <%= int %>. Enchanted Armoire: Rancher Set (Item 1 of 3).",
"headArmoireBlueHairbowText": "Blue Hairbow",
"headArmoireBlueHairbowNotes": "Become perceptive, tough, and smart while wearing this beautiful Blue Hairbow! Increases Perception by <%= per %>, Constitution by <%= con %>, and Intelligence by <%= int %>. Enchanted Armoire: Independent Item.",
"headArmoireBlueHairbowNotes": "Become perceptive, tough, and smart while wearing this beautiful Blue Hairbow! Increases Perception by <%= per %>, Constitution by <%= con %>, and Intelligence by <%= int %>. Enchanted Armoire: Blue Hairbow Set (Item 1 of 2).",
"headArmoireRoyalCrownText": "Royal Crown",
"headArmoireRoyalCrownNotes": "Hooray for the ruler, mighty and strong! Increases Strength by <%= str %>. Enchanted Armoire: Royal Set (Item 1 of 3).",
"headArmoireGoldenLaurelsText": "Golden Laurels",
@@ -1191,7 +1191,7 @@
"headArmoireYellowHairbowText": "Yellow Hairbow",
"headArmoireYellowHairbowNotes": "Become perceptive, strong, and smart while wearing this beautiful Yellow Hairbow! Increases Perception, Strength, and Intelligence by <%= attrs %> each. Enchanted Armoire: Yellow Hairbow Set (Item 1 of 2).",
"headArmoireRedFloppyHatText": "Red Floppy Hat",
"headArmoireRedFloppyHatNotes": "Many spells have been sewn into this simple hat, giving it a radiant red color. Increases Constitution, Intelligence, and Perception by <%= attrs %> each. Enchanted Armoire: Red Loungewear Set (Item 1 of 3).",
"headArmoireRedFloppyHatNotes": "Many spells have been sewn into this simple hat, giving it a radiant red colour. Increases Constitution, Intelligence, and Perception by <%= attrs %> each. Enchanted Armoire: Red Loungewear Set (Item 1 of 3).",
"headArmoirePlagueDoctorHatText": "Plague Doctor Hat",
"headArmoirePlagueDoctorHatNotes": "An authentic hat worn by the doctors who battle the Plague of Procrastination! Increases Strength by <%= str %>, Intelligence by <%= int %>, and Constitution by <%= con %>. Enchanted Armoire: Plague Doctor Set (Item 1 of 3).",
"headArmoireBlackCatText": "Black Cat Hat",
@@ -1199,7 +1199,7 @@
"headArmoireOrangeCatText": "Orange Cat Hat",
"headArmoireOrangeCatNotes": "This orange hat is... purring. And twitching its tail. And breathing? Yeah, you just have a sleeping cat on your head. Increases Strength and Constitution by <%= attrs %> each. Enchanted Armoire: Independent Item.",
"headArmoireBlueFloppyHatText": "Blue Floppy Hat",
"headArmoireBlueFloppyHatNotes": "Many spells have been sewn into this simple hat, giving it a brilliant blue color. Increases Constitution, Intelligence, and Perception by <%= attrs %> each. Enchanted Armoire: Blue Loungewear Set (Item 1 of 3).",
"headArmoireBlueFloppyHatNotes": "Many spells have been sewn into this simple hat, giving it a brilliant blue colour. Increases Constitution, Intelligence, and Perception by <%= attrs %> each. Enchanted Armoire: Blue Loungewear Set (Item 1 of 3).",
"headArmoireShepherdHeaddressText": "Shepherd Headdress",
"headArmoireShepherdHeaddressNotes": "Sometimes the gryphons that you herd like to chew on this headdress, but it makes you seem more intelligent nonetheless. Increases Intelligence by <%= int %>. Enchanted Armoire: Shepherd Set (Item 3 of 3).",
"headArmoireCrystalCrescentHatText": "Crystal Crescent Hat",
@@ -1217,7 +1217,7 @@
"headArmoireGraduateCapText": "Mortar Board",
"headArmoireGraduateCapNotes": "Congratulations! Your deep thoughts have earned you this thinking cap. Increases Intelligence by <%= int %>. Enchanted Armoire: Graduate Set (Item 3 of 3).",
"headArmoireGreenFloppyHatText": "Green Floppy Hat",
"headArmoireGreenFloppyHatNotes": "Many spells have been sewn into this simple hat, giving it a gorgeous green color. Increases Constitution, Intelligence, and Perception by <%= attrs %> each. Enchanted Armoire: Green Loungewear Set (Item 1 of 3).",
"headArmoireGreenFloppyHatNotes": "Many spells have been sewn into this simple hat, giving it a gorgeous green colour. Increases Constitution, Intelligence, and Perception by <%= attrs %> each. Enchanted Armoire: Green Loungewear Set (Item 1 of 3).",
"headArmoireCannoneerBandannaText": "Cannoneer Bandanna",
"headArmoireCannoneerBandannaNotes": "'Tis a cannoneer's life for me! Increases Intelligence and Perception by <%= attrs %> each. Enchanted Armoire: Cannoneer Set (Item 3 of 3).",
"headArmoireFalconerCapText": "Falconer Cap",
@@ -1369,7 +1369,7 @@
"shieldSpecialSpring2016RogueText": "Fire Bolas",
"shieldSpecialSpring2016RogueNotes": "You've mastered the ball, the club, and the knife. Now you advance to juggling fire! Woo! Increases Strength <%= str %>. Limited Edition 2016 Spring Gear.",
"shieldSpecialSpring2016WarriorText": "Cheese Wheel",
"shieldSpecialSpring2016WarriorNotes": "You braved fiendish traps to procure this defense-boosting food. Increases Constitution by <%= con %>. Limited Edition 2016 Spring Gear.",
"shieldSpecialSpring2016WarriorNotes": "You braved fiendish traps to procure this defence-boosting food. Increases Constitution by <%= con %>. Limited Edition 2016 Spring Gear.",
"shieldSpecialSpring2016HealerText": "Floral Buckler",
"shieldSpecialSpring2016HealerNotes": "The April Fool claims this little shield will block Shiny Seeds. Don't believe him. Increases Constitution by <%= con %>. Limited Edition 2016 Spring Gear.",
"shieldSpecialSummer2016RogueText": "Electric Rod",
@@ -1763,7 +1763,7 @@
"shieldMystery201902Text": "Cryptic Confetti",
"shieldMystery201902Notes": "This glittery paper forms magic hearts that slowly drift and dance in the air. Confers no benefit. February 2019 Subscriber Item",
"shieldArmoireMightyPizzaText": "Mighty Pizza",
"shieldArmoireMightyPizzaNotes": "Sure, it's a pretty good shield, but we strongly suggest you eat this fine, fine pizza. Increases Perception by <%= per %>. Enchanted Armoire: Chef Set (Item 4 of 4). ",
"shieldArmoireMightyPizzaNotes": "Sure, it's a pretty good shield, but we strongly suggest you eat this fine, fine pizza. Increases Perception by <%= per %>. Enchanted Armoire: Chef Set (Item 4 of 4).",
"eyewearMystery201902Text": "Cryptic Crush Mask",
"eyewearMystery201902Notes": "This mysterious mask hides your identity but not your winning smile. Confers no benefit. February 2019 Subscriber Item.",
"weaponSpecialSummer2019HealerText": "Bubble Wand",
@@ -1780,5 +1780,250 @@
"weaponSpecialSpring2019WarriorNotes": "Bad habits cower before this verdant blade. Increases Strength by <%= str %>. Limited Edition 2019 Spring Gear.",
"weaponSpecialSpring2019WarriorText": "Stem Sword",
"weaponSpecialSpring2019RogueNotes": "These weapons contain the power of the sky and rain. We recommend that you not use them while immersed in water. Increases Strength by <%= str %>. Limited Edition 2019 Spring Gear.",
"weaponSpecialSpring2019RogueText": "Lightning Bolt"
"weaponSpecialSpring2019RogueText": "Lightning Bolt",
"shieldSpecialPiDayText": "Pi Shield",
"shieldSpecialFall2019WarriorNotes": "The dark sheen of a raven's feather made solid, this shield will frustrate all attacks. Increases Constitution by <%= con %>. Limited Edition 2019 Autumn Gear.",
"shieldSpecialFall2019HealerText": "Grotesque Grimoire",
"shieldSpecialFall2019HealerNotes": "Harness the dark side of the Healer's arts with this Grimoire! Increases Constitution by <%= con %>. Limited Edition 2019 Autumn Gear.",
"shieldSpecialWinter2020WarriorText": "Round Conifer Cone",
"shieldSpecialWinter2020WarriorNotes": "Use it as a shield until the seeds drop, and then you can put it on a wreath! Increases Constitution by <%= con %>. Limited Edition 2019-2020 Winter Gear.",
"shieldSpecialWinter2020HealerText": "Giant Cinnamon Stick",
"shieldSpecialWinter2020HealerNotes": "Do you feel you are too good for this world, too pure? Only this beauty of a spice will do. Increases Constitution by <%= con %>. Limited Edition 2019-2020 Winter Gear.",
"shieldArmoireTrustyUmbrellaText": "Trusty Umbrella",
"shieldArmoireTrustyUmbrellaNotes": "Mysteries are often accompanied by inclement weather, so be prepared! Increases Intelligence by <%= int %>. Enchanted Armoire: Detective Set (Item 4 of 4).",
"shieldArmoirePolishedPocketwatchText": "Polished Pocketwatch",
"shieldArmoirePolishedPocketwatchNotes": "You've got the time. And it looks very nice on you. Increases Intelligence by <%= int %>. Enchanted Armoire: Independent Item.",
"shieldArmoireMasteredShadowText": "Mastered Shadow",
"shieldArmoireMasteredShadowNotes": "Your powers have brought these swirling shadows to your side to do your bidding. Increases Perception and Constitution by <%= attrs %> each. Enchanted Armoire: Shadow Master Set (Item 4 of 4).",
"shieldArmoireAlchemistsScaleText": "Alchemist's Scale",
"shieldArmoireAlchemistsScaleNotes": "Ensure that your mystical ingredients are properly measured using this fine piece of equipment. Increases Intelligence by <%= int %>. Enchanted Armoire: Alchemist Set (Item 4 of 4).",
"shieldArmoireBirthdayBannerText": "Birthday Banner",
"shieldArmoireBirthdayBannerNotes": "Celebrate your special day, the special day of someone you love, or break this out for Habitica's Birthday on January 31! Increases Strength by <%= str %>. Enchanted Armoire: Happy Birthday Set (Item 4 of 4).",
"backMystery201905Text": "Dazzling Dragon Wings",
"backMystery201905Notes": "Fly to untold realms with these iridescent wings. Confers no benefit. May 2019 Subscriber Item.",
"backMystery201912Text": "Polar Pixie Wings",
"shieldSpecialFall2019WarriorText": "Raven-Dark Shield",
"shieldSpecialSummer2019MageNotes": "Sweating in the summer sun? No! Performing a simple elemental conjuration to fill the lily pond. Increases Perception by <%= per %>. Limited Edition 2019 Summer Gear.",
"shieldSpecialSummer2019MageText": "Drops of Pure Water",
"shieldSpecialSummer2019HealerNotes": "Let those who need help know you're coming with the loud blast of this shell trumpet. Limited Edition 2019 Summer Gear. Increases Constitution by 9. ",
"shieldSpecialSummer2019HealerText": "Conch Trumpet",
"shieldSpecialSummer2019WarriorNotes": "Turtle up behind this hefty round shield, etched in the pattern of your favourite reptile's back. Increases Constitution by <%= con %>. Limited Edition 2019 Summer Gear.",
"shieldSpecialSummer2019WarriorText": "Half-Shell Shield",
"shieldSpecialSpring2019HealerNotes": "This bright shield is actually made of candy-coated chocolate. Increases Constitution by <%= con %>. Limited Edition 2019 Spring Gear.",
"shieldSpecialSpring2019HealerText": "Eggshell Shield",
"shieldSpecialSpring2019WarriorNotes": "Let the power of chlorophyll keep your enemies at bay! Increases Constitution by <%= con %>. Limited Edition 2019 Spring Gear.",
"shieldSpecialKS2019Notes": "Sparkling like the shell of a gryphon egg, this magnificent shield shows you how to stand ready to help when your own burdens are light. Increases Perception by <%= per %>.",
"shieldSpecialSpring2019WarriorText": "Leafy Shield",
"shieldSpecialKS2019Text": "Mythic Gryphon Shield",
"shieldSpecialPiDayNotes": "We dare you to calculate the ratio of this shield's circumference to its deliciousness! Confers no benefit.",
"headArmoireFrostedHelmNotes": "The perfect headgear for any celebration! Increases Intelligence by <%= int %>. Enchanted Armoire: Happy Birthday Set (Item 1 of 4).",
"headArmoireFrostedHelmText": "Frosted Helm",
"headArmoireEarflapHatNotes": "If you're looking to keep your head toasty warm, this hat has you covered! Increases Intelligence and Strength by <%= attrs %> each. Enchanted Armoire: Duffle Coat Set (Item 2 of 2).",
"headArmoireEarflapHatText": "Earflap Hat",
"headArmoireAlchemistsHatNotes": "While hats are not strictly necessary for alchemical practice, looking cool certainly doesn't hurt anything! Increases Perception by <%= per %>. Enchanted Armoire: Alchemist Set (Item 2 of 4).",
"headArmoireAlchemistsHatText": "Alchemist's Hat",
"headArmoireShadowMastersHoodNotes": "This hood grants you the power to see through even the deepest darkness. It may occasionally require eyedrops, though. Increases Perception and Constitution by <%= attrs %> each. Enchanted Armoire: Shadow Master Set (Item 2 of 4).",
"headArmoireShadowMastersHoodText": "Shadow Master's Hood",
"headArmoireDeerstalkerCapNotes": "This cap is perfect for rural excursions, but also is acceptable gear for mystery-solving! Increases Intelligence by <%= int %>. Enchanted Armoire: Detective Set (Item 1 of 4).",
"headArmoireDeerstalkerCapText": "Deerstalker Cap",
"headArmoireAstronomersHatNotes": "A perfect hat for celestial observation or a fancy wizard brunch. Increases Constitution by <%= con %>. Enchanted Armoire: Astronomer Mage Set (Item 2 of 3).",
"headArmoireAstronomersHatText": "Astronomer's Hat",
"headArmoireBoaterHatNotes": "This straw chapeau is the bee's knees! Increases Strength, Constitution, and Perception by <%= attrs %> each. Enchanted Armoire: Boating Set (Item 2 of 3).",
"headArmoireBoaterHatText": "Boater Hat",
"headArmoireNephriteHelmNotes": "The carved jade plume atop this helm is enchanted to enhance your aim. Increases Perception by <%= per %> and Intelligence by <%= int %>. Enchanted Armoire: Nephrite Archer Set (Item 2 of 3).",
"headArmoireNephriteHelmText": "Nephrite Helm",
"headArmoireTricornHatNotes": "Become a revolutionary jokester! Increases Perception by <%= per %>. Enchanted Armoire: Independent Item.",
"headArmoireTricornHatText": "Tricorn Hat",
"headMystery202001Notes": "Your hearing will be so sharp, you'll hear the stars twinkling and the moon spinning. Confers no benefit. January 2020 Subscriber Item.",
"headMystery202001Text": "Fabled Fox Ears",
"headMystery201912Notes": "This glittering snowflake grants you resistance to the biting cold no matter how high you fly! Confers no benefit. December 2019 Subscriber Item.",
"headMystery201912Text": "Polar Pixie Crown",
"headMystery201911Notes": "Each of the crystal points attached to this hat endows you with a special power: mystic clairvoyance, arcane wisdom, and... sorcerous plate spinning? All right then. Confers no benefit. November 2019 Subscriber Item.",
"headMystery201911Text": "Charmed Crystal Hat",
"headMystery201910Text": "Cryptic Flame",
"headMystery201909Text": "Affable Acorn Hat",
"headMystery201907Notes": "Nothing says “I'm relaxing here!” like a backwards cap. Confers no benefit. July 2019 Subscriber Item.",
"headMystery201907Text": "Backwards Cap",
"headMystery201904Text": "Opulent Opal Circlet",
"headMystery201903Notes": "Some may call you an egghead, but that's OK because you know how to take a yolk. Confers no benefit. March 2019 Subscriber Item.",
"headSpecialWinter2020HealerNotes": "Please remove it from your head before attempting to brew chai or coffee with it. Increases Intelligence by <%= int %>. Limited Edition 2019-2020 Winter Gear.",
"headMystery201903Text": "Sunny Side Up Helm",
"headSpecialWinter2020HealerText": "Star Anise Emblem",
"headSpecialWinter2020MageNotes": "Oh! How the bells / Sweet golden bells / All seem to say, / “Cast Burst of Flames” Increases Perception by <%= per %>. Limited Edition 2019-2020 Winter Gear.",
"headSpecialWinter2020MageText": "Bell Crown",
"headSpecialWinter2020WarriorNotes": "A prickly feeling on your scalp is a small price to pay for seasonal magnificence. Increases Strength by <%= str %>. Limited Edition 2019-2020 Winter Gear.",
"headSpecialWinter2020WarriorText": "Snow-Dusted Headdress",
"headSpecialWinter2020RogueNotes": "A Rogue walks down the street in that hat, people know they're not afraid of anything. Increases Perception by <%= per %>. Limited Edition 2019-2020 Winter Gear.",
"headSpecialWinter2020RogueText": "Floofy Stocking Cap",
"headSpecialNye2019Text": "Outrageous Party Hat",
"headSpecialNye2019Notes": "You've received an Outrageous Party Hat! Wear it with pride while ringing in the New Year! Confers no benefit.",
"headSpecialFall2019MageNotes": "Its single baleful eye does inhibit depth perception, but that is a small price to pay for the way it hones your focus to a single, intense point. Increases Perception by <%= per %>. Limited Edition 2019 Autumn Gear.",
"headSpecialFall2019MageText": "Cyclops Mask",
"headMystery201910Notes": "These flames reveal arcane secrets before your very eyes! Confers no benefit. October 2019 Subscriber Item.",
"headMystery201909Notes": "Every acorn needs a hat! Er, cupule, if you want to get technical about it. Confers no benefit. September 2019 Subscriber Item.",
"headSpecialFall2019WarriorText": "Obsidian Skull Helmet",
"headSpecialFall2019WarriorNotes": "The dark eye-sockets of this skull helmet will daunt the bravest of your enemies. Increases Strength by <%= str %>. Limited Edition 2019 Autumn Gear.",
"headSpecialFall2019RogueNotes": "Did you find this headpiece at an auction of possibly-cursed costume pieces, or in the attic of an eccentric grandparent? Whatever its origin, its age and wear add to your air of mystery. Increases Perception by <%= per %>. Limited Edition 2019 Autumn Gear.",
"headSpecialSummer2019HealerText": "Conch Crown",
"headSpecialFall2019RogueText": "Antique Opera Hat",
"headSpecialSummer2019MageNotes": "Contrary to popular belief, your head is not an appropriate place for frogs to perch. Increases Perception by <%= per %>. Limited Edition 2019 Summer Gear.",
"headSpecialSummer2019WarriorNotes": "It won't let you pull your head down between your shoulders, but it will protect you if you bonk the bottom of a boat. Increases Strength by <%= str %>. Limited Edition 2019 Summer Gear.",
"headSpecialSummer2019MageText": "Lily Pad Hat",
"headSpecialSummer2019WarriorText": "Turtle Helm",
"headSpecialSummer2019RogueNotes": "This helm gives you a 360 degree view of surrounding waters, which is perfect for sneaking up on unsuspecting red Dailies. Increases Perception by <%= per %>. Limited Edition 2019 Summer Gear.",
"headSpecialSummer2019RogueText": "Hammerhead Helm",
"headSpecialSpring2019HealerNotes": "Be ready for the first day of spring with this cute beaky helm. Increases Intelligence by <%= int %>. Limited Edition 2019 Spring Gear.",
"headSpecialSpring2019HealerText": "Robin Helm",
"headSpecialSpring2019MageNotes": "A glowing amber gem grants this hat the power of arcane natural forces. Increases Perception by <%= per %>. Limited Edition 2019 Spring Gear.",
"headSpecialSpring2019MageText": "Amber Hat",
"headSpecialSpring2019WarriorNotes": "This helm is unbreakable and tough! Also it attracts butterflies. Increases Strength by <%= str %>. Limited Edition 2019 Spring Gear.",
"headSpecialSpring2019WarriorText": "Orchid Helm",
"headSpecialSpring2019RogueNotes": "No one will notice a cloud quietly drifting toward their stash of Gold, right? Increases Perception by <%= per %>. Limited Edition 2019 Spring Gear.",
"headSpecialSpring2019RogueText": "Cloud Helm",
"headSpecialKS2019Notes": "Adorned with a gryphon's likeness and plumage, this glorious helmet symbolises the way your skills and bearing stand as an example to others. Increases Intelligence by <%= int %>.",
"headSpecialKS2019Text": "Mythic Gryphon Helm",
"headSpecialPiDayNotes": "Try to balance this slice of delicious pie on your head while walking in a circle. Or throw it at a red Daily! Or you could just eat it. Your choice! Confers no benefit.",
"headSpecialPiDayText": "Pi Hat",
"armorArmoireLayerCakeArmorNotes": "It's protective and tasty! Increases Constitution by <%= con %>. Enchanted Armoire: Happy Birthday Set (Item 2 of 4).",
"armorArmoireDuffleCoatText": "Duffle Coat",
"armorArmoireAlchemistsRobeNotes": "Any number of dangerous elixirs are involved in creating arcane metals and gems, and these heavy robes will protect you from harm and unintended side effects! Increases Constitution by <%= con %> and Perception by <%= per %>. Enchanted Armoire: Alchemist Set (Item 1 of 4).",
"armorArmoireAlchemistsRobeText": "Alchemist's Robe",
"armorArmoireShadowMastersRobeNotes": "The fabric of this flowy robe is woven from the darkest shadows in the deepest caves of Habitica. Increases Constitution by <%= con %>. Enchanted Armoire: Shadow Master Set (Item 1 of 4).",
"armorArmoireShadowMastersRobeText": "Shadow Master's Robe",
"armorArmoireInvernessCapeNotes": "This sturdy garment will let you search for clues in any type of weather. Increases Perception and Intelligence by <%= attrs %> each. Enchanted Armoire: Detective Set (Item 2 of 4).",
"armorArmoireInvernessCapeText": "Inverness Cape",
"armorArmoireAstronomersRobeNotes": "Turns out silk and starlight make a fabric that is not only magical, but very breathable. Increases Perception and Constitution by <%= attrs %> each. Enchanted Armoire: Astronomer Mage Set (Item 1 of 3).",
"armorArmoireAstronomersRobeText": "Astronomer's Robe",
"armorArmoireBoatingJacketNotes": "Whether you're on a swanky yacht or in a jalopy, you'll be the cat's meow in this jacket and tie. Increases Strength, Intelligence, and Perception by <%= attrs %> each. Enchanted Armoire: Boating Set (Item 1 of 3).",
"armorArmoireBoatingJacketText": "Boating Jacket",
"armorMystery201909Notes": "Your tough exterior is protective, but it's still best to keep an eye out for squirrels... Confers no benefit. September 2019 Subscriber Item.",
"armorMystery201908Notes": "These legs were made for dancing! And that's just what they'll do. Confers no benefit. August 2019 Subscriber Item.",
"armorMystery201908Text": "Footloose Faun Costume",
"armorMystery201907Notes": "Stay cool and look cool on even the hottest summer day. Confers no benefit. July 2019 Subscriber Item.",
"armorMystery201907Text": "Flowery Shirt",
"armorMystery201906Notes": "We will spare you a pun about “playing koi.” Oh wait, oops. Confers no benefit. June 2019 Subscriber Item.",
"backMystery201912Notes": "Glide silently across sparkling snowfields and shimmering mountains with these icy wings. Confers no benefit. December 2019 Subscriber Item.",
"backMystery202001Text": "Five Tails of Fable",
"backMystery202001Notes": "These fluffy tails contain celestial power, and also a high level of cuteness! Confers no benefit. January 2020 Subscriber Item.",
"headAccessoryMystery201905Text": "Dazzling Dragon Horns",
"headAccessoryMystery201905Notes": "These horns are as sharp as they are shimmery. Confers no benefit. May 2019 Subscriber Item.",
"headAccessoryMystery201906Text": "Kindly Koi Ears",
"headAccessoryMystery201906Notes": "Legend has it these finny ears help merfolk hear the calls and songs of all the denizens of the deep! Confers no benefit. June 2019 Subscriber Item.",
"headAccessoryMystery201908Text": "Footloose Faun Horns",
"headAccessoryMystery201908Notes": "If wearing horns floats your goat, you're in luck! Confers no benefit. August 2019 Subscriber Item.",
"eyewearSpecialBlackHalfMoonText": "Black Half-Moon Eyeglasses",
"eyewearSpecialBlackHalfMoonNotes": "Glasses with a black frame and crescent lenses. Confers no benefit.",
"eyewearSpecialBlueHalfMoonText": "Blue Half-Moon Eyeglasses",
"eyewearSpecialBlueHalfMoonNotes": "Glasses with a blue frame and crescent lenses. Confers no benefit.",
"eyewearSpecialGreenHalfMoonText": "Green Half-Moon Eyeglasses",
"eyewearSpecialGreenHalfMoonNotes": "Glasses with a green frame and crescent lenses. Confers no benefit.",
"eyewearSpecialPinkHalfMoonText": "Pink Half-Moon Eyeglasses",
"eyewearSpecialPinkHalfMoonNotes": "Glasses with a pink frame and crescent lenses. Confers no benefit.",
"eyewearSpecialRedHalfMoonText": "Red Half-Moon Eyeglasses",
"eyewearSpecialRedHalfMoonNotes": "Glasses with a red frame and crescent lenses. Confers no benefit.",
"eyewearSpecialWhiteHalfMoonText": "White Half-Moon Eyeglasses",
"eyewearSpecialWhiteHalfMoonNotes": "Glasses with a white frame and crescent lenses. Confers no benefit.",
"eyewearSpecialYellowHalfMoonText": "Yellow Half-Moon Eyeglasses",
"eyewearSpecialYellowHalfMoonNotes": "Glasses with a yellow frame and crescent lenses. Confers no benefit.",
"eyewearSpecialKS2019Text": "Mythic Gryphon Visor",
"eyewearSpecialKS2019Notes": "Bold as a gryphon's... hmm, gryphons don't have visors. It reminds you to... oh, who are we kidding, it just looks cool! Confers no benefit.",
"eyewearSpecialFall2019RogueText": "Bone-White Half Mask",
"eyewearSpecialFall2019RogueNotes": "You'd think a full mask would protect your identity better, but people tend to be too awestruck by its stark design to take note of any identifying features left revealed. Confers no benefit. Limited Edition 2019 Autumn Gear.",
"eyewearSpecialFall2019HealerText": "Dark Visage",
"eyewearSpecialFall2019HealerNotes": "Steel yourself against the toughest foes with this inscrutable mask. Confers no benefit. Limited Edition 2019 Autumn Gear.",
"armorMystery201906Text": "Kindly Koi Tail",
"armorMystery201904Notes": "This shining garment has opals sewn into the front panel to grant you arcane powers and a fabulous look. Confers no benefit. April 2019 Subscriber Item.",
"armorMystery201904Text": "Opalescent Outfit",
"armorMystery201903Notes": "People are dye-ing to know where you got this egg-cellent outfit! Confers no benefit. March 2019 Subscriber Item.",
"armorSpecialWinter2020HealerNotes": "An opulent gown for those with festive zest! Increases Constitution by <%= con %>. Limited Edition 2019-2020 Winter Gear.",
"armorSpecialWinter2020HealerText": "Orange Peel Gown",
"armorSpecialWinter2020MageNotes": "Ring in the new year warm, comfy, and buffered against excessive vibration. Increases Intelligence by <%= int %>. Limited Edition 2019-2020 Winter Gear.",
"armorSpecialWinter2020MageText": "Curvy Coat",
"armorSpecialWinter2020WarriorNotes": "O mighty pine, o towering fir, lend your strength. Or rather, your Constitution! Increases Constitution by <%= con %>. Limited Edition 2019-2020 Winter Gear.",
"armorSpecialWinter2020RogueNotes": "While no doubt you can brave storms with the inner warmth of your drive and devotion, it doesn't hurt to dress for the weather. Increases Perception by <%= per %>. Limited Edition 2019-2020 Winter Gear.",
"armorSpecialWinter2020RogueText": "Poofy Parka",
"armorSpecialFall2019HealerNotes": "It's said these robes are made of pure night. Use the dark power wisely! Increases Constitution by <%= con %>. Limited Edition 2019 Autumn Gear.",
"armorSpecialFall2019HealerText": "Robes of Darkness",
"armorSpecialFall2019MageNotes": "Its namesake met a terrible fate. But you will not be so easily tricked! Garb yourself in this mantle of legend and nobody will surpass you. Increases Intelligence by <%= int %>. Limited Edition 2019 Autumn Gear.",
"armorSpecialFall2019MageText": "Smock of Polyphemus",
"armorSpecialFall2019WarriorNotes": "These feathered robes grant the power of flight, allowing you to soar over any battle. Increases Constitution by <%= con %>. Limited Edition 2019 Autumn Gear.",
"armorSpecialFall2019WarriorText": "Wings of Night",
"armorSpecialFall2019RogueNotes": "This outfit comes complete with white gloves, and is ideal for brooding in your private box above the stage or making startling entrances down grand staircases. Increases Perception by <%= per %>. Limited Edition 2019 Autumn Gear.",
"armorSpecialFall2019RogueText": "Caped Opera Coat",
"armorSpecialSummer2019HealerNotes": "Glide sleekly through warm coastal waters with this elegant tail. Increases Constitution by <%= con %>. Limited Edition 2019 Summer Gear.",
"armorSpecialSummer2019HealerText": "Tropical Tides Tail",
"armorSpecialSummer2019MageNotes": "The lilies will know you as one of their own, and will not fear your approach. Increases Intelligence by <%= int %>. Limited Edition 2019 Summer Gear.",
"armorSpecialSummer2019MageText": "Floral Frock",
"armorSpecialSummer2019RogueNotes": "This sinuous tail is perfect for making tight turns during daring aquatic escapes. Increases Perception by <%= per %>. Limited Edition 2019 Summer Gear.",
"armorSpecialSummer2019RogueText": "Hammerhead Tail",
"armorSpecialSpring2019HealerNotes": "Your bright feathers will let everyone know that the cold and dark of winter has passed. Increases Constitution by <%= con %>. Limited Edition 2019 Spring Gear.",
"armorSpecialSpring2019HealerText": "Robin Costume",
"eyewearMystery201907Text": "Sweet Sunglasses",
"eyewearMystery201907Notes": "Look awesome while protecting your eyes from harmful UV rays! Confers no benefit. July 2019 Subscriber Item.",
"armorSpecialSpring2019MageText": "Amber Robes",
"armorSpecialSpring2019RogueNotes": "Some very tuff fluff. Increases Perception by <%= per %>. Limited Edition 2019 Spring Gear.",
"weaponArmoireHappyBannerNotes": "Is the “H” for Happy, or Habitica? Your choice! Increases Perception by <%= per %>. Enchanted Armoire: Happy Birthday Set (Item 3 of 4).",
"weaponArmoireHappyBannerText": "Happy Banner",
"weaponArmoireAlchemistsDistillerNotes": "Purify metals and other magical compounds with this shiny brass instrument. Increases Strength by <%= str %> and Intelligence by <%= int %>. Enchanted Armoire: Alchemist Set (Item 3 of 4).",
"weaponArmoireAlchemistsDistillerText": "Alchemist's Distiller",
"weaponArmoireShadowMastersMaceNotes": "Creatures of darkness will obey your every command when you wave this glowing mace. Increases Perception by <%= per %>. Enchanted Armoire: Shadow Master Set (Item 3 of 4).",
"weaponArmoireShadowMastersMaceText": "Shadow Master's Mace",
"weaponArmoireResplendentRapierNotes": "Demonstrate your swordsmanship with this sharply pointed weapon. Increases Perception by <%= per %>. Enchanted Armoire: Independent Item.",
"weaponArmoireResplendentRapierText": "Resplendent Rapier",
"weaponArmoireFloridFanNotes": "This lovely silk fan folds when not in use. Increases Constitution by <%= con %>. Enchanted Armoire: Independent Item.",
"weaponArmoireFloridFanText": "Florid Fan",
"weaponArmoireMagnifyingGlassNotes": "Aha! A piece of evidence! Examine it closely with this fine magnifier. Increases Perception by <%= per %>. Enchanted Armoire: Detective Set (Item 3 of 4).",
"weaponArmoireMagnifyingGlassText": "Magnifying Glass",
"weaponArmoireAstronomersTelescopeNotes": "An instrument that will allow you to observe the stars' ancient dance. Increases Perception by <%= per %>. Enchanted Armoire: Astronomer Mage Set (Item 3 of 3).",
"weaponArmoireAstronomersTelescopeText": "Astronomer's Telescope",
"weaponArmoireBambooCaneNotes": "Perfect for assisting you in a stroll, or for dancing the Charleston. Increases Intelligence, Perception, and Constitution by <%= attrs %> each. Enchanted Armoire: Boating Set (Item 3 of 3).",
"weaponArmoireBambooCaneText": "Bamboo Cane",
"weaponArmoireNephriteBowNotes": "This bow shoots special jade-tipped arrows that will take down even your most stubborn bad habits! Increases Intelligence by <%= int %> and Strength by <%= str %>. Enchanted Armoire: Nephrite Archer Set (Item 1 of 3).",
"weaponArmoireNephriteBowText": "Nephrite Bow",
"weaponArmoireSlingshotText": "Slingshot",
"weaponArmoireSlingshotNotes": "Take aim at your red Dailies! Increases Strength by <%= str %>. Enchanted Armoire: Independent Item.",
"weaponArmoireJugglingBallsNotes": "Habiticans are master multi-taskers, so you should have no trouble keeping all these balls in the air! Increases Intelligence by <%= int %>. Enchanted Armoire: Independent Item.",
"weaponArmoireJugglingBallsText": "Juggling Balls",
"weaponMystery201911Notes": "The crystal ball atop this staff can show you the future, but beware! Using such dangerous knowledge can change a person in unexpected ways. Confers no benefit. November 2019 Subscriber Item.",
"weaponMystery201911Text": "Charmed Crystal Staff",
"weaponSpecialWinter2020HealerNotes": "Wave it about, and its aroma will summon your friends and helpers to begin cooking and baking! Increases Intelligence by <%= int %>. Limited Edition 2019-2020 Winter Gear.",
"weaponSpecialWinter2020MageNotes": "With practice, you can project this aural magic at any desired frequency: a meditative hum, a festive chime, or a RED TASK OVERDUE ALARM. Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2019-2020 Winter Gear.",
"headMystery201904Notes": "The opals in this circlet shine in every colour of the rainbow, giving it a variety of magical properties. Confers no benefit. April 2019 Subscriber Item.",
"headSpecialFall2019HealerNotes": "Don this dark mitre to harness the powers of the fearsome Lich. Increases Intelligence by <%= int %>. Limited Edition 2019 Autumn Gear.",
"headSpecialFall2019HealerText": "Dark Mitre",
"headSpecialSummer2019HealerNotes": "The spiralling structure of this shell will help you hear any cry for help across the seven seas. Increases Intelligence by <%= int %>. Limited Edition 2019 Summer Gear.",
"armorArmoireDuffleCoatNotes": "Travel frosty realms in style with this cosy wool coat. Increases Constitution and Perception by <%= attrs %> each. Enchanted Armoire: Duffle Coat Set (Item 1 of 2).",
"armorSpecialSummer2019WarriorNotes": "Warriors are known for their sturdy defences. Turtles are known for their thick shells. It's a perfect match! Just... try not to fall over backward, ever. Increases Constitution by <%= con %>. Limited Edition 2019 Summer Gear.",
"armorSpecialSpring2019MageNotes": "These robes gather power from magic resin embedded in the fibres of ancient bark that compose the cloth. Increases Intelligence by <%= int %>. Limited Edition 2019 Spring Gear.",
"armorArmoireLayerCakeArmorText": "Layer Cake Armour",
"armorArmoireNephriteArmorNotes": "Made from strong steel rings and decorated with jade, this armour will protect you from procrastination! Increases Strength by <%= str %> and Perception by <%= per %>. Enchanted Armoire: Nephrite Archer Set (Item 3 of 3).",
"armorArmoireNephriteArmorText": "Nephrite Armour",
"armorMystery201910Notes": "This enigmatic armour will protect you from terrors seen and unseen. Confers no benefit. October 2019 Subscriber Item.",
"armorMystery201910Text": "Cryptic Armour",
"armorMystery201909Text": "Affable Acorn Armour",
"armorMystery201903Text": "Shell-ebration Armour",
"armorSpecialWinter2020WarriorText": "Bark Armour",
"armorSpecialSummer2019WarriorText": "Carapace Armour",
"armorSpecialSpring2019WarriorNotes": "Steely armour of reinforced petals protects your heart and also looks pretty snazzy. Increases Constitution by <%= con %>. Limited Edition 2019 Spring Gear.",
"armorSpecialSpring2019WarriorText": "Orchid Armour",
"armorSpecialSpring2019RogueText": "Cloud Armour",
"armorSpecialKS2019Notes": "Glowing from within like a gryphon's noble heart, this resplendent armour encourages you to take pride in your accomplishments. Increases Constitution by <%= con %>.",
"armorSpecialKS2019Text": "Mythic Gryphon Armour",
"weaponSpecialWinter2020HealerText": "Clove Sceptre",
"weaponSpecialWinter2020MageText": "Rippling Sound Waves",
"weaponSpecialWinter2020WarriorNotes": "Back, squirrels! You will take no piece of this! ...But if you all want to hang out and have cocoa, that's cool. Increases Strength by <%= str %>. Limited Edition 2019-2020 Winter Gear.",
"weaponSpecialWinter2020WarriorText": "Pointy Conifer Cone",
"weaponSpecialWinter2020RogueNotes": "Darkness is a Rogue's element. Who better, then, to light the way in the darkest time of year? Increases Strength by <%= str %>. Limited Edition 2019-2020 Winter Gear.",
"weaponSpecialWinter2020RogueText": "Lantern Rod",
"weaponSpecialFall2019HealerNotes": "This phylactery can call on the spirits of tasks long slain and use their healing power. Increases Intelligence by <%= int %>. Limited Edition 2019 Autumn Gear.",
"weaponSpecialFall2019HealerText": "Fearsome Phylactery",
"weaponSpecialFall2019MageNotes": "Be it forging thunderbolts, raising fortifications, or simply striking terror into the hearts of mortals, this staff lends the power of giants to work wonders. Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2019 Autumn Gear.",
"weaponSpecialFall2019MageText": "One-Eyed Staff",
"weaponSpecialFall2019WarriorNotes": "Prepare to rend your foes with the talons of a raven! Increases Strength by <%= str %>. Limited Edition 2019 Autumn Gear.",
"weaponSpecialFall2019WarriorText": "Talon Trident",
"weaponSpecialFall2019RogueNotes": "Whether you're conducting the orchestra or singing an aria, this helpful device keeps your hands free for dramatic gestures! Increases Strength by <%= str %>. Limited Edition 2019 Autumn Gear.",
"weaponSpecialFall2019RogueText": "Music Stand",
"weaponSpecialSummer2019HealerNotes": "The bubbles from this wand capture healing energy and ancient oceanic magic. Increases Intelligence by <%= int %>. Limited Edition 2019 Summer Gear.",
"weaponSpecialKS2019Notes": "Curved as a gryphon's beak and talons, this ornate polearm reminds you to power through when the task ahead feels daunting. Increases Strength by <%= str %>.",
"weaponSpecialKS2019Text": "Mythic Gryphon Glaive"
}

View File

@@ -61,7 +61,7 @@
"newGroupTitle": "New Group",
"subscriberItem": "Mystery Item",
"newSubscriberItem": "You have new <span class=\"notification-bold-blue\">Mystery Items</span>",
"subscriberItemText": "Each month, subscribers will receive a mystery item. This is usually released about one week before the end of the month. See the wiki's 'Mystery Item' page for more information.",
"subscriberItemText": "Each month, subscribers will receive a mystery item. It becomes available at the beginning of the month. See the wiki's 'Mystery Item' page for more information.",
"all": "All",
"none": "None",
"more": "<%= count %> more",
@@ -79,7 +79,7 @@
"continue": "Continue",
"accept": "Accept",
"reject": "Reject",
"neverMind": "Never mind",
"neverMind": "Nevermind",
"buyMoreGems": "Buy More Gems",
"notEnoughGems": "Not enough Gems",
"alreadyHave": "Whoops! You already have this item. No need to buy it again!",
@@ -276,7 +276,7 @@
"hobbies_occupations": "Hobbies + Occupations",
"location_based": "Location-based",
"mental_health": "Mental Health + Self-Care",
"getting_organized": "Getting Organized",
"getting_organized": "Getting Organised",
"self_improvement": "Self-Improvement",
"spirituality": "Spirituality",
"time_management": "Time-Management + Accountability",
@@ -291,5 +291,10 @@
"howManyToBuy": "How many would you like to buy?",
"habiticaHasUpdated": "There is a new Habitica update. Refresh to get the latest version!",
"contactForm": "Contact the Moderation Team",
"options": "Options"
"options": "Options",
"loadEarlierMessages": "Load Earlier Messages",
"demo": "Demo",
"congratulations": "Congratulations!",
"onboardingAchievs": "Onboarding Achievements",
"finish": "Finish"
}

View File

@@ -250,19 +250,19 @@
"onlyGroupLeaderCanEditTasks": "Not authorised to manage tasks!",
"onlyGroupTasksCanBeAssigned": "Only group tasks can be assigned",
"assignedTo": "Assigned To",
"assignedToUser": "Assigned to <%= userName %>",
"assignedToMembers": "Assigned to <%= userCount %> members",
"assignedToYouAndMembers": "Assigned to you and <%= userCount %> members",
"assignedToUser": "Assigned to <strong><%= userName %></strong>",
"assignedToMembers": "Assigned to <strong><%= userCount %> members</strong>",
"assignedToYouAndMembers": "Assigned to you and <strong><%= userCount %> members</strong>",
"youAreAssigned": "You are assigned to this task",
"taskIsUnassigned": "This task is unassigned",
"confirmClaim": "Are you sure you want to claim this task?",
"confirmUnClaim": "Are you sure you want to unclaim this task?",
"confirmApproval": "Are you sure you want to approve this task?",
"confirmNeedsWork": "Are you sure you want to mark this task as needing work?",
"userRequestsApproval": "<%= userName %> requests approval",
"userCountRequestsApproval": "<%= userCount %> members request approval",
"userRequestsApproval": "<strong><%= userName %></strong> requests approval",
"userCountRequestsApproval": "<strong><%= userCount %> members</strong> request approval",
"youAreRequestingApproval": "You are requesting approval",
"chatPrivilegesRevoked": "You cannot do that because your chat privileges have been revoked.",
"chatPrivilegesRevoked": "You cannot do this because your chat privileges have been removed. For details or to ask if your privileges can be returned, please email our Community Manager at admin@habitica.com or ask your parent or guardian to email them. Please include your @Username in the email. If a moderator has already told you that your chat ban is temporary, you do not need to send an email.",
"cannotCreatePublicGuildWhenMuted": "You cannot create a public guild because your chat privileges have been revoked.",
"cannotInviteWhenMuted": "You cannot invite anyone to a guild or party because your chat privileges have been revoked.",
"newChatMessagePlainNotification": "New message in <%= groupName %> by <%= authorName %>. Click here to open the chat page!",
@@ -277,10 +277,10 @@
"confirmRemoveTag": "Do you really want to remove \"<%= tag %>\"?",
"groupHomeTitle": "Home",
"assignTask": "Assign Task",
"claim": "Claim",
"claim": "Claim Task",
"removeClaim": "Remove Claim",
"onlyGroupLeaderCanManageSubscription": "Only the group leader can manage the group's subscription",
"yourTaskHasBeenApproved": "Your task <span class=\"notification-green\"><%= taskText %></span> has been approved.",
"yourTaskHasBeenApproved": "Your task <span class=\"notification-green notification-bold\"><%= taskText %></span> has been approved.",
"taskNeedsWork": "<span class=\"notification-bold\"><%= managerName %></span> marked <span class=\"notification-bold\"><%= taskText %></span> as needing additional work.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%= user %></span> requests approval for <span class=\"notification-bold\"><%= taskName %></span>",
"approve": "Approve",
@@ -341,8 +341,8 @@
"leaderCannotLeaveGroupWithActiveGroup": "A leader cannot leave a group while the group has an active plan",
"youHaveGroupPlan": "You have a free subscription because you are a member of a group that has a Group Plan. This will end when you are no longer in the group that has a Group Plan. Any months of extra subscription credit you have will be applied at the end of the Group Plan.",
"cancelGroupSub": "Cancel Group Plan",
"confirmCancelGroupPlan": "Are you sure you want to cancel the group plan and remove its benefits from all members, including their free subscriptions?",
"canceledGroupPlan": "Cancelled Group Plan",
"confirmCancelGroupPlan": "Are you sure you want to cancel your Group Plan? All Group members will lose their subscription and benefits.",
"canceledGroupPlan": "Group Plan Cancelled",
"groupPlanCanceled": "Group Plan will become inactive on",
"purchasedGroupPlanPlanExtraMonths": "You have <%= months %> months of extra group plan credit.",
"addManager": "Assign Manager",
@@ -480,5 +480,9 @@
"recurringCompletion": "None - Group task does not complete",
"singleCompletion": "Single - Completes when any assigned user finishes",
"allAssignedCompletion": "All - Completes when all assigned users finish",
"pmReported": "Thank you for reporting this message."
"pmReported": "Thank you for reporting this message.",
"groupActivityNotificationTitle": "<%= user %> posted in <%= group %>",
"suggestedGroup": "Suggested because youre new to Habitica.",
"taskClaimed": "<%= userName %> has claimed the task <span class=\"notification-bold\"><%= taskText %></span>.",
"youHaveBeenAssignedTask": "<%= managerName %> has assigned you the task <span class=\"notification-bold\"><%= taskText %></span>."
}

View File

@@ -143,11 +143,11 @@
"dateEndAugust": "August 31",
"dateEndSeptember": "September 21",
"dateEndOctober": "October 31",
"dateEndNovember": "December 3",
"dateEndNovember": "November 30",
"dateEndJanuary": "January 31",
"dateEndFebruary": "February 28",
"winterPromoGiftHeader": "GIFT A SUBSCRIPTION AND GET ONE FREE!",
"winterPromoGiftDetails1": "Until January 15th only, when you gift somebody a subscription, you get the same subscription for yourself for free!",
"winterPromoGiftDetails1": "Until January 6th only, when you gift somebody a subscription, you get the same subscription for yourself for free!",
"winterPromoGiftDetails2": "Please note that if you or your gift recipient already have a recurring subscription, the gifted subscription will only start after that subscription is cancelled or has expired. Thanks so much for your support! <3",
"discountBundle": "bundle",
"g1g1Announcement": "Gift a Subscription, Get a Subscription Free event going on now!",
@@ -155,5 +155,22 @@
"spring2019AmberMageSet": "Amber (Mage)",
"spring2019RobinHealerSet": "Robin (Healer)",
"spring2019OrchidWarriorSet": "Orchid (Warrior)",
"spring2019CloudRogueSet": "Cloud (Rogue)"
"spring2019CloudRogueSet": "Cloud (Rogue)",
"september2018": "September 2018",
"september2017": "September 2017",
"decemberYYYY": "December <%= year %>",
"augustYYYY": "August <%= year %>",
"eventAvailabilityReturning": "Available for purchase until <%= availableDate(locale) %>. This potion was last available in <%= previousDate(locale) %>.",
"winter2020LanternSet": "Lantern (Rogue)",
"winter2020WinterSpiceSet": "Winter Spice (Healer)",
"winter2020CarolOfTheMageSet": "Carol of the Mage (Mage)",
"winter2020EvergreenSet": "Evergreen (Warrior)",
"fall2019RavenSet": "Raven (Warrior)",
"fall2019LichSet": "Lich (Healer)",
"fall2019CyclopsSet": "Cyclops (Mage)",
"fall2019OperaticSpecterSet": "Operatic Specter (Rogue)",
"summer2019HammerheadRogueSet": "Hammerhead (Rogue)",
"summer2019ConchHealerSet": "Conch (Healer)",
"summer2019WaterLilyMageSet": "Water Lily (Mage)",
"summer2019SeaTurtleWarriorSet": "Sea Turtle (Warrior)"
}

View File

@@ -51,7 +51,7 @@
"messageGroupChatFlagAlreadyReported": "You have already reported this message",
"messageGroupChatNotFound": "Message not found!",
"messageGroupChatAdminClearFlagCount": "Only an admin can clear the flag count!",
"messageCannotFlagSystemMessages": "You cannot flag a system message. If you need to report a violation of the Community Guidelines related to this message, please email a screenshot and explanation to Lemoness at <%= communityManagerEmail %>.",
"messageCannotFlagSystemMessages": "You cannot report a system message. If you need to report a violation of the Community Guidelines related to this message, please email a screenshot and explanation to our Community Manager at <%= communityManagerEmail %>.",
"messageGroupChatSpam": "Whoops, looks like you're posting too many messages! Please wait a minute and try again. The Tavern chat only holds 200 messages at a time, so Habitica encourages posting longer, more thoughtful messages and consolidating replies. Can't wait to hear what you have to say. :)",
"messageCannotLeaveWhileQuesting": "You cannot accept this party invitation while you are in a quest. If you'd like to join this party, you must first abort your quest, which you can do from your party screen. You will be given back the quest scroll.",
"messageUserOperationProtected": "path `<%= operation %>` was not saved, as it's a protected path.",

View File

@@ -13,15 +13,15 @@
"introTour": "Here we are! I've filled out some Tasks for you based on your interests, so you can get started right away. Click a Task to edit or add new Tasks to fit your routine!",
"prev": "Prev",
"next": "Next",
"randomize": "Randomize",
"randomize": "Randomise",
"mattBoch": "Matt Boch",
"mattShall": "Shall I bring you your steed, <%= name %>? Once you've fed a pet enough food to turn it into a mount, it will appear here. Click a mount to saddle up!",
"mattBochText1": "Welcome to the Stable! I'm Matt, the beast master. Starting at level 3, you will find eggs and potions to hatch pets with. When you hatch a pet in the Market, it will appear here! Click a pet's image to add it to your avatar. Feed them with the food you find after level 3, and they'll grow into hardy mounts.",
"welcomeToTavern": "Welcome to The Tavern!",
"sleepDescription": "Need a break? Check into Daniel's Inn to pause some of Habitica's more difficult game mechanics:",
"sleepBullet1": "Missed Dailies won't damage you",
"sleepBullet2": "Tasks won't lose streaks or decay in color",
"sleepBullet3": "Bosses won't do damage for your missed Dailies",
"sleepBullet2": "Tasks won't lose streaks",
"sleepBullet3": "Bosses won't do damage for your own missed Dailies",
"sleepBullet4": "Your boss damage or collection Quest items will stay pending until check-out",
"pauseDailies": "Pause Damage",
"unpauseDailies": "Unpause Damage",
@@ -91,7 +91,7 @@
"unlocked": "Items have been unlocked",
"alreadyUnlocked": "Full set already unlocked.",
"alreadyUnlockedPart": "Full set already partially unlocked.",
"invalidQuantity": "Quantity to purchase must be a number.",
"invalidQuantity": "Quantity to purchase must be a positive whole number.",
"USD": "(USD)",
"newStuff": "New Stuff by Bailey",
"newBaileyUpdate": "New Bailey Update!",
@@ -168,5 +168,7 @@
"welcome5": "Now you'll customise your avatar and set up your tasks...",
"imReady": "Enter Habitica",
"limitedOffer": "Available until <%= date %>",
"paymentAutoRenew": "This subscription will auto-renew until it is cancelled. If you need to cancel this subscription, you can do so from your settings."
"paymentAutoRenew": "This subscription will auto-renew until it is cancelled. If you need to cancel this subscription, you can do so from your settings.",
"paymentCanceledDisputes": "Weve sent a cancellation confirmation to your email. If you dont see the email, please contact us to prevent future billing disputes.",
"cannotUnpinItem": "This item cannot be unpinned."
}

View File

@@ -1,14 +1,10 @@
{
"needTips": "Need some tips on how to begin? Here's a straightforward guide!",
"step1": "Step 1: Enter Tasks",
"webStep1Text": "Habitica is nothing without real-world goals, so enter a few tasks. You can add more later as you think of them! All tasks can be added by clicking the green \"Create\" button.\n* **Set up [To-Dos](http://habitica.fandom.com/wiki/To-Dos):** Enter tasks you do once or rarely in the To-Dos column, one at a time. You can click on the tasks to edit them and add checklists, due dates, and more!\n* **Set up [Dailies](http://habitica.fandom.com/wiki/Dailies):** Enter activities you need to do daily or on a particular day of the week, month, or year in the Dailies column. Click task to edit when it will be due and/or set a start date. You can also make it due on a repeating basis, for example, every 3 days.\n* **Set up [Habits](http://habitica.fandom.com/wiki/Habits):** Enter habits you want to establish in the Habits column. You can edit the Habit to change it to just a good habit :heavy_plus_sign: or a bad habit :heavy_minus_sign:\n* **Set up [Rewards](http://habitica.fandom.com/wiki/Rewards):** In addition to the in-game Rewards offered, add activities or treats which you want to use as a motivation to the Rewards column. It's important to give yourself a break or allow some indulgence in moderation!\n* If you need inspiration for which tasks to add, you can look at the wiki's pages on [Sample Habits](http://habitica.fandom.com/wiki/Sample_Habits), [Sample Dailies](http://habitica.fandom.com/wiki/Sample_Dailies), [Sample To-Dos](http://habitica.fandom.com/wiki/Sample_To-Dos), and [Sample Rewards](http://habitica.fandom.com/wiki/Sample_Custom_Rewards).",
"step2": "Step 2: Gain Points by Doing Things in Real Life",
"webStep2Text": "Now, start tackling your goals from the list! As you complete tasks and check them off in Habitica, you will gain [Experience](http://habitica.fandom.com/wiki/Experience_Points), which helps you level up, and [Gold](http://habitica.fandom.com/wiki/Gold_Points), which allows you to purchase Rewards. If you fall into bad habits or miss your Dailies, you will lose [Health](http://habitica.fandom.com/wiki/Health_Points). In that way, the Habitica Experience and Health bars serve as a fun indicator of your progress toward your goals. You'll start seeing your real life improve as your character advances in the game.",
"step3": "Step 3: Customise and Explore Habitica",
"webStep3Text": "Once you're familiar with the basics, you can get even more out of Habitica with these nifty features:\n * Organize your tasks with [tags](http://habitica.fandom.com/wiki/Tags) (edit a task to add them).\n * Customize your [avatar](http://habitica.fandom.com/wiki/Avatar) by clicking the user icon in the upper-right corner.\n * Buy your [Equipment](http://habitica.fandom.com/wiki/Equipment) under Rewards or from the [Shops](<%= shopUrl %>), and change it under [Inventory > Equipment](<%= equipUrl %>).\n * Connect with other users via the [Tavern](http://habitica.fandom.com/wiki/Tavern).\n * Starting at Level 3, hatch [Pets](http://habitica.fandom.com/wiki/Pets) by collecting [eggs](http://habitica.fandom.com/wiki/Eggs) and [hatching potions](http://habitica.fandom.com/wiki/Hatching_Potions). [Feed](http://habitica.fandom.com/wiki/Food) them to create [Mounts](http://habitica.fandom.com/wiki/Mounts).\n * At level 10: Choose a particular [class](http://habitica.fandom.com/wiki/Class_System) and then use class-specific [skills](http://habitica.fandom.com/wiki/Skills) (levels 11 to 14).\n * Form a party with your friends (by clicking [Party](<%= partyUrl %>) in the navigation bar) to stay accountable and earn a Quest scroll.\n * Defeat monsters and collect objects on [quests](http://habitica.fandom.com/wiki/Quests) (you will be given a quest at level 15).",
"webStep3Text": "Once you're familiar with the basics, you can get even more out of Habitica with these nifty features:\n * Organise your tasks with [tags](http://habitica.fandom.com/wiki/Tags) (edit a task to add them).\n * Customise your [avatar](http://habitica.fandom.com/wiki/Avatar) by clicking the user icon in the upper-right corner.\n * Buy your [Equipment](http://habitica.fandom.com/wiki/Equipment) under Rewards or from the [Shops](<%= shopUrl %>), and change it under [Inventory > Equipment](<%= equipUrl %>).\n * Connect with other users via the [Tavern](http://habitica.fandom.com/wiki/Tavern).\n * Starting at Level 3, hatch [Pets](http://habitica.fandom.com/wiki/Pets) by collecting [eggs](http://habitica.fandom.com/wiki/Eggs) and [hatching potions](http://habitica.fandom.com/wiki/Hatching_Potions). [Feed](http://habitica.fandom.com/wiki/Food) them to create [Mounts](http://habitica.fandom.com/wiki/Mounts).\n * At level 10: Choose a particular [class](http://habitica.fandom.com/wiki/Class_System) and then use class-specific [skills](http://habitica.fandom.com/wiki/Skills) (levels 11 to 14).\n * Form a party with your friends (by clicking [Party](<%= partyUrl %>) in the navigation bar) to stay accountable and earn a Quest scroll.\n * Defeat monsters and collect objects on [quests](http://habitica.fandom.com/wiki/Quests) (you will be given a quest at level 15).",
"overviewQuestions": "Have questions? Check out the [FAQ](<%= faqUrl %>)! If your question isn't mentioned there, you can ask for further help in the [Habitica Help guild](<%= helpGuildUrl %>).\n\nGood luck with your tasks!"
}

View File

@@ -144,5 +144,6 @@
"notEnoughMounts": "You have not collected enough mounts",
"notEnoughPetsMounts": "You have not collected enough pets and mounts",
"wackyPets": "Wacky Pets",
"filterByWacky": "Wacky"
"filterByWacky": "Wacky",
"gryphatrice": "Gryphatrice"
}

View File

@@ -126,5 +126,16 @@
"bossHealth": "<%= currentHealth %> / <%= maxHealth %> Health",
"rageAttack": "Rage Attack:",
"bossRage": "<%= currentRage %> / <%= maxRage %> Rage",
"rageStrikes": "Rage Strikes"
"rageStrikes": "Rage Strikes",
"tavernBossTired": "<%= bossName %> tries to unleash <%= rageName %> but is too tired.",
"chatQuestCancelled": "<%= username %> cancelled the party quest <%= questName %>.",
"chatQuestAborted": "<%= username %> aborted the party quest <%= questName %>.",
"chatItemQuestFinish": "All items found! Party has received their rewards.",
"chatFindItems": "<%= username %> found <%= items %>.",
"chatBossDefeated": "You defeated <%= bossName %>! Questing party members receive the rewards of victory.",
"chatBossDontAttack": "<%= username %> attacks <%= bossName %> for <%= userDamage %> damage. <%= bossName %> does not attack, because it respects the fact that there are some bugs post-maintenance, and it doesn't want to hurt anyone unfairly. It will continue its rampage soon!",
"chatBossDamage": "<%= username %> attacks <%= bossName %> for <%= userDamage %> damage. <%= bossName %> attacks party for <%= bossDamage %> damage.",
"chatQuestStarted": "Your quest, <%= questName %>, has started.",
"questInvitationNotificationInfo": "You were invited to join a quest",
"hatchingPotionQuests": "Magic Hatching Potion Quests"
}

View File

@@ -1,11 +1,11 @@
{
"questEvilSantaText": "Trapper Santa",
"questEvilSantaNotes": "You hear agonised roars deep in the ice-fields. You follow the growls - punctuated by the sound of cackling - to a clearing in the woods, where you see a fully-grown polar bear. She's caged and shackled, fighting for her life. Dancing atop the cage is a malicious little imp wearing a castaway costume. Vanquish Trapper Santa, and save the beast!",
"questEvilSantaNotes": "You hear agonised roars deep in the icefields. You follow the growls - punctuated by the sound of cackling - to a clearing in the woods, where you see a fully-grown polar bear. She's caged and shackled, fighting for her life. Dancing atop the cage is a malicious little imp wearing a castaway costume. Vanquish Trapper Santa, and save the beast!<br><br><strong>Note</strong>: “Trapper Santa” awards a stackable quest achievement but gives a rare mount that can only be added to your stable once.",
"questEvilSantaCompletion": "Trapper Santa squeals in anger, and bounces off into the night. The grateful she-bear, through roars and growls, tries to tell you something. You take her back to the stables, where Matt Boch the Beast Master listens to her tale with a gasp of horror. She has a cub! He ran off into the ice-fields when mama bear was captured.",
"questEvilSantaBoss": "Trapper Santa",
"questEvilSantaDropBearCubPolarMount": "Polar Bear (Mount)",
"questEvilSanta2Text": "Find The Cub",
"questEvilSanta2Notes": "When Trapper Santa captured the polar bear mount, her cub ran off into the ice-fields. You hear twig-snaps and snow-crunching through the crystalline sound of the forest. Paw prints! You start racing to follow the trail. Find all the prints and broken twigs, and retrieve the cub!",
"questEvilSanta2Notes": "When Trapper Santa captured the polar bear mount, her cub ran off into the icefields. You hear twig-snaps and snow crunch through the crystalline sound of the forest. Paw prints! You start racing to follow the trail. Find all the prints and broken twigs, and retrieve the cub!<br><br><strong>Note</strong>: “Find the Cub” awards a stackable quest achievement but gives a rare pet that can only be added to your stable once.",
"questEvilSanta2Completion": "You've found the cub! It will keep you company forever.",
"questEvilSanta2CollectTracks": "Tracks",
"questEvilSanta2CollectBranches": "Broken Twigs",
@@ -15,49 +15,49 @@
"questGryphonCompletion": "Defeated, the mighty beast ashamedly slinks back to its master. \"My word! Well done, adventurers!\" <strong>baconsaur</strong> exclaims, \"Please, have some of the gryphon's eggs. I am sure you will raise these young ones well!\"",
"questGryphonBoss": "Fiery Gryphon",
"questGryphonDropGryphonEgg": "Gryphon (Egg)",
"questGryphonUnlockText": "Unlocks purchasable Gryphon eggs in the Market",
"questGryphonUnlockText": "Unlocks Gryphon Eggs for purchase in the Market",
"questHedgehogText": "The Hedgebeast",
"questHedgehogNotes": "Hedgehogs are a funny group of animals. They are some of the most affectionate pets a Habiteer could own. But rumor has it, if you feed them milk after midnight, they grow quite irritable. And fifty times their size. And <strong>InspectorCaracal</strong> did just that. Oops.",
"questHedgehogCompletion": "Your party successfully calmed down the hedgehog! After shrinking down to a normal size, she hobbles away to her eggs. She returns squeaking and nudging some of her eggs along towards your party. Hopefully, these hedgehogs like milk better!",
"questHedgehogBoss": "Hedgebeast",
"questHedgehogDropHedgehogEgg": "Hedgehog (Egg)",
"questHedgehogUnlockText": "Unlocks purchasable Hedgehog eggs in the Market",
"questHedgehogUnlockText": "Unlocks Hedgehog Eggs for purchase in the Market",
"questGhostStagText": "The Spirit of Spring",
"questGhostStagNotes": "Ahh, Spring. The time of year when color once again begins to fill the landscape. Gone are the cold, snowy mounds of winter. Where frost once stood, vibrant plant life takes its place. Luscious green leaves fill in the trees, grass returns to its former vivid hue, a rainbow of flowers rise along the plains, and a white mystical fog covers the land! ... Wait. Mystical fog? \"Oh no,\" <strong>InspectorCaracal</strong> says apprehensively, \"It would appear that some kind of spirit is the cause of this fog. Oh, and it is charging right at you.\"",
"questGhostStagNotes": "Ahh, Spring. The time of year when colour once again begins to fill the landscape. Gone are the cold, snowy mounds of winter. Where frost once stood, vibrant plant life takes its place. Luscious green leaves fill in the trees, grass returns to its former vivid hue, a rainbow of flowers rise along the plains, and a white mystical fog covers the land! ... Wait. Mystical fog? \"Oh no,\" <strong>InspectorCaracal</strong> says apprehensively, \"It would appear that some kind of spirit is the cause of this fog. Oh, and it is charging right at you.\"",
"questGhostStagCompletion": "The spirit, seemingly unwounded, lowers its nose to the ground. A calming voice envelops your party. \"I apologise for my behaviour. I have only just awoken from my slumber, and it would appear my wits have not completely returned to me. Please take these as a token of my apology.\" A cluster of eggs materialise on the grass before the spirit. Without another word, the spirit runs off into the forest with flowers falling in his wake.",
"questGhostStagBoss": "Ghost Stag",
"questGhostStagDropDeerEgg": "Deer (Egg)",
"questGhostStagUnlockText": "Unlocks purchasable Deer eggs in the Market",
"questGhostStagUnlockText": "Unlocks Deer Eggs for purchase in the Market",
"questRatText": "The Rat King",
"questRatNotes": "Rubbish! Massive piles of unchecked Dailies are lying all across Habitica. The problem has become so serious that hordes of rats are now seen everywhere. You notice @Pandah petting one of the beasts lovingly. She explains that rats are gentle creatures that feed on unchecked Dailies. The real problem is that the Dailies have fallen into the sewer, creating a dangerous pit that must be cleared. As you descend into the sewers, a massive rat, with blood red eyes and mangled yellow teeth, attacks you, defending its horde. Will you cower in fear or face the fabled Rat King?",
"questRatCompletion": "Your final strike saps the gargantuan rat's strength, his eyes fading to a dull grey. The beast splits into many tiny rats, which scurry off in fright. You notice @Pandah standing behind you, looking at the once mighty creature. She explains that the citizens of Habitica have been inspired by your courage and are quickly completing all their unchecked Dailies. She warns you that we must be vigilant, for should we let down our guard, the Rat King will return. As payment, @Pandah offers you several rat eggs. Noticing your uneasy expression, she smiles, \"They make wonderful pets.\"",
"questRatBoss": "Rat King",
"questRatDropRatEgg": "Rat (Egg)",
"questRatUnlockText": "Unlocks purchasable Rat eggs in the Market",
"questRatUnlockText": "Unlocks Rat Eggs for purchase in the Market",
"questOctopusText": "The Call of Octothulu",
"questOctopusNotes": "@Urse, a wild-eyed young scribe, has asked for your help exploring a mysterious cave by the sea shore. Among the twilight tidepools stands a massive gate of stalactites and stalagmites. As you near the gate, a dark whirlpool begins to spin at its base. You stare in awe as a squid-like dragon rises through the maw. \"The sticky spawn of the stars has awakened,\" roars @Urse madly. \"After vigintillions of years, the great Octothulu is loose again, and ravening for delight!\"",
"questOctopusCompletion": "With a final blow, the creature slips away into the whirlpool from which it came. You cannot tell if @Urse is happy with your victory or saddened to see the beast go. Wordlessly, your companion points to three slimy, gargantuan eggs in a nearby tide-pool, set in a nest of gold coins. \"Probably just octopus eggs,\" you say nervously. As you return home, @Urse frantically scribbles in a journal and you suspect this is not the last time you will hear of the great Octothulu.",
"questOctopusBoss": "Octothulu",
"questOctopusDropOctopusEgg": "Octopus (Egg)",
"questOctopusUnlockText": "Unlocks purchasable Octopus eggs in the Market",
"questOctopusUnlockText": "Unlocks Octopus Eggs for purchase in the Market",
"questHarpyText": "Help! Harpy!",
"questHarpyNotes": "The brave adventurer @UncommonCriminal has disappeared into the forest, following the trail of a winged monster that was sighted several days ago. You are about to begin a search when a wounded parrot lands on your arm, an ugly scar marring its beautiful plumage. Attached to its leg is a scrawled note explaining that while defending the parrots, @UncommonCriminal was captured by a vicious Harpy, and desperately needs your help to escape. Will you follow the bird, defeat the Harpy, and save @UncommonCriminal?",
"questHarpyCompletion": "A final blow to the Harpy brings it down, feathers flying in all directions. After a quick climb to its nest you find @UncommonCriminal, surrounded by parrot eggs. As a team, you quickly place the eggs back in the nearby nests. The scarred parrot who found you caws loudly, dropping several eggs in your arms. \"The Harpy attack has left some eggs in need of protection,\" explains @UncommonCriminal. \"It seems you have been made an honorary parrot.\"",
"questHarpyBoss": "Harpy",
"questHarpyDropParrotEgg": "Parrot (Egg)",
"questHarpyUnlockText": "Unlocks purchasable Parrot eggs in the Market",
"questHarpyUnlockText": "Unlocks Parrot Eggs for purchase in the Market",
"questRoosterText": "Rooster Rampage",
"questRoosterNotes": "For years the farmer @extrajordinary has used Roosters as an alarm clock. But now a giant Rooster has appeared, crowing louder than any before and waking up everyone in Habitica! The sleep-deprived Habiticans struggle through their daily tasks. @Pandoro decides the time has come to put a stop to this. \"Please, is there anyone who can teach that Rooster to crow quietly?\" You volunteer, approaching the Rooster early one morning but it turns, flapping its giant wings and showing its sharp claws, and crows a battle cry.",
"questRoosterCompletion": "With finesse and strength, you have tamed the wild beast. Its ears, once filled with feathers and half-remembered tasks, are now clear as day. It crows at you quietly, snuggling its beak into your shoulder. The next day youre set to take your leave, but @EmeraldOx runs up to you with a covered basket. “Wait! When I went into the farmhouse this morning, the Rooster had pushed these against the door where you slept. I think he wants you to have them.” You uncover the basket to see three delicate eggs.",
"questRoosterBoss": "Rooster",
"questRoosterDropRoosterEgg": "Rooster (Egg)",
"questRoosterUnlockText": "Unlocks purchasable Rooster eggs in the Market",
"questRoosterUnlockText": "Unlocks Rooster Eggs for purchase in the Market",
"questSpiderText": "The Icy Arachnid",
"questSpiderNotes": "As the weather starts cooling down, delicate frost begins appearing on Habiticans' windowpanes in lacy webs... except for @Arcosine, whose windows are frozen completely shut by the Frost Spider currently taking up residence in his home. Oh dear.",
"questSpiderCompletion": "The Frost Spider collapses, leaving behind a small pile of frost and a few of her enchanted egg sacs. @Arcosine rather hurriedly offers them to you as a reward--perhaps you could raise some non-threatening spiders as pets of your own?",
"questSpiderBoss": "Spider",
"questSpiderDropSpiderEgg": "Spider (Egg)",
"questSpiderUnlockText": "Unlocks purchasable Spider eggs in the Market",
"questSpiderUnlockText": "Unlocks Spider Eggs for purchase in the Market",
"questGroupVice": "Vice the Shadow Wyrm",
"questVice1Text": "Vice, Part 1: Free Yourself of the Dragon's Influence",
"questVice1Notes": "<p>They say there lies a terrible evil in the caverns of Mt. Habitica. A monster whose presence twists the wills of the strong heroes of the land, turning them towards bad habits and laziness! The beast is a grand dragon of immense power and comprised of the shadows themselves: Vice, the treacherous Shadow Wyrm. Brave Habiteers, stand up and defeat this foul beast once and for all, but only if you believe you can stand against its immense power. </p><h3>Vice Part 1: </h3><p>How can you expect to fight the beast if it already has control over you? Don't fall victim to laziness and vice! Work hard to fight against the dragon's dark influence and dispel its hold on you!</p>",
@@ -102,7 +102,7 @@
"questGoldenknight2Text": "The Golden Knight, Part 2: Gold Knight",
"questGoldenknight2Notes": "Armed with dozens of Habiticans' testimonies, you finally confront the Golden Knight. You begin to recite the Habitcans' complaints to her, one by one. \"And @Pfeffernusse says that your constant bragging-\" The knight raises her hand to silence you and scoffs, \"Please, these people are merely jealous of my success. Instead of complaining, they should simply work as hard as I! Perhaps I shall show you the power you can attain through diligence such as mine!\" She raises her morningstar and prepares to attack you!",
"questGoldenknight2Boss": "Gold Knight",
"questGoldenknight2Completion": "The Golden Knight lowers her Morningstar in consternation. “I apologize for my rash outburst,” she says. “The truth is, its painful to think that Ive been inadvertently hurting others, and it made me lash out in defense… but perhaps I can still apologize?”",
"questGoldenknight2Completion": "The Golden Knight lowers her Morningstar in consternation. “I apologise for my rash outburst,” she says. “The truth is, its painful to think that Ive been inadvertently hurting others, and it made me lash out in defence… but perhaps I can still apologise?”",
"questGoldenknight2DropGoldenknight3Quest": "The Golden Knight Part 3: The Iron Knight (Scroll)",
"questGoldenknight3Text": "The Golden Knight, Part 3: The Iron Knight",
"questGoldenknight3Notes": "@Jon Arinbjorn cries out to you to get your attention. In the aftermath of your battle, a new figure has appeared. A knight coated in stained-black iron slowly approaches you with sword in hand. The Golden Knight shouts to the figure, \"Father, no!\" but the knight shows no signs of stopping. She turns to you and says, \"I am sorry. I have been a fool, with a head too big to see how cruel I have been. But my father is crueler than I could ever be. If he isn't stopped he'll destroy us all. Here, use my morningstar and halt the Iron Knight!\"",
@@ -133,11 +133,11 @@
"questDilatoryBossRageMarket": "`Dread Drag'on Casts NEGLECT STRIKE!`\n\nAhhh!! Alex the Merchant just had his shop smashed to smithereens by the Drag'on's Neglect Strike! But it seems like we're really wearing this beast down. I doubt it has enough energy for another strike.\n\nSo do not waver, Habitica! Let's drive this beast away from our shores!",
"questDilatoryCompletion": "`The Defeat Of The Dread Drag'On Of Dilatory`\n\nWe've done it! With a final last roar, the Dread Drag'on collapses and swims far, far away. Crowds of cheering Habiticans line the shores! We've helped Matt, Daniel, and Alex rebuild their buildings. But what's this?\n\n`The Citizens Return!`\n\nNow that the Drag'on has fled, thousands of sparkling colours are ascending through the sea. It is a rainbow swarm of Mantis Shrimp... and among them, hundreds of merpeople!\n\n\"We are the lost citizens of Dilatory!\" explains their leader, Manta. \"When Dilatory sank, the Mantis Shrimp that lived in these waters used a spell to transform us into merpeople so that we could survive. But in its rage, the Dread Drag'on trapped us all in the dark crevasse. We have been imprisoned there for hundreds of years - but now at last we are free to rebuild our city!\"\n\n\"As a thank you,\" says his friend @Ottl, \"Please accept this Mantis Shrimp pet and Mantis Shrimp mount, as well as XP, gold, and our eternal gratitude.\"\n\n`Rewards`\n * Mantis Shrimp Pet\n * Mantis Shrimp Mount\n * Chocolate, Blue Candyfloss, Pink Candyfloss, Fish, Honey, Meat, Milk, Potato, Rotten Meat, Strawberry",
"questSeahorseText": "The Dilatory Derby",
"questSeahorseNotes": "It's Derby Day, and Habiticans from all over the continent have traveled to Dilatory to race their pet seahorses! Suddenly, a great splashing and snarling breaks out at the racetrack, and you hear Seahorse Keeper @Kiwibot shouting above the roar of the waves. \"The gathering of seahorses has attracted a fierce Sea Stallion!\" she cries. \"He's smashing through the stables and destroying the ancient track! Can anyone calm him down?\"",
"questSeahorseNotes": "It's Derby Day, and Habiticans from all over the continent have travelled to Dilatory to race their pet seahorses! Suddenly, a great splashing and snarling breaks out at the racetrack, and you hear Seahorse Keeper @Kiwibot shouting above the roar of the waves. \"The gathering of seahorses has attracted a fierce Sea Stallion!\" she cries. \"He's smashing through the stables and destroying the ancient track! Can anyone calm him down?\"",
"questSeahorseCompletion": "The now-tame Sea Stallion swims docilely to your side. \"Oh, look!\" Kiwibot says. \"He wants us to take care of his children.\" She gives you three eggs. \"Raise them well,\" she says. \"You're welcome at the Dilatory Derby any day!\"",
"questSeahorseBoss": "Sea Stallion",
"questSeahorseDropSeahorseEgg": "Seahorse (Egg)",
"questSeahorseUnlockText": "Unlocks purchasable Seahorse eggs in the Market",
"questSeahorseUnlockText": "Unlocks Seahorse Eggs for purchase in the Market",
"questGroupAtom": "Attack of the Mundane",
"questAtom1Text": "Attack of the Mundane, Part 1: Dish Disaster!",
"questAtom1Notes": "You reach the shores of Washed-Up Lake for some well-earned relaxation... But the lake is polluted with unwashed dishes! How did this happen? Well, you simply cannot allow the lake to be in this state. There is only one thing you can do: clean the dishes and save your vacation spot! Better find some soap to clean up this mess. A lot of soap...",
@@ -159,13 +159,13 @@
"questOwlCompletion": "The Night-Owl fades before the dawn,<br>But even so, you feel a yawn.<br>Perhaps it's time to get some rest?<br>Then on your bed, you see a nest!<br>A Night-Owl knows it can be great<br>To finish work and stay up late,<br>But your new pets will softly peep<br>To tell you when it's time to sleep.",
"questOwlBoss": "The Night-Owl",
"questOwlDropOwlEgg": "Owl (Egg)",
"questOwlUnlockText": "Unlocks purchasable Owl eggs in the Market",
"questOwlUnlockText": "Unlocks Owl Eggs for purchase in the Market",
"questPenguinText": "The Fowl Frost",
"questPenguinNotes": "Although it's a hot summer day in the southernmost tip of Habitica, an unnatural chill has fallen upon Lively Lake. Strong, frigid winds rush around as the shore begins to freeze over. Ice spikes jut up from the ground, pushing grass and dirt away. @Melynnrose and @Breadstrings run up to you.<br><br>\"Help!\" says @Melynnrose. \"We brought a giant penguin in to freeze the lake so we could all go ice skating, but we ran out of fish to feed him!\"<br><br>\"He got angry and is using his freeze breath on everything he sees!\" says @Breadstrings. \"Please, you have to subdue him before all of us are covered in ice!\" Looks like you need this penguin to... <em>cool down.</em>",
"questPenguinCompletion": "Upon the penguin's defeat, the ice melts away. The giant penguin settles down in the sunshine, slurping up an extra bucket of fish you found. He skates off across the lake, blowing gently downwards to create smooth, sparkling ice. What an odd bird! \"It appears he left behind a few eggs, as well,\" says @Painter de Cluster. <br><br>@Rattify laughs. \"Maybe these penguins will be a little more... chill?\"",
"questPenguinBoss": "Frost Penguin",
"questPenguinDropPenguinEgg": "Penguin (Egg)",
"questPenguinUnlockText": "Unlocks purchasable Penguin eggs in the Market",
"questPenguinUnlockText": "Unlocks Penguin Eggs for purchase in the Market",
"questStressbeastText": "The Abominable Stressbeast of the Stoïkalm Steppes",
"questStressbeastNotes": "Complete Dailies and To-Dos to damage the World Boss! Incomplete Dailies fill the Stress Strike Bar. When the Stress Strike bar is full, the World Boss will attack an NPC. A World Boss will never damage individual players or accounts in any way. Only active accounts who are not resting in the inn will have their incomplete Dailies tallied.<br><br>~*~<br><br>The first thing we hear are the footsteps, slower and more thundering than the stampede. One by one, Habiticans look outside their doors, and words fail us.<br><br>We've all seen Stressbeasts before, of course - tiny vicious creatures that attack during difficult times. But this? This towers taller than the buildings, with paws that could crush a dragon with ease. Frost swings from its stinking fur, and as it roars, the icy blast rips the roofs off our houses. A monster of this magnitude has never been mentioned outside of distant legend.<br><br>\"Beware, Habiticans!\" SabreCat cries. \"Barricade yourselves indoors - this is the Abominable Stressbeast itself!\"<br><br>\"That thing must be made of centuries of stress!\" Kiwibot says, locking the Tavern door tightly and shuttering the windows.<br><br>\"The Stoïkalm Steppes,\" Lemoness says, face grim. \"All this time, we thought they were placid and untroubled, but they must have been secretly hiding their stress somewhere. Over generations, it grew into this, and now it's broken free and attacked them - and us!\"<br><br>There's only one way to drive away a Stressbeast, Abominable or otherwise, and that's to attack it with completed Dailies and To-Dos! Let's all band together and fight off this fearsome foe - but be sure not to slack on your tasks, or our undone Dailies may enrage it so much that it lashes out...",
"questStressbeastBoss": "The Abominable Stressbeast",
@@ -176,9 +176,9 @@
"questStressbeastBossRageStables": "`Abominable Stressbeast uses STRESS STRIKE!`\n\nThe surge of stress heals Abominable Stressbeast!\n\nOh no! Despite our best efforts, we've let some Dailies get away from us, and their dark-red colour has infuriated the Abominable Stressbeast and caused it to regain some of its health! The horrible creature lunges for the Stables, but Matt the Beast Master heroically leaps into the fray to protect the pets and mounts. The Stressbeast has seized Matt in its vicious grip, but at least it's distracted for the moment. Hurry! Let's keep our Dailies in check and defeat this monster before it attacks again!",
"questStressbeastBossRageBailey": "`Abominable Stressbeast uses STRESS STRIKE!`\n\nThe surge of stress heals Abominable Stressbeast!\n\nAhh!!! Our incomplete Dailies caused the Abominable Stressbeast to become madder than ever and regain some of its health! Bailey the Town Crier was shouting for citizens to get to safety, and now it has seized her in its other hand! Look at her, valiantly reporting on the news as the Stressbeast swings her around viciously... Let's be worthy of her bravery by being as productive as we can to save our NPCs!",
"questStressbeastBossRageGuide": "`Abominable Stressbeast uses STRESS STRIKE!`\n\nThe surge of stress heals Abominable Stressbeast!\n\nLook out! Justin the Guide is trying to distract the Stressbeast by running around its ankles, yelling productivity tips! The Abominable Stressbeast is stomping madly, but it seems like we're really wearing this beast down. I doubt it has enough energy for another strike. Don't give up... we're so close to finishing it off!",
"questStressbeastDesperation": "`Abominable Stressbeast reaches 500K health! Abominable Stressbeast uses Desperate Defense!`\n\nWe're almost there, Habiticans! With diligence and Dailies, we've whittled the Stressbeast's health down to only 500K! The creature roars and flails in desperation, rage building faster than ever. Bailey and Matt yell in terror as it begins to swing them around at a terrifying pace, raising a blinding snowstorm that makes it harder to hit.\n\nWe'll have to redouble our efforts, but take heart - this is a sign that the Stressbeast knows it is about to be defeated. Don't give up now!",
"questStressbeastDesperation": "`Abominable Stressbeast reaches 500K health! Abominable Stressbeast uses Desperate Defence!`\n\nWe're almost there, Habiticans! With diligence and Dailies, we've whittled the Stressbeast's health down to only 500K! The creature roars and flails in desperation, rage building faster than ever. Bailey and Matt yell in terror as it begins to swing them around at a terrifying pace, raising a blinding snowstorm that makes it harder to hit.\n\nWe'll have to redouble our efforts, but take heart - this is a sign that the Stressbeast knows it is about to be defeated. Don't give up now!",
"questStressbeastCompletion": "<strong>The Abominable Stressbeast is DEFEATED!</strong><br><br>We've done it! With a final bellow, the Abominable Stressbeast dissipates into a cloud of snow. The flakes twinkle down through the air as cheering Habiticans embrace their pets and mounts. Our animals and our NPCs are safe once more!<br><br><strong>Stoïkalm is Saved!</strong><br><br>SabreCat speaks gently to a small sabertooth. \"Please find the citizens of the Stoïkalm Steppes and bring them to us,\" he says. Several hours later, the sabertooth returns, with a herd of mammoth riders following slowly behind. You recognise the head rider as Lady Glaciate, the leader of Stoïkalm.<br><br>\"Mighty Habiticans,\" she says, \"My citizens and I owe you the deepest thanks, and the deepest apologies. In an effort to protect our Steppes from turmoil, we began to secretly banish all of our stress into the icy mountains. We had no idea that it would build up over generations into the Stressbeast that you saw! When it broke loose, it trapped all of us in the mountains in its stead and went on a rampage against our beloved animals.\" Her sad gaze follows the falling snow. \"We put everyone at risk with our foolishness. Rest assured that in the future, we will come to you with our problems before our problems come to you.\"<br><br>She turns to where @Baconsaur is snuggling with some of the baby mammoths. \"We have brought your animals an offering of food to apologise for frightening them, and as a symbol of trust, we will leave some of our pets and mounts with you. We know that you will all take care good care of them.\"",
"questStressbeastCompletionChat": "`The Abominable Stressbeast is DEFEATED!`\n\nWe've done it! With a final bellow, the Abominable Stressbeast dissipates into a cloud of snow. The flakes twinkle down through the air as cheering Habiticans embrace their pets and mounts. Our animals and our NPCs are safe once more!\n\n`Stoïkalm is Saved!`\n\nSabreCat speaks gently to a small sabertooth. \"Please find the citizens of the Stoïkalm Steppes and bring them to us,\" he says. Several hours later, the sabertooth returns, with a herd of mammoth riders following slowly behind. You recognize the head rider as Lady Glaciate, the leader of Stoïkalm.\n\n\"Mighty Habiticans,\" she says, \"My citizens and I owe you the deepest thanks, and the deepest apologies. In an effort to protect our Steppes from turmoil, we began to secretly banish all of our stress into the icy mountains. We had no idea that it would build up over generations into the Stressbeast that you saw! When it broke loose, it trapped all of us in the mountains in its stead and went on a rampage against our beloved animals.\" Her sad gaze follows the falling snow. \"We put everyone at risk with our foolishness. Rest assured that in the future, we will come to you with our problems before our problems come to you.\"\n\nShe turns to where @Baconsaur is snuggling with some of the baby mammoths. \"We have brought your animals an offering of food to apologise for frightening them, and as a symbol of trust, we will leave some of our pets and mounts with you. We know that you will all take care good care of them.\"",
"questStressbeastCompletionChat": "`The Abominable Stressbeast is DEFEATED!`\n\nWe've done it! With a final bellow, the Abominable Stressbeast dissipates into a cloud of snow. The flakes twinkle down through the air as cheering Habiticans embrace their pets and mounts. Our animals and our NPCs are safe once more!\n\n`Stoïkalm is Saved!`\n\nSabreCat speaks gently to a small sabertooth. \"Please find the citizens of the Stoïkalm Steppes and bring them to us,\" he says. Several hours later, the sabertooth returns, with a herd of mammoth riders following slowly behind. You recognise the head rider as Lady Glaciate, the leader of Stoïkalm.\n\n\"Mighty Habiticans,\" she says, \"My citizens and I owe you the deepest thanks, and the deepest apologies. In an effort to protect our Steppes from turmoil, we began to secretly banish all of our stress into the icy mountains. We had no idea that it would build up over generations into the Stressbeast that you saw! When it broke loose, it trapped all of us in the mountains in its stead and went on a rampage against our beloved animals.\" Her sad gaze follows the falling snow. \"We put everyone at risk with our foolishness. Rest assured that in the future, we will come to you with our problems before our problems come to you.\"\n\nShe turns to where @Baconsaur is snuggling with some of the baby mammoths. \"We have brought your animals an offering of food to apologise for frightening them, and as a symbol of trust, we will leave some of our pets and mounts with you. We know that you will all take care good care of them.\"",
"questTRexText": "King of the Dinosaurs",
"questTRexNotes": "Now that ancient creatures from the Stoïkalm Steppes are roaming throughout all of Habitica, @Urse has decided to adopt a full-grown Tyrannosaur. What could go wrong?<br><br>Everything.",
"questTRexCompletion": "The wild dinosaur finally stops its rampage and settles down to make friends with the giant roosters. @Urse beams down at it. \"They're not such terrible pets, after all! They just need a little discipline. Here, take some Tyrannosaur eggs for yourself.\"",
@@ -191,43 +191,43 @@
"questTRexUndeadRageDescription": "This bar fills when you don't complete your Dailies. When it is full, the Skeletal Tyrannosaur will heal 30% of its remaining health!",
"questTRexUndeadRageEffect": "`Skeletal Tyrannosaur uses SKELETON HEALING!`\n\nThe monster lets forth an unearthly roar, and some of its damaged bones knit back together!",
"questTRexDropTRexEgg": "Tyrannosaur (Egg)",
"questTRexUnlockText": "Unlocks purchasable Tyrannosaur eggs in the Market",
"questTRexUnlockText": "Unlocks Tyrannosaur Eggs for purchase in the Market",
"questRockText": "Escape the Cave Creature",
"questRockNotes": "Crossing Habitica's Meandering Mountains with some friends, you make camp one night in a beautiful cave laced with shining minerals. But when you wake up the next morning, the entrance has disappeared and the floor of the cave is shifting underneath you.<br><br>\"The mountain's alive!\" shouts your companion @pfeffernusse. \"These aren't crystals—these are teeth!\"<br><br>@Painter de Cluster grabs your hand. \"We'll have to find another way out—stay with me and don't get distracted, or we could be trapped in here forever!\"",
"questRockBoss": "Crystal Colossus",
"questRockCompletion": "Your diligence has allowed you to find a safe path through the living mountain. Standing in the sunshine, your friend @intune notices something glinting on the ground by the cave's exit. You stoop to pick it up, and see that it's a small rock with a vein of gold running through it. Beside it are a number of other rocks with rather peculiar shapes. They almost look like... eggs?",
"questRockDropRockEgg": "Rock (Egg)",
"questRockUnlockText": "Unlocks purchasable Rock eggs in the Market",
"questRockUnlockText": "Unlocks Rock Eggs for purchase in the Market",
"questBunnyText": "The Killer Bunny",
"questBunnyNotes": "After many difficult days, you reach the peak of Mount Procrastination and stand before the imposing doors of the Fortress of Neglect. You read the inscription in the stone. \"Inside resides the creature that embodies your greatest fears, the reason for your inaction. Knock and face your demon!\" You tremble, imagining the horror within and feel the urge to flee as you have done so many times before. @Draayder holds you back. \"Steady, my friend! The time has come at last. You must do this!\"<br><br>You knock and the doors swing inward. From within the gloom you hear a deafening roar, and you draw your weapon.",
"questBunnyBoss": "Killer Bunny",
"questBunnyCompletion": "With one final blow the killer rabbit sinks to the ground. A sparkly mist rises from her body as she shrinks down into a tiny bunny... nothing like the cruel beast you faced a moment before. Her nose twitches adorably and she hops away, leaving some eggs behind. @Gully laughs. \"Mount Procrastination has a way of making even the smallest challenges seem insurmountable. Let's gather these eggs and head for home.\"",
"questBunnyDropBunnyEgg": "Bunny (Egg)",
"questBunnyUnlockText": "Unlocks purchasable Bunny eggs in the Market",
"questBunnyUnlockText": "Unlocks Bunny Eggs for purchase in the Market",
"questSlimeText": "The Jam Regent",
"questSlimeNotes": "As you work on your tasks, you notice you are moving slower and slower. \"It's like walking through molasses,\" @Leephon grumbles. \"No, like walking through jam!\" @starsystemic says. \"That slimy Jelly Regent has slathered his stuff all over Habitica. It's gumming up the works. Everybody is slowing down.\" You look around. The streets are slowly filling with clear, colourful ooze, and Habiticans are struggling to get anything done. As others flee the area, you grab a mop and prepare for battle!",
"questSlimeBoss": "Jam Regent",
"questSlimeCompletion": "With a final jab, you trap the Jam Regent in an over-sized doughnut, rushed in by @Overomega, @LordDarkly, and @Shaner, the quick-thinking leaders of the pastry club. As everyone is patting you on the back, you feel someone slip something into your pocket. Its the reward for your sweet success: three Marshmallow Slime eggs.",
"questSlimeDropSlimeEgg": "Marshmallow Slime (Egg)",
"questSlimeUnlockText": "Unlocks purchasable Slime eggs in the Market",
"questSlimeUnlockText": "Unlocks Marshmallow Slime Eggs for purchase in the Market",
"questSheepText": "The Thunder Ram",
"questSheepNotes": "As you wander the rural Taskan countryside with friends, taking a \"quick break\" from your obligations, you find a cosy yarn shop. You are so absorbed in your procrastination that you hardly notice the ominous clouds creep over the horizon. \"I've got a ba-a-a-ad feeling about this weather,\" mutters @Misceo, and you look up. The stormy clouds are swirling together, and they look a lot like a... \"We don't have time for cloud-gazing!\" @starsystemic shouts. \"It's attacking!\" The Thunder Ram hurtles forward, slinging bolts of lightning right at you!",
"questSheepBoss": "Thunder Ram",
"questSheepCompletion": "Impressed by your diligence, the Thunder Ram is drained of its fury. It launches three huge hailstones in your direction, and then fades away with a low rumble. Upon closer inspection, you discover that the hailstones are actually three fluffy eggs. You gather them up, and then stroll home under a blue sky.",
"questSheepDropSheepEgg": "Sheep (Egg)",
"questSheepUnlockText": "Unlocks purchasable Sheep eggs in the Market",
"questSheepUnlockText": "Unlocks Sheep Eggs for purchase in the Market",
"questKrakenText": "The Kraken of Inkomplete",
"questKrakenNotes": "It's a warm, sunny day as you sail across the Inkomplete Bay, but your thoughts are clouded with worries about everything that you still need to do. It seems that as soon as you finish one task, another crops up, and then another...<br><br>Suddenly, the boat gives a horrible jolt, and slimy tentacles burst out of the water on all sides! \"We're being attacked by the Kraken of Inkomplete!\" Wolvenhalo cries.<br><br>\"Quickly!\" Lemoness calls to you. \"Strike down as many tentacles and tasks as you can, before new ones can rise up to take their place!\"",
"questKrakenBoss": "The Kraken of Inkomplete",
"questKrakenCompletion": "As the Kraken flees, several eggs float to the surface of the water. Lemoness examines them, and her suspicion turns to delight. \"Cuttlefish eggs!\" she says. \"Here, take them as a reward for everything you've completed.\"",
"questKrakenDropCuttlefishEgg": "Cuttlefish (Egg)",
"questKrakenUnlockText": "Unlocks purchasable Cuttlefish eggs in the Market",
"questKrakenUnlockText": "Unlocks Cuttlefish Eggs for purchase in the Market",
"questWhaleText": "Wail of the Whale",
"questWhaleNotes": "You arrive at the Diligent Docks, hoping to take a submarine to watch the Dilatory Derby. Suddenly, a deafening bellow forces you to stop and cover your ears. \"Thar she blows!\" cries Captain @krazjega, pointing to a huge, wailing whale. \"It's not safe to send out the submarines while she's thrashing around!\"<br><br>\"Quick,\" calls @UncommonCriminal. \"Help me calm the poor creature so we can figure out why she's making all this noise!\"",
"questWhaleBoss": "Wailing Whale",
"questWhaleCompletion": "After much hard work, the whale finally ceases her thunderous cry. \"Looks like she was drowning in waves of negative habits,\" @zoebeagle explains. \"Thanks to your consistent effort, we were able to turn the tides!\" As you step into the submarine, several whale eggs bob towards you, and you scoop them up.",
"questWhaleDropWhaleEgg": "Whale (Egg)",
"questWhaleUnlockText": "Unlocks purchasable Whale eggs in the Market",
"questWhaleUnlockText": "Unlocks Whale Eggs for purchase in the Market",
"questGroupDilatoryDistress": "Dilatory Distress",
"questDilatoryDistress1Text": "Dilatory Distress, Part 1: Message in a Bottle",
"questDilatoryDistress1Notes": "A message in a bottle arrived from the newly rebuilt city of Dilatory! It reads: \"Dear Habiticans, we need your help once again. Our princess has disappeared and the city is under siege by some unknown watery demons! The mantis shrimps are holding the attackers at bay. Please aid us!\" To make the long journey to the sunken city, one must be able to breathe water. Fortunately, the alchemists @Benga and @hazel can make it all possible! You only have to find the proper ingredients.",
@@ -257,13 +257,13 @@
"questCheetahCompletion": "The new Habitican is breathing heavily after the wild ride, but thanks you and your friends for your help. \"I'm glad that Cheetah won't be able to grab anyone else. It did leave some Cheetah eggs for us, so maybe we can raise them into more trustworthy pets!\"",
"questCheetahBoss": "Cheetah",
"questCheetahDropCheetahEgg": "Cheetah (Egg)",
"questCheetahUnlockText": "Unlocks purchasable Cheetah eggs in the Market",
"questCheetahUnlockText": "Unlocks Cheetah Eggs for purchase in the Market",
"questHorseText": "Ride the Night-Mare",
"questHorseNotes": "While relaxing in the Tavern with @beffymaroo and @JessicaChase, the talk turns to good-natured boasting about your adventuring accomplishments. Proud of your deeds, and perhaps getting a bit carried away, you brag that you can tame any task around. A nearby stranger turns toward you and smiles. One eye twinkles as he invites you to prove your claim by riding his horse.\nAs you all head for the stables, @UncommonCriminal whispers, \"You may have bitten off more than you can chew. That's no horse - that's a Night-Mare!\" Looking at its stamping hooves, you begin to regret your words...",
"questHorseCompletion": "It takes all your skill, but finally the horse stamps a couple of hooves and nuzzles you in the shoulder before allowing you to mount. You ride briefly but proudly around the Tavern grounds while your friends cheer. The stranger breaks into a broad grin.\n\"I can see that was no idle boast! Your determination is truly impressive. Take these eggs to raise horses of your own, and perhaps we'll meet again one day.\" You take the eggs, the stranger tips his hat... and vanishes.",
"questHorseBoss": "Night-Mare",
"questHorseDropHorseEgg": "Horse (Egg)",
"questHorseUnlockText": "Unlocks purchasable Horse eggs in the Market",
"questHorseUnlockText": "Unlocks Horse Eggs for purchase in the Market",
"questBurnoutText": "Burnout and the Exhaust Spirits",
"questBurnoutNotes": "It is well past midnight, still and stiflingly hot, when Redphoenix and scout captain Kiwibot abruptly burst through the city gates. \"We need to evacuate all the wooden buildings!\" Redphoenix shouts. \"Hurry!\"<br><br>Kiwibot grips the wall as she catches her breath. \"It's draining people and turning them into Exhaust Spirits! That's why everything was delayed. That's where the missing people have gone. It's been stealing their energy!\"<br><br>\"'It'?'\" asks Lemoness.<br><br>And then the heat takes form.<br><br>It rises from the earth in a billowing, twisting mass, and the air chokes with the scent of smoke and sulphur. Flames lick across the molten ground and contort into limbs, writhing to horrific heights. Smoldering eyes snap open, and the creature lets out a deep and crackling cackle.<br><br> Kiwibot whispers a single word.<br><br><em>\"Burnout.\"</em>",
"questBurnoutCompletion": "<strong>Burnout is DEFEATED!</strong><br><br>With a great, soft sigh, Burnout slowly releases the ardent energy that was fueling its fire. As the monster curls quietly into ashes, its stolen energy shimmers through the air, rejuvenating the Exhaust Spirits and returning them to their true forms.<br><br>Ian, Daniel, and the Seasonal Sorceress cheer as Habiticans rush to greet them, and all the missing citizens of the Flourishing Fields embrace their friends and families. The final Exhaust Spirit transforms into the Joyful Reaper herself!<br><br>\"Look!\" whispers @Baconsaur, as the ashes begin to glitter. Slowly, they resolve into hundreds of shining phoenixes!<br><br>One of the glowing birds alights on the Joyful Reaper's skeletal arm, and she grins at it. \"It has been a long time since I've had the exquisite privilege to behold a phoenix in the Flourishing Fields,\" she says. \"Although given recent occurrences, I must say, this is highly thematically appropriate!\"<br><br>Her tone sobers, although (naturally) her grin remains. \"We're known for being hard-working here, but we are also known for our feasts and festivities. Rather ironic, I suppose, that as we strove to plan a spectacular party, we refused to permit ourselves any time for fun. We certainly won't make the same mistake twice!\"<br><br>She claps her hands. \"Now - let's celebrate!\"",
@@ -281,41 +281,41 @@
"questFrogCompletion": "The frog cowers back into the muck, defeated. As it slinks away, the blue slime fades, leaving the way ahead clear.<br><br>Sitting in the middle of the path are three pristine eggs. \"You can even see the tiny tadpoles through the clear casing!\" @Breadstrings says. \"Here, you should take them.\"",
"questFrogBoss": "Clutter Frog",
"questFrogDropFrogEgg": "Frog (Egg)",
"questFrogUnlockText": "Unlocks purchasable Frog eggs in the Market",
"questFrogUnlockText": "Unlocks Frog Eggs for purchase in the Market",
"questSnakeText": "The Serpent of Distraction",
"questSnakeNotes": "It takes a hardy soul to live in the Sand Dunes of Distraction. The arid desert is hardly a productive place, and the shimmering dunes have led many a traveler astray. However, something has even the locals spooked. The sands have been shifting and upturning entire villages. Residents claim a monster with an enormous serpentine body lies in wait under the sands, and they have all pooled together a reward for whomever will help them find and stop it. The much-lauded snake charmers @EmeraldOx and @PainterProphet have agreed to help you summon the beast. Can you stop the Serpent of Distraction?",
"questSnakeNotes": "It takes a hardy soul to live in the Sand Dunes of Distraction. The arid desert is hardly a productive place, and the shimmering dunes have led many a traveller astray. However, something has even the locals spooked. The sands have been shifting and upturning entire villages. Residents claim a monster with an enormous serpentine body lies in wait under the sands, and they have all pooled together a reward for whomever will help them find and stop it. The much-lauded snake charmers @EmeraldOx and @PainterProphet have agreed to help you summon the beast. Can you stop the Serpent of Distraction?",
"questSnakeCompletion": "With assistance from the charmers, you banish the Serpent of Distraction. Though you were happy to help the inhabitants of the Dunes, you can't help but feel a little sad for your fallen foe. While you contemplate the sights, @LordDarkly approaches you. \"Thank you! It's not much, but I hope this can express our gratitude properly.\" He hands you some Gold and... some Snake eggs! You will see that majestic animal again after all.",
"questSnakeBoss": "Serpent of Distraction",
"questSnakeDropSnakeEgg": "Snake (Egg)",
"questSnakeUnlockText": "Unlocks purchasable Snake eggs in the Market",
"questSnakeUnlockText": "Unlocks Snake Eggs for purchase in the Market",
"questUnicornText": "Convincing the Unicorn Queen",
"questUnicornNotes": "Conquest Creek has become muddied, destroying Habit City's fresh water supply! Luckily, @Lukreja knows an old legend that claims that a unicorn's horn can purify the foulest of waters. Together with your intrepid guide @UncommonCriminal, you hike through the frozen peaks of the Meandering Mountains. Finally, at the icy summit of Mount Habitica itself, you find the Unicorn Queen amid the glittering snows. \"Your pleas are compelling,\" she tells you. \"But first you must prove that you are worthy of my aid!\"",
"questUnicornCompletion": "Impressed by your diligence and strength, the Unicorn Queen at last agrees that your cause is worthy. She allows you to ride on her back as she soars to the source of Conquest Creek. As she lowers her golden horn to the befouled waters, a brilliant blue light rises from the waters surface. It is so blinding that you are forced to close your eyes. When you open them a moment later, the unicorn is gone. However, @rosiesully lets out a cry of delight: the water is now clear, and three shining eggs rest at the creeks edge.",
"questUnicornBoss": "The Unicorn Queen",
"questUnicornDropUnicornEgg": "Unicorn (Egg)",
"questUnicornUnlockText": "Unlocks purchasable Unicorn eggs in the Market",
"questUnicornUnlockText": "Unlocks Unicorn Eggs for purchase in the Market",
"questSabretoothText": "The Sabre Cat",
"questSabretoothNotes": "A roaring monster is terrorizing Habitica! The creature stalks through the wilds and woods, then bursts forth to attack before vanishing again. It's been hunting innocent pandas and frightening the flying pigs into fleeing their pens to roost in the trees. @InspectorCaracal and @icefelis explain that the Zombie Sabre Cat was set free while they were excavating in the ancient, untouched ice-fields of the Stoïkalm Steppes. \"It was perfectly friendly at first I don't know what happened. Please, you have to help us recapture it! Only a champion of Habitica can subdue this prehistoric beast!\"",
"questSabretoothCompletion": "After a long and tiring battle, you wrestle the Zombie Sabre Cat to the ground. As you are finally able to approach, you notice a nasty cavity in one of its sabre teeth. Realising the true cause of the cat's wrath, you're able to get the cavity filled by @Fandekasp, and advise everyone to avoid feeding their friend sweets in future. The Sabre Cat flourishes, and in gratitude, its tamers send you a generous reward a clutch of sabretooth eggs!",
"questSabretoothBoss": "Zombie Sabre Cat",
"questSabretoothDropSabretoothEgg": "Sabretooth (Egg)",
"questSabretoothUnlockText": "Unlocks purchasable Sabretooth eggs in the Market",
"questSabretoothUnlockText": "Unlocks Sabretooth Eggs for purchase in the Market",
"questMonkeyText": "Monstrous Mandrill and the Mischief Monkeys",
"questMonkeyNotes": "The Sloensteadi Savannah is being torn apart by the Monstrous Mandrill and his Mischief Monkeys! They shriek loudly enough to drown out the sound of approaching deadlines, encouraging everyone to avoid their duties and keep monkeying around. Alas, plenty of people ape this bad behavior. If no one stops these primates, soon everyone's tasks will be as red as the Monstrous Mandrill's face!<br><br>\"It will take a dedicated adventurer to resist them,\" says @yamato.<br><br>\"Quick, let's get this monkey off everyone's backs!\" @Oneironaut yells, and you charge into battle.",
"questMonkeyCompletion": "You did it! No bananas for those fiends today. Overwhelmed by your diligence, the monkeys flee in panic. \"Look,\" says @Misceo. \"They left a few eggs behind.\"<br><br>@Leephon grins. \"Maybe a well-trained pet monkey can help you as much as the wild ones hinder you!\"",
"questMonkeyBoss": "Monstrous Mandrill",
"questMonkeyDropMonkeyEgg": "Monkey (Egg)",
"questMonkeyUnlockText": "Unlocks purchasable Monkey eggs in the Market",
"questMonkeyUnlockText": "Unlocks Monkey Eggs for purchase in the Market",
"questSnailText": "The Snail of Drudgery Sludge",
"questSnailNotes": "You're excited to begin questing in the abandoned Dungeons of Drudgery, but as soon as you enter, you feel the ground under your feet start to suck at your boots. You look up to the path ahead and see Habiticans mired in slime. @Overomega yells, \"They have too many unimportant tasks and dailies, and they're getting stuck on things that don't matter! Pull them out!\"<br><br>\"You need to find the source of the ooze,\" @Pfeffernusse agrees, \"or the tasks that they cannot accomplish will drag them down forever!\"<br><br>Pulling out your weapon, you wade through the gooey mud.... and encounter the fearsome Snail of Drudgery Sludge.",
"questSnailCompletion": "You bring your weapon down on the great Snail's shell, cracking it in two, releasing a flood of water. The slime is washed away, and the Habiticans around you rejoice. \"Look!\" says @Misceo. \"There's a small group of snail eggs in the remnants of the muck.\"",
"questSnailBoss": "Snail of Drudgery Sludge",
"questSnailDropSnailEgg": "Snail (Egg)",
"questSnailUnlockText": "Unlocks purchasable Snail eggs in the Market",
"questSnailUnlockText": "Unlocks Snail Eggs for purchase in the Market",
"questBewilderText": "The Be-Wilder",
"questBewilderNotes": "The party begins like any other.<br><br>The appetisers are excellent, the music is swinging, and even the dancing elephants have become routine. Habiticans laugh and frolic amid the overflowing floral centrepieces, happy to have a distraction from their least-favourite tasks, and the April Fool whirls among them, eagerly providing an amusing trick here and a witty twist there.<br><br>As the Mistiflying clock tower strikes midnight, the April Fool leaps onto the stage to give a speech.<br><br>“Friends! Enemies! Tolerant acquaintances! Lend me your ears.” The crowd chuckles as animal ears sprout from their heads, and they pose with their new accessories.<br><br>“As you know,” the Fool continues, “my confusing illusions usually only last a single day. But Im pleased to announce that Ive discovered a shortcut that will guarantee us non-stop fun, without having to deal with the pesky weight of our responsibilities. Charming Habiticans, meet my magical new friend... the Be-Wilder!”<br><br>Lemoness pales suddenly, dropping her hors d'oeuvres. “Wait! Dont trust--”<br><br>But suddenly mists are pouring into the room, glittering and thick, and they swirl around the April Fool, coalescing into cloudy feathers and a stretching neck. The crowd is speechless as an monstrous bird unfolds before them, its wings shimmering with illusions. It lets out a horrible screeching laugh.<br><br>“Oh, it has been ages since a Habitican has been foolish enough to summon me! How wonderful it feels, to have a tangible form at last.”<br><br>Buzzing in terror, the magic bees of Mistiflying flee the floating city, which sags from the sky. One by one, the brilliant spring flowers wither up and wisp away.<br><br>“My dearest friends, why so alarmed?” crows the Be-Wilder, beating its wings. “Theres no need to toil for your rewards any more. Ill just give you all the things that you desire!”<br><br>A rain of coins pours from the sky, hammering into the ground with brutal force, and the crowd screams and flees for cover. “Is this a joke?” Baconsaur shouts, as the gold smashes through windows and shatters roof shingles.<br><br>PainterProphet ducks as lightning bolts crackle overhead, and fog blots out the sun. “No! This time, I dont think it is!”<br><br>Quickly, Habiticans, dont let this World Boss distract us from our goals! Stay focused on the tasks that you need to complete so we can rescue Mistiflying -- and hopefully, ourselves.",
"questBewilderCompletion": "<strong>The Be-Wilder is DEFEATED!</strong><br><br>We've done it! The Be-Wilder lets out a ululating cry as it twists in the air, shedding feathers like falling rain. Slowly, gradually, it coils into a cloud of sparkling mist. As the newly-revealed sun pierces the fog, it burns away, revealing the coughing, mercifully human forms of Bailey, Matt, Alex.... and the April Fool himself.<br><br><strong>Mistiflying is saved!</strong><br><br>The April Fool has enough shame to look a bit sheepish. “Oh, hm,” he says. “Perhaps I got a little…. carried away.”<br><br>The crowd mutters. Sodden flowers wash up on pavements. Somewhere in the distance, a roof collapses with a spectacular splash.<br><br>“Er, yes,” the April Fool says. “That is. What I meant to say was, Im dreadfully sorry.” He heaves a sigh. “I suppose it cant all be fun and games, after all. It might not hurt to focus occasionally. Maybe Ill get a head start on next years pranking.”<br><br>Redphoenix coughs meaningfully.<br><br>“I mean, get a head start on this years spring cleaning!” the April Fool says. “Nothing to fear, Ill have Habit City in spit-shape soon. Luckily nobody is better than I at dual-wielding mops.”<br><br>Encouraged, the marching band starts up.<br><br>It isnt long before all is back to normal in Habit City. Plus, now that the Be-Wilder has evaporated, the magical bees of Mistiflying bustle back to work, and soon the flowers are blooming and the city is floating once more.<br><br>As Habiticans cuddle the magical fuzzy bees, the April Fools eyes light up. “Oho, Ive had a thought! Why dont you all keep some of these fuzzy Bee Pets and Mounts? Its a gift that perfectly symbolizes the balance between hard work and sweet rewards, if Im going to get all boring and allegorical on you.” He winks. “Besides, they dont have stingers! Fools honour.”",
"questBewilderCompletionChat": "`The Be-Wilder is DEFEATED!`\n\nWe've done it! The Be-Wilder lets out a ululating cry as it twists in the air, shedding feathers like falling rain. Slowly, gradually, it coils into a cloud of sparkling mist. As the newly-revealed sun pierces the fog, it burns away, revealing the coughing, mercifully human forms of Bailey, Matt, Alex.... and the April Fool himself.\n\n`Mistiflying is saved!`\n\nThe April Fool has enough shame to look a bit sheepish. “Oh, hm,” he says. “Perhaps I got a little…. carried away.”\n\nThe crowd mutters. Sodden flowers wash up on pavements. Somewhere in the distance, a roof collapses with a spectacular splash.\n\n“Er, yes,” the April Fool says. “That is. What I meant to say was, Im dreadfully sorry.” He heaves a sigh. “I suppose it cant all be fun and games, after all. It might not hurt to focus occasionally. Maybe Ill get a head start on next years pranking.”\n\nRedphoenix coughs meaningfully.\n\n“I mean, get a head start on this years spring cleaning!” the April Fool says. “Nothing to fear, Ill have Habit City in spit-shape soon. Luckily nobody is better than I at dual-wielding mops.”\n\nEncouraged, the marching band starts up.\n\nIt isnt long before all is back to normal in Habit City. Plus, now that the Be-Wilder has evaporated, the magical bees of Mistiflying bustle back to work, and soon the flowers are blooming and the city is floating once more.\n\nAs Habiticans cuddle the magical fuzzy bees, the April Fools eyes light up. “Oho, Ive had a thought! Why dont you all keep some of these fuzzy Bee Pets and Mounts? Its a gift that perfectly symbolizes the balance between hard work and sweet rewards, if Im going to get all boring and allegorical on you.” He winks. “Besides, they dont have stingers! Fools honour.”",
"questBewilderCompletion": "<strong>The Be-Wilder is DEFEATED!</strong><br><br>We've done it! The Be-Wilder lets out a ululating cry as it twists in the air, shedding feathers like falling rain. Slowly, gradually, it coils into a cloud of sparkling mist. As the newly-revealed sun pierces the fog, it burns away, revealing the coughing, mercifully human forms of Bailey, Matt, Alex.... and the April Fool himself.<br><br><strong>Mistiflying is saved!</strong><br><br>The April Fool has enough shame to look a bit sheepish. “Oh, hm,” he says. “Perhaps I got a little…. carried away.”<br><br>The crowd mutters. Sodden flowers wash up on pavements. Somewhere in the distance, a roof collapses with a spectacular splash.<br><br>“Er, yes,” the April Fool says. “That is. What I meant to say was, Im dreadfully sorry.” He heaves a sigh. “I suppose it cant all be fun and games, after all. It might not hurt to focus occasionally. Maybe Ill get a head start on next years pranking.”<br><br>Redphoenix coughs meaningfully.<br><br>“I mean, get a head start on this years spring cleaning!” the April Fool says. “Nothing to fear, Ill have Habit City in spit-shape soon. Luckily nobody is better than I at dual-wielding mops.”<br><br>Encouraged, the marching band starts up.<br><br>It isnt long before all is back to normal in Habit City. Plus, now that the Be-Wilder has evaporated, the magical bees of Mistiflying bustle back to work, and soon the flowers are blooming and the city is floating once more.<br><br>As Habiticans cuddle the magical fuzzy bees, the April Fools eyes light up. “Oho, Ive had a thought! Why dont you all keep some of these fuzzy Bee Pets and Mounts? Its a gift that perfectly symbolises the balance between hard work and sweet rewards, if Im going to get all boring and allegorical on you.” He winks. “Besides, they dont have stingers! Fools honour.”",
"questBewilderCompletionChat": "`The Be-Wilder is DEFEATED!`\n\nWe've done it! The Be-Wilder lets out a ululating cry as it twists in the air, shedding feathers like falling rain. Slowly, gradually, it coils into a cloud of sparkling mist. As the newly-revealed sun pierces the fog, it burns away, revealing the coughing, mercifully human forms of Bailey, Matt, Alex.... and the April Fool himself.\n\n`Mistiflying is saved!`\n\nThe April Fool has enough shame to look a bit sheepish. “Oh, hm,” he says. “Perhaps I got a little…. carried away.”\n\nThe crowd mutters. Sodden flowers wash up on pavements. Somewhere in the distance, a roof collapses with a spectacular splash.\n\n“Er, yes,” the April Fool says. “That is. What I meant to say was, Im dreadfully sorry.” He heaves a sigh. “I suppose it cant all be fun and games, after all. It might not hurt to focus occasionally. Maybe Ill get a head start on next years pranking.”\n\nRedphoenix coughs meaningfully.\n\n“I mean, get a head start on this years spring cleaning!” the April Fool says. “Nothing to fear, Ill have Habit City in spit-shape soon. Luckily nobody is better than I at dual-wielding mops.”\n\nEncouraged, the marching band starts up.\n\nIt isnt long before all is back to normal in Habit City. Plus, now that the Be-Wilder has evaporated, the magical bees of Mistiflying bustle back to work, and soon the flowers are blooming and the city is floating once more.\n\nAs Habiticans cuddle the magical fuzzy bees, the April Fools eyes light up. “Oho, Ive had a thought! Why dont you all keep some of these fuzzy Bee Pets and Mounts? Its a gift that perfectly symbolises the balance between hard work and sweet rewards, if Im going to get all boring and allegorical on you.” He winks. “Besides, they dont have stingers! Fools honour.”",
"questBewilderBossRageTitle": "Beguilement Strike",
"questBewilderBossRageDescription": "When this gauge fills, The Be-Wilder will unleash its Beguilement Strike on Habitica!",
"questBewilderDropBumblebeePet": "Magical Bee (Pet)",
@@ -328,19 +328,19 @@
"questFalconCompletion": "Having finally triumphed over the Birds of Preycrastination, you settle down to enjoy the view and your well-earned rest.<br><br>\"Wow!\" says @Trogdorina. \"You won!\"<br><br>@Squish adds, \"Here, take these eggs I found as a reward.\"",
"questFalconBoss": "Birds of Preycrastination",
"questFalconDropFalconEgg": "Falcon (Egg)",
"questFalconUnlockText": "Unlocks purchasable Falcon eggs in the Market",
"questFalconUnlockText": "Unlocks Falcon Eggs for purchase in the Market",
"questTreelingText": "The Tangle Tree",
"questTreelingNotes": "It's the annual Garden Competition, and everyone is talking about the mysterious project which @aurakami has promised to unveil. You join the crowd on the day of the big announcement, and marvel at the introduction of a moving tree. @fuzzytrees explains that the tree will help with garden maintenance, showing how it can mow the lawn, trim the hedge and prune the roses all at the same time until the tree suddenly goes wild, turning its secateurs on its creator! The crowd panics as everyone tries to flee, but you aren't afraid you leap forward, ready to do battle.",
"questTreelingCompletion": "You dust yourself off as the last few leaves drift to the floor. In spite of the upset, the Garden Competition is now safe although the tree you just reduced to a heap of wood chips won't be winning any prizes! \"Still a few kinks to work out there,\" @PainterProphet says. \"Perhaps someone else would do a better job of training the saplings. Do you fancy a go?\"",
"questTreelingBoss": "Tangle Tree",
"questTreelingDropTreelingEgg": "Treeling (Egg)",
"questTreelingUnlockText": "Unlocks purchasable Treeling eggs in the Market",
"questTreelingUnlockText": "Unlocks Treeling Eggs for purchase in the Market",
"questAxolotlText": "The Magical Axolotl",
"questAxolotlNotes": "From the depths of Washed-Up Lake you see rising bubbles and... fire? A little axolotl rises from the murky water spewing streaks of colours. Suddenly it begins to open its mouth and @streak yells, \"Look out!\" as the Magical Axolotl starts to gulp up your willpower!<br><br>The Magical Axolotl swells with spells, taunting you. \"Have you heard of my powers of regeneration? You'll tire before I do!\"<br><br>\"We can defeat you with the good habits we've built!\" @PainterProphet defiantly shouts. You steel yourself to be productive to defeat the Magical Axolotl and regain your stolen willpower!",
"questAxolotlCompletion": "After defeating the Magical Axolotl, you realise that you regained your willpower all on your own.<br><br>\"The willpower? The regeneration? It was all just an illusion?\" @Kiwibot asks.<br><br>\"Most magic is,\" the Magical Axolotl replies. \"I'm sorry for tricking you. Please take these eggs as an apology. I trust you to raise them to use their magic for good habits and not evil!\"<br><br>You and @hazel40 clutch your new eggs in one hand and wave goodbye with the other as the Magical Axolotl returns to the lake.",
"questAxolotlBoss": "Magical Axolotl",
"questAxolotlDropAxolotlEgg": "Axolotl (Egg)",
"questAxolotlUnlockText": "Unlocks purchasable Axolotl eggs in the Market",
"questAxolotlUnlockText": "Unlocks Axolotl Eggs for purchase in the Market",
"questAxolotlRageTitle": "Axolotl Regeneration",
"questAxolotlRageDescription": "This bar fills when you don't complete your Dailies. When it is full, the Magical Axolotl will heal 30% of its remaining health!",
"questAxolotlRageEffect": "`Magical Axolotl uses AXOLOTL REGENERATION!`\n\n`A curtain of colourful bubbles obscures the monster for a moment, and when it clears, some of its wounds have vanished!`",
@@ -349,25 +349,25 @@
"questTurtleCompletion": "Your valiant work has cleared the waters for our sea turtle to find her beach. You, @Bambin, and @JaizakAripaik watch as she buries her brood of eggs deep in the sand so they can grow and hatch into hundreds of little sea turtles. Ever the lady, she gives you three eggs each, asking that you feed and nurture them so one day they become big sea turtles themselves.",
"questTurtleBoss": "Task Flotsam",
"questTurtleDropTurtleEgg": "Turtle (Egg)",
"questTurtleUnlockText": "Unlocks purchasable Turtle eggs in the Market",
"questTurtleUnlockText": "Unlocks Turtle Eggs for purchase in the Market",
"questArmadilloText": "The Indulgent Armadillo",
"questArmadilloNotes": "It's time to get outside and start your day. You swing open your door only to be met with what looks like a sheet of rock. \"I'm just giving you the day off!\" says a muffled voice through the blocked door. \"Don't be such a bummer, just relax today!\"<br><br>Suddenly, @Beffymaroo and @PainterProphet knock on your window. \"Looks like the Indulgent Armadillo has taken a liking to you! C'mon, we'll help you get her out of your way!\"",
"questArmadilloCompletion": "Finally, after a long morning of convincing the Indulgent Armadillo that you do, in fact, want to work, she caves. \"I'm sorry!\" She apologises. \"I just wanted to help. I thought everyone liked lazy days!\"<br><br>You smile, and let her know that next time you've earned a day off you'll invite her over. She grins back at you. Passers-by @Tipsy and @krajzega congratulate you on the good work as she rolls away, leaving a few eggs as an apology.",
"questArmadilloBoss": "Indulgent Armadillo",
"questArmadilloDropArmadilloEgg": "Armadillo (Egg)",
"questArmadilloUnlockText": "Unlocks purchasable Armadillo eggs in the Market",
"questArmadilloUnlockText": "Unlocks Armadillo Eggs for purchase in the Market",
"questCowText": "The Mootant Cow",
"questCowNotes": "Its been a long, hot day at Sparring Farms, and there is nothing more you want than a long sip of water and some sleep. You're standing there daydreaming when @Soloana suddenly screams, \"Everyone run! The prize cow has mootated!\"<br><br>@eevachu gulps. \"It must be our bad habits that infected it.\"<br><br>\"Quick!\" @Feralem Tau says. \"Lets do something before the udder cows mootate, too.\"<br><br>Youve herd enough. No more daydreaming -- it's time to get those bad habits under control!",
"questCowCompletion": "You milk your good habits for all they are worth until the cow reverts to its original form. The cow looks over at you with her pretty brown eyes and nudges over three eggs.<br><br>@fuzzytrees laughs and hands you the eggs, \"Maybe it still is mootated if there are baby cows in these eggs. But I trust you to stick to your good habits when you raise them!\"",
"questCowBoss": "Mootant Cow",
"questCowDropCowEgg": "Cow (Egg)",
"questCowUnlockText": "Unlocks purchasable Cow eggs in the Market",
"questCowUnlockText": "Unlocks Cow Eggs for purchase in the Market",
"questBeetleText": "The CRITICAL BUG",
"questBeetleNotes": "Something in the domain of Habitica has gone awry. The Blacksmiths' forges have extinguished, and strange errors are appearing everywhere. With an ominous tremor, an insidious foe worms from the earth... a CRITICAL BUG! You brace yourself as it infects the land, and glitches begin to overtake the Habiticans around you. @starsystemic yells, \"We need to help the Blacksmiths get this Bug under control!\" It looks like you'll have to make this programmer's pest your top priority.",
"questBeetleCompletion": "With a final attack, you crush the CRITICAL BUG. @starsystemic and the Blacksmiths rush up to you, overjoyed. \"I can't thank you enough for smashing that bug! Here, take these.\" You are presented with three shiny beetle eggs. Hopefully these little bugs will grow up to help Habitica, not hurt it.",
"questBeetleBoss": "CRITICAL BUG",
"questBeetleDropBeetleEgg": "Beetle (Egg)",
"questBeetleUnlockText": "Unlocks purchasable Beetle eggs in the Market",
"questBeetleUnlockText": "Unlocks Beetle Eggs for purchase in the Market",
"questGroupTaskwoodsTerror": "Terror in the Taskwoods",
"questTaskwoodsTerror1Text": "Terror in the Taskwoods, Part 1: The Blaze in the Taskwoods",
"questTaskwoodsTerror1Notes": "You have never seen the Joyful Reaper so agitated. The ruler of the Flourishing Fields lands her skeleton gryphon mount right in the middle of Productivity Plaza and shouts without dismounting. \"Lovely Habiticans, we need your help! Something is starting fires in the Taskwoods, and we still haven't fully recovered from our battle against Burnout. If it's not halted, the flames could engulf all of our wild orchards and berry bushes!\"<br><br>You quickly volunteer, and hasten to the Taskwoods. As you creep into Habiticas biggest fruit-bearing forest, you suddenly hear clanking and cracking voices from far ahead, and catch the faint smell of smoke. Soon enough, a horde of cackling, flaming skull-creatures flies by you, biting off branches and setting the treetops on fire!",
@@ -397,7 +397,7 @@
"questFerretCompletion": "You defeat the soft-furred swindler and @UncommonCriminal gives the crowd their refunds. There's even a little gold left over for you. Plus, it looks like the Nefarious Ferret dropped some eggs in his hurry to get away!",
"questFerretBoss": "Nefarious Ferret",
"questFerretDropFerretEgg": "Ferret (Egg)",
"questFerretUnlockText": "Unlocks purchasable Ferret eggs in the Market",
"questFerretUnlockText": "Unlocks Ferret Eggs for purchase in the Market",
"questDustBunniesText": "The Feral Dust Bunnies",
"questDustBunniesNotes": "It's been a while since you've done any dusting in here, but you're not too worried—a little dust never hurt anyone, right? It's not until you stick your hand into one of the dustiest corners and feel something bite that you remember @InspectorCaracal's warning: leaving harmless dust sit too long causes it to turn into vicious dust bunnies! You'd better defeat them before they cover all of Habitica in fine particles of dirt!",
"questDustBunniesCompletion": "The dust bunnies vanish into a puff of... well, dust. As it clears, you look around. You'd forgotten how nice this place looks when it's clean. You spy a small pile of gold where the dust used to be. Huh, you'd been wondering where that was!",
@@ -419,17 +419,17 @@
"questMoon3Boss": "Monstrous Moon",
"questMoon3DropWeapon": "Lunar Scythe (Two-Handed Weapon)",
"questSlothText": "The Somnolent Sloth",
"questSlothNotes": "As you and your party venture through the Somnolent Snowforest, you're relieved to see a glimmering of green among the white snowdrifts... until an enormous sloth emerges from the frosty trees! Green emeralds shimmer hypnotically on its back.<br><br>\"Hello, adventurers... why don't you take it slow? You've been walking for a while... so why not... stop? Just lie down, and rest...\"<br><br>You feel your eyelids grow heavy, and you realize: It's the Somnolent Sloth! According to @JaizakAripaik, it got its name from the emeralds on its back which are rumored to... send people to... sleep...<br><br>You shake yourself awake, fighting drowsiness. In the nick of time, @awakebyjava and @PainterProphet begin to shout spells, forcing your party awake. \"Now's our chance!\" @Kiwibot yells.",
"questSlothNotes": "As you and your party venture through the Somnolent Snowforest, you're relieved to see a glimmering of green among the white snowdrifts... until an enormous sloth emerges from the frosty trees! Green emeralds shimmer hypnotically on its back.<br><br>\"Hello, adventurers... why don't you take it slow? You've been walking for a while... so why not... stop? Just lie down, and rest...\"<br><br>You feel your eyelids grow heavy, and you realise: It's the Somnolent Sloth! According to @JaizakAripaik, it got its name from the emeralds on its back which are rumored to... send people to... sleep...<br><br>You shake yourself awake, fighting drowsiness. In the nick of time, @awakebyjava and @PainterProphet begin to shout spells, forcing your party awake. \"Now's our chance!\" @Kiwibot yells.",
"questSlothCompletion": "You did it! As you defeat the Somnolent Sloth, its emeralds break off. \"Thank you for freeing me of my curse,\" says the sloth. \"I can finally sleep well, without those heavy emeralds on my back. Have these eggs as thanks, and you can have the emeralds too.\" The sloth gives you three sloth eggs and heads off for warmer climates.",
"questSlothBoss": "Somnolent Sloth",
"questSlothDropSlothEgg": "Sloth (Egg)",
"questSlothUnlockText": "Unlocks purchasable Sloth eggs in the Market",
"questSlothUnlockText": "Unlocks Sloth Eggs for purchase in the Market",
"questTriceratopsText": "The Trampling Triceratops",
"questTriceratopsNotes": "The snow-capped Stoïkalm Volcanoes are always bustling with hikers and sight-seers. One tourist, @plumilla, calls over a crowd. \"Look! I enchanted the ground to glow so that we can play field games on it for our outdoor activity Dailies!\" Sure enough, the ground is swirling with glowing red patterns. Even some of the prehistoric pets from the area come over to play.<br><br>Suddenly, there's a loud snap -- a curious Triceratops has stepped on @plumilla's wand! It's engulfed in a burst of magic energy, and the ground starts shaking and growing hot. The Triceratops' eyes shine red, and it roars and begins to stampede!<br><br>\"That's not good,\" calls @McCoyly, pointing in the distance. Each magic-fueled stomp is causing the volcanoes to erupt, and the glowing ground is turning to lava beneath the dinosaur's feet! Quickly, you must hold off the Trampling Triceratops until someone can reverse the spell!",
"questTriceratopsCompletion": "With quick thinking, you herd the creature towards the soothing Stoïkalm Steppes so that @*~Seraphina~* and @PainterProphet can reverse the lava spell without distraction. The calming aura of the Steppes takes effect, and the Triceratops curls up as the volcanoes go dormant once more. @PainterProphet passes you some eggs that were rescued from the lava. \"Without you, we wouldn't have been able to concentrate to stop the eruptions. Give these pets a good home.\"",
"questTriceratopsBoss": "Trampling Triceratops",
"questTriceratopsDropTriceratopsEgg": "Triceratops (Egg)",
"questTriceratopsUnlockText": "Unlocks purchasable Triceratops eggs in the Market",
"questTriceratopsUnlockText": "Unlocks Triceratops Eggs for purchase in the Market",
"questGroupStoikalmCalamity": "Stoïkalm Calamity",
"questStoikalmCalamity1Text": "Stoïkalm Calamity, Part 1: Earthen Enemies",
"questStoikalmCalamity1Notes": "A terse missive arrives from @Kiwibot, and the frost-crusted scroll chills your heart as well as your fingertips. \"Visiting Stoïkalm Steppes -- monsters bursting from earth -- send help!\" You gather your party and ride north, but as soon as you venture down from the mountains, the snow beneath your feet explodes and gruesomely grinning skulls surround you!<br><br>Suddenly, a spear sails past, burying itself in a skull that was burrowing through the snow in an attempt to catch you unawares. A tall woman in finely-crafted armour gallops into the fray on the back of a mastodon, her long braid swinging as she yanks the spear unceremoniously from the crushed beast. It's time to fight off these foes with the help of Lady Glaciate, the leader of the Mammoth Riders!",
@@ -458,19 +458,19 @@
"questGuineaPigCompletion": "\"We submit!\" The Guinea Pig Gang Boss waves his paws at you, fluffy head hanging in shame. From underneath his hat falls a list, and @snazzyorange quickly swipes it for evidence. \"Wait a minute,\" you say. \"It's no wonder you've been getting hurt! You've got way too many Dailies. You don't need health potions -- you just need help organising.\"<br><br>\"Really?\" squeaks the Guinea Pig Gang Boss. \"We've robbed so many people because of this! Please take our eggs as an apology for our crooked ways.\"",
"questGuineaPigBoss": "Guinea Pig Gang",
"questGuineaPigDropGuineaPigEgg": "Guinea Pig (Egg)",
"questGuineaPigUnlockText": "Unlocks purchasable Guinea Pig eggs in the Market",
"questGuineaPigUnlockText": "Unlocks Guinea Pig Eggs for purchase in the Market",
"questPeacockText": "The Push-and-Pull Peacock",
"questPeacockNotes": "You trek through the Taskwoods, wondering which of the enticing new goals you should pick. As you go deeper into the forest, you realise that you're not alone in your indecision. \"I could learn a new language, or go to the gym...\" @Cecily Perez mutters. \"I could sleep more,\" muses @Lilith of Alfheim, \"or spend time with my friends...\" It looks like @PainterProphet, @Pfeffernusse, and @Draayder are equally paralysed by the overwhelming options.<br><br>You realise that these ever-more-demanding feelings aren't really your own... you've stumbled straight into the trap of the pernicious Push-and-Pull Peacock! Before you can run, it leaps from the bushes. With each head pulling you in conflicting directions, you start to feel burnout overcoming you. You can't defeat both foes at once, so you only have one option -- concentrate on the nearest task to fight back!",
"questPeacockCompletion": "The Push-and-Pull Peacock is caught off guard by your sudden conviction. Defeated by your single-minded drive, its heads merge back into one, revealing the most beautiful creature you've ever seen. \"Thank you,\" the peacock says. \"Ive spent so long pulling myself in different directions that I lost sight of what I truly wanted. Please accept these eggs as a token of my gratitude.\"",
"questPeacockBoss": "Push-and-Pull Peacock",
"questPeacockDropPeacockEgg": "Peacock (Egg)",
"questPeacockUnlockText": "Unlocks purchasable Peacock eggs in the Market",
"questPeacockUnlockText": "Unlocks Peacock Eggs for purchase in the Market",
"questButterflyText": "Bye, Bye, Butterfry",
"questButterflyNotes": "Your gardener friend @Megan sends you an invitation: “These warm days are the perfect time to visit Habiticas butterfly garden in the Taskan countryside. Come see the butterflies migrate!” When you arrive, however, the garden is in shambles -- little more than scorched grass and dried-out weeds. Its been so hot that the Habiticans havent come out to water the flowers, and the dark-red Dailies have turned it into a dry, sun-baked, fire-hazard. There's only one butterfly there, and there's something odd about it...<br><br>“Oh no! This is the perfect hatching ground for the Flaming Butterfry,” cries @Leephon.<br><br>“If we dont catch it, itll destroy everything!” gasps @Eevachu.<br><br>Time to say bye, bye to Butterfry!",
"questButterflyCompletion": "After a blazing battle, the Flaming Butterfry is captured. “Great job catching the that would-be arsonist,” says @Megan with a sigh of relief. “Still, its hard to vilify even the vilest butterfly. Wed better free this Butterfry someplace safe…like the desert.”<br><br>One of the other gardeners, @Beffymaroo, comes up to you, singed but smiling. “Will you help raise these foundling chrysalises we found? Perhaps next year well have a greener garden for them.”",
"questButterflyBoss": "Flaming Butterfry",
"questButterflyDropButterflyEgg": "Caterpillar (Egg)",
"questButterflyUnlockText": "Unlocks purchasable Caterpillar eggs in the Market",
"questButterflyUnlockText": "Unlocks Caterpillar Eggs for purchase in the Market",
"questGroupMayhemMistiflying": "Mayhem in Mistiflying",
"questMayhemMistiflying1Text": "Mayhem in Mistiflying, Part 1: In Which Mistiflying Experiences a Dreadful Bother",
"questMayhemMistiflying1Notes": "Although local soothsayers predicted pleasant weather, the afternoon is extremely breezy, so you gratefully follow your friend @Kiwibot into their house to escape the blustery day.<br><br>Neither of you expects to find the April Fool lounging at the kitchen table.<br><br>“Oh, hello,” he says. “Fancy seeing you here. Please, let me offer you some of this delicious tea.”<br><br>“Thats…” @Kiwibot begins. “Thats MY—“<br><br>“Yes, yes, of course,” says the April Fool, helping himself to some cookies. “Just thought Id pop indoors and get a nice reprieve from all the tornado-summoning skulls.” He takes a casual sip from his teacup. “Incidentally, the city of Mistiflying is under attack.”<br><br>Horrified, you and your friends race to the Stables and saddle your fastest winged mounts. As you soar towards the floating city, you see that a swarm of chattering, flying skulls are laying siege to the city… and several turn their attentions towards you!",
@@ -490,7 +490,7 @@
"questMayhemMistiflying2CollectGreenMistiflies": "Green Mistiflies",
"questMayhemMistiflying2DropHeadgear": "Roguish Rainbow Messenger Hood (Headgear)",
"questMayhemMistiflying3Text": "Mayhem in Mistiflying, Part 3: In Which a Mailman is Extremely Rude",
"questMayhemMistiflying3Notes": "The Mistiflies are whirling so thickly through the tornado that its hard to see. Squinting, you spot a many-winged silhouette floating at the center of the tremendous storm.<br><br>“Oh, dear,” the April Fool sighs, nearly drowned out by the howl of the weather. “Looks like Winny went and got himself possessed. Very relatable problem, that. Could happen to anybody.”<br><br>“The Wind-Worker!” @Beffymaroo hollers at you. “Hes Mistiflyings most talented messenger-mage, since hes so skilled with weather magic. Normally hes a very polite mailman!”<br><br>As if to counteract this statement, the Wind-Worker lets out a scream of fury, and even with your magic robes, the storm nearly rips you from your mount.<br><br>“That gaudy mask is new,” the April Fool remarks. “Perhaps you should relieve him of it?”<br><br>Its a good idea… but the enraged mage isnt going to give it up without a fight.",
"questMayhemMistiflying3Notes": "The Mistiflies are whirling so thickly through the tornado that its hard to see. Squinting, you spot a many-winged silhouette floating at the centre of the tremendous storm.<br><br>“Oh, dear,” the April Fool sighs, nearly drowned out by the howl of the weather. “Looks like Winny went and got himself possessed. Very relatable problem, that. Could happen to anybody.”<br><br>“The Wind-Worker!” @Beffymaroo hollers at you. “Hes Mistiflyings most talented messenger-mage, since hes so skilled with weather magic. Normally hes a very polite mailman!”<br><br>As if to counteract this statement, the Wind-Worker lets out a scream of fury, and even with your magic robes, the storm nearly rips you from your mount.<br><br>“That gaudy mask is new,” the April Fool remarks. “Perhaps you should relieve him of it?”<br><br>Its a good idea… but the enraged mage isnt going to give it up without a fight.",
"questMayhemMistiflying3Completion": "Just as you think you cant withstand the wind any longer, you manage to snatch the mask from the Wind-Workers face. Instantly, the tornado is sucked away, leaving only balmy breezes and sunshine. The Wind-Worker looks around in bemusement. “Where did she go?”<br><br>“Who?” your friend @khdarkwolf asks.<br><br>“That sweet woman who offered to deliver a package for me. Tzina.” As he takes in the wind-swept city below him, his expression darkens. “Then again, maybe she wasnt so sweet…”<br><br>The April Fool pats him on the back, then hands you two shimmering envelopes. “Here. Why dont you let this distressed fellow rest, and take charge of the mail for a bit? I hear the magic in those envelopes will make them worth your while.”",
"questMayhemMistiflying3Boss": "The Wind-Worker",
"questMayhemMistiflying3DropPinkCottonCandy": "Pink Cotton Candy (Food)",
@@ -498,12 +498,12 @@
"questMayhemMistiflying3DropWeapon": "Roguish Rainbow Message (Main-Hand Item)",
"featheredFriendsText": "Feathered Friends Quest Bundle",
"featheredFriendsNotes": "Contains 'Help! Harpy!,' 'The Night-Owl,' and 'The Birds of Preycrastination.' Available until May 31.",
"questNudibranchText": "Infestation of the NowDo Nudibranches",
"questNudibranchNotes": "You finally get around to checking your To-dos on a lazy day in Habitica. Bright against your deepest red tasks are a gaggle of vibrant blue sea slugs. You are entranced! Their sapphire colours make your most intimidating tasks look as easy as your best Habits. In a feverish stupor you get to work, tackling one task after the other in a ceaseless frenzy...<br><br>The next thing you know, @LilithofAlfheim is pouring cold water over you. “The NowDo Nudibranches have been stinging you all over! You need to take a break!”<br><br>Shocked, you see that your skin is as bright red as your To-Do list was. \"Being productive is one thing,\" @beffymaroo says, \"but you've also got to take care of yourself. Hurry, let's get rid of them!\"",
"questNudibranchCompletion": "You see the last of the NowDo Nudibranches sliding off of a pile of completed tasks as @amadshade washes them away. One leaves behind a cloth bag, and you open it to reveal some gold and a few little ellipsoids you guess are eggs.",
"questNudibranchText": "Infestation of the NowDo Nudibranchs",
"questNudibranchNotes": "You finally get around to checking your To-dos on a lazy day in Habitica. Bright against your deepest red tasks are a gaggle of vibrant blue sea slugs. You are entranced! Their sapphire colours make your most intimidating tasks look as easy as your best Habits. In a feverish stupor you get to work, tackling one task after the other in a ceaseless frenzy...<br><br>The next thing you know, @LilithofAlfheim is pouring cold water over you. “The NowDo Nudibranchs have been stinging you all over! You need to take a break!”<br><br>Shocked, you see that your skin is as bright red as your To-Do list was. \"Being productive is one thing,\" @beffymaroo says, \"but you've also got to take care of yourself. Hurry, let's get rid of them!\"",
"questNudibranchCompletion": "You see the last of the NowDo Nudibranchs sliding off of a pile of completed tasks as @amadshade washes them away. One leaves behind a cloth bag, and you open it to reveal some gold and a few little ellipsoids you guess are eggs.",
"questNudibranchBoss": "NowDo Nudibranch",
"questNudibranchDropNudibranchEgg": "Nudibranch (Egg)",
"questNudibranchUnlockText": "Unlocks purchasable Nudibranch eggs in the Market",
"questNudibranchUnlockText": "Unlocks Nudibranch Eggs for purchase in the Market",
"splashyPalsText": "Splashy Pals Quest Bundle",
"splashyPalsNotes": "Contains 'The Dilatory Derby', 'Guide the Turtle', and 'Wail of the Whale'. Available until July 31.",
"questHippoText": "What a Hippo-Crite",
@@ -511,9 +511,9 @@
"questHippoCompletion": "The hippo bows in surrender. “I underestimated you. It seems you werent being lazy. My apologies. Truth be told, I may have been projecting a bit. Perhaps I should get some work done myself. Here, take these eggs as a sign of my gratitude.” Grabbing them, you settle down by the water, ready to relax at last.",
"questHippoBoss": "The Hippo-Crite",
"questHippoDropHippoEgg": "Hippo (Egg)",
"questHippoUnlockText": "Unlocks purchasable Hippo eggs in the Market",
"questHippoUnlockText": "Unlocks Hippo Eggs for purchase in the Market",
"farmFriendsText": "Farm Friends Quest Bundle",
"farmFriendsNotes": "Contains 'The Mootant Cow', 'Ride the Night-Mare', and 'The Thunder Ram'. Available until September 30.",
"farmFriendsNotes": "Contains 'The Mootant Cow', 'Ride the Night-Mare', and 'The Thunder Ram'. Available until August 31.",
"witchyFamiliarsText": "Witchy Familiars Quest Bundle",
"witchyFamiliarsNotes": "Contains 'The Rat King', 'The Icy Arachnid', and 'Swamp of the Clutter Frog'. Available until October 31.",
"questGroupLostMasterclasser": "Mystery of the Masterclassers",
@@ -557,25 +557,25 @@
"questYarnCompletion": "With a feeble swipe of a pin-riddled appendage and a weak roar, the Dread Yarnghetti finally unravels into a pile of yarn balls.<br><br>\"Take care of this yarn,\" shopkeeper @JinjooHat says, handing them to you. \"If you feed them and care for them properly, they'll grow into new and exciting projects that just might make your heart take flight…\"",
"questYarnBoss": "The Dread Yarnghetti",
"questYarnDropYarnEgg": "Yarn (Egg)",
"questYarnUnlockText": "Unlocks purchasable Yarn eggs in the Market",
"questYarnUnlockText": "Unlocks Yarn Eggs for purchase in the Market",
"winterQuestsText": "Winter Quest Bundle",
"winterQuestsNotes": "Contains 'Trapper Santa', 'Find the Cub', and 'The Fowl Frost'. Available until December 31.",
"winterQuestsNotes": "Contains 'Trapper Santa', 'Find the Cub', and 'The Fowl Frost'. Available until January 31. Note that Trapper Santa and Find the Cub have stackable quest achievements but give a rare pet and mount that can only be added to your stable once.",
"questPterodactylText": "The Pterror-dactyl",
"questPterodactylNotes": "You're taking a stroll along the peaceful Stoïkalm Cliffs when an evil screech rends the air. You turn to find a hideous creature flying towards you and are overcome by a powerful terror. As you turn to flee, @Lilith of Alfheim grabs you. \"Don't panic! It's just a Pterror-dactyl.\"<br><br>@Procyon P nods. \"They nest nearby, but they're attracted to the scent of negative Habits and undone Dailies.\"<br><br>\"Don't worry,\" @Katy133 says. \"We just need to be extra productive to defeat it!\" You are filled with a renewed sense of purpose and turn to face your foe.",
"questPterodactylCompletion": "With one last screech the Pterror-dactyl plummets over the side of the cliff. You run forward to watch it soar away over the distant steppes. \"Phew, I'm glad that's over,\" you say. \"Me too,\" replies @GeraldThePixel. \"But look! It's left some eggs behind for us.\" @Edge passes you three eggs, and you vow to raise them in tranquility, surrounded by positive Habits and blue Dailies.",
"questPterodactylBoss": "Pterror-dactyl",
"questPterodactylDropPterodactylEgg": "Pterodactyl (Egg)",
"questPterodactylUnlockText": "Unlocks purchasable Pterodactyl eggs in the Market",
"questPterodactylUnlockText": "Unlocks Pterodactyl Eggs for purchase in the Market",
"questBadgerText": "Stop Badgering Me!",
"questBadgerNotes": "Ah, winter in the Taskwoods. The softly falling snow, the branches sparkling with frost, the Flourishing Fairies… still not snoozing?<br><br>“Why are they still awake?” cries @LilithofAlfheim. “If they don't hibernate soon, they'll never have the energy for planting season.”<br><br>As you and @Willow the Witty hurry to investigate, a furry head pops up from the ground. Before you can yell, “Its the Badgering Bother!” its back in its burrow—but not before snatching up the Fairies' “Hibernate” To-Dos and dropping a giant list of pesky tasks in their place!<br><br>“No wonder the fairies aren't resting, if they're constantly being badgered like that!” @plumilla says. Can you chase off this beast and save the Taskwoods harvest this year?",
"questBadgerCompletion": "You finally drive away the the Badgering Bother and hurry into its burrow. At the end of a tunnel, you find its hoard of the faeries “Hibernate” To-Dos. The den is otherwise abandoned, except for three eggs that look ready to hatch.",
"questBadgerBoss": "The Badgering Bother",
"questBadgerDropBadgerEgg": "Badger (Egg)",
"questBadgerUnlockText": "Unlocks purchasable Badger eggs in the Market",
"questBadgerUnlockText": "Unlocks Badger Eggs for purchase in the Market",
"questDysheartenerText": "The Dysheartener",
"questDysheartenerNotes": "The sun is rising on Valentines Day when a shocking crash splinters the air. A blaze of sickly pink light lances through all the buildings, and bricks crumble as a deep crack rips through Habit Citys main street. An unearthly shrieking rises through the air, shattering windows as a hulking form slithers forth from the gaping earth.<br><br>Mandibles snap and a carapace glitters; legs upon legs unfurl in the air. The crowd begins to scream as the insectoid creature rears up, revealing itself to be none other than that cruelest of creatures: the fearsome Dysheartener itself. It howls in anticipation and lunges forward, hungering to gnaw on the hopes of hard-working Habiticans. With each rasping scrape of its spiny forelegs, you feel a vise of despair tightening in your chest.<br><br>“Take heart, everyone!” Lemoness shouts. “It probably thinks that were easy targets because so many of us have daunting New Years Resolutions, but its about to discover that Habiticans know how to stick to their goals!”<br><br>AnnDeLune raises her staff. “Lets tackle our tasks and take this monster down!”",
"questDysheartenerCompletion": "<strong>The Dysheartener is DEFEATED!</strong><br><br>Together, everyone in Habitica strikes a final blow to their tasks, and the Dysheartener rears back, shrieking with dismay. “What's wrong, Dysheartener?” AnnDeLune calls, eyes sparkling. “Feeling discouraged?”<br><br>Glowing pink fractures crack across the Dysheartener's carapace, and it shatters in a puff of pink smoke. As a renewed sense of vigor and determination sweeps across the land, a flurry of delightful sweets rains down upon everyone.<br><br>The crowd cheers wildly, hugging each other as their pets happily chew on the belated Valentine's treats. Suddenly, a joyful chorus of song cascades through the air, and gleaming silhouettes soar across the sky.<br><br>Our newly-invigorated optimism has attracted a flock of Hopeful Hippogriffs! The graceful creatures alight upon the ground, ruffling their feathers with interest and prancing about. “It looks like we've made some new friends to help keep our spirits high, even when our tasks are daunting,” Lemoness says.<br><br>Beffymaroo already has her arms full with feathered fluffballs. “Maybe they'll help us rebuild the damaged areas of Habitica!”<br><br>Crooning and singing, the Hippogriffs lead the way as all the Habitcans work together to restore our beloved home.",
"questDysheartenerCompletionChat": "`The Dysheartener is DEFEATED!`\n\nTogether, everyone in Habitica strikes a final blow to their tasks, and the Dysheartener rears back, shrieking with dismay. “What's wrong, Dysheartener?” AnnDeLune calls, eyes sparkling. “Feeling discouraged?”\n\nGlowing pink fractures crack across the Dysheartener's carapace, and it shatters in a puff of pink smoke. As a renewed sense of vigor and determination sweeps across the land, a flurry of delightful sweets rains down upon everyone.\n\nThe crowd cheers wildly, hugging each other as their pets happily chew on the belated Valentine's treats. Suddenly, a joyful chorus of song cascades through the air, and gleaming silhouettes soar across the sky.\n\nOur newly-invigorated optimism has attracted a flock of Hopeful Hippogriffs! The graceful creatures alight upon the ground, ruffling their feathers with interest and prancing about. “It looks like we've made some new friends to help keep our spirits high, even when our tasks are daunting,” Lemoness says.\n\nBeffymaroo already has her arms full with feathered fluffballs. “Maybe they'll help us rebuild the damaged areas of Habitica!”\n\nCrooning and singing, the Hippogriffs lead the way as all the Habitcans work together to restore our beloved home.",
"questDysheartenerCompletion": "<strong>The Dysheartener is DEFEATED!</strong><br><br>Together, everyone in Habitica strikes a final blow to their tasks, and the Dysheartener rears back, shrieking with dismay. “What's wrong, Dysheartener?” AnnDeLune calls, eyes sparkling. “Feeling discouraged?”<br><br>Glowing pink fractures crack across the Dysheartener's carapace, and it shatters in a puff of pink smoke. As a renewed sense of vigour and determination sweeps across the land, a flurry of delightful sweets rains down upon everyone.<br><br>The crowd cheers wildly, hugging each other as their pets happily chew on the belated Valentine's treats. Suddenly, a joyful chorus of song cascades through the air, and gleaming silhouettes soar across the sky.<br><br>Our newly-invigorated optimism has attracted a flock of Hopeful Hippogriffs! The graceful creatures alight upon the ground, ruffling their feathers with interest and prancing about. “It looks like we've made some new friends to help keep our spirits high, even when our tasks are daunting,” Lemoness says.<br><br>Beffymaroo already has her arms full with feathered fluffballs. “Maybe they'll help us rebuild the damaged areas of Habitica!”<br><br>Crooning and singing, the Hippogriffs lead the way as all the Habitcans work together to restore our beloved home.",
"questDysheartenerCompletionChat": "`The Dysheartener is DEFEATED!`\n\nTogether, everyone in Habitica strikes a final blow to their tasks, and the Dysheartener rears back, shrieking with dismay. “What's wrong, Dysheartener?” AnnDeLune calls, eyes sparkling. “Feeling discouraged?”\n\nGlowing pink fractures crack across the Dysheartener's carapace, and it shatters in a puff of pink smoke. As a renewed sense of vigour and determination sweeps across the land, a flurry of delightful sweets rains down upon everyone.\n\nThe crowd cheers wildly, hugging each other as their pets happily chew on the belated Valentine's treats. Suddenly, a joyful chorus of song cascades through the air, and gleaming silhouettes soar across the sky.\n\nOur newly-invigorated optimism has attracted a flock of Hopeful Hippogriffs! The graceful creatures alight upon the ground, ruffling their feathers with interest and prancing about. “It looks like we've made some new friends to help keep our spirits high, even when our tasks are daunting,” Lemoness says.\n\nBeffymaroo already has her arms full with feathered fluffballs. “Maybe they'll help us rebuild the damaged areas of Habitica!”\n\nCrooning and singing, the Hippogriffs lead the way as all the Habitcans work together to restore our beloved home.",
"questDysheartenerBossRageTitle": "Shattering Heartbreak",
"questDysheartenerBossRageDescription": "The Rage Attack gauge fills when Habiticans miss their Dailies. If it fills up, the Dysheartener will unleash its Shattering Heartbreak attack on one of Habitica's shopkeepers, so be sure to do your tasks!",
"questDysheartenerBossRageSeasonal": "`The Dysheartener uses SHATTERING HEARTBREAK!`\n\nOh, no! After feasting on our undone Dailies, the Dysheartener has gained the strength to unleash its Shattering Heartbreak attack. With a shrill shriek, it brings its spiny forelegs down upon the pavilion that houses the Seasonal Shop! The concussive blast of magic shreds the wood, and the Seasonal Sorceress is overcome by sorrow at the sight.\n\nQuickly, let's keep doing our Dailies so that the beast won't strike again!",
@@ -596,11 +596,11 @@
"hugabugText": "Hug a Bug Quest Bundle",
"hugabugNotes": "Contains 'The CRITICAL BUG,' 'The Snail of Drudgery Sludge,' and 'Bye, Bye, Butterfry.' Available until March 31.",
"questSquirrelText": "The Sneaky Squirrel",
"questSquirrelNotes": "You wake up and find youve overslept! Why didnt your alarm go off? … How did an acorn get stuck in the ringer?<br><br>When you try to make breakfast, the toaster is stuffed with acorns. When you go to retrieve your mount, @Shtut is there, trying unsuccessfully to unlock their stable. They look into the keyhole. “Is that an acorn in there?”<br><br>@randomdaisy cries out, “Oh no! I knew my pet squirrels had gotten out, but I didnt know theyd made such trouble! Can you help me round them up before they make any more of a mess?”<br><br>Following the trail of mischievously placed oak nuts, you track and catch the wayward sciurines, with @Cantras helping secure each one safely at home. But just when you think your task is almost complete, an acorn bounces off your helm! You look up to see a mighty beast of a squirrel, crouched in defense of a prodigious pile of seeds.<br><br>“Oh dear,” says @randomdaisy, softly. “Shes always been something of a resource guarder. Well have to proceed very carefully!” You circle up with your party, ready for trouble!",
"questSquirrelNotes": "You wake up and find youve overslept! Why didnt your alarm go off? … How did an acorn get stuck in the ringer?<br><br>When you try to make breakfast, the toaster is stuffed with acorns. When you go to retrieve your mount, @Shtut is there, trying unsuccessfully to unlock their stable. They look into the keyhole. “Is that an acorn in there?”<br><br>@randomdaisy cries out, “Oh no! I knew my pet squirrels had gotten out, but I didnt know theyd made such trouble! Can you help me round them up before they make any more of a mess?”<br><br>Following the trail of mischievously placed oak nuts, you track and catch the wayward sciurines, with @Cantras helping secure each one safely at home. But just when you think your task is almost complete, an acorn bounces off your helm! You look up to see a mighty beast of a squirrel, crouched in defence of a prodigious pile of seeds.<br><br>“Oh dear,” says @randomdaisy, softly. “Shes always been something of a resource guarder. Well have to proceed very carefully!” You circle up with your party, ready for trouble!",
"questSquirrelCompletion": "With a gentle approach, offers of trade, and a few soothing spells, youre able to coax the squirrel away from its hoard and back to the stables, which @Shtut has just finished de-acorning. Theyve set aside a few of the acorns on a worktable. “These ones are squirrel eggs! Maybe you can raise some that dont play with their food quite so much.”",
"questSquirrelBoss": "Sneaky Squirrel",
"questSquirrelDropSquirrelEgg": "Squirrel (Egg)",
"questSquirrelUnlockText": "Unlocks purchasable Squirrel eggs in the Market",
"questSquirrelUnlockText": "Unlocks Squirrel Eggs for purchase in the Market",
"cuddleBuddiesText": "Cuddle Buddies Quest Bundle",
"cuddleBuddiesNotes": "Contains 'The Killer Bunny', 'The Nefarious Ferret', and 'The Guinea Pig Gang'. Available until May 31.",
"aquaticAmigosText": "Aquatic Amigos Quest Bundle",
@@ -610,13 +610,13 @@
"questSeaSerpentCompletion": "Battered by your commitment, the sea serpent flees, disappearing into the depths. When you arrive in Dilatory, you breathe a sigh of relief before noticing @*~Seraphina~ approaching with three translucent eggs cradled in her arms. “Here, you should have these,” she says. “You know how to handle a sea serpent!” As you accept the eggs, you vow anew to remain steadfast in completing your tasks to ensure that theres not a repeat occurrence.",
"questSeaSerpentBoss": "The Mighty Sea Serpent",
"questSeaSerpentDropSeaSerpentEgg": "Sea Serpent (Egg)",
"questSeaSerpentUnlockText": "Unlocks purchasable Sea Serpent eggs in the Market",
"questSeaSerpentUnlockText": "Unlocks Sea Serpent Eggs for purchase in the Market",
"questKangarooText": "Kangaroo Catastrophe",
"questKangarooNotes": "Maybe you should have finished that last task… you know, the one you keep avoiding, even though it always comes back around? But @Mewrose and @LilithofAlfheim invited you and @stefalupagus to see a rare kangaroo troop hopping through the Sloensteadi Savannah; how could you say no?! As the troop comes into view, something hits you on the back of the head with a mighty <em>whack!</em><br><br>Shaking the stars from your vision, you pick up the responsible object--a dark red boomerang, with the very task you continually push back etched into its surface. A quick glance around confirms the rest of your party met a similar fate. One larger kangaroo looks at you with a smug grin, like shes daring you to face her and that dreaded task once and for all!",
"questKangarooCompletion": "“NOW!” You signal your party to throw the boomerangs back at the kangaroo. The beast hops further away with each hit until she flees, leaving nothing more than a dark red cloud of dust, a few eggs, and some gold coins.<br><br>@Mewrose walks forward to where the kangaroo once stood. “Hey, where did the boomerangs go?”<br><br>“They probably dissolved into dust, making that dark red cloud, when we finished our respective tasks,” @stefalupagus speculates.<br><br>@LilithofAlfheim squints at the horizon. “Is that another kangaroo troop heading our way?”<br><br>You all break into a run back to Habit City. Better to face your difficult tasks than take another lump to the back of the head!",
"questKangarooBoss": "Catastrophic Kangaroo",
"questKangarooDropKangarooEgg": "Kangaroo (Egg)",
"questKangarooUnlockText": "Unlocks purchasable Kangaroo eggs in the Market",
"questKangarooUnlockText": "Unlocks Kangaroo Eggs for purchase in the Market",
"forestFriendsText": "Forest Friends Quest Bundle",
"forestFriendsNotes": "Contains 'The Spirit of Spring', 'The Hedgebeast', and 'The Tangle Tree'. Available until September 30.",
"questAlligatorText": "The Insta-Gator",
@@ -624,9 +624,9 @@
"questAlligatorCompletion": "With your attention focused on whats important and not the Insta-Gators distractions, the Insta-Gator flees. Victory! “Are those eggs? They look like gator eggs to me,” asks @mfonda. “If we care for them correctly, theyll be loyal pets or faithful steeds,” answers @UncommonCriminal, handing you three to care for. Lets hope so, or else the Insta-Gator might make a return…",
"questAlligatorBoss": "Insta-Gator",
"questAlligatorDropAlligatorEgg": "Alligator (Egg)",
"questAlligatorUnlockText": "Unlocks purchasable Alligator eggs in the Market",
"questAlligatorUnlockText": "Unlocks Alligator Eggs for purchase in the Market",
"oddballsText": "Oddballs Quest Bundle",
"oddballsNotes": "Contains 'The Jelly Regent,' 'Escape the Cave Creature,' and 'A Tangled Yarn.' Available until December 3.",
"oddballsNotes": "Contains 'The Jelly Regent,' 'Escape the Cave Creature,' and 'A Tangled Yarn.' Available until June 30.",
"birdBuddiesText": "Bird Buddies Quest Bundle",
"birdBuddiesNotes": "Contains 'The Fowl Frost,' 'Rooster Rampage,' and 'The Push-and-Pull Peacock.' Available until December 31.",
"questVelociraptorText": "The Veloci-Rapper",
@@ -634,7 +634,46 @@
"questVelociraptorCompletion": "You burst through the grass, confronting the Veloci-Rapper.<br><br><em>See here, rapper, youre no quitter,<br>Youre Bad Habits' hardest hitter!<br>Check off your To-Dos like a boss,<br>Dont mourn over one days loss!</em><br><br>Filled with renewed confidence, it bounds off to freestyle another day, leaving behind three eggs where it sat.",
"questVelociraptorBoss": "Veloci-Rapper",
"questVelociraptorDropVelociraptorEgg": "Velociraptor (Egg)",
"questVelociraptorUnlockText": "Unlocks purchasable Velociraptor eggs in the Market",
"questVelociraptorUnlockText": "Unlocks Velociraptor Eggs for purchase in the Market",
"mythicalMarvelsText": "Mythical Marvels Quest Bundle",
"mythicalMarvelsNotes": "Contains 'Convincing the Unicorn Queen,' 'The Fiery Gryphon,' and 'Danger in the Depths: Sea Serpent Strike!' Available until February 28."
"mythicalMarvelsNotes": "Contains 'Convincing the Unicorn Queen,' 'The Fiery Gryphon,' and 'Danger in the Depths: Sea Serpent Strike!' Available until February 28.",
"questSilverDropSilverPotion": "Silver Hatching Potion",
"questSilverCollectSilverIngots": "Silver Ingots",
"rockingReptilesText": "Rocking Reptiles Quest Bundle",
"questRobotUnlockText": "Unlocks purchasable Robot Eggs in the Market",
"questRobotDropRobotEgg": "Robot (Egg)",
"questRobotCollectSprings": "Springs",
"questRobotCollectGears": "Gears",
"questRobotCollectBolts": "Bolts",
"questRobotCompletion": "As @Rev and the Accountability Buddy place the last bolt in place, the time machine buzzes to life. @FolleMente and @McCoyly jump aboard. “Thanks for the assist! Well see you in the future! By the way, these should help you with your next invention!” With that, the time travellers disappear, but left behind in the wreckage of the old Productivity Stabiliser are three clockwork eggs. Perhaps these will be the crucial components for a new production line of Accountability Buddies!",
"questRobotNotes": "At Max Capacity labs, @Rev is putting the finishing touches on their newest invention, a robotic Accountability Buddy, when a strange metal vehicle suddenly appears in a plume of smoke, inches from the robots Fluctuation Detector! Its occupants, two strange figures dressed in silver, emerge and remove their space helmets, revealing themselves as @FolleMente and @McCoyly.<br><br>“I hypothesise that there was an anomaly in our productivity implementation,” @FolleMente says sheepishly.<br><br>@McCoyly crosses her arms. “That means they neglected to complete their Dailies, which I postulate led to the disintegration of our Productivity Stabiliser. Its an essential component to time travel that needs consistency to work properly. Our accomplishments power our movement through time and space! I dont have time to explain further, @Rev. Youll discover it in 37 years, or perhaps your allies the Mysterious Time Travellers can fill you in. For now, can you help us fix our time machine?”",
"questRobotText": "Mysterious Mechanical Marvels!",
"questSilverUnlockText": "Unlocks Silver Hatching Potions for purchase in the Market",
"questSilverCollectMoonRunes": "Moon Runes",
"questSilverCollectCancerRunes": "Cancer Zodiac Runes",
"questSilverCompletion": "You've delved. You've dredged. You've scavenged. At last you emerge from the Dungeons, laden with runes and bars of silver, covered in sludge but exhilarated with success. You journey back to Habit City and set to work in an alchemy lab. You and @starsystemic follow the formulas @QuartzFox found, under the careful supervision of @Edge. Finally, in a great puff of glitter and smoke, your concoction settles into the familiar viscosity of a Hatching Potion!<br><br>@Edge scoops the mixture into vials and grins. “Let's give it a try, shall we? Anyone got any Eggs?”<br><br>You rush to the Stables, wondering what shining secrets may yet remain undiscovered...",
"questSilverNotes": "The recent discovery of Bronze Hatching Potions has all of Habitica talking. Could potions of even brighter metals be possible? You head to Habit City's central Public Library, accompanied by @QuartzFox and @starsystemic, and gather up great armloads of books on alchemy to study.<br><br>After hours of eye-straining labour, @QuartzFox lets out a not-quite-library-appropriate shout of triumph. “Aha! I've found it!” You hurry over to see. “A Silver Hatching Potion can be made with runes of the zodiac sign Cancer, dissolved in pure silver melted over flame infused with the power of Moon runes.”<br><br>“We'll need a lot of those ingredients,” muses @starsystemic. “In case an attempt goes wrong.”<br><br>“There's only one place to find huge quantities of such random crafting materials,” says @Edge, standing in the shadow of the stacks with arms crossed. Have they been there the whole time? “The Dungeons of Drudgery. Let's get going.”",
"questSilverText": "The Silver Solution",
"questDolphinUnlockText": "Unlocks Dolphin Eggs for purchase in the Market",
"questDolphinDropDolphinEgg": "Dolphin (Egg)",
"questDolphinCompletion": "Your battle of wills with the dolphin has left you tired but victorious. With your determination and encouragement, @mewrose, @khdarkwolf, and @confusedcicada pick themselves up and shake off the dolphins insidious telepathy. The four of you shield yourselves with a sense of accomplishment in your consistent Dailies, strong Habits, and completed To-Dos until it closes its glowing eyes in silent acknowledgment of your successes. With that, it tumbles back into the bay. As you trade high-fives and congratulations, you notice three eggs wash ashore.<br><br>“Hm, I wonder what we can do with those,” @khdarkwolf muses.",
"questDolphinBoss": "Dolphin of Doubt",
"questDolphinNotes": "You walk upon the shores of Inkomplete Bay, pondering the daunting work ahead of you. A splash in the water catches your eye. A magnificent dolphin arcs over the waves. Sunlight glimmers off its fins and tail. But wait...thats not sunlight, and the dolphin doesnt dip back into the sea. It fixes its gaze on @khdarkwolf.<br><br>“Ill never finish all these Dailies,” said @khdarkwolf.<br><br>“Im not good enough to reach my goals,” said @confusedcicada as the dolphin turned its glare on them.<br><br>“Why did I even bother trying?” asked @mewrose, withering under the stare of the beast.<br><br>Its eyes meet yours, and feel your mind begin to sink under the rising tide of doubt. You steel yourself; someone has to defeat this creature, and its going to be you!",
"questDolphinText": "The Dolphin of Doubt",
"questBronzeUnlockText": "Unlocks Bronze Hatching Potions for purchase in the Market",
"questBronzeDropBronzePotion": "Bronze Hatching Potion",
"questBronzeBoss": "Brazen Beetle",
"questBronzeCompletion": "“Well met, warrior!” says the beetle as she settles to the ground. Is she smiling? It's hard to tell from those mandibles. “You've truly earned these potions!”<br<br>“Oh wow, weve never gotten a reward like this for winning a battle before!” says @UncommonCriminal, turning a shimmering bottle in their hand. “Let's go hatch our new pets!”",
"questBronzeNotes": "On a refreshing break between tasks, you and some friends take a stroll through the forest trails of the Taskwoods. You come upon a large hollow log and a sparkle from inside catches your attention.<br><br>Why, it's a cache of Magic Hatching Potions! The shimmering bronze liquid swirls gently in the bottles, and @Hachiseiko reaches to pick one up to examine it.<br><br>“Halt!” hisses a voice from behind you. It's a gigantic beetle with a carapace of gleaming bronze, raising her clawed feet in a fighting stance. “Those are my potions, and if you wish to earn them, you must prove yourself in a gentlefolks' duel!”",
"questBronzeText": "Brazen Beetle Battle",
"evilSantaAddlNotes": "Note that Trapper Santa and Find the Cub have stackable quest achievements but give a rare pet and mount that can only be added to your stable once.",
"rockingReptilesNotes": "Contains 'The Insta-Gator,' 'The Serpent of Distraction,' and 'The Veloci-Rapper.' Available until September 30.",
"delightfulDinosText": "Delightful Dinos Quest Bundle",
"delightfulDinosNotes": "Contains 'The Pterror-dactyl,' 'The Trampling Triceratops,' and 'The Dinosaur Unearthed.' Available until November 30.",
"questAmberText": "The Amber Alliance",
"questAmberNotes": "Youre sitting in the Tavern with @beffymaroo and @-Tyr- when @Vikte bursts through the door and excitedly tells you about the rumors of another type of Magic Hatching Potion hidden in the Taskwoods. Having completed your Dailies, the three of you immediately agree to help @Vikte on their search. After all, whats the harm in a little adventure?<br><br>After walking through the Taskwoods for hours, youre beginning to regret joining such a wild chase. Youre about to head home, when you hear a surprised yelp and turn to see a huge lizard with shiny amber scales coiled around a tree, clutching @Vikte in her claws. @beffymaroo reaches for her sword.<br><br>“Wait!” cries @-Tyr-. “Its the Trerezin! Shes not dangerous, just dangerously clingy!”",
"questAmberCompletion": "“Trerezin?” @-Tyr- says calmly. “Could you let @Vikte go? I dont think theyre enjoying being so high up.”<br><br>The Trerezins amber skin blushes crimson and she gently lowers @Vikte to the ground. “My apologies! Its been so long since Ive had any guests that Ive forgotten my manners!” She slithers forward to greet you properly before disappearing into her treehouse, and returning with an armful of Amber Hatching Potions as thank-you gifts!<br><br>“Magic Potions!” @Vikte gasps.<br><br>“Oh, these old things?” The Trerezin's tongue flickers as she thinks. “How about this? Ill give you this whole stack if you promise to visit me every so often...”<br><br>And so you leave the Taskwoods, excited to tell everyone about the new potions--and your new friend!",
"questAmberBoss": "Trerezin",
"questAmberDropAmberPotion": "Amber Hatching Potion",
"questAmberUnlockText": "Unlocks Amber Hatching Potions for purchase in the Market"
}

View File

@@ -21,9 +21,10 @@
"rebirthOrb": "Used an Orb of Rebirth to start over after attaining Level <%= level %>.",
"rebirthOrb100": "Used an Orb of Rebirth to start over after attaining Level 100 or higher.",
"rebirthOrbNoLevel": "Used an Orb of Rebirth to start over.",
"rebirthPop": "Instantly restart your character as a Level 1 Warrior, while retaining achievements, collectibles, and equipment. Your tasks and their history will remain but they will be reset to yellow. Your streaks will be removed, except from challenge tasks. Your Gold, Experience, Mana, and the effects of all Skills will be removed. All of this will take effect immediately. For more information, see the wiki's <a href='http://habitica.fandom.com/wiki/Orb_of_Rebirth' target='_blank'>Orb of Rebirth</a> page.",
"rebirthPop": "Instantly restart your character as a Level 1 Warrior while retaining achievements, collectibles, and equipment. Your tasks and their history will remain but they will be reset to yellow. Your streaks will be removed except from tasks belonging to active Challenges and Group Plans. Your Gold, Experience, Mana, and the effects of all Skills will be removed. All of this will take effect immediately. For more information, see the wiki's <a href='http://habitica.fandom.com/wiki/Orb_of_Rebirth' target='_blank'>Orb of Rebirth</a> page.",
"rebirthName": "Orb of Rebirth",
"reborn": "Reborn, max level <%= reLevel %>",
"confirmReborn": "Are you sure?",
"rebirthComplete": "You have been reborn!"
"rebirthComplete": "You have been reborn!",
"nextFreeRebirth": "<strong><%= days %> days</strong> until <strong>FREE</strong> Orb of Rebirth"
}

View File

@@ -119,8 +119,8 @@
"giftedSubscriptionInfo": "<%= name %> gifted you a <%= months %> month subscription",
"giftedSubscriptionFull": "Hello <%= username %>, <%= sender %> has sent you <%= monthCount %> months of subscription!",
"giftedSubscriptionWinterPromo": "Hello <%= username %>, you received <%= monthCount %> months of subscription as part of our holiday gift-giving promotion!",
"invitedParty": "Invited To Party",
"invitedGuild": "Invited To Guild",
"invitedParty": "You were invited to a Party",
"invitedGuild": "You were invited to a Guild",
"importantAnnouncements": "Reminders to check in to complete tasks and receive prizes",
"weeklyRecaps": "Summaries of your account activity in the past week (Note: this is currently disabled due to performance issues, but we hope to have this back up and sending e-mails again soon!)",
"onboarding": "Guidance with setting up your Habitica account",
@@ -203,6 +203,14 @@
"goToSettings": "Go to Settings",
"usernameVerifiedConfirmation": "Your username, <%= username %>, is confirmed!",
"usernameNotVerified": "Please confirm your username.",
"changeUsernameDisclaimer": "We will be transitioning login names to unique, public usernames soon. This username will be used for invitations, @mentions in chat, and messaging.",
"verifyUsernameVeteranPet": "One of these Veteran Pets will be waiting for you after you've finished confirming!"
"changeUsernameDisclaimer": "This username will be used for invitations, @mentions in chat, and messaging.",
"verifyUsernameVeteranPet": "One of these Veteran Pets will be waiting for you after you've finished confirming!",
"everywhere": "Everywhere",
"onlyPrivateSpaces": "Only in private spaces",
"suggestMyUsername": "Suggest my username",
"mentioning": "Mentioning",
"subscriptionReminders": "Subscriptions Reminders",
"newPMNotificationTitle": "New Message from <%= name %>",
"chatExtensionDesc": "The Chat Extension for Habitica adds an intuitive chat box to all of habitica.com. It allows users to chat in the Tavern, their party, and any guilds they are in.",
"chatExtension": "<a target='blank' href='https://chrome.google.com/webstore/detail/habitrpg-chat-client/hidkdfgonpoaiannijofifhjidbnilbb'>Chrome Chat Extension</a> and <a target='blank' href='https://addons.mozilla.org/en-US/firefox/addon/habitica-chat-client-2/'>Firefox Chat Extension</a>"
}

View File

@@ -23,7 +23,7 @@
"spellRogueToolsOfTradeText": "Tools of the Trade",
"spellRogueToolsOfTradeNotes": "Your tricky talents buff your whole Party's Perception! (Based on: Unbuffed PER)",
"spellRogueStealthText": "Stealth",
"spellRogueStealthNotes": "With each cast, a few of your undone Dailies won't cause damage tonight. Their streaks and colors won't change. (Based on: PER)",
"spellRogueStealthNotes": "With each cast, a few of your undone Dailies won't cause damage tonight. Their streaks and colours won't change. (Based on: PER)",
"spellRogueStealthDaliesAvoided": "<%= originalText %> Number of dailies avoided: <%= number %>.",
"spellRogueStealthMaxedOut": " You have already avoided all your dailies; there's no need to cast this again.",
"spellHealerHealText": "Healing Light",

View File

@@ -215,5 +215,19 @@
"gemsPurchaseNote": "Subscribers can buy gems for gold in the Market! For easy access, you can also pin the gem to your Rewards column.",
"gemsRemaining": "gems remaining",
"notEnoughGemsToBuy": "You are unable to buy that amount of gems",
"mysterySet201902": "Cryptic Crush Set"
"mysterySet201902": "Cryptic Crush Set",
"mysterySet201908": "Footloose Faun Set",
"mysterySet201907": "Beach Buddy Set",
"mysterySet201906": "Kindly Koi Set",
"mysterySet201905": "Dazzling Dragon Set",
"mysterySet201904": "Opulent Opal Set",
"mysterySet201903": "Egg-squisite Set",
"subWillBecomeInactive": "Will become inactive",
"confirmCancelSub": "Are you sure you want to cancel your subscription? You will lose all of your subscription benefits.",
"mysterySet201909": "Affable Acorn Set",
"mysterySet201910": "Cryptic Flame Set",
"mysterySet201911": "Crystal Charmer Set",
"mysterySet201912": "Polar Pixie Set",
"mysterySet202001": "Fabled Fox Set",
"subCanceledTitle": "Subscription Cancelled"
}

View File

@@ -1820,5 +1820,42 @@
"weaponArmoireFloridFanNotes": "Te encariñan los pliegues de seda cuando no están en uso. Incrementa la Constitución en <%= con %>. Armario Encantado: Objeto Independiente.",
"weaponArmoireFloridFanText": "Abanico Florido",
"eyewearMystery201907Notes": "¡Luce asombroso mientras proteges tus ojos de los dañinos rayos UV! No confiere beneficios. Equipamiento de suscripción de julio del 2019.",
"weaponSpecialWinter2020WarriorNotes": "¡Atrás, ardillas! ¡No os llevaréis ni un poco de esto! ... Pero si todas vosotras queréis pasar el rato y tomar chocolate caliente, está guay. Aumenta la fuerza en <%= str %>. Edición limitada del invierno 2019-2020."
"weaponSpecialWinter2020WarriorNotes": "¡Atrás, ardillas! ¡No os llevaréis ni un poco de esto! ... Pero si todas vosotras queréis pasar el rato y tomar chocolate caliente, está guay. Aumenta la fuerza en <%= str %>. Edición limitada del invierno 2019-2020.",
"weaponSpecialWinter2020RogueText": "Varilla de Linterna",
"shieldSpecialPiDayText": "Escudo Pi",
"headArmoireFrostedHelmText": "Casco Congelado",
"headArmoireAlchemistsHatText": "Sombrero de Alquemista",
"headArmoireAstronomersHatText": "Sombrero de Astrónomo",
"headMystery201911Text": "Sombrero Encantado de Cristal",
"headSpecialWinter2020MageText": "Corona de Campana",
"headSpecialFall2019MageText": "Máscara de Cíclope",
"headSpecialFall2019WarriorText": "Casco de Obsidiana",
"headSpecialFall2019RogueText": "Sombrero Antiguo de Ópera",
"headSpecialSummer2019WarriorText": "Casco de Tortuga",
"headSpecialSummer2019RogueText": "Casco de Martillo",
"headSpecialSpring2019MageText": "Casco de Ámbar",
"headSpecialSpring2019WarriorText": "Casco de Orquídea",
"headSpecialSpring2019RogueText": "Casco de Nube",
"headSpecialPiDayText": "Sombrero Pi",
"armorArmoireLayerCakeArmorText": "Armadura de Tarta",
"armorArmoireAlchemistsRobeText": "Bata de Alquemista",
"armorArmoireAstronomersRobeText": "Bata de Astrónomo",
"armorMystery201910Text": "Armadura Críptica",
"armorMystery201907Text": "Camiseta de Flores",
"armorMystery201904Text": "Traje Opalescente",
"armorSpecialWinter2020MageText": "Abrigo con Curvas",
"armorSpecialWinter2020WarriorText": "Armadura de Corteza",
"armorSpecialFall2019WarriorText": "Alas de la Noche",
"armorSpecialSummer2019WarriorText": "Armadura de Caparazón",
"armorSpecialSpring2019WarriorText": "Armadura de Orquídea",
"armorSpecialSpring2019RogueText": "Armadura de Nube",
"weaponArmoireShadowMastersMaceText": "Maza del Maestro de las Sombras",
"weaponArmoireResplendentRapierNotes": "Demuestra tu habilidad en el manejo de la espada con este arma bien afilada. Aumenta la Percepción por <%= per %>. Armario Encantado: Ítem Independiente.",
"weaponArmoireResplendentRapierText": "Espada Resplandeciente",
"weaponSpecialWinter2020HealerNotes": "Sacúdelo y su aroma reunirá a tus amigos y ayudantes para que empiecen a cocinar y hornear. Aumenta la Inteligencia por <%= int %>. Edición Limitada Equipamiento de Invierno 2019-2020.",
"weaponSpecialWinter2020HealerText": "Cetro de Clavo",
"weaponSpecialWinter2020MageNotes": "Con práctica, puedes proyecta tu aura mágica con la frecuencia que quieras: un mantra meditativo, una campanada festiva or una ALARMA DE TAREA SIN FINALIZAR. Aumenta la Inteligencia por <%= int %> y la Percepción por by <%= per %>. Edición Limitada Equipamiento de Invierno 2019-2020.",
"weaponSpecialWinter2020MageText": "Ondas de Sonido",
"weaponSpecialWinter2020WarriorText": "Cono de Conífera Puntiagudo",
"weaponSpecialWinter2020RogueNotes": "La oscuridad es el elemento del Pícaro. ¿Quién mejor que él para iluminar la época más oscura del año? Aumenta la Fuerza por <%= str %>. Edición Limitada. Equipamiento de Invierno 2019-2020."
}

View File

@@ -168,5 +168,10 @@
"summer2019ConchHealerSet": "Caracola (Sanador)",
"summer2019WaterLilyMageSet": "Nenúfar (Mago)",
"summer2019SeaTurtleWarriorSet": "Tortuga Marina (Guerrero)",
"augustYYYY": "Agosto del <%= year %>"
"augustYYYY": "Agosto del <%= year %>",
"decemberYYYY": "Diciembre <%= year %>",
"winter2020LanternSet": "Linterna (Pícaro)",
"winter2020WinterSpiceSet": "Especia de Invierno (Sanador)",
"winter2020CarolOfTheMageSet": "Villancico del Mago",
"winter2020EvergreenSet": "Siempre Joven (Guerrero)"
}

View File

@@ -485,5 +485,12 @@
"backgroundHolidayWreathText": "Couronne de Noël",
"backgroundHolidayMarketNotes": "trouvez les cadeaux et les décorations parfaites au marché de Noël.",
"backgroundHolidayMarketText": "Marché de Noël",
"backgrounds122019": "Ensemble 67 : sorti en décembre 2019"
"backgrounds122019": "Ensemble 67 : sorti en décembre 2019",
"backgroundSnowglobeNotes": "Secouez une boule à neige et prenez part au microcosme d'un paysage hivernal.",
"backgroundSnowglobeText": "Boule à neige",
"backgroundDesertWithSnowNotes": "Soyez témoin de la rare et tranquille beauté d'un désert enneigé.",
"backgroundDesertWithSnowText": "Désert enneigé",
"backgroundBirthdayPartyNotes": "Célébrez la fête d'anniversaire de votre acolyte préféré.",
"backgroundBirthdayPartyText": "Fête d'anniversaire",
"backgrounds012020": "Ensemble 68 : sorti en janvier 2020"
}

View File

@@ -2017,5 +2017,13 @@
"backMystery202001Text": "Les cinq queues de la légende",
"headMystery202001Notes": "Votre ouïe sera si fine que vous entendrez les étoiles scintiller et la lune tourner. Ne confère aucun bonus. Équipement d'abonnement de janvier 2020.",
"headMystery202001Text": "Oreilles de renard légendaire",
"headSpecialNye2019Text": "Chapeau de fête outrageux"
"headSpecialNye2019Text": "Chapeau de fête outrageux",
"shieldArmoireBirthdayBannerNotes": "Célébrez votre jour spécial, le jour spécial de quelqu'un que vous aimez, ou sortez la pour l'anniversaire d'Habitica le 31 Janvier ! Augmente la force de <%= str %>. Armoire enchantée : ensemble de joyeux anniversaire (objet 4 de 4).",
"shieldArmoireBirthdayBannerText": "Bannière d'anniversaire",
"headArmoireFrostedHelmNotes": "Le parfait couvre-chef pour n'importe quelle fête ! Augmente l'intelligence de <%= int %>. Armoire enchantée : ensemble de joyeux anniversaire (objet 1 de 4).",
"headArmoireFrostedHelmText": "Casque glaçé",
"armorArmoireLayerCakeArmorNotes": "Ça protège et c'est délicieux ! Augmente la constitution de <%= con %>. Armoire enchantée : ensemble de joyeux anniversaire (objet 2 de 4).",
"armorArmoireLayerCakeArmorText": "Armure de gâteau en couches",
"weaponArmoireHappyBannerNotes": "Est ce que le \"H\" est pour Heureuse, ou Habitica ? A vous de choisir ! Augmente la perception de <%= per %>. Armoire enchantée : ensemble de joyeux anniversaire (objet 3 de 4).",
"weaponArmoireHappyBannerText": "Heureuse bannière"
}

View File

@@ -40,5 +40,28 @@
"letsGetStarted": "はじめましょう!",
"onboardingProgress": "<%= percentage %>% 進捗",
"gettingStartedDesc": "タスクを作成して、完了して、ごほうびをチェックしましょう。 一度やると<strong>5つの実績</strong>と<strong class=\"gold-amount\">100ゴールド</strong>を獲得できます!",
"earnedAchievement": "実績を獲得しました!"
"earnedAchievement": "実績を獲得しました!",
"achievementPrimedForPainting": "下塗り完了",
"achievementPearlyPro": "真珠色の玄人",
"achievementPearlyProModalText": "白い乗騎をすべて手なずけました!",
"achievementPearlyProText": "白い乗騎をすべて手なずけました。",
"achievementPrimedForPaintingModalText": "白いペットをすべて集めました!",
"achievementPrimedForPaintingText": "白いペットをすべて集めました。",
"achievementPurchasedEquipmentModalText": "装備はアバターをカスタマイズして、能力値を上げる手段です",
"achievementPurchasedEquipmentText": "最初の装備の1つを買いました。",
"achievementPurchasedEquipment": "装備を買う",
"achievementFedPetModalText": "たくさんの異なるえさがあり、ペットには好き嫌いがあります",
"achievementFedPetText": "最初のペットにえさをやりました。",
"achievementFedPet": "ペットにえさをやる",
"achievementHatchedPetModalText": "所持品のページへ行って、たまごがえしの薬とたまごを組み合わせることに挑戦しました",
"achievementHatchedPetText": "最初のペットをかえしました。",
"achievementHatchedPet": "ペットをかえす",
"achievementCompletedTaskModalText": "ごほうびをもらうためにいずれかのタスクをチェックしました",
"achievementCompletedTaskText": "最初のタスクを完了しました。",
"achievementCompletedTask": "タスクを完了する",
"achievementCreatedTaskModalText": "今週に達成したいことをタスクとして追加しました",
"achievementCreatedTaskText": "最初のタスクを作成しました。",
"achievementCreatedTask": "タスクを作成する",
"hideAchievements": "<%= category %>をたたむ",
"showAllAchievements": "すべての<%= category %>を表示する"
}

View File

@@ -352,5 +352,6 @@
"questEggRobotAdjective": "未来的な",
"questEggRobotMountText": "ロボット",
"questEggRobotText": "ロボット",
"hatchingPotionAmber": "琥珀の"
"hatchingPotionAmber": "琥珀の",
"hatchingPotionAurora": "オーロラの"
}

View File

@@ -331,5 +331,6 @@
"getStarted": "はじめましょう!",
"mobileApps": "モバイルアプリ",
"learnMore": "もっと詳しく知る",
"communityInstagram": "Instagram"
"communityInstagram": "Instagram",
"minPasswordLength": "パスワードは8文字以上にする必要があります。"
}

View File

@@ -1,7 +1,7 @@
{
"achievement": "업적",
"share": "공유하기",
"onwards": "앞으로!",
"onwards": "야호!",
"levelup": "당신의 실제 삶의 목표들을 달성함으로써 레벨 업 했고 이제 완전히 회복되었어요!",
"reachedLevel": "레벨<%= level %>에 도달했습니다.",
"achievementLostMasterclasser": "퀘스트 완료자: 마스터클래서 시리즈",
@@ -26,5 +26,11 @@
"achievementUndeadUndertaker": "좀비 장의사",
"achievementKickstarter2019": "Pin Kickstarter 후원자",
"achievementAridAuthority": "권세",
"achievementMindOverMatter": "의지의 문제"
"achievementMindOverMatter": "의지의 문제",
"gettingStartedDesc": "할 일을 등록하고, 실행한 후, 보상을 가져가세요",
"achievementMindOverMatterModalText": "돌멩이, 슬라임, 털실 펫 퀘스트를 완료했습니다!",
"hideAchievements": "<%= category %> 숨기기",
"earnedAchievement": "업적을 획득했습니다!",
"viewAchievements": "업적 보기",
"letsGetStarted": "시작합시다!"
}

View File

@@ -1,10 +1,10 @@
{
"iAcceptCommunityGuidelines": "커뮤니티 가이드라인에 따를 것을 동의합니다",
"tavernCommunityGuidelinesPlaceholder": "잠시 알려드립니다: 이곳은 전연령 채팅창이니, 사용하시는 언어와 내용을 주의해주세요! 궁금하신 점이 있다면 사이드바의 커뮤니티 가이드라인을 참고해주세요.",
"lastUpdated": "Last updated:",
"lastUpdated": "최종 업데이트:",
"commGuideHeadingWelcome": "Habitica에 오신것을 환영합니다!",
"commGuidePara001": "Greetings, adventurer! Welcome to Habitica, the land of productivity, healthy living, and the occasional rampaging gryphon. We have a cheerful community full of helpful people supporting each other on their way to self-improvement. To fit in, all it takes is a positive attitude, a respectful manner, and the understanding that everyone has different skills and limitations -- including you! Habiticans are patient with one another and try to help whenever they can.",
"commGuidePara002": "To help keep everyone safe, happy, and productive in the community, we do have some guidelines. We have carefully crafted them to make them as friendly and easy-to-read as possible. Please take the time to read them before you start chatting.",
"commGuidePara001": "반갑습니다, 모험자님! 생산성, 건강한 생활, 그리고 가끔은 미친 그리핀이 있는 땅, Habitica에 오신 것을 환영합니다. 이 곳엔 스스로의 발전을 위해 각자의 방법으로 도움을 주고자 하는 지원자로 가득한 활발한 커뮤니티가 있습니다. 이 곳에서 함께하기 위해, 모든 사람들은 긍정적인 태도와 서로를 존중하는 예의를 지니며, 모두가 다른 능력과 규칙을 갖고 있다는 사실을 알고 있어야 합니다- 물론 당신도요! Habitican은 항상 상대방에게 인내하고 할 수 있는 일이라면 언제든지 도우려 노력합니다.",
"commGuidePara002": "모두가 안전하고 행복하게 하며, 커뮤니티 활동이 활발히 이뤄지도록, 저희는 몇 가지 가이드라인을 가지고 있습니다. 친숙하고 가능한 읽기 쉽게 하는 데 주의를 기울여 만들었으니, 시간이 걸리더라도 채팅을 시작하기 전에 꼭 읽어주세요.",
"commGuidePara003": "이곳의 규칙은 Trello, GitHub, Transifex와 Wikia(위키)를 포함한 (그러나 여기에만 한정되지 않은) 모든 커뮤니티 소통 공간에 적용됩니다. 때때로 가이드라인에 언급이 되지 않은 종류의 충돌이 벌어지거나 사악한 네크로맨서가 나타나는 등 예측하지 못한 상황이 벌어지기도 합니다. 그럴 때면 커뮤니티를 새로운 위협에서 안전하게 보호하기 위해 관리자들이 가이드라인을 변경해야 할 수도 있습니다. 하지만 안심하세요: 가이드라인이 변경된다면 베일리가 여러분에게 소식을 알려드릴 것입니다.",
"commGuidePara004": "그럼 필기할 깃펜과 두루마리를 준비하시고 바로 시작해봅시다!",
"commGuideHeadingInteractions": "Interactions in Habitica",

View File

@@ -3,7 +3,7 @@
"potionNotes": "체력 15 회복 (일회용)",
"armoireText": "마법의 장롱",
"armoireNotesFull": "랜덤으로 특별한 장비, 경험치 혹은 펫 먹이를 받으려면 장롱문을 열어주세요! 아직 못찾은 특별장비:",
"armoireLastItem": "마법의 장롱에서 마지막 남은 희귀 장비를 찾으셨습니다!",
"armoireLastItem": "마법의 장롱에서 마지막 남은 레어 장비를 찾습니다!",
"armoireNotesEmpty": "매달 첫주마다 새로운 장비가 구비될 것입니다. 그 때까지는 경험치와 먹이를 받으러 클릭하세요!",
"dropEggWolfText": "늑대",
"dropEggWolfMountText": "늑대",
@@ -306,5 +306,7 @@
"foodSaddleText": "안장",
"foodSaddleNotes": "즉시 펫 한마리를 탑승펫으로 성장시킵니다.",
"foodSaddleSellWarningNote": "Hey! This is a pretty useful item! Are you familiar with how to use a Saddle with your Pets?",
"foodNotes": "이것을 펫에게 먹이면 튼튼한 탑승펫으로 성장시킬 수 있습니다."
"foodNotes": "이것을 펫에게 먹이면 튼튼한 탑승펫으로 성장시킬 수 있습니다.",
"questEggRobotText": "로봇",
"questEggDolphinText": "돌고래"
}

View File

@@ -1,5 +1,33 @@
{
"termsAndAgreement": "아래에 있는 버튼을 클릭함으로써, 당신은 당신이 서비스 약관<a href='/static/terms'> 과 <a href='/static/privacy'> 개인정보 정책 </a>을 읽었고 이에 동의했음을 나타냅니다.",
"termsAndAgreement": "<a href='/static/privacy'>아래에 있는 버튼을 클릭함으로써, 당신은 당신이 서비스 약관<a href='/static/terms'> 과 <a href='/static/privacy'> 개인정보 정책 </a>을 읽었고 이에 동의했음을 나타냅니다.",
"FAQ": "FAQ",
"althaireQuote": "정기적으로 퀘스트를 하는건 내가 나의 모든 일일과제를 하도록 동기를 부여해주고 해야 할 일에도 동기를 부여해줘요. 저의 가장 큰 동기부여는 제 파티를 내려놓지 않는 것입니다."
"althaireQuote": "정기적으로 퀘스트를 하는건 내가 모든 일일과제 해야 할 일을 하도록 동기를 부여해줘요. 저의 가장 큰 동기부여는 제 파티의 기대를 저버리지 않도록 하는 것입니다.",
"sendLink": "링크 보내기",
"forgotPasswordSteps": "Habitica 계정으로 등록할 메일 주소를 입력하세요.",
"emailNewPass": "메일로 비밀번호 재설정 링크 보내기",
"forgotPassword": "비밀번호를 잊으셨습니까?",
"elmiQuote": "매일 아침 저는 일어나면서 골드를 벌 수 있기를 기대해요!",
"dreimQuote": "지난 여름 제가 [Habitica]를 발견했을 즈음이, 전체 시험 과목의 반 정도를 불합격했던 때였어요. 일일 과제 덕분에… 저는 스스로 준비하고 단련할 수 있었고, 실제로 몇 달 전 좋은 성적으로 모든 시험을 통과했어요.",
"dragonsilverQuote": "얼마나 긴 시간이라 말하긴 어렵지만 저는 수십 년 동안 과제를 정리하는 여러 방법을 시도해 왔어요… [Habitica]는 실제로 제가 과제를 단순히 리스트로 만들었을 때보다 정확히 완료하도록 도운 유일한 방법입니다.",
"companyVideos": "동영상",
"companyPrivacy": "사생활",
"companyDonate": "기부하기",
"companyContribute": "기여하기",
"companyBlog": "블로그",
"companyAbout": "작동하는 원리",
"choreSample1": " 빨래바구니에 빨랫감 넣기",
"communityInstagram": "인스타그램",
"communityFacebook": "페이스북",
"chores": "집안일",
"choreSample5": "빨랫감 세탁하고 널기",
"choreSample4": "방 정리정돈하기",
"businessText": "업무 관리에 Habitica를 활용하세요",
"businessSample5": "고객과 전화하기/끊기",
"businessSample3": "편지함 정렬 및 처리하기",
"businessSample1": "인벤토리 1쪽 보기",
"alexandraQuote": "제가 마드리드에서 연설하는 동안 절대 [Habitica]에 대해 말하면 안 돼요. 아직 보스가 필요한 프리랜서들을 위해 도구를 지니세요.",
"footerCompany": "회사",
"featurePetHeading": "펫과 탑승펫",
"featurePetByline": "알과 아이템은 과제를 완료했을 때 얻을 수 있습니다. 생산적인 일을 많이 할수록 펫과 탑승펫을 많이 모을 수 있습니다!",
"featureEquipHeading": "장비와 여분"
}

View File

@@ -40,5 +40,18 @@
"achievementPartyUp": "Te ad socium contubernii adiunxisti!",
"achievementDustDevilModalText": "Omnia animalia coloris deserti collegisti!",
"achievementDustDevilText": "Omnia animalia coloris deserti collegit.",
"achievementLostMasterclasserModalText": "Sedecim investigationes ad Investigationum Masterclasser Thesaurum pertinentes perfecisti et arcanum Magistrae Ordinum Oblitae solvisti!"
"achievementLostMasterclasserModalText": "Sedecim investigationes ad Investigationum Masterclasser Thesaurum pertinentes perfecisti et arcanum Magistrae Ordinum Oblitae solvisti!",
"gettingStartedDesc": "Munus crea, quod perficias; tum praemia observa. Merebis <strong>5 res perfectas</strong> et <strong class=\"gold amount\">100 nummi auri</strong> cum primum finivisti.",
"showAllAchievements": "Praebe omnia <%=category %>",
"onboardingCompleteDesc": "Album perficiens <strong>5 res perfectas</strong> et <strong class=\"gold-amount\">100</strong> nummos auri meruisti.",
"earnedAchievement": "Rem perfectam meruisti!",
"viewAchievements": "Res perfectas inspice",
"letsGetStarted": "Proficiamus!",
"onboardingProgress": "<%=percentage %>% progressionis",
"achievementCompletedTaskText": "Primum munus perfecit.",
"achievementCompletedTask": "Munus perfice",
"achievementCreatedTaskModalText": "Munus unius rei adde, quam hac hebdomade perficere vis.",
"achievementCreatedTaskText": "Munus primum creavit.",
"achievementCreatedTask": "Munus crea",
"hideAchievements": "Cela genus <%= category %>"
}

View File

@@ -23,8 +23,8 @@
"glossary": "<a target='_blank' href='http://habitica.fandom.com/wiki/Glossary'>Glossário</a>",
"wiki": "Wiki",
"wikiLink": "<a target='_blank' href='http://habitica.fandom.com/'>Wiki</a>",
"reportAP": "Reportar um Problema",
"requestAF": "Solicitar uma Funcionalidade",
"reportAP": "Reportar um problema",
"requestAF": "Solicitar uma funcionalidade",
"community": "<a target='_blank' href='http://habitica.fandom.com/wiki/Special:Forum'>Fórum da Comunidade</a>",
"dataTool": "Ferramenta de Exibição de Dados",
"resources": "Recursos",

View File

@@ -485,5 +485,12 @@
"backgroundWinterNocturneNotes": "Aproveite as luzes das estrelas de uma Noite de Inverno.",
"backgroundWinterNocturneText": "Noite de Inverno",
"backgroundHolidayWreathNotes": "Enfeite seu avatar com uma perfumada Guirlanda Festiva.",
"backgroundHolidayWreathText": "Guirlanda Festiva"
"backgroundHolidayWreathText": "Guirlanda Festiva",
"backgroundSnowglobeNotes": "Agite um globo de neve e tome o seu lugar em um microcosmo de uma paisagem de inverno.",
"backgroundSnowglobeText": "Globo de neve",
"backgroundDesertWithSnowNotes": "Testemunhe a beleza rara e tranquila de um deserto nevado.",
"backgroundDesertWithSnowText": "Deserto Nevado",
"backgroundBirthdayPartyNotes": "Comemore a festa de aniversário do(a) seu/sua habiticano(a) favorito(a).",
"backgroundBirthdayPartyText": "Festa de Aniversário",
"backgrounds012020": "Conjunto 68: Lançado em Janeiro de 2020"
}

View File

@@ -45,9 +45,9 @@
"androidFaqAnswer10": "Gemas são compradas com dinheiro real ao clicar no ícone de Gema no cabeçalho. Ao comprar gemas, as pessoas ajudam a manter o site funcionando. Ficamos muito felizes com seu apoio!\n\nAlém de comprar Gemas diretamente, existem outras três maneiras em que jogadores podem adquirir Gemas:\n\n* Ganhe um Desafio que tenha sido feito por outro jogador. Vá em Social > Desafios para entrar em alguns.\n* Assine e desboquei a habilidade de comprar uma certa quantidade de Gemas por mês.\n* Contribua pro Habitica com suas habilidades. Veja a página da Wiki [Contribuindo para o Habitica](https://habitica.fandom.com/pt-br/wiki/Contributing_to_Habitica).\n\nLembre-se que itens que são comprados com Gemas não oferecem nenhuma vantagem estatística, de forma que os jogadores ainda poderão usar o app sem elas!",
"webFaqAnswer10": "Gemas são [compradas com dinheiro real](https://habitica.com/#/options/settings/subscription), apesar de que [assinantes](https://habitica.com/#/options/settings/subscription) podem comprá-las usando Ouro. Quando alguém assina o site ou compra Gemas, esta pessoa está nos ajudando a manter o site funcionando. Ficamos muito agradecidos com esse suporte!Além de comprar Gemas diretamente ou se tornar assinante, existem outras duas maneiras de se conseguir Gemas:\n* Vença um Desafio feito por outro jogador em Desafios > Descubra.\n* Contribua com seus talentos para o projeto do Habitica. Veja essa página da wiki para mais detalhes: [Contribuindo com o Habitica](https://habitica.fandom.com/pt-br/wiki/Contributing_to_Habitica). Tenha em mente que itens comprados com Gemas não oferecem nenhuma vantagem de atributos então todos podem utilizar o site sem elas!",
"faqQuestion11": "Como eu relato um bug ou solicito uma funcionalidade?",
"iosFaqAnswer11": "Você pode relatar um bug, solicitar uma funcionalidade ou enviar sua opinião através do Menu > Sobre > Reportar um Problema e Menu > Sobre > Enviar Opinião! Vamos fazer tudo que pudermos para te ajudar.",
"androidFaqAnswer11": "Você pode reportar um bug, pedir uma funcionalidade ou enviar sua opinião pelo menu Ajuda > Reportar um Problema e Ajuda > Enviar Opinião. Faremos todo o possível para ajudá-lo(a).",
"webFaqAnswer11": "Para reportar um bug, vá para [Ajuda > Reportar um Problema](https://habitica.com/groups/guild/a29da26b-37de-4a71-b0c6-48e72a900dac) e leia os pontos acima da caixa de chat. Se você não conseguir logar no Habitica, envie suas informações de login (não a sua senha!) para [<%= techAssistanceEmail %>](<%= wikiTechAssistanceEmail %>). Não se preocupe, nós corrigiremos isso para você rapidamente! <br><br> Pedidos de funcionalidades são pegos nos fóruns do Trello. Vá para [Ajuda > Solicitar funcionalidade](https://trello.com/c/odmhIqyW/440-read-first-table-of-contents) e siga as instruções. Tcharammmm!",
"iosFaqAnswer11": "Você pode relatar um bug, solicitar uma funcionalidade ou enviar sua opinião através do Menu > Sobre > Reportar um problema e Menu > Sobre > Enviar Opinião! Vamos fazer tudo que pudermos para te ajudar.",
"androidFaqAnswer11": "Você pode reportar um bug, pedir uma funcionalidade ou enviar sua opinião pelo menu Ajuda > Reportar um problema e Ajuda > Enviar Opinião. Faremos todo o possível para ajudá-lo(a).",
"webFaqAnswer11": "Para reportar um bug, vá para [Ajuda > Reportar um problema](https://habitica.com/groups/guild/a29da26b-37de-4a71-b0c6-48e72a900dac) e leia os pontos acima da caixa de bate-papo. Se você não conseguir logar no Habitica, envie suas informações de login (não a sua senha!) para [<%= techAssistanceEmail %>](<%= wikiTechAssistanceEmail %>). Não se preocupe, nós corrigiremos isso para você rapidamente! <br><br> Pedidos de funcionalidades são pegos nos fóruns do Trello. Vá para [Ajuda > Solicitar funcionalidade](https://trello.com/c/odmhIqyW/440-read-first-table-of-contents) e siga as instruções. Tcharammmm!",
"faqQuestion12": "Como luto contra um Chefão Global?",
"iosFaqAnswer12": "Chefões Globais são monstros especiais que aparecem na Taverna. Todos os usuários ativos o enfrentam automaticamente e suas tarefas e habilidades causarão dano no Chefão como de costume.\n\nVocê pode estar em uma Missão normal ao mesmo tempo. Suas tarefas e Habilidades contarão para ambos Chefão Global e missões de Chefão/Coleta do seu grupo.\n\nUm Chefão Global nunca irá machucar você ou sua conta de qualquer maneira. Ao invés disso, ele tem uma Barra de Fúria que encherá quando usuários não fizerem as Diárias. Se a Barra de Fúria encher, ele atacará um dos NPC do site e a imagem dele mudará.\n\nVocê pode ler mais sobre [Chefões Globais anteriores](https://habitica.fandom.com/pt-br/wiki/World_Bosses) na wiki.",
"androidFaqAnswer12": "Chefões Globais são monstros especiais que aparecem na Taverna. Todos os usuários ativos o enfrentam automaticamente e suas tarefas e habilidades causarão dano no Chefão como de costume.\n\nVocê pode estar em uma Missão normal ao mesmo tempo. Suas tarefas e Habilidades contarão para ambos Chefão Global e missões de Chefão/Coleta do seu grupo.\n\nUm Chefão Global nunca irá machucar você ou sua conta de qualquer maneira. Ao invés disso, ele tem uma Barra de Fúria que encherá quando usuários não fizerem as Diárias. Se a Barra de Fúria encher, ele atacará um dos NPC do site e a imagem dele mudará.\n\nVocê pode ler mais sobre [Chefões Globais anteriores](https://habitica.fandom.com/pt-br/wiki/World_Bosses) na wiki.",

View File

@@ -27,7 +27,7 @@
"communityForum": "<a target='_blank' href='http://habitica.fandom.com/wiki/Special:Forum'>Fórum</a>",
"communityKickstarter": "Kickstarter",
"communityReddit": "Reddit",
"companyAbout": "Como Funciona",
"companyAbout": "Como funciona",
"companyBlog": "Blog",
"devBlog": "Blog do Desenvolvedor",
"companyContribute": "Contribua",

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