Compare commits

..

1 Commits

Author SHA1 Message Date
Kalista Payne c50ae7a900 fix(profile): include gear class bonus in stat readout 2026-02-16 20:06:38 -06:00
288 changed files with 1849 additions and 7378 deletions
+1
View File
@@ -75,6 +75,7 @@
"S3_ACCESS_KEY_ID": "accessKeyId",
"S3_BUCKET": "bucket",
"S3_SECRET_ACCESS_KEY": "secretAccessKey",
"SESSION_SECRET_IV": "12345678912345678912345678912345",
"SESSION_SECRET_KEY": "1234567891234567891234567891234567891234567891234567891234567891",
"SESSION_SECRET": "YOUR SECRET HERE",
"SITE_HTTP_AUTH_ENABLED": "false",
+81 -141
View File
@@ -1,12 +1,12 @@
{
"name": "habitica",
"version": "5.47.2",
"version": "5.44.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "habitica",
"version": "5.47.2",
"version": "5.44.3",
"hasInstallScript": true,
"dependencies": {
"@babel/core": "^7.22.10",
@@ -44,7 +44,7 @@
"gulp-filter": "^7.0.0",
"gulp-imagemin": "^7.1.0",
"gulp.spritesmith": "^6.13.0",
"habitica-markdown": "^4.1.0",
"habitica-markdown": "^3.0.0",
"heapdump": "^0.3.15",
"helmet": "^4.6.0",
"in-app-purchase": "^1.11.3",
@@ -105,9 +105,6 @@
"npm": "^10"
}
},
"../habitica-markdown/habitica-markdown": {
"extraneous": true
},
"node_modules/@aashutoshrathi/word-wrap": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
@@ -4170,12 +4167,6 @@
"node": ">=14.0.0"
}
},
"node_modules/apidoc/node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"license": "Python-2.0"
},
"node_modules/apidoc/node_modules/bootstrap": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.1.tgz",
@@ -4211,15 +4202,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/apidoc/node_modules/linkify-it": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
"integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
"license": "MIT",
"dependencies": {
"uc.micro": "^1.0.1"
}
},
"node_modules/apidoc/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -4231,22 +4213,6 @@
"node": ">=10"
}
},
"node_modules/apidoc/node_modules/markdown-it": {
"version": "12.3.2",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
"integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1",
"entities": "~2.1.0",
"linkify-it": "^3.0.1",
"mdurl": "^1.0.1",
"uc.micro": "^1.0.5"
},
"bin": {
"markdown-it": "bin/markdown-it.js"
}
},
"node_modules/apidoc/node_modules/nodemon": {
"version": "2.0.22",
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz",
@@ -12531,15 +12497,50 @@
}
},
"node_modules/habitica-markdown": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/habitica-markdown/-/habitica-markdown-4.1.0.tgz",
"integrity": "sha512-iqiFT8BbuWIrrs6v9eIXSG7UfWOBdJVGDi9FjGiFFOe8+dOPi62yyXhm81vrx79/5Y2s+jG+7LItyaemD310uQ==",
"license": "GPL-3.0",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/habitica-markdown/-/habitica-markdown-3.0.0.tgz",
"integrity": "sha512-rw1LJ5Vsjx8sfjNa4e2wFuZf5eqqyb5/kfZXPxqfMMgJCCgIhWStDqY3nIclnpGWpemlKd+qbdh2rLiLgm9kng==",
"dependencies": {
"markdown-it": "^14.0.0",
"markdown-it-emoji": "^2.0.2",
"markdown-it-link-attributes": "^4.0.1",
"markdown-it-linkify-images": "^3.0.0"
"habitica-markdown-emoji": "1.2.4",
"markdown-it": "10.0.0",
"markdown-it-link-attributes": "3.0.0",
"markdown-it-linkify-images": "^1.1.1"
}
},
"node_modules/habitica-markdown-emoji": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/habitica-markdown-emoji/-/habitica-markdown-emoji-1.2.4.tgz",
"integrity": "sha512-UV0AxpDToldFQULuhTxC1y4sdNTApaIOh7ZuV/92HCPmCGkv3DAlHtYE67OmCqLVfs26HWAGVJaU3+OEnW3gjg==",
"dependencies": {
"markdown-it-emoji": "^1.1.1"
}
},
"node_modules/habitica-markdown/node_modules/entities": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz",
"integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ=="
},
"node_modules/habitica-markdown/node_modules/linkify-it": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
"integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
"dependencies": {
"uc.micro": "^1.0.1"
}
},
"node_modules/habitica-markdown/node_modules/markdown-it": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz",
"integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==",
"dependencies": {
"argparse": "^1.0.7",
"entities": "~2.0.0",
"linkify-it": "^2.0.0",
"mdurl": "^1.0.1",
"uc.micro": "^1.0.5"
},
"bin": {
"markdown-it": "bin/markdown-it.js"
}
},
"node_modules/handlebars": {
@@ -14551,20 +14552,13 @@
"integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA=="
},
"node_modules/linkify-it": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
"integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
"license": "MIT",
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
"integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
"dependencies": {
"uc.micro": "^2.0.0"
"uc.micro": "^1.0.1"
}
},
"node_modules/linkify-it/node_modules/uc.micro": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
"license": "MIT"
},
"node_modules/load-json-file": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
@@ -14912,79 +14906,59 @@
}
},
"node_modules/markdown-it": {
"version": "14.1.0",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
"integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
"license": "MIT",
"version": "12.3.2",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
"integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
"dependencies": {
"argparse": "^2.0.1",
"entities": "^4.4.0",
"linkify-it": "^5.0.0",
"mdurl": "^2.0.0",
"punycode.js": "^2.3.1",
"uc.micro": "^2.1.0"
"entities": "~2.1.0",
"linkify-it": "^3.0.1",
"mdurl": "^1.0.1",
"uc.micro": "^1.0.5"
},
"bin": {
"markdown-it": "bin/markdown-it.mjs"
"markdown-it": "bin/markdown-it.js"
}
},
"node_modules/markdown-it-emoji": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-2.0.2.tgz",
"integrity": "sha512-zLftSaNrKuYl0kR5zm4gxXjHaOI3FAOEaloKmRA5hijmJZvSjmxcokOLlzycb/HXlUFWzXqpIEoyEMCE4i9MvQ==",
"license": "MIT"
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz",
"integrity": "sha512-QCz3Hkd+r5gDYtS2xsFXmBYrgw6KuWcJZLCEkdfAuwzZbShCmCfta+hwAMq4NX/4xPzkSHduMKgMkkPUJxSXNg=="
},
"node_modules/markdown-it-link-attributes": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/markdown-it-link-attributes/-/markdown-it-link-attributes-4.0.1.tgz",
"integrity": "sha512-pg5OK0jPLg62H4k7M9mRJLT61gUp9nvG0XveKYHMOOluASo9OEF13WlXrpAp2aj35LbedAy3QOCgQCw0tkLKAQ==",
"license": "MIT"
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/markdown-it-link-attributes/-/markdown-it-link-attributes-3.0.0.tgz",
"integrity": "sha512-B34ySxVeo6MuEGSPCWyIYryuXINOvngNZL87Mp7YYfKIf6DcD837+lXA8mo6EBbauKsnGz22ZH0zsbOiQRWTNg=="
},
"node_modules/markdown-it-linkify-images": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/markdown-it-linkify-images/-/markdown-it-linkify-images-3.0.0.tgz",
"integrity": "sha512-Vs5yGJa5MWjFgytzgtn8c1U6RcStj3FZKhhx459U8dYbEE5FTWZ6mMRkYMiDlkFO0j4VCsQT1LT557bY0ETgtg==",
"license": "MIT",
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/markdown-it-linkify-images/-/markdown-it-linkify-images-1.1.1.tgz",
"integrity": "sha512-1IEmAaAjIgAwY+tZI0sxDXdy9QKHutj5cN0lH2JBiSZt+2NYKrWRJj0cloQW3OFIfP2MLFA1E+6OLJhXPiLgNw==",
"dependencies": {
"markdown-it": "^13.0.1"
"markdown-it": "^8.4.2"
}
},
"node_modules/markdown-it-linkify-images/node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"license": "Python-2.0"
},
"node_modules/markdown-it-linkify-images/node_modules/entities": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
"integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
},
"node_modules/markdown-it-linkify-images/node_modules/linkify-it": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz",
"integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==",
"license": "MIT",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
"integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
"dependencies": {
"uc.micro": "^1.0.1"
}
},
"node_modules/markdown-it-linkify-images/node_modules/markdown-it": {
"version": "13.0.2",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.2.tgz",
"integrity": "sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==",
"license": "MIT",
"version": "8.4.2",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz",
"integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==",
"dependencies": {
"argparse": "^2.0.1",
"entities": "~3.0.1",
"linkify-it": "^4.0.1",
"argparse": "^1.0.7",
"entities": "~1.1.1",
"linkify-it": "^2.0.0",
"mdurl": "^1.0.1",
"uc.micro": "^1.0.5"
},
@@ -14995,32 +14969,7 @@
"node_modules/markdown-it/node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"license": "Python-2.0"
},
"node_modules/markdown-it/node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/markdown-it/node_modules/mdurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
"license": "MIT"
},
"node_modules/markdown-it/node_modules/uc.micro": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
"license": "MIT"
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"node_modules/matchdep": {
"version": "2.0.0",
@@ -18100,15 +18049,6 @@
"node": ">=6"
}
},
"node_modules/punycode.js": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
"integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/q": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "habitica",
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
"version": "5.47.2",
"version": "5.44.3",
"main": "./website/server/index.js",
"dependencies": {
"@babel/core": "^7.22.10",
@@ -39,7 +39,7 @@
"gulp-filter": "^7.0.0",
"gulp-imagemin": "^7.1.0",
"gulp.spritesmith": "^6.13.0",
"habitica-markdown": "^4.1.0",
"habitica-markdown": "^3.0.0",
"heapdump": "^0.3.15",
"helmet": "^4.6.0",
"in-app-purchase": "^1.11.3",
@@ -66,15 +66,13 @@ describe('Amazon Payments - Cancel Subscription', () => {
group = generateGroup({
name: 'test group',
type: 'guild',
privacy: 'private',
privacy: 'public',
leader: user._id,
});
group.purchased.plan.customerId = 'customer-id';
group.purchased.plan.planId = subKey;
group.purchased.plan.lastBillingDate = new Date();
await group.save();
user.guilds.push(group._id);
await user.save();
subscriptionBlock = common.content.subscriptionBlocks[subKey];
subscriptionLength = subscriptionBlock.months * 30;
@@ -30,14 +30,12 @@ describe('Amazon Payments - Subscribe', () => {
group = generateGroup({
name: 'test group',
type: 'guild',
privacy: 'private',
privacy: 'public',
leader: user._id,
});
group.purchased.plan.customerId = 'customer-id';
group.purchased.plan.planId = subKey;
await group.save();
user.guilds.push(group._id);
await user.save();
amount = common.content.subscriptionBlocks[subKey].price;
billingAgreementId = 'billingAgreementId';
@@ -248,6 +246,11 @@ describe('Amazon Payments - Subscribe', () => {
user.guilds.push(groupId);
await user.save();
// Add existing users
user = new User();
user.guilds.push(groupId);
await user.save();
// Set expected amount
sub.key = 'group_monthly';
sub.price = 9;
@@ -128,12 +128,11 @@ describe('Purchasing a group plan for group', () => {
expect(publicGroup.purchased.plan.planId).to.not.exist;
data.groupId = publicGroup._id;
// Public Guilds are no longer even findable
await expect(api.createSubscription(data))
.to.eventually.be.rejected.and.to.eql({
httpCode: 404,
name: 'NotFound',
message: i18n.t('groupNotFound'),
httpCode: 401,
name: 'NotAuthorized',
message: i18n.t('onlyPrivateGuildsCanUpgrade'),
});
const updatedGroup = await Group.findById(publicGroup._id).exec();
@@ -30,15 +30,13 @@ describe('paypal - subscribeCancel', () => {
group = generateGroup({
name: 'test group',
type: 'guild',
privacy: 'private',
privacy: 'public',
leader: user._id,
});
group.purchased.plan.customerId = groupCustomerId;
group.purchased.plan.planId = subKey;
group.purchased.plan.lastBillingDate = new Date();
await group.save();
user.guilds.push(group._id);
await user.save();
nextBillingDate = new Date();
@@ -236,7 +236,7 @@ describe('Stripe - Checkout', () => {
const group = generateGroup({
name: 'test group',
type: 'guild',
privacy: 'private',
privacy: 'public',
leader: user._id,
});
const groupId = group._id;
@@ -376,13 +376,11 @@ describe('Stripe - Checkout', () => {
group = generateGroup({
name: 'test group',
type: 'guild',
privacy: 'private',
privacy: 'public',
leader: user._id,
});
groupId = group._id;
await group.save();
user.guilds.push(group._id);
await user.save();
});
it('throws if user is not allowed to change group plan', async () => {
@@ -136,7 +136,7 @@ describe('Stripe - Subscriptions', () => {
group = generateGroup({
name: 'test group',
type: 'guild',
privacy: 'private',
privacy: 'public',
leader: user._id,
});
groupId = group._id;
@@ -315,14 +315,12 @@ describe('Stripe - Subscriptions', () => {
group = generateGroup({
name: 'test group',
type: 'guild',
privacy: 'private',
privacy: 'public',
leader: user._id,
});
group.purchased.plan.customerId = 'customer-id';
group.purchased.plan.planId = subKey;
await group.save();
user.guilds.push(group._id);
await user.save();
groupId = group._id;
});
@@ -50,59 +50,5 @@ describe('UserNotification Model', () => {
expect(safeNotifications[0].type).to.equal('NEW_CHAT_MESSAGE');
expect(safeNotifications[0].id).to.equal('123');
});
it('removes duplicate STREAK_ACHIEVEMENT notifications', () => {
// Fixes issue #13325 - Users receiving duplicate streak achievement notifications
const notifications = [
new UserNotification({
type: 'STREAK_ACHIEVEMENT',
id: 123,
data: {},
}),
new UserNotification({
type: 'STREAK_ACHIEVEMENT',
id: 456,
data: {},
}),
new UserNotification({
type: 'CRON',
id: 789,
data: {},
}), // different type, should be kept
];
const safeNotifications = UserNotification.cleanupCorruptData(notifications);
expect(safeNotifications.length).to.equal(2);
expect(safeNotifications[0].type).to.equal('STREAK_ACHIEVEMENT');
expect(safeNotifications[0].id).to.equal('123');
expect(safeNotifications[1].type).to.equal('CRON');
expect(safeNotifications[1].id).to.equal('789');
});
it('handles multiple STREAK_ACHIEVEMENT duplicates correctly', () => {
// Test case: 3 duplicate STREAK_ACHIEVEMENT notifications
const notifications = [
new UserNotification({
type: 'STREAK_ACHIEVEMENT',
id: 111,
data: {},
}),
new UserNotification({
type: 'STREAK_ACHIEVEMENT',
id: 222,
data: {},
}),
new UserNotification({
type: 'STREAK_ACHIEVEMENT',
id: 333,
data: {},
}),
];
const safeNotifications = UserNotification.cleanupCorruptData(notifications);
expect(safeNotifications.length).to.equal(1);
expect(safeNotifications[0].type).to.equal('STREAK_ACHIEVEMENT');
expect(safeNotifications[0].id).to.equal('111'); // Keep first one
});
});
});
@@ -5,8 +5,6 @@ import {
createAndPopulateGroup,
translate as t,
} from '../../../../helpers/api-integration/v3';
import { model as Group } from '../../../../../website/server/models/group';
import { TAVERN_ID } from '../../../../../website/common/script/constants';
describe('POST /challenges/:challengeId/join', () => {
it('returns error when challengeId is not a valid UUID', async () => {
@@ -29,37 +27,6 @@ describe('POST /challenges/:challengeId/join', () => {
});
});
context('public Guild', () => {
let group;
let groupLeader;
let members;
let challenge;
before(async () => {
({ group, groupLeader, members } = await createAndPopulateGroup({
groupDetails: {
name: 'test group',
type: 'guild',
privacy: 'private',
},
members: 1,
upgradeToGroupPlan: true,
}));
challenge = await generateChallenge(groupLeader, group);
// Creation API is shut down, we need to simulate an extant public group
await Group.updateOne({ _id: group._id }, { $set: { privacy: 'public' }, $unset: { 'purchased.plan': 1 } }).exec();
});
it('returns error when challengeId is in an old public Guild', async () => {
const authorizedUser = members[0]; // eslint-disable-line prefer-destructuring
await expect(authorizedUser.post(`/challenges/${challenge._id}/join`)).to.eventually.be.rejected.and.eql({
code: 404,
error: 'NotFound',
message: t('challengeNotFound'),
});
});
});
context('Joining a valid challenge', () => {
let groupLeader;
let group;
@@ -99,15 +66,6 @@ describe('POST /challenges/:challengeId/join', () => {
expect(res.name).to.equal(challenge.name);
});
it('succeeds when it\'s a Tavern challenge, even if the user isn\'t a "member" of Tavern', async () => {
const tavern = await groupLeader.get(`/groups/${TAVERN_ID}`);
const tavernChallenge = await generateChallenge(groupLeader, tavern, { prize: 1 });
const generalUser = await generateUser();
const res = await generalUser.post(`/challenges/${tavernChallenge._id}/join`);
expect(res.name).to.equal(tavernChallenge.name);
});
it('returns challenge data', async () => {
const res = await authorizedUser.post(`/challenges/${challenge._id}/join`);
@@ -62,9 +62,9 @@ describe('GET /groups/:groupId/chat', () => {
it('returns error if user attempts to fetch a sunset Guild', async () => {
await expect(user.get(`/groups/${group._id}/chat`)).to.eventually.be.rejected.and.eql({
code: 404,
error: 'NotFound',
message: t('groupNotFound'),
code: 400,
error: 'BadRequest',
message: t('featureRetired'),
});
});
});
@@ -121,9 +121,9 @@ describe('POST /chat/:chatId/like', () => {
await expect(user.post(`/groups/${groupWithChat._id}/chat/${message.message.id}/like`))
.to.eventually.be.rejected.and.eql({
code: 404,
error: 'NotFound',
message: t('groupNotFound'),
code: 400,
error: 'BadRequest',
message: t('featureRetired'),
});
});
});
@@ -0,0 +1,35 @@
import { v4 as generateUUID } from 'uuid';
import {
generateUser,
translate as t,
} from '../../../../helpers/api-integration/v3';
xdescribe('GET /export/avatar-:memberId.html', () => {
let user;
before(async () => {
user = await generateUser();
});
it('validates req.params.memberId', async () => {
await expect(user.get('/export/avatar-:memberId.html')).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: t('invalidReqParams'),
});
});
it('handles non-existing members', async () => {
const dummyId = generateUUID();
await expect(user.get(`/export/avatar-${dummyId}.html`)).to.eventually.be.rejected.and.eql({
code: 404,
error: 'NotFound',
message: t('userWithIDNotFound', { userId: dummyId }),
});
});
it('returns an html page', async () => {
const res = await user.get(`/export/avatar-${user._id}.html`);
expect(res.substring(0, 100).indexOf('<!DOCTYPE html>')).to.equal(0);
});
});
@@ -0,0 +1,3 @@
// TODO how to test this route since it points to a file on AWS s3?
describe('GET /export/avatar-:memberId.png', () => {});
@@ -38,7 +38,7 @@ describe('GET /export/inbox.html', () => {
it('renders the markdown messages as html', async () => {
const res = await user.get('/export/inbox.html');
expect(res).to.include('😄');
expect(res).to.include('img class="habitica-emoji"');
expect(res).to.include('<h1>Hello!</h1>');
expect(res).to.include('<li>list 1</li>');
});
@@ -46,7 +46,7 @@ describe('GET /export/inbox.html', () => {
it('sorts messages from newest to oldest', async () => {
const res = await user.get('/export/inbox.html');
const emojiPosition = res.indexOf('😄');
const emojiPosition = res.indexOf('img class="habitica-emoji"');
const headingPosition = res.indexOf('<h1>Hello!</h1>');
const listPosition = res.indexOf('<li>list 1</li>');
-67
View File
@@ -1,67 +0,0 @@
import md from 'habitica-markdown';
describe('habiticaMarkdown emoji plugin', () => {
it('renders standard emoji as Unicode', () => {
const result = md.render(':smile:');
expect(result).to.include('😄');
expect(result).not.to.include('img');
});
it('renders thumbsup emoji as Unicode', () => {
const result = md.render(':thumbsup:');
expect(result).to.include('👍');
});
it('renders +1 emoji as Unicode', () => {
const result = md.render(':+1:');
expect(result).to.include('👍');
});
it('renders melior as an img tag', () => {
const result = md.render(':melior:');
expect(result).to.include('<img class="habitica-emoji"');
expect(result).to.include('src="https://s3.amazonaws.com/habitica-assets/cdn/emoji/melior.png"');
expect(result).to.include('alt="melior"');
});
it('does NOT convert emoji inside markdown links', () => {
const result = md.render('[:smile: link](http://example.com)');
expect(result).to.include(':smile: link');
expect(result).not.to.include('😄');
});
it('converts emoji outside of links normally', () => {
const result = md.render(':smile: [link](http://example.com)');
expect(result).to.include('😄');
expect(result).to.include('link');
});
it('leaves removed custom emoji (bowtie) as literal text', () => {
const result = md.render(':bowtie:');
expect(result).to.include(':bowtie:');
expect(result).not.to.include('img');
});
it('leaves unknown shortcodes as literal text', () => {
const result = md.render(':nonexistent_emoji_xyz:');
expect(result).to.include(':nonexistent_emoji_xyz:');
});
it('renders new emoji not in the old dataset', () => {
const result = md.render(':yawning_face:');
expect(result).to.include('🥱');
});
it('supports unsafeHTMLRender', () => {
const result = md.unsafeHTMLRender('<b>bold</b> :smile:');
expect(result).to.include('<b>bold</b>');
expect(result).to.include('😄');
});
it('supports renderWithMentions', () => {
const result = md.renderWithMentions(':smile: @testuser', { userName: 'testuser' });
expect(result).to.include('😄');
expect(result).to.include('at-text');
expect(result).to.include('at-highlight');
});
});
+8 -17
View File
@@ -211,32 +211,22 @@ describe('shared.ops.rebirth', () => {
expect(user.achievements.rebirthLevel).to.equal(2);
});
it('increments rebirth achievements even when level is lower than previous', async () => {
it('does not increment rebirth achievements when level is lower than previous', async () => {
user.stats.lvl = 2;
user.achievements.rebirths = 1;
user.achievements.rebirthLevel = 3;
await rebirth(user);
expect(user.achievements.rebirths).to.equal(2);
expect(user.achievements.rebirths).to.equal(1);
expect(user.achievements.rebirthLevel).to.equal(3);
});
it('updates rebirthLevel when current level is higher than previous', async () => {
user.stats.lvl = 5;
user.achievements.rebirths = 1;
user.achievements.rebirthLevel = 3;
await rebirth(user);
expect(user.achievements.rebirths).to.equal(2);
expect(user.achievements.rebirthLevel).to.equal(5);
});
it('increments rebirth achievements when level is MAX_LEVEL', async () => {
it('always increments rebirth achievements when level is MAX_LEVEL', async () => {
user.stats.lvl = MAX_LEVEL;
user.achievements.rebirths = 1;
user.achievements.rebirthLevel = MAX_LEVEL;
// this value is not actually possible (actually capped at MAX_LEVEL) but makes a good test
user.achievements.rebirthLevel = MAX_LEVEL + 1;
await rebirth(user);
@@ -244,10 +234,11 @@ describe('shared.ops.rebirth', () => {
expect(user.achievements.rebirthLevel).to.equal(MAX_LEVEL);
});
it('increments rebirth achievements when level is greater than MAX_LEVEL', async () => {
it('always increments rebirth achievements when level is greater than MAX_LEVEL', async () => {
user.stats.lvl = MAX_LEVEL + 1;
user.achievements.rebirths = 1;
user.achievements.rebirthLevel = MAX_LEVEL;
// this value is not actually possible (actually capped at MAX_LEVEL) but makes a good test
user.achievements.rebirthLevel = MAX_LEVEL + 2;
await rebirth(user);
-41
View File
@@ -1,41 +0,0 @@
import { getMatchingSwap, makeSubstitutionMap } from '../../website/common/script/content/constants/aprilFools';
describe('April Fools', () => {
describe('getMatchingSwap', () => {
it('returns Veggie for 2020', () => {
const swap = getMatchingSwap(new Date('2020-04-01'));
expect(swap).to.equal('Veggie');
});
it('returns Alien for 2026', () => {
const swap = getMatchingSwap(new Date('2026-04-01'));
expect(swap).to.equal('Alien');
});
it('Cycles through swaps correctly', () => {
const swap = getMatchingSwap(new Date('2027-04-01'));
expect(swap).to.equal('Veggie');
});
});
describe('makeSubstitutionMap', () => {
it('returns correct substitution for Veggie', () => {
const substitutions = makeSubstitutionMap('Veggie');
expect(substitutions.pets['Pet-Wolf-']).to.equal('Pet-Wolf-Veggie');
expect(substitutions.pets['Pet-TigerCub-']).to.equal('Pet-TigerCub-Veggie');
expect(substitutions.pets['Pet-Yarn-']).to.equal('Pet-BearCub-Veggie');
expect(substitutions.pets.default).to.equal('Pet-Dragon-Veggie');
expect(substitutions.pets.noPet).to.equal('Pet-Wolf-Veggie');
expect(substitutions.pets.noPetIOS).to.equal('Pet-TigerCub-Veggie');
expect(substitutions.pets.noPetAndroid).to.equal('Pet-Cactus-Veggie');
});
it('returns correct substitution for Cryptid', () => {
const substitutions = makeSubstitutionMap('Cryptid');
expect(substitutions.pets['Pet-Fox-']).to.equal('Pet-Fox-Cryptid');
expect(substitutions.pets['Pet-FlyingPig-']).to.equal('Pet-FlyingPig-Cryptid');
expect(substitutions.pets['Pet-Yarn-']).to.equal('Pet-BearCub-Cryptid');
expect(substitutions.pets.default).to.equal('Pet-Dragon-Cryptid');
expect(substitutions.pets.noPet).to.equal('Pet-Wolf-Cryptid');
expect(substitutions.pets.noPetAndroid).to.equal('Pet-Cactus-Cryptid');
});
});
});
+83 -43
View File
@@ -23,7 +23,7 @@
"eslint-config-habitrpg": "6.2.0",
"eslint-plugin-mocha": "5.3.0",
"eslint-plugin-vue": "7.20.0",
"habitica-markdown": "^4.0.0",
"habitica-markdown": "^3.0.0",
"hellojs": "^1.20.0",
"intro.js": "^7.2.0",
"jquery": "^3.7.1",
@@ -6929,17 +6929,69 @@
"license": "ISC"
},
"node_modules/habitica-markdown": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/habitica-markdown/-/habitica-markdown-4.1.0.tgz",
"integrity": "sha512-iqiFT8BbuWIrrs6v9eIXSG7UfWOBdJVGDi9FjGiFFOe8+dOPi62yyXhm81vrx79/5Y2s+jG+7LItyaemD310uQ==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/habitica-markdown/-/habitica-markdown-3.0.0.tgz",
"integrity": "sha512-rw1LJ5Vsjx8sfjNa4e2wFuZf5eqqyb5/kfZXPxqfMMgJCCgIhWStDqY3nIclnpGWpemlKd+qbdh2rLiLgm9kng==",
"license": "GPL-3.0",
"dependencies": {
"markdown-it": "^14.0.0",
"markdown-it-emoji": "^2.0.2",
"markdown-it-link-attributes": "^4.0.1",
"markdown-it-linkify-images": "^3.0.0"
"habitica-markdown-emoji": "1.2.4",
"markdown-it": "10.0.0",
"markdown-it-link-attributes": "3.0.0",
"markdown-it-linkify-images": "^1.1.1"
}
},
"node_modules/habitica-markdown-emoji": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/habitica-markdown-emoji/-/habitica-markdown-emoji-1.2.4.tgz",
"integrity": "sha512-UV0AxpDToldFQULuhTxC1y4sdNTApaIOh7ZuV/92HCPmCGkv3DAlHtYE67OmCqLVfs26HWAGVJaU3+OEnW3gjg==",
"license": "GPL-3.0",
"dependencies": {
"markdown-it-emoji": "^1.1.1"
}
},
"node_modules/habitica-markdown/node_modules/entities": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz",
"integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==",
"license": "BSD-2-Clause"
},
"node_modules/habitica-markdown/node_modules/linkify-it": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
"integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
"license": "MIT",
"dependencies": {
"uc.micro": "^1.0.1"
}
},
"node_modules/habitica-markdown/node_modules/markdown-it": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz",
"integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==",
"license": "MIT",
"dependencies": {
"argparse": "^1.0.7",
"entities": "~2.0.0",
"linkify-it": "^2.0.0",
"mdurl": "^1.0.1",
"uc.micro": "^1.0.5"
},
"bin": {
"markdown-it": "bin/markdown-it.js"
}
},
"node_modules/habitica-markdown/node_modules/mdurl": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
"integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==",
"license": "MIT"
},
"node_modules/habitica-markdown/node_modules/uc.micro": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
"license": "MIT"
},
"node_modules/has-bigints": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
@@ -8032,62 +8084,50 @@
}
},
"node_modules/markdown-it-emoji": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-2.0.2.tgz",
"integrity": "sha512-zLftSaNrKuYl0kR5zm4gxXjHaOI3FAOEaloKmRA5hijmJZvSjmxcokOLlzycb/HXlUFWzXqpIEoyEMCE4i9MvQ==",
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz",
"integrity": "sha512-QCz3Hkd+r5gDYtS2xsFXmBYrgw6KuWcJZLCEkdfAuwzZbShCmCfta+hwAMq4NX/4xPzkSHduMKgMkkPUJxSXNg==",
"license": "MIT"
},
"node_modules/markdown-it-link-attributes": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/markdown-it-link-attributes/-/markdown-it-link-attributes-4.0.1.tgz",
"integrity": "sha512-pg5OK0jPLg62H4k7M9mRJLT61gUp9nvG0XveKYHMOOluASo9OEF13WlXrpAp2aj35LbedAy3QOCgQCw0tkLKAQ==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/markdown-it-link-attributes/-/markdown-it-link-attributes-3.0.0.tgz",
"integrity": "sha512-B34ySxVeo6MuEGSPCWyIYryuXINOvngNZL87Mp7YYfKIf6DcD837+lXA8mo6EBbauKsnGz22ZH0zsbOiQRWTNg==",
"license": "MIT"
},
"node_modules/markdown-it-linkify-images": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/markdown-it-linkify-images/-/markdown-it-linkify-images-3.0.0.tgz",
"integrity": "sha512-Vs5yGJa5MWjFgytzgtn8c1U6RcStj3FZKhhx459U8dYbEE5FTWZ6mMRkYMiDlkFO0j4VCsQT1LT557bY0ETgtg==",
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/markdown-it-linkify-images/-/markdown-it-linkify-images-1.1.1.tgz",
"integrity": "sha512-1IEmAaAjIgAwY+tZI0sxDXdy9QKHutj5cN0lH2JBiSZt+2NYKrWRJj0cloQW3OFIfP2MLFA1E+6OLJhXPiLgNw==",
"license": "MIT",
"dependencies": {
"markdown-it": "^13.0.1"
"markdown-it": "^8.4.2"
}
},
"node_modules/markdown-it-linkify-images/node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"license": "Python-2.0"
},
"node_modules/markdown-it-linkify-images/node_modules/entities": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
"integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
"license": "BSD-2-Clause"
},
"node_modules/markdown-it-linkify-images/node_modules/linkify-it": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz",
"integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
"integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
"license": "MIT",
"dependencies": {
"uc.micro": "^1.0.1"
}
},
"node_modules/markdown-it-linkify-images/node_modules/markdown-it": {
"version": "13.0.2",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.2.tgz",
"integrity": "sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==",
"version": "8.4.2",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz",
"integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==",
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1",
"entities": "~3.0.1",
"linkify-it": "^4.0.1",
"argparse": "^1.0.7",
"entities": "~1.1.1",
"linkify-it": "^2.0.0",
"mdurl": "^1.0.1",
"uc.micro": "^1.0.5"
},
+1 -1
View File
@@ -28,7 +28,7 @@
"eslint-config-habitrpg": "6.2.0",
"eslint-plugin-mocha": "5.3.0",
"eslint-plugin-vue": "7.20.0",
"habitica-markdown": "^4.0.0",
"habitica-markdown": "^3.0.0",
"hellojs": "^1.20.0",
"intro.js": "^7.2.0",
"jquery": "^3.7.1",
-5
View File
@@ -229,11 +229,6 @@ export default {
}
return Promise.resolve(error);
}
if (error.response.status === 404
&& error.response.config.method === 'get'
&& error.response.config.url.indexOf('/api/v4/groups/party') !== -1) {
return Promise.reject(error);
}
}
const errorData = error.response.data;
+1 -12
View File
@@ -22,15 +22,8 @@
height: 219px;
}
.quest_alien {
background: url("https://habitica-assets.s3.amazonaws.com/mobileApp/images/quest_alien.gif") no-repeat;
width: 219px;
height: 219px;
}
.Pet_HatchingPotion_Dessert, .Pet_HatchingPotion_Veggie, .Pet_HatchingPotion_Windup,
.Pet_HatchingPotion_VirtualPet, .Pet_HatchingPotion_Fungi, .Pet_HatchingPotion_Cryptid,
.Pet_HatchingPotion_Alien {
.Pet_HatchingPotion_VirtualPet, .Pet_HatchingPotion_Fungi, .Pet_HatchingPotion_Cryptid {
width: 68px;
height: 68px;
}
@@ -59,10 +52,6 @@
background: url("https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet_HatchingPotion_Cryptid.gif") no-repeat;
}
.Pet_HatchingPotion_Alien {
background: url("https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet_HatchingPotion_Alien.gif") no-repeat;
}
.Gems {
display:inline-block;
margin-right:5px;
@@ -1060,11 +1060,6 @@
width: 141px;
height: 147px;
}
.background_elven_citadel {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/background_elven_citadel.png');
width: 141px;
height: 147px;
}
.background_enchanted_music_room {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/background_enchanted_music_room.png');
width: 141px;
@@ -1801,11 +1796,6 @@
width: 141px;
height: 147px;
}
.background_on_a_strange_planet {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/background_on_a_strange_planet.png');
width: 141px;
height: 147px;
}
.background_on_tree_branch {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/background_on_tree_branch.png');
width: 141px;
@@ -1941,11 +1931,6 @@
width: 141px;
height: 147px;
}
.background_riding_a_comet {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/background_riding_a_comet.png');
width: 141px;
height: 147px;
}
.background_rime_ice {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/background_rime_ice.png');
width: 141px;
@@ -2442,11 +2427,6 @@
width: 141px;
height: 147px;
}
.background_waterfall_with_rainbow {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/background_waterfall_with_rainbow.png');
width: 141px;
height: 147px;
}
.background_wedding_arch {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/background_wedding_arch.png');
width: 141px;
@@ -29820,11 +29800,6 @@
width: 114px;
height: 90px;
}
.broad_armor_armoire_handstandOutfit {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_armoire_handstandOutfit.png');
width: 114px;
height: 90px;
}
.broad_armor_armoire_hattersSuit {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_armoire_hattersSuit.png');
width: 114px;
@@ -30100,11 +30075,6 @@
width: 114px;
height: 90px;
}
.broad_armor_armoire_softYellowSuit {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_armoire_softYellowSuit.png');
width: 114px;
height: 90px;
}
.broad_armor_armoire_springPetalYukata {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_armoire_springPetalYukata.png');
width: 114px;
@@ -30415,11 +30385,6 @@
width: 114px;
height: 90px;
}
.head_armoire_floppyYellowHat {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_armoire_floppyYellowHat.png');
width: 114px;
height: 90px;
}
.head_armoire_flutteryWig {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_armoire_flutteryWig.png');
width: 114px;
@@ -30740,11 +30705,6 @@
width: 114px;
height: 90px;
}
.head_armoire_verdantArmingCap {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_armoire_verdantArmingCap.png');
width: 114px;
height: 90px;
}
.head_armoire_vermilionArcherHelm {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_armoire_vermilionArcherHelm.png');
width: 90px;
@@ -31160,11 +31120,6 @@
width: 114px;
height: 90px;
}
.shield_armoire_softYellowPillow {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shield_armoire_softYellowPillow.png');
width: 114px;
height: 90px;
}
.shield_armoire_spanishGuitar {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shield_armoire_spanishGuitar.png');
width: 114px;
@@ -31215,11 +31170,6 @@
width: 114px;
height: 90px;
}
.shield_armoire_verdantBanner {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shield_armoire_verdantBanner.png');
width: 114px;
height: 90px;
}
.shield_armoire_vikingShield {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shield_armoire_vikingShield.png');
width: 90px;
@@ -31490,11 +31440,6 @@
width: 114px;
height: 90px;
}
.slim_armor_armoire_handstandOutfit {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_armoire_handstandOutfit.png');
width: 114px;
height: 90px;
}
.slim_armor_armoire_hattersSuit {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_armoire_hattersSuit.png');
width: 114px;
@@ -31770,11 +31715,6 @@
width: 114px;
height: 90px;
}
.slim_armor_armoire_softYellowSuit {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_armoire_softYellowSuit.png');
width: 114px;
height: 90px;
}
.slim_armor_armoire_springPetalYukata {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_armoire_springPetalYukata.png');
width: 114px;
@@ -34185,21 +34125,11 @@
width: 114px;
height: 90px;
}
.back_mystery_202605 {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/back_mystery_202605.png');
width: 114px;
height: 90px;
}
.broad_armor_mystery_202512 {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_mystery_202512.png');
width: 114px;
height: 90px;
}
.broad_armor_mystery_202604 {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_mystery_202604.png');
width: 114px;
height: 90px;
}
.head_mystery_202512 {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_mystery_202512.png');
width: 114px;
@@ -34210,31 +34140,11 @@
width: 114px;
height: 90px;
}
.head_mystery_202603 {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_mystery_202603.png');
width: 114px;
height: 90px;
}
.head_mystery_202604 {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_mystery_202604.png');
width: 114px;
height: 90px;
}
.shield_mystery_202605 {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shield_mystery_202605.png');
width: 114px;
height: 90px;
}
.slim_armor_mystery_202512 {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_mystery_202512.png');
width: 114px;
height: 90px;
}
.slim_armor_mystery_202604 {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_mystery_202604.png');
width: 114px;
height: 90px;
}
.weapon_mystery_202512 {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/weapon_mystery_202512.png');
width: 114px;
@@ -34245,11 +34155,6 @@
width: 114px;
height: 90px;
}
.weapon_mystery_202603 {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/weapon_mystery_202603.png');
width: 114px;
height: 90px;
}
.back_mystery_201402 {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/back_mystery_201402.png');
width: 90px;
@@ -36370,26 +36275,6 @@
width: 114px;
height: 90px;
}
.broad_armor_special_spring2026Healer {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_special_spring2026Healer.png');
width: 114px;
height: 90px;
}
.broad_armor_special_spring2026Mage {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_special_spring2026Mage.png');
width: 114px;
height: 90px;
}
.broad_armor_special_spring2026Rogue {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_special_spring2026Rogue.png');
width: 114px;
height: 90px;
}
.broad_armor_special_spring2026Warrior {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_special_spring2026Warrior.png');
width: 114px;
height: 90px;
}
.broad_armor_special_springHealer {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_special_springHealer.png');
width: 90px;
@@ -36710,26 +36595,6 @@
width: 114px;
height: 90px;
}
.head_special_spring2026Healer {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_special_spring2026Healer.png');
width: 114px;
height: 90px;
}
.head_special_spring2026Mage {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_special_spring2026Mage.png');
width: 114px;
height: 90px;
}
.head_special_spring2026Rogue {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_special_spring2026Rogue.png');
width: 114px;
height: 90px;
}
.head_special_spring2026Warrior {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_special_spring2026Warrior.png');
width: 114px;
height: 90px;
}
.head_special_springHealer {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_special_springHealer.png');
width: 90px;
@@ -36915,21 +36780,6 @@
width: 114px;
height: 90px;
}
.shield_special_spring2026Healer {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shield_special_spring2026Healer.png');
width: 114px;
height: 90px;
}
.shield_special_spring2026Rogue {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shield_special_spring2026Rogue.png');
width: 114px;
height: 90px;
}
.shield_special_spring2026Warrior {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shield_special_spring2026Warrior.png');
width: 114px;
height: 90px;
}
.shield_special_springHealer {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shield_special_springHealer.png');
width: 90px;
@@ -37165,26 +37015,6 @@
width: 114px;
height: 90px;
}
.slim_armor_special_spring2026Healer {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_special_spring2026Healer.png');
width: 114px;
height: 90px;
}
.slim_armor_special_spring2026Mage {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_special_spring2026Mage.png');
width: 114px;
height: 90px;
}
.slim_armor_special_spring2026Rogue {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_special_spring2026Rogue.png');
width: 114px;
height: 90px;
}
.slim_armor_special_spring2026Warrior {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_special_spring2026Warrior.png');
width: 114px;
height: 90px;
}
.slim_armor_special_springHealer {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_special_springHealer.png');
width: 90px;
@@ -37425,26 +37255,6 @@
width: 114px;
height: 90px;
}
.weapon_special_spring2026Healer {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/weapon_special_spring2026Healer.png');
width: 114px;
height: 90px;
}
.weapon_special_spring2026Mage {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/weapon_special_spring2026Mage.png');
width: 114px;
height: 90px;
}
.weapon_special_spring2026Rogue {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/weapon_special_spring2026Rogue.png');
width: 114px;
height: 90px;
}
.weapon_special_spring2026Warrior {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/weapon_special_spring2026Warrior.png');
width: 114px;
height: 90px;
}
.weapon_special_springHealer {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/weapon_special_springHealer.png');
width: 90px;
@@ -53228,11 +53038,6 @@
width: 81px;
height: 99px;
}
.Pet-BearCub-Alien {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-BearCub-Alien.png');
width: 81px;
height: 99px;
}
.Pet-BearCub-Amber {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-BearCub-Amber.png');
width: 81px;
@@ -53723,11 +53528,6 @@
width: 81px;
height: 99px;
}
.Pet-Cactus-Alien {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-Cactus-Alien.png');
width: 81px;
height: 99px;
}
.Pet-Cactus-Amber {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-Cactus-Amber.png');
width: 81px;
@@ -54518,11 +54318,6 @@
width: 81px;
height: 99px;
}
.Pet-Dragon-Alien {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-Dragon-Alien.png');
width: 81px;
height: 99px;
}
.Pet-Dragon-Amber {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-Dragon-Amber.png');
width: 81px;
@@ -55018,11 +54813,6 @@
width: 81px;
height: 99px;
}
.Pet-FlyingPig-Alien {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-FlyingPig-Alien.png');
width: 81px;
height: 99px;
}
.Pet-FlyingPig-Amber {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-FlyingPig-Amber.png');
width: 81px;
@@ -55358,11 +55148,6 @@
width: 81px;
height: 99px;
}
.Pet-Fox-Alien {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-Fox-Alien.png');
width: 81px;
height: 99px;
}
.Pet-Fox-Amber {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-Fox-Amber.png');
width: 81px;
@@ -56143,11 +55928,6 @@
width: 81px;
height: 99px;
}
.Pet-LionCub-Alien {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-LionCub-Alien.png');
width: 81px;
height: 99px;
}
.Pet-LionCub-Amber {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-LionCub-Amber.png');
width: 81px;
@@ -56753,11 +56533,6 @@
width: 81px;
height: 99px;
}
.Pet-PandaCub-Alien {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-PandaCub-Alien.png');
width: 81px;
height: 99px;
}
.Pet-PandaCub-Amber {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-PandaCub-Amber.png');
width: 81px;
@@ -58153,11 +57928,6 @@
width: 81px;
height: 99px;
}
.Pet-TigerCub-Alien {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-TigerCub-Alien.png');
width: 81px;
height: 99px;
}
.Pet-TigerCub-Amber {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-TigerCub-Amber.png');
width: 81px;
@@ -58803,11 +58573,6 @@
width: 81px;
height: 99px;
}
.Pet-Wolf-Alien {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-Wolf-Alien.png');
width: 81px;
height: 99px;
}
.Pet-Wolf-Amber {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet-Wolf-Amber.png');
width: 81px;
Binary file not shown.

Before

Width:  |  Height:  |  Size: 375 B

@@ -58,11 +58,6 @@ h3.markdown {
img {
max-width: 100%;
}
.emoji-native {
font-size: 0.85em;
vertical-align: middle;
}
blockquote {
padding: 0 16px;
@@ -1,5 +0,0 @@
<svg width="330" height="80" viewBox="0 0 330 80" preserveAspectRatio="none" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M159.797 60.5502C165.534 61.8466 171.631 62.7536 178.221 63.1767C208.94 65.1492 233.733 56.6838 260.68 47.483C282.33 40.091 305.37 32.2243 333.99 28.9144L336 16.3018C260.81 7.08865 233.373 23.1672 205.362 39.5825C192.037 47.3908 178.583 55.2753 159.797 60.5502Z" fill="#BDA8FF"/>
<path d="M0 80L331.948 79.9998V29.1594C268.976 36.9871 233.03 66.6959 178.221 63.1767C112.951 58.9858 95.9516 7.31934 0.000104656 0L0 80Z" fill="#925CF3"/>
<path d="M203.54 40.6496C166.339 36.8525 141.531 39.6251 122.334 45.4666C133.94 51.8989 145.792 57.3851 159.797 60.5502C177.727 55.5155 190.801 48.1036 203.54 40.6496Z" fill="#D5C8FF"/>
</svg>

Before

Width:  |  Height:  |  Size: 803 B

@@ -1,228 +1,53 @@
<template>
<b-modal
id="rebirth"
size="sm"
:hide-header="true"
:title="$t('modalAchievement')"
size="md"
:hide-footer="true"
>
<div
class="close-x"
@click.stop="close()"
>
<div
class="svg-icon svg-close"
v-html="icons.close"
></div>
</div>
<div class="content text-center">
<h2
v-once
class="header"
>
{{ $t('rebirthNewAchievement') }}
</h2>
<div class="d-flex align-items-center justify-content-center icon-area">
<div
v-once
class="svg-icon sparkles mirror"
v-html="icons.starGroup"
></div>
<Sprite
class="achievement-icon"
image-name="achievement-sun2x"
/>
<div
v-once
class="svg-icon sparkles"
v-html="icons.starGroup"
></div>
<div class="modal-body">
<div class="col-12">
<!-- @TODO: +achievementAvatar('sun',0)--><achievement-avatar class="avatar" />
</div><div class="col-6 offset-3 text-center">
<div v-if="user.achievements.rebirthLevel < 100">
{{ $t('rebirthAchievement', {
number: user.achievements.rebirths,
level: user.achievements.rebirthLevel}) }}
</div><div v-if="user.achievements.rebirthLevel >= 100">
{{ $t('rebirthAchievement100', {number: user.achievements.rebirths}) }}
</div><br><button
class="btn btn-primary"
@click="close()"
>
{{ $t('huzzah') }}
</button>
</div>
<p class="subtitle">
{{ $t('rebirthNewAdventure') }}
</p>
<p
class="description"
v-html="achievementText"
></p>
<p
v-once
class="stack-info"
>
{{ $t('rebirthStackInfo') }}
</p>
<button
v-once
class="btn btn-primary"
@click="close()"
>
{{ $t('onwards') }}
</button>
</div>
<div
slot="modal-footer"
class="footer-wave"
v-html="icons.purpleWaves"
></div>
</div><achievement-footer />
</b-modal>
</template>
<style lang="scss">
@import '@/assets/scss/colors.scss';
#rebirth {
.modal-dialog {
width: 330px;
}
.modal-content {
border: none;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 14px 28px 0 rgba($black, 0.24), 0 10px 10px 0 rgba($black, 0.28);
}
.modal-body {
padding: 0;
}
.modal-footer {
padding: 0;
border-top: none;
border-radius: 0;
margin: 0;
line-height: 0;
}
}
</style>
<style lang="scss" scoped>
@import '@/assets/scss/colors.scss';
.content {
padding: 24px 24px 0;
}
.header {
font-size: 1.25rem;
line-height: 1.4;
color: $purple-200;
margin-top: 8px;
margin-bottom: 16px;
}
.icon-area {
margin-bottom: 16px;
}
.sparkles {
width: 40px;
height: 64px;
&.mirror {
transform: scaleX(-1);
}
}
.close-x {
position: absolute;
right: 16px;
top: 16px;
cursor: pointer;
z-index: 2;
&:hover .svg-close {
opacity: 0.75;
}
.svg-close {
width: 16px;
height: 16px;
opacity: 0.5;
transition: opacity 0.2s ease;
pointer-events: none;
}
}
.achievement-icon {
margin: 0 24px;
}
.subtitle {
font-family: 'Roboto', sans-serif;
font-weight: 700;
font-style: normal;
font-size: 14px;
line-height: 24px;
letter-spacing: 0;
margin-bottom: 12px;
color: $gray-10;
}
.description {
font-size: 0.875rem;
line-height: 1.71;
margin-bottom: 12px;
color: $gray-50;
}
.stack-info {
font-size: 0.875rem;
line-height: 1.71;
color: $gray-50;
margin-bottom: 24px;
}
.btn-primary {
margin-bottom: 8px;
}
.footer-wave {
width: 100%;
::v-deep svg {
display: block;
width: calc(100% + 8px);
height: auto;
margin: 0 -4px -4px;
}
<style scoped>
.avatar {
width: 140px;
margin: 0 auto;
margin-bottom: 1.5em;
margin-top: 1.5em;
}
</style>
<script>
import closeIcon from '@/assets/svg/close.svg?raw';
import Sprite from '@/components/ui/sprite';
import starGroup from '@/assets/svg/star-group.svg?raw';
import purpleWaves from '@/assets/svg/purple-waves.svg?raw';
import achievementFooter from './achievementFooter';
import achievementAvatar from './achievementAvatar';
import { mapState } from '@/libs/store';
export default {
components: {
Sprite,
},
data () {
return {
icons: Object.freeze({
starGroup,
purpleWaves,
close: closeIcon,
}),
};
achievementFooter,
achievementAvatar,
},
computed: {
...mapState({ user: 'user.data' }),
achievementText () {
const rebirths = this.user.achievements.rebirths || 0;
const level = this.user.achievements.rebirthLevel || 0;
if (level >= 100) {
return this.$t('rebirthAchievement100', { number: rebirths, level });
}
if (rebirths === 1) {
return this.$t('rebirthAchievement', { number: rebirths, level });
}
return this.$t('rebirthAchievementPlural', { number: rebirths, level });
},
},
methods: {
close () {
@@ -1,186 +1,41 @@
<template>
<b-modal
id="rebirth-enabled"
size="sm"
:hide-header="true"
:title="$t('rebirthNew')"
size="md"
:hide-footer="true"
>
<div
class="close-x"
@click.stop="close()"
>
<div
class="svg-icon svg-close"
v-html="icons.close"
></div>
</div>
<div class="content text-center">
<h2
v-once
class="header"
>
{{ $t('rebirthUnlockedNewItem') }}
</h2>
<div class="d-flex align-items-center justify-content-center icon-area">
<div
v-once
class="svg-icon sparkles mirror"
v-html="icons.starGroup"
></div>
<img
class="orb-icon"
src="@/assets/images/rebirth-orb.png"
alt="Orb of Rebirth"
>
<div
v-once
class="svg-icon sparkles"
v-html="icons.starGroup"
></div>
<div class="modal-body">
<div class="col-12">
<div class="rebirth_orb"></div>
<p>
<span>{{ $t('rebirthUnlock') }}</span>
</p>
</div>
</div>
<div class="modal-footer">
<div class="col-12 text-center">
<button
class="btn btn-primary"
@click="close()"
>
{{ $t('close') }}
</button>
</div>
<p
v-once
class="subtitle"
>
{{ $t('rebirthUnlockedOrb') }}
</p>
<p
v-once
class="description"
>
{{ $t('rebirthUnlockedDesc') }}
</p>
<button
v-once
class="btn btn-primary"
@click="close()"
>
{{ $t('onwards') }}
</button>
</div>
<div
slot="modal-footer"
class="clearfix"
></div>
</b-modal>
</template>
<style lang="scss">
@import '@/assets/scss/colors.scss';
#rebirth-enabled {
.modal-dialog {
width: 330px;
}
.modal-content {
border-radius: 8px;
overflow: hidden;
box-shadow: 0 14px 28px 0 rgba($black, 0.24), 0 10px 10px 0 rgba($black, 0.28);
}
.modal-body {
padding: 0;
}
.modal-footer {
padding: 0;
border-top: none;
}
}
</style>
<style lang="scss" scoped>
@import '@/assets/scss/colors.scss';
.content {
padding: 24px 24px 0;
}
.header {
font-size: 1.25rem;
line-height: 1.4;
color: $purple-200;
margin-top: 8px;
margin-bottom: 12px;
}
.icon-area {
margin-bottom: 12px;
}
.sparkles {
width: 40px;
height: 64px;
&.mirror {
transform: scaleX(-1);
}
}
.close-x {
position: absolute;
right: 16px;
top: 16px;
cursor: pointer;
z-index: 2;
&:hover .svg-close {
opacity: 0.75;
}
.svg-close {
width: 16px;
height: 16px;
opacity: 0.5;
transition: opacity 0.2s ease;
pointer-events: none;
}
}
.orb-icon {
width: 62px;
height: 62px;
margin: 0 24px;
image-rendering: pixelated;
}
.subtitle {
font-family: 'Roboto', sans-serif;
font-weight: 700;
font-style: normal;
font-size: 14px;
line-height: 24px;
letter-spacing: 0;
margin-bottom: 12px;
color: $gray-50;
}
.description {
font-size: 0.875rem;
line-height: 1.71;
margin-bottom: 24px;
color: $gray-100;
}
.btn-primary {
margin-bottom: 24px;
<style scoped>
.rebirth_orb {
margin: 0 auto;
}
</style>
<script>
import closeIcon from '@/assets/svg/close.svg?raw';
import starGroup from '@/assets/svg/star-group.svg?raw';
import { mapState } from '@/libs/store';
export default {
data () {
return {
icons: Object.freeze({
starGroup,
close: closeIcon,
}),
};
},
computed: {
...mapState({ user: 'user.data' }),
},
@@ -43,14 +43,6 @@
<p class="purple-600">
{{ $t('usernameLimitations') }}
</p>
<input
v-if="needsEmailField"
id="emailInput"
v-model="email"
class="form-control dark"
type="text"
:placeholder="$t('email')"
>
<div class="custom-control custom-checkbox mb-4">
<input
id="privacyTOS"
@@ -173,7 +165,6 @@ export default {
registrationMethod: null,
username: '',
usernameIssues: [],
needsEmailField: false,
};
},
computed: {
@@ -192,30 +183,22 @@ export default {
},
},
mounted () {
if (window.sessionStorage.getItem('apple-token')) {
this.registrationMethod = 'apple';
} else if (!this.$store.state.registrationOptions.registrationMethod) {
this.$router.push('/');
} else {
this.registrationMethod = this.$store.state.registrationOptions.registrationMethod;
}
this.authData = this.$store.state.registrationOptions.authData;
this.email = this.$store.state.registrationOptions.email;
this.username = this.$store.state.registrationOptions.username;
this.password = this.$store.state.registrationOptions.password;
this.passwordConfirm = this.$store.state.registrationOptions.passwordConfirm;
if (window.sessionStorage.getItem('apple-token')) {
this.registrationMethod = 'apple';
if (!this.email) {
this.email = window.sessionStorage.getItem('apple-email');
}
} else if (!this.$store.state.registrationOptions.registrationMethod) {
this.$router.push('/');
} else {
this.registrationMethod = this.$store.state.registrationOptions.registrationMethod;
}
if (!this.email && this.registrationMethod !== 'apple') {
if (!this.email) {
return;
}
if ((!this.email || this.email === '') && this.registrationMethod === 'apple') {
this.needsEmailField = true;
}
const usernameToCheck = this.email.split('@')[0].replace(/[^a-zA-Z0-9\-_]/g, '');
this.$store.dispatch('auth:verifyUsername', {
username: usernameToCheck,
@@ -254,7 +237,6 @@ export default {
idToken: window.sessionStorage.getItem('apple-token'),
name: window.sessionStorage.getItem('apple-name'),
username: this.username,
email: this.email,
allowRegister: true,
});
} else {
+4 -5
View File
@@ -321,11 +321,10 @@ export default {
return null;
},
petClass () {
const substitutionEvent = this.currentEventList?.find(event => event.spriteSubstitutions
&& moment().isBetween(event.start, event.end));
if (substitutionEvent && substitutionEvent.spriteSubstitutions.pets) {
return this.foolPet(`Pet-${this.member.items.currentPet}`,
substitutionEvent.spriteSubstitutions.pets);
const foolEvent = this.currentEventList?.find(event => event.aprilFools && moment()
.isBetween(event.start, event.end));
if (foolEvent) {
return this.foolPet(this.member.items.currentPet, foolEvent.aprilFools);
}
if (this.member?.items.currentPet) return `Pet-${this.member.items.currentPet}`;
return '';
@@ -12,39 +12,23 @@
<label>
<strong v-once>{{ $t('name') }} *</strong>
</label>
<input
ref="nameInput"
<b-form-input
v-model="workingChallenge.name"
class="form-control"
type="text"
:placeholder="$t('challengeNamePlaceholder')"
@focus="setActiveField('name')"
@keydown="onFieldKeydown($event)"
@keydown.tab="autoCompleteMixinHandleTab($event)"
@keydown.up="autoCompleteMixinSelectPreviousAutocomplete($event)"
@keydown.down="autoCompleteMixinSelectNextAutocomplete($event)"
@keypress.enter="autoCompleteMixinSelectAutocomplete($event)"
@keydown.esc="autoCompleteMixinHandleEscape($event)"
>
@keydown="enableSubmit"
/>
</div>
<div class="form-group">
<label>
<strong v-once>{{ $t('shortName') }} *</strong>
</label>
<input
ref="shortNameInput"
<b-form-input
v-model="workingChallenge.shortName"
class="form-control"
type="text"
:placeholder="$t('shortNamePlaceholder')"
@focus="setActiveField('shortName')"
@keydown="onFieldKeydown($event)"
@keydown.tab="autoCompleteMixinHandleTab($event)"
@keydown.up="autoCompleteMixinSelectPreviousAutocomplete($event)"
@keydown.down="autoCompleteMixinSelectNextAutocomplete($event)"
@keypress.enter="autoCompleteMixinSelectAutocomplete($event)"
@keydown.esc="autoCompleteMixinHandleEscape($event)"
>
@keydown="enableSubmit"
/>
</div>
<div class="form-group">
<label>
@@ -56,17 +40,10 @@
{{ $t('charactersRemaining', {characters: charactersRemaining}) }}
</div>
<textarea
ref="summaryTextarea"
v-model="workingChallenge.summary"
class="summary-textarea form-control"
:placeholder="$t('challengeSummaryPlaceholder')"
@focus="setActiveField('summary')"
@keydown="onFieldKeydown($event)"
@keydown.tab="autoCompleteMixinHandleTab($event)"
@keydown.up="autoCompleteMixinSelectPreviousAutocomplete($event)"
@keydown.down="autoCompleteMixinSelectNextAutocomplete($event)"
@keypress.enter="autoCompleteMixinSelectAutocomplete($event)"
@keydown.esc="autoCompleteMixinHandleEscape($event)"
@keydown="enableSubmit"
></textarea>
</div>
<div class="form-group">
@@ -78,26 +55,11 @@
class="float-right"
></a>
<textarea
ref="descriptionTextarea"
v-model="workingChallenge.description"
class="description-textarea form-control"
:placeholder="$t('challengeDescriptionPlaceholder')"
@focus="setActiveField('description')"
@keydown="onFieldKeydown($event)"
@keydown.tab="autoCompleteMixinHandleTab($event)"
@keydown.up="autoCompleteMixinSelectPreviousAutocomplete($event)"
@keydown.down="autoCompleteMixinSelectNextAutocomplete($event)"
@keypress.enter="autoCompleteMixinSelectAutocomplete($event)"
@keydown.esc="autoCompleteMixinHandleEscape($event)"
@keydown="enableSubmit"
></textarea>
<emoji-auto-complete
ref="emojiAutocomplete"
:text="activeFieldText"
:textbox="textbox"
:coords="mixinData.autoComplete.coords"
:caret-position="mixinData.autoComplete.caretPosition"
@select="selectedAutocomplete"
/>
</div>
<div
v-if="creating"
@@ -318,17 +280,12 @@ import { TAVERN_ID, MIN_SHORTNAME_SIZE_FOR_CHALLENGES, MAX_SUMMARY_SIZE_FOR_CHAL
import CategoryOptions from '@/../../common/script/content/categoryOptions';
import markdownDirective from '@/directives/markdown';
import { userStateMixin } from '../../mixins/userState';
import emojiAutoComplete from '@/components/chat/emojiAutoComplete';
import { autoCompleteHelperMixin } from '@/mixins/autoCompleteHelper';
export default {
components: {
emojiAutoComplete,
},
directives: {
markdown: markdownDirective,
},
mixins: [userStateMixin, autoCompleteHelperMixin],
mixins: [userStateMixin],
props: ['groupId'],
data () {
const categoryOptions = CategoryOptions;
@@ -362,14 +319,9 @@ export default {
categoriesHashByKey,
loading: false,
groups: [],
textbox: null,
activeField: 'name',
};
},
computed: {
activeFieldText () {
return this.workingChallenge[this.activeField] || '';
},
creating () {
return !this.workingChallenge.id;
},
@@ -637,29 +589,6 @@ export default {
toggleCategorySelect () {
this.showCategorySelect = !this.showCategorySelect;
},
setActiveField (field) {
this.activeField = field;
const refMap = {
name: 'nameInput',
shortName: 'shortNameInput',
summary: 'summaryTextarea',
description: 'descriptionTextarea',
};
this.textbox = this.$refs[refMap[field]] || null;
},
onFieldKeydown (e) {
this.enableSubmit();
this.autoCompleteMixinUpdateCarretPosition(e);
},
selectedAutocomplete (newText, newCaret) {
this.workingChallenge[this.activeField] = newText;
this.$nextTick(() => {
if (this.textbox) {
this.textbox.setSelectionRange(newCaret, newCaret);
this.textbox.focus();
}
});
},
enableSubmit: throttle(function enableSubmit () {
/* Enables the submit button if it was disabled */
if (this.loading) {
@@ -1,282 +0,0 @@
<template>
<div
v-if="searchResults.length > 0"
class="autocomplete-selection"
:style="autocompleteStyle"
>
<div
v-for="result in searchResults"
:key="result.shortcode"
class="autocomplete-results d-flex align-items-center"
:class="{'hover-background': result.hover}"
@click="select(result)"
@mouseenter="setHover(result)"
@mouseleave="resetSelection()"
>
<img
v-if="result.imageUrl"
class="emoji-img"
:src="result.imageUrl"
:alt="result.shortcode"
>
<span
v-else
class="emoji-char"
>{{ result.emoji }}</span>
<span
class="shortcode ml-2"
:class="{'hover-foreground': result.hover}"
>:{{ result.shortcode }}:</span>
</div>
</div>
</template>
<style lang="scss" scoped>
@import '@/assets/scss/colors.scss';
.autocomplete-results {
padding: .5em;
}
.autocomplete-selection {
box-shadow: 1px 1px 1px #efefef;
}
.hover-background {
background-color: rgba(213, 200, 255, 0.32);
cursor: pointer;
}
.hover-foreground {
color: $purple-300 !important;
}
.emoji-char {
font-size: 20px;
line-height: 1;
}
.emoji-img {
height: 20px;
width: 20px;
}
.shortcode {
color: $gray-200;
font-size: 14px;
}
</style>
<script>
import habiticaMarkdown from 'habitica-markdown';
export default {
props: ['text', 'caretPosition', 'coords', 'textbox'],
data () {
return {
colonRegex: /:([a-zA-Z0-9_+]*)$/,
currentSearch: '',
searchActive: false,
searchResults: [],
selected: null,
emojiList: [],
renderTick: 0,
internalCoords: { TOP: 0, LEFT: 0 },
};
},
computed: {
autocompleteStyle () {
// eslint-disable-next-line no-unused-vars
const _tick = this.renderTick;
const isTextarea = this.textbox.tagName === 'TEXTAREA';
const dropdownPA = (this.$el && this.$el.nodeType === 1) ? this.$el.offsetParent : null;
const textboxOP = this.textbox.offsetParent;
const needsRectCalc = dropdownPA && textboxOP && dropdownPA !== textboxOP;
let top;
let left;
const caretLeft = this.internalCoords.LEFT - (this.textbox.scrollLeft || 0);
if (needsRectCalc) {
const textboxRect = this.textbox.getBoundingClientRect();
const parentRect = dropdownPA.getBoundingClientRect();
const parentScrollTop = dropdownPA.scrollTop || 0;
if (isTextarea) {
const computedStyle = window.getComputedStyle(this.textbox);
const lineHeight = parseFloat(computedStyle.lineHeight)
|| (parseFloat(computedStyle.fontSize) * 1.4);
const caretTopInTextbox = this.internalCoords.TOP
- (this.textbox.scrollTop || 0) + lineHeight;
const clamped = Math.min(Math.max(caretTopInTextbox, 0), this.textbox.offsetHeight);
top = (textboxRect.top - parentRect.top) + parentScrollTop + clamped + 2;
} else {
top = (textboxRect.bottom - parentRect.top) + parentScrollTop + 2;
}
left = (textboxRect.left - parentRect.left) + caretLeft;
} else {
if (isTextarea) {
const computedStyle = window.getComputedStyle(this.textbox);
const lineHeight = parseFloat(computedStyle.lineHeight)
|| (parseFloat(computedStyle.fontSize) * 1.4);
const caretTopInTextbox = this.internalCoords.TOP
- (this.textbox.scrollTop || 0) + lineHeight;
const clamped = Math.min(Math.max(caretTopInTextbox, 0), this.textbox.offsetHeight);
top = this.textbox.offsetTop + clamped + 2;
} else {
top = this.textbox.offsetTop + this.textbox.offsetHeight + 2;
}
left = this.textbox.offsetLeft + caretLeft;
}
return {
top: `${top}px`,
left: `${left}px`,
position: 'absolute',
minWidth: '150px',
zIndex: 100,
backgroundColor: 'white',
};
},
},
watch: {
searchResults (results, oldResults) {
if (results.length > 0 && (!oldResults || oldResults.length === 0)) {
this.$nextTick(() => {
this.renderTick += 1;
});
}
},
text (newText, prevText) {
if (!this.textbox) return;
this._measureCaretCoords();
const delCharsBool = prevText.length > newText.length;
const caretPosition = this.textbox.selectionEnd;
const lastFocusChar = delCharsBool ? prevText[caretPosition] : newText[caretPosition - 1];
if (
newText.length === 0
|| (lastFocusChar === ':' && delCharsBool)
) {
this.cancel();
} else {
if (lastFocusChar === ':') this.searchActive = true;
if (this.searchActive) {
this.searchResults = this.solveSearchResults(newText.substring(0, caretPosition));
}
}
},
},
created () {
const defs = habiticaMarkdown.emojiDefs;
if (!defs) return;
const customEmojis = habiticaMarkdown.customEmojis || {};
const list = [];
const keys = Object.keys(defs);
keys.sort();
for (const key of keys) {
const entry = { shortcode: key, emoji: defs[key], hover: false };
if (customEmojis[key]) {
entry.imageUrl = customEmojis[key];
}
list.push(entry);
}
this.emojiList = list;
},
methods: {
solveSearchResults (textFocus) {
const regexRes = this.colonRegex.exec(textFocus);
if (!regexRes) {
this.cancel();
return [];
}
this.currentSearch = regexRes[1];
if (this.currentSearch.length === 0) return [];
const lowerSearch = this.currentSearch.toLowerCase();
return this.emojiList
.filter(entry => entry.shortcode.startsWith(lowerSearch))
.slice(0, 6)
.map(entry => ({ ...entry, hover: false }));
},
select (result) {
const { text } = this;
const targetName = `${result.shortcode}: `;
const oldCaret = this.caretPosition;
const escapedSearch = this.currentSearch.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
let newText = text.substring(0, this.caretPosition)
.replace(new RegExp(`${escapedSearch}$`), targetName);
const newCaret = newText.length;
newText += text.substring(oldCaret, text.length);
this.$emit('select', newText, newCaret);
this.cancel();
},
setHover (result) {
this.resetSelection();
result.hover = true;
},
clearHover () {
for (const selection of this.searchResults) {
selection.hover = false;
}
},
resetSelection () {
this.clearHover();
this.selected = null;
},
selectNext () {
if (this.searchResults.length > 0) {
this.clearHover();
this.selected = this.selected === null
? 0
: (this.selected + 1) % this.searchResults.length;
this.searchResults[this.selected].hover = true;
}
},
selectPrevious () {
if (this.searchResults.length > 0) {
this.clearHover();
this.selected = this.selected === null
? this.searchResults.length - 1
: (this.selected - 1 + this.searchResults.length) % this.searchResults.length;
this.searchResults[this.selected].hover = true;
}
},
makeSelection () {
if (this.searchResults.length > 0 && this.selected !== null) {
const result = this.searchResults[this.selected];
this.select(result);
}
},
_measureCaretCoords () {
const el = this.textbox;
const caretPosition = el.selectionEnd;
const div = document.createElement('div');
const span = document.createElement('span');
const copyStyle = getComputedStyle(el);
[].forEach.call(copyStyle, prop => {
div.style[prop] = copyStyle[prop];
});
div.style.position = 'absolute';
div.style.visibility = 'hidden';
document.body.appendChild(div);
div.textContent = el.value.substr(0, caretPosition);
span.textContent = el.value.substr(caretPosition) || '.';
div.appendChild(span);
this.internalCoords = {
TOP: span.offsetTop,
LEFT: span.offsetLeft,
};
document.body.removeChild(div);
},
cancel () {
this.searchActive = false;
this.searchResults = [];
this.resetSelection();
},
},
};
</script>
@@ -187,8 +187,7 @@
</div>
</div>
<div
v-if="user.purchased.background.birthday_bash
|| user.purchased.background.on_a_strange_planet"
v-if="user.purchased.background.birthday_bash"
>
<div
class="row justify-content-center title-row mb-3"
@@ -1,577 +0,0 @@
<template>
<b-modal
id="group-plan-selection"
:hide-footer="true"
:hide-header="true"
size="md"
@show="loadData"
@hide="onHide"
>
<div class="selection-modal">
<div class="modal-header-row">
<h2 class="title">
{{ $t('chooseAnOption') }}
</h2>
<div class="header-actions">
<span
class="cancel-text"
@click="close"
>
{{ $t('cancel') }}
</span>
<button
class="btn btn-primary next-button"
:class="{ disabled: !selectedOption }"
:disabled="!selectedOption"
@click="continueFlow"
>
{{ $t('next') }}
</button>
</div>
</div>
<div
v-if="loading"
class="loading-container"
>
<div class="spinner-border text-secondary"></div>
</div>
<template v-else>
<div
v-if="hasUpgradeableGroups"
class="section-header"
>
{{ $t('upgradeExistingGroup') }}
</div>
<selectable-card
v-for="group in upgradeableGuilds"
:key="group._id"
class="option-card"
:selected="isSelected(group)"
@click="selectOption(group)"
>
<div class="option-content">
<div class="option-info">
<div class="option-name">
{{ group.name }}
</div>
<div class="option-members">
{{ formatMemberCount(group.memberCount) }}
</div>
<div class="option-label previously-upgraded">
<div
class="svg-icon sparkle-icon"
v-html="icons.sparkles"
></div>
{{ $t('previouslyUpgradedGroup') }}
</div>
</div>
<div class="option-price">
${{ calculatePrice(group.memberCount) }}.00/mo
</div>
</div>
</selectable-card>
<selectable-card
v-if="upgradeableParty"
class="option-card"
:class="{ 'has-pending-warning': partyPendingInviteCount > 0 }"
:selected="isSelected(upgradeableParty)"
@click="selectOption(upgradeableParty)"
>
<div class="option-content">
<div class="option-info">
<div class="option-name">
{{ upgradeableParty.name }}
</div>
<div class="option-members">
{{ formatMemberCount(upgradeableParty.memberCount) }}
<span
v-if="partyPendingInviteCount > 0"
class="pending-count"
>
{{ $t('pendingCount', { count: partyPendingInviteCount }) }}
</span>
</div>
<div
v-if="isPartyPreviouslyUpgraded"
class="option-label previously-upgraded"
>
<div
class="svg-icon sparkle-icon"
v-html="icons.sparkles"
></div>
{{ $t('previouslyUpgradedGroup') }}
</div>
<div
v-else
class="option-label your-party"
>
<div
class="svg-icon member-icon"
v-html="icons.member"
></div>
{{ $t('yourParty') }}
</div>
</div>
<div class="option-price">
${{ calculatePrice(upgradeableParty.memberCount) }}.00/mo
</div>
</div>
<div
v-if="partyPendingInviteCount > 0"
class="pending-warning-banner"
>
<div
class="svg-icon alert-icon"
v-html="icons.alert"
></div>
<span class="warning-text">{{ $t('upgradeCancelsPendingInvites') }}</span>
</div>
</selectable-card>
<div
v-if="hasUpgradeableGroups"
class="or-divider"
>
<div class="divider-line"></div>
<span class="or-text">{{ $t('or') }}</span>
<div class="divider-line"></div>
</div>
<selectable-card
class="option-card create-new"
:selected="selectedOption === 'new'"
@click="selectOption('new')"
>
<div class="option-content">
<div class="option-info">
<div class="option-name">
{{ $t('createNewGroup') }}
</div>
<div class="option-description">
{{ $t('inviteOthersForAdditional') }}
<span class="price-highlight">${{ perMemberPrice }}.00</span>
{{ $t('perMember') }}.
</div>
</div>
<div class="option-price">
${{ basePrice }}.00/mo
</div>
</div>
</selectable-card>
<div class="footer-note">
{{ $t('additionalMembersProrated') }}
</div>
</template>
</div>
</b-modal>
</template>
<style lang="scss" scoped>
@import '@/assets/scss/colors.scss';
.selection-modal {
padding: 24px;
}
.modal-header-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24px;
}
.title {
font-family: 'Roboto Condensed', sans-serif;
font-weight: 700;
font-size: 20px;
line-height: 28px;
color: $purple-200;
margin: 0;
}
.header-actions {
display: flex;
align-items: center;
}
.cancel-text {
color: $blue-10;
font-size: 0.875rem;
margin-right: 16px;
cursor: pointer;
}
.next-button {
min-width: 64px;
&.disabled {
background-color: $gray-300;
border-color: $gray-300;
cursor: not-allowed;
}
}
.loading-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 200px;
}
.section-header {
font-family: 'Roboto', sans-serif;
font-weight: 700;
font-size: 14px;
line-height: 24px;
color: $gray-10;
margin-bottom: 12px;
}
.option-card {
margin-bottom: 12px;
::v-deep .option-name {
color: $gray-50;
}
&.selected ::v-deep .option-name {
color: $purple-200;
}
}
.pending-warning-banner {
display: flex;
align-items: center;
justify-content: center;
height: 32px;
background-color: $yellow-50;
border-radius: 0 0 6px 6px;
margin: 16px -16px 0 -16px;
gap: 4px;
.selected & {
margin: 15px -15px 0 -15px;
}
.alert-icon {
width: 16px;
height: 16px;
flex-shrink: 0;
::v-deep path {
fill: $gray-10;
}
}
.warning-text {
font-family: 'Roboto', sans-serif;
font-weight: 400;
font-size: 12px;
line-height: 16px;
color: $gray-10;
}
}
.option-content {
display: flex;
justify-content: space-between;
align-items: flex-start;
padding-left: 32px;
padding-right: 8px;
}
.option-info {
flex: 1;
}
.option-name {
font-family: 'Roboto', sans-serif;
font-size: 14px;
font-weight: 700;
line-height: 24px;
margin-bottom: 4px;
}
.option-members {
font-family: 'Roboto', sans-serif;
font-weight: 400;
font-size: 12px;
line-height: 16px;
color: $gray-100;
margin-bottom: 8px;
.pending-count {
font-weight: 700;
color: $yellow-5;
}
}
.option-label {
display: flex;
align-items: center;
font-family: 'Roboto', sans-serif;
font-size: 12px;
line-height: 16px;
gap: 4px;
&.previously-upgraded {
font-weight: 700;
color: $blue-10;
}
&.your-party {
font-weight: 700;
color: $gray-100;
}
.svg-icon {
width: 14px;
height: 14px;
}
.sparkle-icon {
color: $blue-10;
}
.member-icon {
color: $gray-100;
::v-deep path {
fill: $gray-100;
stroke: $gray-100;
stroke-width: 0.5px;
}
}
}
.option-description {
font-family: 'Roboto', sans-serif;
font-weight: 400;
font-size: 12px;
line-height: 16px;
color: $gray-100;
.price-highlight {
font-weight: 700;
}
}
.option-price {
font-family: 'Roboto', sans-serif;
font-weight: 700;
font-size: 20px;
line-height: 24px;
color: $purple-200;
white-space: nowrap;
}
.or-divider {
display: flex;
align-items: center;
margin: 20px 0;
.divider-line {
flex: 1;
height: 1px;
background-color: $gray-500;
}
.or-text {
padding: 0 16px;
font-family: 'Roboto', sans-serif;
font-weight: 700;
font-size: 12px;
line-height: 16px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: $gray-100;
}
}
.create-new {
.option-name {
margin-bottom: 8px;
}
}
.footer-note {
font-family: 'Roboto', sans-serif;
font-weight: 400;
font-size: 12px;
line-height: 16px;
color: $gray-100;
text-align: center;
margin-top: 16px;
margin-left: 24px;
margin-right: 24px;
}
</style>
<style lang="scss">
#group-plan-selection {
.modal-dialog {
max-width: 504px;
}
.modal-content {
border-radius: 8px;
box-shadow: 0 14px 28px 0 rgba(26, 24, 29, 0.24), 0 10px 10px 0 rgba(26, 24, 29, 0.28);
}
.modal-body {
padding: 0;
}
.option-card.has-pending-warning.selectable-card {
padding-bottom: 0;
}
}
</style>
<script>
import axios from 'axios';
import paymentsMixin from '@/mixins/payments';
import { mapState } from '@/libs/store';
import SelectableCard from '@/components/ui/selectableCard.vue';
import svgSparkles from '@/assets/svg/sparkles.svg?raw';
import svgMember from '@/assets/svg/member-icon.svg?raw';
import svgAlert from '@/assets/svg/for-css/alert.svg?raw';
export default {
components: {
SelectableCard,
},
mixins: [paymentsMixin],
data () {
return {
selectedOption: null,
userGuilds: [],
userParty: null,
activeGroupPlanIds: [],
loading: true,
basePrice: 9,
perMemberPrice: 3,
icons: Object.freeze({
sparkles: svgSparkles,
member: svgMember,
alert: svgAlert,
}),
partyPendingInviteCount: 0,
};
},
computed: {
...mapState({ user: 'user.data' }),
upgradeableGuilds () {
return this.userGuilds.filter(group => {
const leaderId = group.leader?._id || group.leader;
if (leaderId !== this.user._id) return false;
const purchased = group.purchased;
if (!purchased?.wasUpgraded) return false;
if (this.activeGroupPlanIds.includes(group._id)) return false;
if (!purchased.dateTerminated) return false;
return new Date(purchased.dateTerminated) < new Date();
});
},
upgradeableParty () {
if (!this.userParty) return null;
const leaderId = this.userParty.leader?._id || this.userParty.leader;
if (leaderId !== this.user._id) return null;
if (this.activeGroupPlanIds.includes(this.userParty._id)) return null;
return this.userParty;
},
hasUpgradeableGroups () {
return this.upgradeableGuilds.length > 0 || this.upgradeableParty !== null;
},
isPartyPreviouslyUpgraded () {
if (!this.userParty) return false;
const purchased = this.userParty.purchased;
if (!purchased?.wasUpgraded) return false;
if (!purchased.dateTerminated) return false;
return new Date(purchased.dateTerminated) < new Date();
},
},
methods: {
async loadData () {
this.loading = true;
this.selectedOption = null;
this.partyPendingInviteCount = 0;
try {
const [guildsResponse, partyResponse] = await Promise.all([
axios.get('/api/v4/groups', { params: { type: 'guilds', includeExpiredPlans: 'true' } }),
axios.get('/api/v4/groups/party').catch(() => ({ data: { data: null } })),
]);
this.userGuilds = guildsResponse.data.data || [];
this.userParty = partyResponse.data.data;
if (this.userParty) {
try {
const invitesResponse = await axios.get(`/api/v4/groups/${this.userParty._id}/invites`);
this.partyPendingInviteCount = invitesResponse.data.data?.length || 0;
} catch (e) {
this.partyPendingInviteCount = 0;
}
}
await this.$store.dispatch('guilds:getGroupPlans', true);
const groupPlans = this.$store.state.groupPlans?.data || [];
this.activeGroupPlanIds = groupPlans.map(g => g._id);
} catch (e) {
console.error('Error loading group data:', e);
}
this.loading = false;
this.$nextTick(() => {
if (this.upgradeableGuilds.length > 0) {
this.selectedOption = this.upgradeableGuilds[0];
} else if (this.upgradeableParty) {
this.selectedOption = this.upgradeableParty;
} else {
this.selectedOption = 'new';
}
});
},
selectOption (option) {
this.selectedOption = option;
},
isSelected (group) {
if (!this.selectedOption || this.selectedOption === 'new') return false;
return this.selectedOption._id === group._id;
},
calculatePrice (memberCount) {
return this.basePrice + (this.perMemberPrice * (memberCount - 1));
},
formatMemberCount (count) {
return count === 1 ? this.$t('oneMember') : this.$t('membersCount', { count });
},
continueFlow () {
if (!this.selectedOption) return;
const selection = this.selectedOption;
this.close();
if (selection === 'new') {
this.$root.$emit('bv::show::modal', 'create-group');
} else {
this.stripeGroup({ group: selection, upgrade: true });
}
},
close () {
this.$root.$emit('bv::hide::modal', 'group-plan-selection');
},
onHide () {
this.selectedOption = null;
},
},
};
</script>
@@ -41,14 +41,6 @@
:chat="group.chat"
@select="selectedAutocomplete"
/>
<emoji-auto-complete
ref="emojiAutocomplete"
:text="newMessage"
:textbox="textbox"
:coords="mixinData.autoComplete.coords"
:caret-position="mixinData.autoComplete.caretPosition"
@select="selectedAutocomplete"
/>
</div>
<community-guidelines />
<div class="row chat-actions">
@@ -98,7 +90,6 @@ import { MAX_MESSAGE_LENGTH } from '@/../../common/script/constants';
import externalLinks from '../../mixins/externalLinks';
import autocomplete from '../chat/autoComplete';
import emojiAutoComplete from '../chat/emojiAutoComplete';
import communityGuidelines from './communityGuidelines';
import chatMessages from '../chat/chatMessages';
import { mapState } from '@/libs/store';
@@ -111,7 +102,6 @@ export default {
},
components: {
autocomplete,
emojiAutoComplete,
communityGuidelines,
chatMessages,
},
+57 -82
View File
@@ -25,61 +25,53 @@
<div class="col-12 col-md-6">
<div class="row icon-row">
<div
class="item-with-icon p-2"
class="item-with-icon"
tabindex="0"
role="button"
@keyup.enter="showMemberModal()"
@click="showMemberModal()"
>
<div class="box-content">
<div class="icon-number-row">
<div
v-if="group.memberCount > 1000"
class="svg-icon shield"
v-html="icons.goldGuildBadgeIcon"
></div>
<div
v-if="group.memberCount > 100 && group.memberCount < 999"
class="svg-icon shield"
v-html="icons.silverGuildBadgeIcon"
></div>
<div
v-if="group.memberCount < 100"
class="svg-icon shield"
v-html="icons.bronzeGuildBadgeIcon"
></div>
<span class="number">{{ group.memberCount | abbrNum }}</span>
</div>
<div
v-once
class="details"
>
{{ $t('memberList') }}
</div>
<div
v-if="group.memberCount > 1000"
class="svg-icon shield"
v-html="icons.goldGuildBadgeIcon"
></div>
<div
v-if="group.memberCount > 100 && group.memberCount < 999"
class="svg-icon shield"
v-html="icons.silverGuildBadgeIcon"
></div>
<div
v-if="group.memberCount < 100"
class="svg-icon shield"
v-html="icons.bronzeGuildBadgeIcon"
></div>
<span class="number">{{ group.memberCount | abbrNum }}</span>
<div
v-once
class="member-list label"
>
{{ $t('memberList') }}
</div>
</div>
<div v-if="!isParty">
<div
class="item-with-icon p-2"
class="item-with-icon"
tabindex="0"
role="button"
@keyup.enter="showGroupGems()"
@click="showGroupGems()"
>
<div class="box-content">
<div class="icon-number-row">
<div
class="svg-icon gem"
v-html="icons.gem"
></div>
<span class="number">{{ group.balance * 4 }}</span>
</div>
<div
v-once
class="details"
>
{{ $t('guildBank') }}
</div>
<div
class="svg-icon gem"
v-html="icons.gem"
></div>
<span class="number">{{ group.balance * 4 }}</span>
<div
v-once
class="label"
>
{{ $t('guildBank') }}
</div>
</div>
</div>
@@ -136,57 +128,35 @@
}
.item-with-icon {
display: inline-block;
border-radius: 2px;
background-color: $white;
background-color: #ffffff;
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
margin-left: 1em;
width: 120px;
height: 76px;
padding: 1em;
text-align: center;
font-size: 20px;
vertical-align: bottom;
overflow: hidden;
position: relative;
min-width: 120px;
height: 76px;
margin-right: 1rem;
.box-content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
width: 100%;
&:last-of-type {
margin-left: 0.5rem;
}
.icon-number-row {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 0.1em;
.number {
font-size: 18px;
font-weight: normal;
margin-left: 0.2em;
}
}
.svg-icon {
width: 24px;
height: 24px;
.svg-icon.shield, .svg-icon.gem {
width: 28px;
height: auto;
margin: 0 auto;
display: inline-block;
vertical-align: bottom;
margin-right: 0.5em;
}
.details {
font-size: 11px;
color: $gray-200;
width: 100%;
padding: 0 4px;
line-height: 1.1;
word-break: break-word;
max-height: 2.2em;
overflow: visible;
.number {
font-size: 22px;
font-weight: bold;
}
.label {
margin-top: .5em;
}
}
@@ -245,6 +215,11 @@
.icon-row {
margin-top: 1em;
justify-content: flex-end;
.number {
font-size: 22px;
font-weight: bold;
}
}
.chat-row {
@@ -182,10 +182,12 @@ export default {
return 'GreyedOut';
},
imageName () {
const substitutionEvent = this.currentEventList?.find(event => moment()
.isBetween(event.start, event.end) && event.spriteSubstitutions);
if (this.isOwned() && substitutionEvent && substitutionEvent.spriteSubstitutions.pets) {
return `stable_${this.foolPet(`Pet-${this.item.key}`, substitutionEvent.spriteSubstitutions.pets)}`;
const foolEvent = this.currentEventList?.find(event => moment()
.isBetween(event.start, event.end) && event.aprilFools);
if (this.isOwned() && foolEvent) {
if (this.isSpecial()) return `stable_${this.foolPet(this.item.key, foolEvent.aprilFools)}`;
const petString = `${this.item.eggKey}-${this.item.key}`;
return `stable_${this.foolPet(petString, foolEvent.aprilFools)}`;
}
if (this.isOwned() || (this.mountOwned() && this.isHatchable())) {
@@ -10,9 +10,6 @@
>
<div class="modal-body">
<news-content ref="newsContent" />
<close-x
@close="dismissAlert()"
/>
</div>
<div class="modal-footer d-flex align-items-center pb-0">
@@ -33,18 +30,12 @@
</template>
<script>
import { mapState } from '@/libs/store';
import newsContent from './newsContent';
import closeX from '../ui/closeX.vue';
export default {
components: {
closeX,
newsContent,
},
computed: {
...mapState({ user: 'user.data' }),
},
methods: {
async onShow () {
this.$refs.newsContent.getPosts();
@@ -330,7 +330,6 @@ export default {
handledNotifications,
isInitialLoadComplete: false,
pendingRebirthNotification: null,
lastShownStreakCount: null, // Track last shown streak to prevent duplicates
};
},
computed: {
@@ -727,24 +726,17 @@ export default {
this.$root.$emit('habitica:won-challenge', notification);
break;
case 'REBIRTH_ACHIEVEMENT':
if (localStorage.getItem('show-rebirth-confirmation') !== 'true') {
if (!this.isInitialLoadComplete) {
this.pendingRebirthNotification = notification;
markAsRead = false;
} else {
this.playSound('Achievement_Unlocked');
this.$root.$emit('bv::show::modal', 'rebirth');
}
if (localStorage.getItem('show-rebirth-confirmation') === 'true') {
markAsRead = false;
} else if (!this.isInitialLoadComplete) {
this.pendingRebirthNotification = notification;
markAsRead = false;
} else {
this.playSound('Achievement_Unlocked');
this.$root.$emit('bv::show::modal', 'rebirth');
}
break;
case 'STREAK_ACHIEVEMENT':
// Client-side deduplication: prevent showing duplicate streak achievements
if (this.lastShownStreakCount === this.user.achievements.streak) {
// Same streak already shown, skip this notification
break;
}
this.lastShownStreakCount = this.user.achievements.streak;
this.text(`${this.$t('streaks')}: ${this.user.achievements.streak}`, () => {
this.$root.$emit('bv::show::modal', 'streak');
}, this.user.preferences.suppressModals.streak);
@@ -42,7 +42,7 @@
:hide-class-badge="true"
:with-background="true"
:override-avatar-gear="getAvatarOverrides(item)"
:sprites-margin="'0px auto 0px -2px'"
:sprites-margin="'0px auto 0px -24px'"
/>
</div>
<item
@@ -37,7 +37,6 @@ export default {
window.location.href = '/';
} else {
window.sessionStorage.setItem('apple-token', response.idToken);
window.sessionStorage.setItem('apple-email', response.email);
window.location.href = '/username';
}
},
@@ -1,6 +1,5 @@
<template>
<div>
<group-plan-selection-modal />
<group-plan-creation-modal />
<div class="d-flex justify-content-center">
<div
@@ -316,12 +315,10 @@
import { setup as setupPayments } from '@/libs/payments';
import paymentsMixin from '../../mixins/payments';
import GroupPlanCreationModal from '../group-plans/groupPlanCreationModal.vue';
import GroupPlanSelectionModal from '../group-plans/groupPlanSelectionModal.vue';
export default {
components: {
GroupPlanCreationModal,
GroupPlanSelectionModal,
},
mixins: [paymentsMixin],
data () {
@@ -362,7 +359,7 @@ export default {
if (this.upgradingGroup._id) {
return this.stripeGroup({ group: this.upgradingGroup, upgrade: true });
}
return this.$root.$emit('bv::show::modal', 'group-plan-selection');
return this.$root.$emit('bv::show::modal', 'create-group');
},
},
};
+19 -3
View File
@@ -348,6 +348,7 @@
import throttle from 'lodash/throttle';
import isEmpty from 'lodash/isEmpty';
import draggable from 'vuedraggable';
import { shouldDo } from '@/../../common/script/cron';
import inAppRewards from '@/../../common/script/libs/inAppRewards';
import taskDefaults from '@/../../common/script/libs/taskDefaults';
import Task from './task';
@@ -481,10 +482,25 @@ export default {
return this.$t('addATask', { type });
},
badgeCount () {
if (this.type === 'reward') {
return 0;
// 0 means the badge will not be shown
// It is shown for the all and due views of dailies
// and for the active and scheduled views of todos.
if (this.type === 'todo' && this.activeFilter.label !== 'complete2') {
return this.taskList.length;
} if (this.type === 'daily') {
if (this.activeFilter.label === 'due') {
return this.taskList.length;
} if (this.activeFilter.label === 'all') {
return this.taskList
.reduce(
(count, t) => (!t.completed
&& shouldDo(new Date(), t, this.getUserPreferences) ? count + 1 : count),
0,
);
}
}
return this.taskList.length;
return 0;
},
},
watch: {
@@ -48,19 +48,11 @@
/>
<input
:ref="'checklistItem-' + $index"
v-model="item.text"
class="inline-edit-input checklist-item form-control"
type="text"
:disabled="disabled || disableEdit"
:class="summaryClass(item)"
@focus="setActiveItem($index)"
@keydown="autoCompleteMixinUpdateCarretPosition"
@keydown.tab="autoCompleteMixinHandleTab($event)"
@keydown.up="autoCompleteMixinSelectPreviousAutocomplete($event)"
@keydown.down="autoCompleteMixinSelectNextAutocomplete($event)"
@keypress.enter="autoCompleteMixinSelectAutocomplete($event)"
@keydown.esc="autoCompleteMixinHandleEscape($event)"
>
<span
v-if="!disabled && !disableEdit"
@@ -89,30 +81,15 @@
</span>
<input
ref="newChecklistInput"
v-model="newChecklistItem"
class="inline-edit-input checklist-item form-control"
type="text"
:placeholder="$t('newChecklistItem')"
@focus="setActiveItem(-1)"
@keydown="autoCompleteMixinUpdateCarretPosition"
@keydown.tab="autoCompleteMixinHandleTab($event)"
@keydown.up="autoCompleteMixinSelectPreviousAutocomplete($event)"
@keydown.down="autoCompleteMixinSelectNextAutocomplete($event)"
@keypress.enter="newChecklistEnterHandler($event)"
@keypress.enter="setHasPossibilityOfIMEConversion(false)"
@keyup.enter="addChecklistItem($event, true)"
@keydown.esc="autoCompleteMixinHandleEscape($event)"
@blur="addChecklistItem($event, false)"
>
</div>
<emoji-auto-complete
ref="emojiAutocomplete"
:text="activeFieldText"
:textbox="textbox"
:coords="mixinData.autoComplete.coords"
:caret-position="mixinData.autoComplete.caretPosition"
@select="selectedAutocomplete"
/>
</b-collapse>
</div>
</template>
@@ -128,8 +105,6 @@ import chevronIcon from '@/assets/svg/chevron.svg?raw';
import gripIcon from '@/assets/svg/grip.svg?raw';
import checkbox from '@/components/ui/checkbox';
import lockableLabel from './lockableLabel';
import emojiAutoComplete from '@/components/chat/emojiAutoComplete';
import { autoCompleteHelperMixin } from '@/mixins/autoCompleteHelper';
export default {
name: 'Checklist',
@@ -137,9 +112,7 @@ export default {
checkbox,
draggable,
lockableLabel,
emojiAutoComplete,
},
mixins: [autoCompleteHelperMixin],
props: {
disabled: {
type: Boolean,
@@ -160,8 +133,6 @@ export default {
showChecklist: true,
hasPossibilityOfIMEConversion: true,
newChecklistItem: null,
textbox: null,
activeItemIndex: -1,
icons: Object.freeze({
positive: positiveIcon,
destroy: deleteIcon,
@@ -170,15 +141,6 @@ export default {
}),
};
},
computed: {
activeFieldText () {
if (this.activeItemIndex === -1) {
return this.newChecklistItem || '';
}
const item = this.checklist[this.activeItemIndex];
return item ? item.text || '' : '';
},
},
methods: {
summaryClass (item) {
if (!this.disableEdit) return '';
@@ -217,40 +179,6 @@ export default {
this.checklist.splice(i, 1);
this.updateChecklist();
},
setActiveItem (index) {
this.activeItemIndex = index;
if (index === -1) {
this.textbox = this.$refs.newChecklistInput;
} else {
const refArr = this.$refs[`checklistItem-${index}`];
this.textbox = refArr ? refArr[0] || refArr : null;
}
},
newChecklistEnterHandler (e) {
const ac = this._getActiveAutocomplete();
if (ac && ac.selected !== null) {
e.preventDefault();
ac.makeSelection();
} else if (ac) {
ac.cancel();
this.setHasPossibilityOfIMEConversion(false);
} else {
this.setHasPossibilityOfIMEConversion(false);
}
},
selectedAutocomplete (newText, newCaret) {
if (this.activeItemIndex === -1) {
this.newChecklistItem = newText;
} else {
this.checklist[this.activeItemIndex].text = newText;
}
this.$nextTick(() => {
if (this.textbox) {
this.textbox.setSelectionRange(newCaret, newCaret);
this.textbox.focus();
}
});
},
},
};
</script>
@@ -259,7 +187,6 @@ export default {
@import '@/assets/scss/colors.scss';
.checklist-component {
position: relative;
.chevron-flip {
transform: translateY(-5px) rotate(180deg);
@@ -9,27 +9,12 @@
@toggle="openOrClose($event)"
>
<b-dropdown-header>
<div class="mb-2 search-input-wrapper">
<div class="mb-2">
<b-form-input
ref="searchInput"
v-model="search"
type="text"
:placeholder="searchPlaceholder"
@focus="setTextbox"
@keydown="autoCompleteMixinUpdateCarretPosition"
@keydown.tab="autoCompleteMixinHandleTab($event)"
@keydown.up="autoCompleteMixinSelectPreviousAutocomplete($event)"
@keydown.down="autoCompleteMixinSelectNextAutocomplete($event)"
@keydown.enter="searchEnterHandler($event)"
@keydown.esc="searchEscHandler($event)"
/>
<emoji-auto-complete
ref="emojiAutocomplete"
:text="search"
:textbox="textbox"
:coords="mixinData.autoComplete.coords"
:caret-position="mixinData.autoComplete.caretPosition"
@select="selectedAutocomplete"
@keyup.enter="handleSubmit"
/>
</div>
@@ -56,7 +41,7 @@
v-if="addNew || availableToSelect.length > 0"
:class="{
'item-group': true,
'add-new': search !== '' && !hasExactMatch,
'add-new': availableToSelect.length === 0 && search !== '',
'scroll': availableToSelect.length > 5
}"
>
@@ -86,7 +71,7 @@
</b-dropdown-item-button>
<div
v-if="addNew && search !== '' && !hasExactMatch"
v-if="addNew"
class="hint"
>
{{ $t('pressEnterToAddTag', { tagName: search }) }}
@@ -109,10 +94,6 @@ $itemHeight: 2rem;
}
.select-multi {
.search-input-wrapper {
position: relative;
}
.dropdown-toggle {
padding-left: 0.75rem;
}
@@ -171,8 +152,7 @@ $itemHeight: 2rem;
max-height: #{5*$itemHeight};
&.add-new {
min-height: 30px;
height: auto;
height: 30px;
.hint {
display: block;
@@ -205,8 +185,6 @@ $itemHeight: 2rem;
import Vue from 'vue';
import MultiList from '@/components/tasks/modal-controls/multiList';
import markdownDirective from '@/directives/markdown';
import emojiAutoComplete from '@/components/chat/emojiAutoComplete';
import { autoCompleteHelperMixin } from '@/mixins/autoCompleteHelper';
export default {
directives: {
@@ -214,9 +192,7 @@ export default {
},
components: {
MultiList,
emojiAutoComplete,
},
mixins: [autoCompleteHelperMixin],
props: {
addNew: {
type: Boolean,
@@ -245,8 +221,6 @@ export default {
wasTagAdded: false,
selected: this.selectedItems,
search: '',
textbox: null,
itemsAdded: [],
};
},
computed: {
@@ -274,16 +248,6 @@ export default {
return filteredItems;
},
hasExactMatch () {
const searchTerm = this.search.trim().toLowerCase();
if (!searchTerm) return false;
if (this.itemsAdded.indexOf(searchTerm) !== -1) return true;
if (this.availableToSelect.length === 0) return false;
if (this.availableToSelect[0].name.toLowerCase() === searchTerm) {
return true;
}
return false;
},
},
watch: {
selected () {
@@ -322,7 +286,6 @@ export default {
this.closeSelectPopup();
},
selectItem (item) {
if (!item) return;
this.selectedItems.push(item.id);
this.$emit('toggle', item.id);
this.preventHide = true;
@@ -349,51 +312,12 @@ export default {
this.closeSelectPopup();
}
},
setTextbox () {
const ref = this.$refs.searchInput;
this.textbox = ref ? (ref.$el || ref) : null;
},
searchEnterHandler (e) {
const ac = this._getActiveAutocomplete();
if (ac && ac.selected !== null) {
e.preventDefault();
e.stopPropagation();
ac.makeSelection();
} else {
if (ac) ac.cancel();
this.handleSubmit();
}
},
searchEscHandler (e) {
const ac = this._getActiveAutocomplete();
if (ac && ac.searchActive) {
e.preventDefault();
e.stopPropagation();
ac.cancel();
}
},
selectedAutocomplete (newText, newCaret) {
this.search = newText;
this.$nextTick(() => {
if (this.textbox) {
this.textbox.setSelectionRange(newCaret, newCaret);
this.textbox.focus();
}
});
},
handleSubmit () {
if (!this.addNew) return;
const { search } = this;
// If there is a existing tag
if (this.hasExactMatch) {
this.selectItem(this.availableToSelect[0]);
this.search = '';
} else {
// Creating a new tag as there is no existing tag present
this.$emit('addNew', search);
this.itemsAdded.push(search.toLowerCase());
this.search = '';
}
this.$emit('addNew', search);
this.search = '';
},
},
};
@@ -70,13 +70,6 @@
spellcheck="true"
:disabled="challengeAccessRequired"
:placeholder="$t('addATitle')"
@focus="setActiveField('title')"
@keydown="autoCompleteMixinUpdateCarretPosition"
@keydown.tab="autoCompleteMixinHandleTab($event)"
@keydown.up="autoCompleteMixinSelectPreviousAutocomplete($event)"
@keydown.down="autoCompleteMixinSelectNextAutocomplete($event)"
@keypress.enter="titleEnterHandler($event)"
@keydown.esc="autoCompleteMixinHandleEscape($event)"
>
</div>
<div
@@ -99,27 +92,11 @@
</small>
</div>
<textarea
ref="notesTextarea"
v-model="task.notes"
class="form-control input-notes"
:class="cssClass('input')"
:placeholder="$t('addNotes')"
@focus="setActiveField('notes')"
@keydown="autoCompleteMixinUpdateCarretPosition"
@keydown.tab="autoCompleteMixinHandleTab($event)"
@keydown.up="autoCompleteMixinSelectPreviousAutocomplete($event)"
@keydown.down="autoCompleteMixinSelectNextAutocomplete($event)"
@keypress.enter="autoCompleteMixinSelectAutocomplete($event)"
@keydown.esc="autoCompleteMixinHandleEscape($event)"
></textarea>
<emoji-auto-complete
ref="emojiAutocomplete"
:text="activeFieldText"
:textbox="textbox"
:coords="mixinData.autoComplete.coords"
:caret-position="mixinData.autoComplete.caretPosition"
@select="selectedAutocomplete"
/>
</div>
</div>
<div
@@ -382,12 +359,6 @@
</div>
</div>
</div>
<p
v-if="task.type === 'daily' && schedulingSummary"
class="scheduling-summary text-center mt-2 mb-0"
>
{{ schedulingSummary }}
</p>
<div
v-if="!groupId"
class="tags-select option mt-3"
@@ -741,7 +712,6 @@
}
.task-modal-header {
position: relative;
color: $white;
width: 100%;
border-top-left-radius: 8px;
@@ -1071,12 +1041,6 @@
height: 1rem;
}
.scheduling-summary {
font-size: 12px;
line-height: 1.33;
color: $gray-200;
}
label {
display: inline-flex;
align-items: center;
@@ -1196,8 +1160,6 @@ import lockableLabel from '@/components/tasks/modal-controls/lockableLabel';
import selectList from '@/components/ui/selectList';
import syncTask from '../../mixins/syncTask';
import emojiAutoComplete from '@/components/chat/emojiAutoComplete';
import { autoCompleteHelperMixin } from '@/mixins/autoCompleteHelper';
import positiveIcon from '@/assets/svg/positive.svg?raw';
import negativeIcon from '@/assets/svg/negative.svg?raw';
@@ -1220,18 +1182,15 @@ export default {
toggleCheckbox,
lockableLabel,
selectList,
emojiAutoComplete,
},
directives: {
markdown: markdownDirective,
},
mixins: [syncTask, autoCompleteHelperMixin],
mixins: [syncTask],
// purpose is either create or edit, task is the task created or edited
props: ['task', 'purpose', 'challengeId', 'groupId'],
data () {
return {
textbox: null,
activeField: 'title',
showAssignedSelect: false,
newChecklistItem: null,
icons: Object.freeze({
@@ -1338,84 +1297,6 @@ export default {
}
return null;
},
schedulingSummary () {
if (!this.task || this.task.type !== 'daily') return '';
const { task } = this;
const everyXValue = +task.everyX;
let interval;
if (task.frequency === 'daily') {
interval = everyXValue === 1 ? this.$t('everyDay') : `${this.$t('every')} ${everyXValue} ${this.$t('days')}`;
} else if (task.frequency === 'weekly') {
interval = everyXValue === 1 ? this.$t('everyWeek') : `${this.$t('every')} ${everyXValue} ${this.$t('weeks')}`;
} else if (task.frequency === 'monthly') {
interval = everyXValue === 1 ? this.$t('everyMonth') : this.$t('everyXMonths', { count: everyXValue });
} else if (task.frequency === 'yearly') {
interval = everyXValue === 1 ? this.$t('everyYear') : `${this.$t('every')} ${everyXValue} ${this.$t('years')}`;
} else {
return '';
}
let details = '';
if (task.frequency === 'weekly') {
const dayNames = {
su: 'Sunday',
m: 'Monday',
t: 'Tuesday',
w: 'Wednesday',
th: 'Thursday',
f: 'Friday',
s: 'Saturday',
};
const activeDays = Object.keys(task.repeat || {}).filter(d => task.repeat[d]);
if (activeDays.length > 0) {
details = ` on ${activeDays.map(d => dayNames[d]).join(', ')}`;
}
} else if (task.frequency === 'monthly' && task.startDate) {
const dayOfMonth = moment(task.startDate).date();
if (task.weeksOfMonth && task.weeksOfMonth.length > 0) {
const weekNum = task.weeksOfMonth[0] + 1;
const weekStr = String(weekNum);
const lastDigit = weekStr.slice(-1);
let suffix = 'th';
if (lastDigit === '1' && weekStr !== '11') suffix = 'st';
if (lastDigit === '2' && weekStr !== '12') suffix = 'nd';
if (lastDigit === '3' && weekStr !== '13') suffix = 'rd';
const dayName = moment(task.startDate).format('dddd');
details = ` on the ${weekNum}${suffix} ${dayName} of the month`;
} else if (task.daysOfMonth && task.daysOfMonth.length > 0) {
const dom = task.daysOfMonth[0];
const domStr = String(dom);
const lastDigit = domStr.slice(-1);
let suffix = 'th';
if (lastDigit === '1' && domStr !== '11') suffix = 'st';
if (lastDigit === '2' && domStr !== '12') suffix = 'nd';
if (lastDigit === '3' && domStr !== '13') suffix = 'rd';
details = ` on the ${dom}${suffix}`;
} else {
const domStr = String(dayOfMonth);
const lastDigit = domStr.slice(-1);
let suffix = 'th';
if (lastDigit === '1' && domStr !== '11') suffix = 'st';
if (lastDigit === '2' && domStr !== '12') suffix = 'nd';
if (lastDigit === '3' && domStr !== '13') suffix = 'rd';
details = ` on the ${dayOfMonth}${suffix}`;
}
} else if (task.frequency === 'yearly' && task.startDate) {
details = ` on ${moment(task.startDate).format('MMMM Do')}`;
}
let summary = `${this.$t('repeats')} ${interval}${details}`;
if (task.frequency === 'monthly'
&& task.weeksOfMonth && task.weeksOfMonth.length > 0
&& task.weeksOfMonth[0] === 4) {
const dayName = moment(task.startDate).format('dddd');
summary += `. ${this.$t('fifthWeekWarning', { day: dayName })}`;
}
return summary;
},
repeatsOn: {
get () {
let repeatsOn = 'dayOfMonth';
@@ -1433,10 +1314,6 @@ export default {
selectedTags () {
return this.getTagsFor(this.task);
},
activeFieldText () {
if (!this.task) return '';
return this.activeField === 'title' ? (this.task.text || '') : (this.task.notes || '');
},
showStatAssignment () {
return this.task.type !== 'reward'
&& !this.groupId
@@ -1612,35 +1489,6 @@ export default {
},
focusInput () {
this.$refs.inputToFocus.focus();
this.setActiveField('title');
},
setActiveField (field) {
this.activeField = field;
if (field === 'title') {
this.textbox = this.$refs.inputToFocus;
} else {
this.textbox = this.$refs.notesTextarea;
}
},
titleEnterHandler (e) {
const ac = this._getActiveAutocomplete();
if (ac && ac.selected !== null) {
e.preventDefault();
ac.makeSelection();
} else if (ac) {
ac.cancel();
}
},
selectedAutocomplete (newText, newCaret) {
if (this.activeField === 'title') {
this.task.text = newText;
} else {
this.task.notes = newText;
}
this.$nextTick(() => {
this.textbox.setSelectionRange(newCaret, newCaret);
this.textbox.focus();
});
},
async addTag (name) {
const tagResult = await this.createTag({ name });
@@ -222,22 +222,14 @@ export default {
return usernames;
},
summarySentence () {
let fifthWeekWarning = '';
if (this.task.type === 'daily' && this.task.frequency === 'monthly'
&& this.task.weeksOfMonth && this.task.weeksOfMonth.length > 0
&& this.task.weeksOfMonth[0] === 4) {
const activeDays = keys(pickBy(this.task.repeat, value => value === true));
const dayName = this.expandDayString[activeDays[0]];
fifthWeekWarning = ` ${this.$t('fifthWeekWarning', { day: dayName })}`;
}
if (this.task.type === 'daily' && moment().isBefore(this.task.startDate)) {
return `This is ${this.formattedDifficulty(this.task.priority)} task that will repeat
${this.formattedRepeatInterval(this.task.frequency, this.task.everyX)}${this.formattedDays(this.task.frequency, this.task.repeat, this.task.daysOfMonth, this.task.weeksOfMonth, this.task.startDate)}
starting on <strong>${moment(this.task.startDate).format('MM/DD/YYYY')}</strong>.${fifthWeekWarning}`;
starting on <strong>${moment(this.task.startDate).format('MM/DD/YYYY')}</strong>.`;
}
if (this.task.type === 'daily') {
return `This is ${this.formattedDifficulty(this.task.priority)} task that repeats
${this.formattedRepeatInterval(this.task.frequency, this.task.everyX)}${this.formattedDays(this.task.frequency, this.task.repeat, this.task.daysOfMonth, this.task.weeksOfMonth, this.task.startDate)}.${fifthWeekWarning}`;
${this.formattedRepeatInterval(this.task.frequency, this.task.everyX)}${this.formattedDays(this.task.frequency, this.task.repeat, this.task.daysOfMonth, this.task.weeksOfMonth, this.task.startDate)}.`;
}
if (this.task.date) {
return `This is ${this.formattedDifficulty(this.task.priority)} task that is due <strong>${moment(this.task.date).format('MM/DD/YYYY')}.`;
@@ -295,14 +287,25 @@ export default {
});
dayStringArray.push('</strong>');
} else if (weeksOfMonth.length > 0) {
const weekNum = weeksOfMonth[0] + 1;
const weekNumStr = String(weekNum);
const lastDigit = weekNumStr.slice(-1);
let ordinalSuffix = 'th';
if (lastDigit === '1' && weekNumStr !== '11') ordinalSuffix = 'st';
if (lastDigit === '2' && weekNumStr !== '12') ordinalSuffix = 'nd';
if (lastDigit === '3' && weekNumStr !== '13') ordinalSuffix = 'rd';
dayStringArray.push(`${weekNum}${ordinalSuffix}`);
switch (weeksOfMonth[0]) {
case 0:
dayStringArray.push('first');
break;
case 1:
dayStringArray.push('second');
break;
case 2:
dayStringArray.push('third');
break;
case 3:
dayStringArray.push('fourth');
break;
case 4:
dayStringArray.push('fifth');
break;
default:
break;
}
activeDays = keys(pickBy(repeat, value => value === true));
dayStringArray.push(` ${this.expandDayString[activeDays[0]]} of the month</strong>`);
}
@@ -340,8 +343,9 @@ export default {
if (numericX === 2) return '<strong>every other week</strong>';
return `<strong>every ${numericX} weeks</strong>`;
case 'monthly':
if (numericX === 1) return `<strong>${this.$t('everyMonth')}</strong>`;
return `<strong>${this.$t('everyXMonths', { count: numericX })}</strong>`;
if (numericX === 1) return '<strong>every month</strong>';
if (numericX === 2) return '<strong>every other month</strong>';
return `<strong>every ${numericX} months</strong>`;
case 'yearly':
if (numericX === 1) return '<strong>every year</strong>';
return `<strong>every ${everyX} years</strong>`;
+1 -75
View File
@@ -80,17 +80,9 @@
v-html="icons.drag"
></div>
<input
:ref="'tagInput-' + tagIndex"
v-model="tag.name"
class="tag-edit-input inline-edit-input form-control"
type="text"
@focus="setActiveTag(tagIndex)"
@keydown="autoCompleteMixinUpdateCarretPosition"
@keydown.tab="autoCompleteMixinHandleTab($event)"
@keydown.up="autoCompleteMixinSelectPreviousAutocomplete($event)"
@keydown.down="autoCompleteMixinSelectNextAutocomplete($event)"
@keypress.enter="autoCompleteMixinSelectAutocomplete($event)"
@keydown.esc="autoCompleteMixinHandleEscape($event)"
>
<div
class="input-group-append"
@@ -108,18 +100,11 @@
class="col-6 dragSpace"
>
<input
ref="newTagInput"
v-model="newTag"
class="new-tag-item edit-tag-item inline-edit-input form-control"
type="text"
:placeholder="$t('newTag')"
@focus="setActiveTag(-1)"
@keydown="autoCompleteMixinUpdateCarretPosition"
@keydown.tab="autoCompleteMixinHandleTab($event)"
@keydown.up="autoCompleteMixinSelectPreviousAutocomplete($event)"
@keydown.down="autoCompleteMixinSelectNextAutocomplete($event)"
@keypress.enter="newTagEnterHandler($event, tagsType.key)"
@keydown.esc="autoCompleteMixinHandleEscape($event)"
@keydown.enter="addTag($event, tagsType.key)"
>
</div>
</draggable>
@@ -149,15 +134,6 @@
</div>
</div>
</div>
<emoji-auto-complete
v-if="editingTags"
ref="emojiAutocomplete"
:text="activeTagText"
:textbox="textbox"
:coords="mixinData.autoComplete.coords"
:caret-position="mixinData.autoComplete.caretPosition"
@select="selectedTagAutocomplete"
/>
<div class="filter-panel-footer clearfix">
<template v-if="editingTags === true">
<div class="text-center">
@@ -429,8 +405,6 @@ import dragIcon from '@/assets/svg/drag_indicator.svg?raw';
import { mapState, mapActions } from '@/libs/store';
import brokenTaskModal from './brokenTaskModal';
import emojiAutoComplete from '@/components/chat/emojiAutoComplete';
import { autoCompleteHelperMixin } from '@/mixins/autoCompleteHelper';
export default {
components: {
@@ -440,12 +414,10 @@ export default {
spells,
brokenTaskModal,
draggable,
emojiAutoComplete,
},
directives: {
markdown,
},
mixins: [autoCompleteHelperMixin],
data () {
return {
columns: ['habit', 'daily', 'todo', 'reward'],
@@ -473,19 +445,10 @@ export default {
newTag: null,
editingTask: null,
creatingTask: null,
textbox: null,
activeTagIndex: -1,
};
},
computed: {
...mapState({ user: 'user.data' }),
activeTagText () {
if (this.activeTagIndex === -1) {
return this.newTag || '';
}
const tag = this.tagsSnap.tags[this.activeTagIndex];
return tag ? tag.name || '' : '';
},
tagsByType () {
const userTags = this.user.tags;
const tagsByType = {
@@ -551,43 +514,6 @@ export default {
this.tagsSnap[key].push({ id: uuid(), name: this.newTag });
this.newTag = null;
},
setActiveTag (index) {
this.activeTagIndex = index;
if (index === -1) {
const refArr = this.$refs.newTagInput;
this.textbox = Array.isArray(refArr) ? refArr[0] : refArr;
} else {
const refArr = this.$refs[`tagInput-${index}`];
if (!refArr) {
this.textbox = null;
} else {
this.textbox = Array.isArray(refArr) ? refArr[0] : refArr;
}
}
},
newTagEnterHandler (e, key) {
const ac = this._getActiveAutocomplete();
if (ac && ac.selected !== null) {
e.preventDefault();
ac.makeSelection();
} else {
if (ac) ac.cancel();
this.addTag(e, key);
}
},
selectedTagAutocomplete (newText, newCaret) {
if (this.activeTagIndex === -1) {
this.newTag = newText;
} else {
this.tagsSnap.tags[this.activeTagIndex].name = newText;
}
this.$nextTick(() => {
if (this.textbox) {
this.textbox.setSelectionRange(newCaret, newCaret);
this.textbox.focus();
}
});
},
removeTag (index, key) {
const tagId = this.tagsSnap[key][index].id;
const indexInSelected = this.selectedTags.indexOf(tagId);
@@ -1,92 +0,0 @@
<template>
<div
class="selectable-card"
:class="{ selected }"
@click="$emit('click')"
>
<div
v-if="selected"
class="checkmark-corner"
>
<div
class="svg-icon check-icon"
v-html="icons.check"
></div>
</div>
<slot></slot>
</div>
</template>
<style lang="scss" scoped>
@import '@/assets/scss/colors.scss';
.selectable-card {
position: relative;
background: $white;
border: 1px solid $gray-400;
border-radius: 8px;
padding: 16px;
cursor: pointer;
box-shadow: 0px 1px 2px 0px rgba(26, 24, 29, 0.08);
&:hover {
box-shadow: 0px 3px 6px 0px rgba(26, 24, 29, 0.16), 0px 3px 6px 0px rgba(26, 24, 29, 0.24);
}
&.selected {
border: 2px solid $purple-300;
padding: 15px;
box-shadow: 0px 3px 6px 0px rgba(26, 24, 29, 0.16), 0px 3px 6px 0px rgba(26, 24, 29, 0.24);
}
}
.checkmark-corner {
position: absolute;
top: 0;
left: 0;
width: 48px;
height: 48px;
overflow: hidden;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
border-style: solid;
border-width: 48px 48px 0 0;
border-color: $purple-300 transparent transparent transparent;
border-radius: 6px 0 0 0;
}
.check-icon {
position: absolute;
top: 8px;
left: 8px;
width: 16px;
height: 16px;
color: $white;
}
}
</style>
<script>
import svgCheck from '@/assets/svg/check.svg?raw';
export default {
props: {
selected: {
type: Boolean,
default: false,
},
},
emits: ['click'],
data () {
return {
icons: Object.freeze({
check: svgCheck,
}),
};
},
};
</script>
@@ -398,29 +398,14 @@
:placeholder="$t('imageUrl')"
>
</div>
<div class="form-group" style="position: relative;">
<div class="form-group">
<label>{{ $t('about') }}</label>
<textarea
ref="blurbTextarea"
v-model="editingProfile.blurb"
class="form-control"
rows="5"
:placeholder="$t('displayBlurbPlaceholder')"
@keydown="autoCompleteMixinUpdateCarretPosition"
@keydown.tab="autoCompleteMixinHandleTab($event)"
@keydown.up="autoCompleteMixinSelectPreviousAutocomplete($event)"
@keydown.down="autoCompleteMixinSelectNextAutocomplete($event)"
@keypress.enter="autoCompleteMixinSelectAutocomplete($event)"
@keydown.esc="autoCompleteMixinHandleEscape($event)"
></textarea>
<emoji-auto-complete
ref="emojiAutocomplete"
:text="editingProfile.blurb"
:textbox="textbox"
:coords="mixinData.autoComplete.coords"
:caret-position="mixinData.autoComplete.caretPosition"
@select="selectedAutocomplete"
/>
<!-- include ../../shared/formatting-help-->
</div>
</div>
@@ -1016,8 +1001,6 @@ import mute from '@/assets/svg/mute.svg?raw';
import shadowMute from '@/assets/svg/shadow-mute.svg?raw';
import externalLinks from '../../mixins/externalLinks';
import { userCustomStateMixin } from '../../mixins/userState';
import emojiAutoComplete from '@/components/chat/emojiAutoComplete';
import { autoCompleteHelperMixin } from '@/mixins/autoCompleteHelper';
// @TODO: EMAILS.COMMUNITY_MANAGER_EMAIL
const COMMUNITY_MANAGER_EMAIL = 'admin@habitica.com';
@@ -1029,9 +1012,8 @@ export default {
MemberDetails,
profileStats,
toggleSwitch,
emojiAutoComplete,
},
mixins: [externalLinks, userCustomStateMixin('userLoggedIn'), autoCompleteHelperMixin],
mixins: [externalLinks, userCustomStateMixin('userLoggedIn')],
props: ['userId', 'startingPage'],
data () {
return {
@@ -1051,7 +1033,6 @@ export default {
mute,
shadowMute,
}),
textbox: null,
userIdToMessage: '',
editing: false,
editingProfile: {
@@ -1140,13 +1121,6 @@ export default {
userLoggedIn () {
this.loadUser();
},
editing (val) {
if (val) {
this.$nextTick(() => {
this.textbox = this.$refs.blurbTextarea;
});
}
},
},
mounted () {
this.loadUser();
@@ -1357,13 +1331,6 @@ export default {
this.$emit('toggled', this.isOpened);
},
selectedAutocomplete (newText, newCaret) {
this.editingProfile.blurb = newText;
this.$nextTick(() => {
this.textbox.setSelectionRange(newCaret, newCaret);
this.textbox.focus();
});
},
reportPlayer () {
this.$root.$emit('habitica::report-profile', {
memberId: this.user._id,
@@ -1373,7 +1340,7 @@ export default {
},
openAdminPanel () {
this.$router.push(`/admin/panel/${this.hero._id}`);
this.$router.push(`/admin-panel/${this.hero._id}`);
},
},
};
@@ -246,9 +246,7 @@
:class="{white: user.preferences.background}"
style="overflow:hidden"
>
<Sprite
v-if="user.preferences.background && user.preferences.background !== ''"
:image-name="'icon_background_' + user.preferences.background" />
<Sprite :image-name="'icon_background_' + user.preferences.background" />
</div>
<b-popover
v-if="label !== 'skip'
+14 -28
View File
@@ -15,60 +15,46 @@ export const autoCompleteHelperMixin = {
};
},
methods: {
_getActiveAutocomplete () {
if (this.$refs.autocomplete && this.$refs.autocomplete.searchActive) {
return this.$refs.autocomplete;
}
if (this.$refs.emojiAutocomplete && this.$refs.emojiAutocomplete.searchActive) {
return this.$refs.emojiAutocomplete;
}
return null;
},
autoCompleteMixinHandleTab (e) {
const ac = this._getActiveAutocomplete();
if (ac) {
if (this.$refs.autocomplete.searchActive) {
e.preventDefault();
if (e.shiftKey) {
ac.selectPrevious();
this.$refs.autocomplete.selectPrevious();
} else {
ac.selectNext();
this.$refs.autocomplete.selectNext();
}
}
},
autoCompleteMixinHandleEscape (e) {
const ac = this._getActiveAutocomplete();
if (ac) {
if (this.$refs.autocomplete.searchActive) {
e.preventDefault();
ac.cancel();
this.$refs.autocomplete.cancel();
}
},
autoCompleteMixinSelectNextAutocomplete (e) {
const ac = this._getActiveAutocomplete();
if (ac) {
if (this.$refs.autocomplete.searchActive) {
e.preventDefault();
ac.selectNext();
this.$refs.autocomplete.selectNext();
}
},
autoCompleteMixinSelectPreviousAutocomplete (e) {
const ac = this._getActiveAutocomplete();
if (ac) {
if (this.$refs.autocomplete.searchActive) {
e.preventDefault();
ac.selectPrevious();
this.$refs.autocomplete.selectPrevious();
}
},
autoCompleteMixinSelectAutocomplete (e) {
const ac = this._getActiveAutocomplete();
if (ac) {
if (ac.selected !== null) {
if (this.$refs.autocomplete.searchActive) {
if (this.$refs.autocomplete.selected !== null) {
e.preventDefault();
ac.makeSelection();
this.$refs.autocomplete.makeSelection();
} else {
ac.cancel();
// no autocomplete selected, newline instead
this.$refs.autocomplete.cancel();
}
}
},
+50 -8
View File
@@ -1,14 +1,56 @@
import includes from 'lodash/includes';
export default {
methods: {
foolPet (pet, substitutions) {
if (!pet || pet === 'Pet-') return substitutions.noPet;
if (substitutions[pet]) return substitutions[pet];
for (const key in substitutions) {
if (pet.startsWith(key)) {
return substitutions[key];
}
foolPet (pet, prank) {
const SPECIAL_PETS = [
'Bear-Veteran',
'BearCub-Polar',
'Cactus-Veteran',
'Dragon-Hydra',
'Dragon-Veteran',
'Fox-Veteran',
'Gryphatrice-Jubilant',
'Gryphon-Gryphatrice',
'Gryphon-RoyalPurple',
'Hippogriff-Hopeful',
'Jackalope-RoyalPurple',
'JackOLantern-Base',
'JackOLantern-Ghost',
'JackOLantern-Glow',
'JackOLantern-RoyalPurple',
'Lion-Veteran',
'MagicalBee-Base',
'Mammoth-Base',
'MantisShrimp-Base',
'Orca-Base',
'Phoenix-Base',
'Tiger-Veteran',
'Turkey-Base',
'Turkey-Gilded',
'Wolf-Cerberus',
'Wolf-Veteran',
];
const BASE_PETS = [
'BearCub',
'Cactus',
'Dragon',
'FlyingPig',
'Fox',
'LionCub',
'PandaCub',
'TigerCub',
'Wolf',
];
if (!pet) return `Pet-TigerCub-${prank}`;
if (SPECIAL_PETS.indexOf(pet) !== -1) {
return `Pet-Dragon-${prank}`;
}
return substitutions.default;
const species = pet.slice(0, pet.indexOf('-'));
if (includes(BASE_PETS, species)) {
return `Pet-${species}-${prank}`;
}
return `Pet-BearCub-${prank}`;
},
},
};
@@ -153,23 +153,9 @@
:placeholder="$t('needsTextPlaceholder')"
:maxlength="MAX_MESSAGE_LENGTH"
:class="{'has-content': newMessage.trim() !== '', 'disabled': newMessageDisabled}"
@keydown="autoCompleteMixinUpdateCarretPosition"
@keyup.ctrl.enter="sendPrivateMessage()"
@keydown.tab="autoCompleteMixinHandleTab($event)"
@keydown.up="autoCompleteMixinSelectPreviousAutocomplete($event)"
@keydown.down="autoCompleteMixinSelectNextAutocomplete($event)"
@keypress.enter="autoCompleteMixinSelectAutocomplete($event)"
@keydown.esc="autoCompleteMixinHandleEscape($event)"
>
</textarea>
<emoji-auto-complete
ref="emojiAutocomplete"
:text="newMessage"
:textbox="textbox"
:coords="mixinData.autoComplete.coords"
:caret-position="mixinData.autoComplete.caretPosition"
@select="selectedAutocomplete"
/>
</div>
<div
class="sub-new-message-row d-flex"
@@ -554,7 +540,6 @@ h3 {
}
.new-message-row {
position: relative;
width: 100%;
padding-left: 1.5rem;
padding-top: 1.5rem;
@@ -691,8 +676,6 @@ import PmNewMessageStarted from './pm-new-message-started.vue';
import StartNewConversationInputHeader from './start-new-conversation-input-header.vue';
import positiveIcon from '@/assets/svg/positive.svg?raw';
import NotificationMixins from '@/mixins/notifications';
import emojiAutoComplete from '@/components/chat/emojiAutoComplete';
import { autoCompleteHelperMixin } from '@/mixins/autoCompleteHelper';
// extract to a shared path
const CONVERSATIONS_PER_PAGE = 10;
@@ -717,14 +700,13 @@ export default defineComponent({
toggleSwitch,
userLink,
faceAvatar,
emojiAutoComplete,
},
filters: {
timeAgo (value) {
return moment(new Date(value)).fromNow();
},
},
mixins: [styleHelper, NotificationMixins, autoCompleteHelperMixin],
mixins: [styleHelper, NotificationMixins],
beforeRouteEnter (to, from, next) {
next(vm => {
const data = vm.$store.state.privateMessageOptions;
@@ -769,7 +751,6 @@ export default defineComponent({
/** @type {Record<string, PrivateMessages.PrivateMessageEntry[]>} */
messagesByConversation: {}, // cache {uuid: []}
textbox: null,
newMessage: '',
messages: [],
messagesLoading: false,
@@ -982,15 +963,6 @@ export default defineComponent({
}
},
},
watch: {
shouldShowInputPanel (val) {
if (val) {
this.$nextTick(() => {
this.textbox = this.$refs.textarea;
});
}
},
},
async mounted () {
this.$store.dispatch('common:setTitle', {
section: this.$t('messages'),
@@ -1252,13 +1224,6 @@ export default defineComponent({
triggerStartNewConversationState () {
this.showStartNewConversationInput = true;
},
selectedAutocomplete (newText, newCaret) {
this.newMessage = newText;
this.$nextTick(() => {
this.textbox.setSelectionRange(newCaret, newCaret);
this.textbox.focus();
});
},
async startConversationByUsername (targetUserName) {
// check if the target user exists in current conversations, select that conversation
/** @type {PrivateMessages.ConversationSummaryMessageEntry} */
-4
View File
@@ -295,10 +295,6 @@ export default {
appState = JSON.parse(appState);
if (appState.paymentCompleted) {
removeLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE);
if (appState.paymentType === 'groupPlan') {
this.$store.state.upgradingGroup = {};
this.$store.dispatch('guilds:getGroupPlans', true);
}
this.$root.$emit('habitica:payment-success', appState);
}
}
-14
View File
@@ -85,13 +85,6 @@ const router = new VueRouter({
props: true,
},
{ name: 'profile', path: '/user/profile' },
{
name: 'avatar',
path: '/avatar',
children: [
{ name: 'backgrounds', path: 'backgrounds' },
],
},
{ name: 'stats', path: '/user/stats' },
{ name: 'achievements', path: '/user/achievements' },
{
@@ -417,13 +410,6 @@ router.beforeEach(async (to, from, next) => {
router.app.$root.$emit('bv::hide::modal', 'profile');
}
if (to.name === 'backgrounds') {
store.state.avatarEditorOptions.editingUser = true;
store.state.avatarEditorOptions.startingPage = 'backgrounds';
router.app.$root.$emit('bv::show::modal', 'avatar-modal');
return null;
}
return next();
});
+1 -1
View File
@@ -122,7 +122,7 @@ export default defineConfig({
},
rollupOptions: {
output: {
experimentalMinChunkSize: 20000
experimentalMinChunkSize: 1000
}
}
},
+4 -11
View File
@@ -104,15 +104,15 @@
"achievementSkeletonCrewModalText": "Posbíral/a jsi všechna kostnatá zvířata!",
"achievementSkeletonCrewText": "Posbíral/a všechna kostnatá zvířata.",
"achievementLegendaryBestiaryModalText": "Posbíral/a jsi všechny mytické mazlíčky!",
"achievementLegendaryBestiaryText": "Posbíral/a všechny barvy mytických mazlíčků: drak, létající prase, gryfon, mořský hady a jednorožec!",
"achievementLegendaryBestiaryText": "Posbíral/a jsi všechny základní barvy mytických mazlíčků: draka, létajícího prasete, gryfona, mořského hada a jednorožce!",
"achievementLegendaryBestiary": "Legendární bestiář",
"achievementSeasonalSpecialist": "Sezónní specialista",
"achievementVioletsAreBlueText": "Získal/a všechny cukrově modré mazlíčky.",
"achievementVioletsAreBlue": "Fialky jsou modré",
"achievementVioletsAreBlue": "Fialky jsou Modré",
"achievementVioletsAreBlueModalText": "Posbíral/a jsi všechny mazlíčky z Modré Cukrové Vaty!",
"achievementSeasonalSpecialistModalText": "Dokončl/a jsi všechny sezónní úkoly!",
"achievementDomesticatedModalText": "Sesbíral/a jsi všechna domácí zvířata!",
"achievementSeasonalSpecialistText": "Splnil/a všechny jarní a zimní sezonní úkoly: Lov Vajec, Uvězněný Santa, a Najdi Mládě!",
"achievementSeasonalSpecialistText": "Dokončil/a jsi všechny Jarní a Zimní sezónní úkoly: Honba za vajíčky, Pastičkář Santa, a najdi Cuba!",
"achievementWildBlueYonderText": "Ochočil/a všechny zvířata z Modré Cukrové Vaty.",
"achievementWildBlueYonderModalText": "Ochočil/a jsi všechny mazlíčky z Modré Cukrové Vaty!",
"achievementDomesticatedText": "Vylíhl/a všechna standardní zbarvení domácích zvířat: Fretka, morče, kohout, létající prasátko, krysa, králík, kůň a kráva!",
@@ -157,12 +157,5 @@
"achievementBonelessBossModalText": "Získal/a jsi všechny bezobratlé mazlíčky!",
"achievementDuneBuddy": "Kámoš z dun",
"achievementDuneBuddyText": "Vylíhl/a jsi všechny, v poušti se vyskytující, mazlíčky: pásovce, kaktus, lišku, žábu, hada a pavouka!",
"achievementDuneBuddyModalText": "Sesbíral jsi všechna zvířata žijící v poušti!",
"achievementRodentRulerText": "Vylíhly se všechny standardní barvy hlodavců: morčata, krysy a veverky!",
"achievementCatsModalText": "Nasbíral jsi všechny kočičí mazlíčky!",
"achievementRoughRiderModalText": "Nasbíral jsi všechny základní barvy nepohodlných mazlíčků a mountů!",
"achievementRodentRulerModalText": "Nasbíral jsi všechny hlodavce!",
"achievementCatsText": "Vylíhly se všechny standardní barvy kočičích mazlíčků: gepard, lev, šavlozubý tygr a tygr!",
"achievementRodentRuler": "Vládce hlodavců",
"achievementCats": "Pasák koček"
"achievementDuneBuddyModalText": "Sesbíral jsi všechna zvířata žijící v poušti!"
}
+1 -4
View File
@@ -735,8 +735,5 @@
"backgroundMaskMakersWorkshopText": "Maskářova dílna",
"backgroundMaskMakersWorkshopNotes": "Vyzkoušej novou tvář v maskářově dílně.",
"backgroundCemeteryGateText": "Hřbitovní brána",
"backgroundCemeteryGateNotes": "Straš u hřbitovní brány.",
"backgroundAutumnBridgeText": "Podzimní most",
"backgroundAutumnBridgeNotes": "Obdivuj krásu podzimního mostu.",
"backgroundInsideACrystalText": "Uvnitř krystalu."
"backgroundCemeteryGateNotes": "Straš u hřbitovní brány."
}
+3 -14
View File
@@ -4,7 +4,7 @@
"brokenChaLink": "Nefunkční odkaz na výzvu",
"keepIt": "Ponechat",
"removeIt": "Odstranit",
"brokenChallenge": "Neplatný odkaz na výzvu",
"brokenChallenge": "Nefunkční odkaz na výzvu: tento úkol byl součástí výzvy, ale ta (nebo skupina, která ji vytvořila) byla odstraněna. Co chceš dělat s osiřelými úkoly?",
"challengeCompleted": "Výzva byla ukončena a vítězem se stal <span class=\"badge\"><%= user %></span>! Co chceš dělat s osiřelými úkoly?",
"unsubChallenge": "Nefunkční odkaz na výzvu: tento úkol byl součástí výzvy, ze které jsi se odhlásil/a. Co chceš dělat s osiřelými úkoly?",
"challenges": "Výzvy",
@@ -85,7 +85,7 @@
"summaryRequired": "Je požadováno shrnutí",
"summaryTooLong": "Shrnutí je příliš dlouhé",
"descriptionRequired": "Je požadován popis",
"locationRequired": "Je nutné vybrat umístění výzvy (Přidat do“)",
"locationRequired": "Je požadováno vybrat lokaci výzvy ('Přidat k')",
"categoiresRequired": "Musí být vybrána jedna nebo více kategorií",
"viewProgressOf": "Zobrazit pokrok",
"viewProgress": "Zobrazit pokrok",
@@ -94,16 +94,5 @@
"selectParticipant": "Zvol účastníka",
"filters": "Filtry",
"wonChallengeDesc": "Vyhrál/a jsi výzvu <%= challengeName %>! Tvá výhra je zaznamenána ve tvých úspěších.",
"yourReward": "Tvá odměna",
"brokenTaskDescription": "Tento úkol byl součástí výzvy, ale byl z ní odstraněn. Co chceš udělat?",
"brokenChallengeDescription": "Tento úkol byl součástí výzvy, ale výzva (nebo skupina) byla smazána. Co chceš udělat s osiřelými úkoly?",
"challengeCompletedDescription": "Vítězem je <%= user %>! Co chceš udělat s osiřelými úkoly?",
"messageChallengeFlagAlreadyReported": "Tuto výzvu jsi už nahlásil.",
"flaggedNotHidden": "Výzva byla nahlášena jednou, není skrytá",
"flaggedAndHidden": "Výzva byla nahlášena a je skrytá",
"resetFlagCount": "Resetovat počet nahlášení",
"deleteChallengeRefundDescription": "Pokud tuto výzvu smažeš, bude ti vrácena odměna v drahokamech a úkoly z výzvy zůstanou na nástěnkách úkolů účastníků.",
"messageChallengeFlagOfficial": "Oficiální výzvy nelze nahlásit.",
"brokenTask": "Nefunkční odkaz na výzvu",
"removeTasks": "Odstranit Úkoly"
"yourReward": "Tvá odměna"
}
+7 -13
View File
@@ -3,9 +3,9 @@
"iosFaqStillNeedHelp": "Jestli máš otázku, která není na tomto seznamu nebo na [Wiki FAQ](http://habitica.fandom.com/wiki/FAQ), použij formulář Ask a Question v sekci Nápověda na horní liště rozhraní. Jsme rádi když můžeme pomoct.",
"androidFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.fandom.com/wiki/FAQ), come ask in the Tavern chat under Menu > Tavern! We're happy to help.",
"webFaqStillNeedHelp": "Pokud máš otázku, která není na tomto seznamu nebo na [Wiki FAQ](https://habitica.fandom.com/wiki/FAQ), přijď se zeptat do [Cechu „Habitica Help‟](https://habitica.com/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a)! Rádi ti pomůžeme.",
"webFaqAnswer25": "Habitica používá tři různé typy úkolů, které se přizpůsobují tvým potřebám: Návyky, Denní úkoly a Úkolníček.\n\nNávyky mohou být pozitivní či negativní a vyjadřují něco, co můžeš chtít zaznamenat několikrát denně, nebo dle nestálého rozvrhu. Pozitivní návyky ti získají odměny, jako zlaťáky a zkušenosti , zatímco negativní návyky způsobí, že ztratíš body zdraví.\n\nDenní úkoly jsou úkoly, které chceš splnit pravidelněji, například jednou denně, třikrát týdně, nebo čtyřikrát za měsíc. Nesplněné denní úkoly tě stojí body zdraví, ale zároveň čím jsou náročnější, tím lepší odměnu nabízejí.\n\nÚkolníček zahrnuje jednorázové úkoly, ze kterých po jejich splnění získáš odměny. Úkoly v úkolníčku mohou mít zadané datum dokončení, ale pokud ho nestihneš, neztratíš žádné zkušenostní body.\n\nVyber si takový typ úkolu, který ti nejlépe pomůže dosáhnout tvých cílů!",
"webFaqAnswer25": "Habitica používá tři různé typy úkolů, které se přizpůsobují tvým potřebám: Návyky, Denní úkoly a Úkolníček.\n\nNávyky mohou být pozitivní či negativní a vyjadřují něco, co můžeš chtít zaznamenat několikrát denně, nebo dle nestálého rozvrhu. Pozitivní návyky ti získají odměny, jako zlaťáky a zkušenosti , zatímco negativní návyky způsobí, že ztratíš body zdraví. \n\nDenní úkoly jsou úkoly, které chceš splnit pravidelněji, například jednou denně, třikrát týdně, nebo čtyřikrát za měsíc. Nesplněné denní úkoly tě stojí body zdraví, ale zároveň čím jsou náročnější, tím lepší odměnu nabízejí.\n\nÚkolníček zahrnuje jednorázové úkoly, ze kterých po jejich splnění získáš odměny. Úkoly v úkolníčku mohou mít zadané datum dokončení, ale pokud ho nestihneš, neztratíš žádné zkušenostní body.\n\nVyber si takový typ úkolu, který ti nejlépe pomůže dosáhnout tvých cílů!",
"webFaqAnswer26": "Pozitivní návyky (návyky, které chceš udržovat; měly by mít tlačítko plus)\n\n * Sněz vitamíny\n * Vyčisti si zuby\n * Hodina učení se\n\nNegativní návyky (návyky které chceš omezit nebo se jim zcela vyhnout; měly by mít tlačítko mínus)\n\n * Kouření\n * Bezmyšlenkovité scrollování\n * Kousání si nehtů\n\nOboustranné návyky (Návyky které mají jak pozitivní, tak negativní možnost; měly by mít tlačítko plus i mínus)\n\n * Pít vodu vs. Pít limonádu\n * Učit se vs. prokrastinovat\n\nNávrhy denních úkolů (úkoly, které chceš plnit pravidelně)\n * Umýt nádobí\n * Zalít kytky\n * 30 minut nějaké fyzické aktivity\n\nNávrhy úkolů do Úkolníčku (úkoly co chceš splnit jen jednou)\n\n * Objednat se k doktorovi\n * Zorganizovat obsah skříně\n * Dopsat esej",
"webFaqAnswer35": "Jakmile jsi nakrmil svého mazlíčka natolik, že vyrostl v dospělé zvíře, budeš ten typ mazlíčka muset nechat vylíhnout znovu, pokud ho chceš mít nadále ve stáji.\n\nPokud chceš vidět zvířata na mobilních aplikacích:\n\n * Na menu vyber “Mazlíčci & zvířata” (Pets & Mounts) a klikni na popisek Zvířata (Mounts)\n\nPokud chceš vidět zvířata na webových stránkách:\n\n * Z inventáře na menu vyber “Domácí zvířata a mounti” and sjeď dolů, k sekci Stáj",
"webFaqAnswer35": "Jakmile jsi nakrmil svého mazlíčka natolik, že vyrostl v dospělé zvíře, budeš ten typ mazlíčka muset nechat vylíhnout znovu, pokud ho chceš mít nadále ve stáji.\n\nPokud chceš vidět zvířata na mobilních aplikacích:\n\n * Na menu vyber “Mazlíčci & zvířata” (Pets & Mounts) a klikni na popisek Zvířata (Mounts)\n\nPokud chceš vidět zvířata na webových stránkách:\n\n * Z inventáře na menu vyber “Stáj” and sjeď dolů, k sekci Stáj",
"commonQuestions": "Časté otázky",
"faqQuestion25": "Jaké různé úkoly existují?",
"faqQuestion26": "Jaké úkoly mohu například vytvořit?",
@@ -13,25 +13,19 @@
"faqQuestion29": "Jak získám zpět Zdraví?",
"webFaqAnswer29": "Můžeš získat 15 bodů zdraví zakoupením Lektvaru zdraví ze sloupce Odměny za 25 zlaťáků. Navíc, pokud postoupíš do další úrovně, tak se ti všechno zdraví automaticky obnoví!",
"faqQuestion30": "Co se stane, když mi dojde zdraví?",
"webFaqAnswer30": "Pokud tvé zdraví dosáhne hodnoty nula, přijdeš o jednu úroveň, všechny zlaťáky a jeden kousek vybavení, který se dá znovu zakoupit. Můžete se znovu postavit plněním úkolů a opětovným zvyšováním úrovně.",
"webFaqAnswer30": "Pokud tvé zdraví dosáhne hodnoty nula, přijdeš o jednu úroveň, všechny zlaťáky a jeden kousek vybavení, který se dá znovu zakoupit.",
"faqQuestion31": "Proč jsem ztratil body, když jsem řešil úkol, který nebyl negativní?",
"webFaqAnswer31": "Když doděláš úkol a ztratíš zdraví i když bys správně neměl, narazil jsi na zpoždění, během kterého server synchronizoval změny na jiných platformách. Například, pokud použiješ zlaťáky, manu nebo ztratíš zkušenosti na aplikaci na mobilu a pak dokončíš akci na webově stránce, server jednoduše potvrzuje, že se všechno synchronizovalo.",
"faqQuestion32": "Jak si mohu vybrat kurz?",
"webFaqAnswer32": "Všichni hráči začínají jako válečníci, dokud nedosáhnou 10. úrovně. Jakmile dosáhneš 10. úrovně, dostaneš na výběr, jestli chceš zůstat válečníkem, nebo si vybrat jinou třídu. \n\nKaždá třída využívá rozdílné vybavení a schopnosti. Pokud si nechceš vybírat třídu, můžeš vybrat „Zatím nic.“ Pokud sis zatím nevybral, můžeš později třídní systém vždycky znovu aktivovat v nastavení.\n\nPokud chcete změnit svou třídu po dosažení úrovně 10, můžete tak učinit pomocí Koule znovuzrození. Koule znovuzrození je k dispozici na trhu za 6 drahokamů na úrovni 50 nebo zdarma na úrovni 100.\n\nAlternativně můžete změnit třídu kdykoli v nastavení za 3 drahokamy. Tím se vaše úroveň nevynuluje jako v případě Koule znovuzrození, ale budete moci přerozdělit body dovedností, které jste nashromáždili při postupu na vyšší úroveň, tak aby odpovídaly vaší nové třídě.",
"faqQuestion32": "Kdy si mohu vybrat třídu?",
"webFaqAnswer32": "V Habitice existují čtyři třídy: Válečník, Mág, Zloděj a Léčitel. Všichni hráči začínají jako válečníci, dokud nedosáhnou 10. úrovně. Jakmile dosáhneš 10. úrovně, dostaneš na výběr, jestli chceš zůstat válečníkem, nebo si vybrat jinou třídu. \n\nKaždá třída využívá rozdílné vybavení a schopnosti. Pokud si nechceš vybírat třídu, můžeš vybrat „Zatím nic.“ Pokud sis zatím nevybral, můžeš později třídní systém vždycky znovu aktivovat v nastavení.",
"faqQuestion33": "Co je to za modrou čáru s popisem Mana, která se objeví po dosažení 10. úrovně?",
"webFaqAnswer33": "Poté, co odemkneš třídní systém, tak odemkneš i schopnosti, jež ke svému použití vyžadují manu. Mana je učena tvou INT (inteligencí) a dá se měnit pomocí schopností a vybavení.",
"faqQuestion34": "Jaký typ jídla má rád můj mazlíček?",
"webFaqAnswer34": "Mazlíčci mají rádi jídla, která jim jdou barevně k srsti. Základní mazlíčci jsou výjimka, ale všichni základní mazlíčci mají rádi stejný předmět. Dole vidíš jídla, která mají specifičtí mazlíčci rádi:\n\n * Základní mazlíčci mají rádi maso\n * Bílí mazlíčci mají rádi mléko\n * Pouštní mazlíčci mají rádi brambory\n * Červení mazlíčci mají rádi jahody\n * Stínoví mazlíčci mají rádi čokoládu\n * Kostnatí mazlíčci mají rádi ryby\n * Zombie mazlíčci mají rádi hnijící maso\n * Cukrově růžoví mazlíčci mají rádi růžovou cukrovou vatu\n * Cukrově modří mazlíčci mají rádi modrou cukrovou vatu\n * Zlatí mazlíčci mají rádi med",
"faqQuestion35": "Nakrmil jsem svého mazlíčka a on zmizel! Co se stalo?",
"faqQuestion36": "Jak mohu změnit vzhled své postavy?",
"webFaqAnswer36": "Existuje nespočet způsobů jak změnit vzhled své postavy na Habitice! Můžeš změnit jeho tělesnou stavbu, barvu a styl vlasů, barvu kůže nebo třeba přidat brýle a pohybové pomůcky tím, že na menu vybereš Přizpůsobit postavu.\n\nAbys upravil postavu na mobilní aplikaci:\n * v menu vyber “Customize Avatar”\n\nAbys upravil postavu na webových stránkách:\n * Z uživatelského menu v navigaci, v pravém rohu, vyber \"Přizpůsobit postavu\"",
"webFaqAnswer36": "Existuje nespočet způsobů jak změnit vzhled své postavy na Habitice! Můžeš změnit jeho tělesnou stavbu, barvu a styl vlasů, barvu kůže nebo třeba přidat brýle a pohybové pomůcky tím, že na menu vybereš Upravit postavu.\n\nAbys upravil postavu na mobilní aplikaci:\n * v menu vyber “Customize Avatar”\n\nAbys upravil postavu na webových stránkách:\n * Z uživatelského menu v navigaci, v pravém rohu, vyber \"Upravit postavu\"",
"faqQuestion27": "Proč úkoly mění barvy?",
"webFaqAnswer27": "Barva úkolu je vizuální ukázkou hodnoty úkolu. Všechny úkoly začínají neutrálně žlutě, modrá je lepší a červená horší. Zde uvidíš jak typ úkolu určuje hodnotu úkolu:\n\nNávyky zmodrají nebo zčervenají podle toho, jestli klikneš na tlačítko plus nebo mínus. Pokud je nebudeš plnit, tak pozitivní a negativní úkoly oslabíš až na žlutou. Dvojité návyky mění barvy pouze na základě tvých zadání.\n\nDenní úkoly mění barvu podle toho, jak často jsou plněny a když se plní, stávají se modřejšími, nebo pokud jsou zanedbány, zčervenají.\n\nČím déle jsou úkoly v úkolníčku nesplněné, tím červenějšími se stávají.\n\nČím červenější úkol, tím víc zlaťáků a zkušeností získáš za jeho splnění, takže se vrhni i na ty nejdrsnější úkoly!",
"faqQuestion28": "Pokud potřebuji pauzu, mohu si pozastavit denní úkoly?",
"faqQuestion37": "Proč se mé vybavení neukazuje na mé postavě?",
"webFaqAnswer37": "Zkontrolujte, zda je zapnutá možnost Kostým. Pokud má váš avatar na sobě kostým, zobrazí se místo vaší bojové výstroje tato sada vybavení.\n\nZapnutí kostýmu v mobilních aplikacích:\n * V nabídce vyberte „Vybavení“ a najděte přepínač Kostým.\n\nZapnutí kostýmu na webových stránkách:\n * V inventáři vyberte „Vybavení“ a najděte přepínač Kostým v záložce Kostým v zásuvce Vybavení",
"faqQuestion38": "Proč nemohu zakoupit určité položky?",
"webFaqAnswer38": "Noví hráči Habitica mohou zakoupit pouze základní vybavení třídy válečník. Hráči musí nakupovat vybavení v pořadí, aby odemkli další kus.\n\nMnoho kusů vybavení je specifických pro danou třídu, což znamená, že hráč může zakoupit pouze vybavení patřící k jeho aktuální třídě.",
"faqQuestion39": "Kde mohu získat další vybavení?",
"faqQuestion40": "Co jsou gemy a jak je dostanu?"
"faqQuestion28": "Pokud potřebuji pauzu, mohu si pozastavit denní úkoly?"
}
+1 -1
View File
@@ -8,7 +8,7 @@
"rebirthOrb": "Použil Kouli Znovozrození, aby začal znova, po dosáhnutí úrovně <%= level %>.",
"rebirthOrb100": "Použil Kouli znovuzrození, aby začal odznovu po dosažení úrovně 100 nebo vyšší.",
"rebirthOrbNoLevel": "Použil Kouli Znovozrození, aby začal znova.",
"rebirthPop": "Obnoví tvou postavu a vrátí jí na 1. úroveň s povoláním Válečníka, zatímco ti zůstanou všechny úspěchy, celá sbírka a vybavení. Tvoje úkoly zůstanou i s historií, ale vrátí se na žlutou barvu. Tvé řady úspěchů se resetují, kromě úkolů patřících do aktivních výzev či do Skupiny. Tvé zlato, zkušenosti, mana a efekty všech schopností budou odstraněny. Toto vše nastane s okamžitou platností.",
"rebirthPop": "Obnoví tvou postavu a vrátí jí na 1. úroveň s povoláním Válečníka, zatímco ti zůstanou všechny úspěchy, celá sbírka a vybavení. Tvoje úkoly zůstanou i s historií, ale vrátí se na žlutou barvu. Tvé řady úspěchů se resetují, kromě úkolů patřících do aktivních výzev či do Skupiny. Tvé zlato, zkušenosti, mana a efekty všech schopností budou odstraněny. Toto vše nastane s okamžitou platností. Pro více informací se podívej na wiki stránku: <a href='https://habitica.fandom.com/wiki/Orb_of_Rebirth' target='_blank'>Orb znovuzrození</a>.",
"rebirthName": "Koule znovuzrození",
"rebirthComplete": "Byl jste znovuzrozen!",
"nextFreeRebirth": "<strong><%= days %> dni</strong> do <strong>bezplatného</strong> Koule znovuzrození"
+2 -7
View File
@@ -873,7 +873,7 @@
"backgrounds072024": "SET 122: Veröffentlicht im Juli 2024",
"backgroundRiverBottomText": "Flussgrund",
"backgroundRiverBottomNotes": "Erkunde den Grund eines Flusses.",
"monthlyBackgrounds": "Monatliche Hintergründe",
"monthlyBackgrounds": "Hintergrund des Monats",
"backgrounds082024": "Set 123: Veröffentlicht im August 2024",
"backgroundSavannaText": "Dunstiges Grasland",
"backgroundSavannaNotes": "Wandere durch Dunstiges Grasland.",
@@ -930,10 +930,5 @@
"backgroundElegantPalaceText": "Eleganter Palast",
"backgroundElegantPalaceNotes": "Bewundere die farbenfrohen Hallen eines Eleganten Palastes.",
"backgroundWinterDesertWithSaguarosText": "Winter-Wüste mit Kakteen",
"backgroundWinterDesertWithSaguarosNotes": "Atme die kalte Luft Wunder Winter-Wüste mit Kakteen.",
"backgrounds032026": "SET 142: Veröffentlicht im März 2026",
"backgroundWaterfallWithRainbowText": "Wasserfall mit Regenbogen",
"backgroundWaterfallWithRainbowNotes": "Bewundere die atemberaubende Schönheit eines Wasserfalls mit Regenbogen.",
"backgrounds042026": "SET 143: Veröffentlicht im April 2026",
"backgrounds052026": "SET 144: Veröffentlicht im Mai 2026"
"backgroundWinterDesertWithSaguarosNotes": "Atme die kalte Luft Wunder Winter-Wüste mit Kakteen."
}
+6 -6
View File
@@ -83,7 +83,7 @@
"allocatePerPop": "Erhöhe Wahrnehmung um einen Punkt",
"allocateInt": "Zugewiesene Intelligenzpunkte:",
"allocateIntPop": "Erhöhe Intelligenz um einen Punkt",
"noMoreAllocate": "Da du nun Level 100 erreicht hast, wirst du keine weiteren Attributpunkte für Levelaufstiege erhalten. Du kannst deine Reise dennoch weiter fortsetzen, oder ein neues Abenteuer auf Level 1 beginnen, indem du die <a href='/shops/market'>Sphäre der Wiedergeburt</a> benutzt.",
"noMoreAllocate": "Nachdem du nun Level 100 erreicht hast, erhältst du keine weiteren Attributpunkte mehr. Du kannst weiter aufsteigen oder mit der <a href=/shops/market>Sphäre der Wiedergeburt</a> ein neues Abenteuer auf Level 1 beginnen.",
"stats": "Attributwerte",
"strength": "Stärke",
"strText": "Stärke erhöht die Wahrscheinlichkeit zufälliger \"kritischer Treffer\" und die Rate mit der durch sie Gold, Beute und Erfahrung gewonnen wird. Und hilft auch dabei, Boss-Monstern Schaden zuzufügen.",
@@ -115,11 +115,11 @@
"autoAllocation": "Verteilungsmuster",
"autoAllocationPop": "Verteilt gemäß Deiner Einstellungen Punkte auf Deine Attribute, wenn Du ein Level aufsteigst.",
"evenAllocation": "Gleichmäßig verteilen",
"evenAllocationPop": "Weist jedem Attribut die gleiche Anzahl von Punkten zu",
"evenAllocationPop": "Weist jedem Attribut die gleiche Anzahl von Punkten zu.",
"classAllocation": "Punkte anhand der Klasse verteilen",
"classAllocationPop": "Weist den Attributen die wichtig für Deine Klasse sind, mehr Punkte zu",
"classAllocationPop": "Weist den Attributen die wichtig für Deine Klasse sind, mehr Punkte zu.",
"taskAllocation": "Verteile Punkte abhängig von Aufgabenaktivität",
"taskAllocationPop": "Verteilt Punkte basierend auf den Kategorien Stärke, Intelligenz, Ausdauer und Wahrnehmung, die mit den von Dir erledigten Aufgaben verbunden sind",
"taskAllocationPop": "Verteilt Punkte basierend auf den Kategorien Stärke, Intelligenz, Konstitution und Wahrnehmung, die mit den von Dir erledigten Aufgaben verbunden sind.",
"distributePoints": "Verteile freie Punkte automatisch",
"distributePointsPop": "Verteilt alle freien Attributpunkte gemäß Deinem gewählten Verteilungsmuster.",
"warriorText": "Krieger verursachen mehr und stärkere \"kritische Treffer\", die zufällige Boni auf Gold, Erfahrung und Beute beim Erfüllen einer Aufgabe geben. Sie sind auch sehr stark gegen Bossmonster. Spiele einen Krieger, wenn Dich die Chance auf Belohnungen im Lottogewinn-Stil besonders reizt und Du besonders effektiv gegen Bossmonster sein willst!",
@@ -185,7 +185,7 @@
"purchasePetItemConfirm": "Dieser Einkauf würde die Anzahl der Gegenstände überschreiten, die Du zum Schlüpfen aller möglichen <%= itemText %>-Tiere benötigst. Bist du sicher?",
"notEnoughGold": "Nicht genügend Gold.",
"chatCastSpellPartyTimes": "<%= username %> wendet <%= spell %> <%= times %> mal für Deine Party an.",
"chatCastSpellUserTimes": "<%= username %> wendet <%= spell %> <%= times %> mal auf <%= target %> an.",
"chatCastSpellUserTimes": "<%= username %> wendet <%= times %> mal <%= spell %> auf <%= target %> an.",
"nextReward": "Nächste Anmelde-Belohnung",
"skins": "Hautfarben",
"titleHaircolor": "Haarfarben",
@@ -200,5 +200,5 @@
"assignedStat": "Zugewiesener Wert",
"intTaskText": "Erhöht die durch Aufgaben gesammelte Erfahrung. Erhöht außerdem deine Manakapazität und Manaregenerationsrate.",
"perTaskText": "Erhöht die Drop-Chance für Gegenstände, die tägliche Drop-Obergrenze für Gegenstände, die Serienboni für Aufgaben und das beim Abschließen von Aufgaben verdiente Gold.",
"statAllocationInfo": "Mit jedem Level erhältst Du einen Punkt, den Du einem Attribut Deiner Wahl zuweisen kannst. Du kannst die Zuweisung manuell vornehmen oder es dem Spiel überlassen, indem Du eine der Optionen zur automatischen Zuweisung nutzt."
"statAllocationInfo": "Mit jedem Level erhältst Du einen Punkt, den Du einem Attribut Deiner Wahl zuweisen kannst. Du kannst die Zuweisung manuell vornehmen oder es dem Spiel überlassen, indem Du eine der Optionen zur automatischen Zuweisung wählst."
}
+1 -7
View File
@@ -245,11 +245,5 @@
"faqQuestion67": "Was sind die Klassen in Habitica?",
"webFaqAnswer67": "Klassen sind verschiedene Rollen, die dein Charakter spielen kann. Jede Klasse bietet ihre eigene Reihe von einzigartigen Vorteilen und Fähigkeiten beim Aufsteigen auf höhere Level. Diese Fähigkeiten können das Bearbeiten deiner Aufgaben ergänzen oder dabei helfen, deine Party beim Abschließen von Quests zu unterstützen.\n\nDeine Klasse bestimmt auch, welche Ausrüstung für dich in den Belohnungen, im Marktplatz und im Jahreszeitenmarkt zum Kauf erhältlich ist.\n\nHier ist eine Zusammenfassung jeder Klasse, um dir dabei zu helfen, diejenige zu wählen, welche am besten zu deinem Spielstil passt:\n#### **Krieger**\n* Die Krieger verursachen hohen Schaden bei Bossen und haben eine hohe Chance für kritische Treffer beim Abschließen von Aufgaben, was dich mit extra Erfahrung und Gold belohnt.\n* Stärke ist ihr primäres Attribut, welches den Schaden erhöht, den sie verursachen.\n* Ausdauer ist ihr sekundäres Attribut, welches den Schaden verringert, den sie erhalten.\n* Die Fähigkeiten der Krieger erhöhen die Ausdauer und Stärke der Gruppenmitglieder.\n* Erwäge, einen Krieger zu spielen, wenn du es liebst, Bosse zu bekämpfen und auch ein wenig Schutz möchtest, wenn du gelegentlich Aufgaben versäumst.\n#### **Heiler**\n* Die Heiler haben eine starke Verteidigung und können sich selbst, sowie Gruppenmitglieder, heilen.\n* Ausdauer ist ihr primäres Attribut, welches ihre Heilungen verstärkt und den Schaden, den sie erhalten, verringert.\n* Intelligenz ist ihr sekundäres Attribut, welches ihr Mana und ihre Erfahrung erhöht.\n* Die Fähigkeiten der Heiler bewirken, dass ihre Aufgaben weniger rot werden und erhöhen die Ausdauer der Gruppenmitglieder.\n* Erwäge, einen Heiler zu spielen, wenn du oft Aufgaben versäumst, und die Fähigkeit benötigst, dich selbst und deine Gruppenmitglieder zu heilen. Heiler erreichen schnell neue Level.\n#### **Magier**\n* Die Magier gewinnen schnell neue Level und viel Mana, und verursachen Schaden bei Bossen in Quests.\n* Intelligenz ist ihr primäres Attribut, welches ihr Mana und ihre Erfahrung erhöht.\n* Wahrnehmung ist ihr sekundäres Attribut, welches ihr gefundenes Gold und ihre gefundenen Gegenstände vermehrt.\n* Die Fähigkeiten der Magier bewirken, dass ihre Aufgaben Strähnen eingefroren werden, stellen das Mana ihrer Gruppenmitglieder wieder her, und erhöhen ihre Intelligenz.\n* Erwäge, einen Magier zu spielen, wenn du durch das schnelle Erreichen neuer Level und das Beisteuern von Schaden in Boss Quests motiviert wirst.\n#### **Schurke**\n* Die Schurken bekommen die meisten erbeuteten Gegenstände und das meiste Gold beim Erledigen von Aufgaben und haben eine höhere Chance, kritische Treffer zu erzielen, was ihnen noch mehr Erfahrung und Gold beschert.\n* Wahrnehmung ist ihr primäres Attribut, welches ihr gefundenes Gold und ihre gefundenen Gegenstände vermehrt.\n* Stärke ist ihr sekundäres Attribut, welches den Schaden erhöht, den sie verursachen.\n* Die Fähigkeiten der Schurken helfen ihnen, versäumten Tagesaufgaben auszuweichen, Gold zu klauen und die Wahrnehmung ihrer Gruppenmitglieder zu erhöhen.\n* Erwäge, einen Schurken zu spielen, wenn du durch Belohnungen sehr motiviert wirst.",
"faqQuestion68": "Wie kann ich den Verlust von HP verhindern?",
"webFaqAnswer68": "Wenn du häufig LP verlierst, probiere diese Tipps aus:\n\n Pausiere deine täglichen Aufgaben. Die Schaltfläche „Schaden pausieren“ in den Einstellungen verhindert, dass du HP für verpasste Aufgaben verlierst.\n Passe den Zeitplan deiner täglichen Aufgaben an. Indem du sie so einstellst, dass sie nie fällig sind, kannst du sie trotzdem abschließen und Belohnungen erhalten, ohne HP zu verlieren.\n Versuche, Klassenfertigkeiten einzusetzen:\n Schurken können „Schleichen“ einsetzen, um Schaden durch verpasste tägliche Aufgaben zu vermeiden.\n Krieger können „Gewaltschlag“ einsetzen, um die Röte einer täglichen Aufgabe zu verringern und so den erlittenen Schaden beim Verpassen zu reduzieren.\n Heiler können „Brennende Helle“ einsetzen, um die Röte einer täglichen Aufgabe zu verringern und so den erlittenen Schaden beim Verpassen zu reduzieren",
"faqQuestion69": "Was sind Charakter-Attributwerte?",
"webFaqAnswer69": "Alle Spieler haben vier Charakter-Attribute, welche verschiedene Vorteile bringen:\n\n* Stärke - Erhöht beim erledigen von Aufgaben den Schaden und die Chance, einen kritischen Treffer zu verursachen. Erhöht außerdem den Schaden gegen Quest-Bosse.\n* Intelligenz - Erhöht die Menge von Erfahrungspunkten, die du von Aufgaben erhältst. Erhöht außerdem deinen Mana-Maximalwert und deine Mana-Regenerationsrate.\n* Ausdauer - Verringert den erhaltenen Schaden von verpassten Tagesaufgaben und negativen Gewohnheiten. Verringert nicht den Schaden den du von Quest-Bossen erhältst.\n* Wahrnehmung - Erhöht die Item-Drop-Wahrscheinlichkeit, das tägliche Item-Drop-Limit, Streak-Boni für Aufgaben und die Menge an Gold, die du für das Erledigen von Aufgaben erhältst.\n\nAttribute können durch das Verteilen von Attributpunkten, Ausrüstung, Klassen-Fähigkeiten und Levelaufstiege erhöht werden. Du erhältst außerdem alle zwei Level einen Bonuspunkt für alle Attribute, bis Level 100.",
"faqQuestion70": "Was sind Attribut-Punkte?",
"faqQuestion71": "Wie funktioniert die automatische Attributverteilung?",
"webFaqAnswer70": "Attributpunkte lassen dich die Kernwerte deines Charakters erhöhen. Du erhältst mit jedem Levelaufstieg einen Attributpunkt (bis Level 100), welchen du entweder manuell oder auch automatisch, durch du die automatische Zuweisungsfunktion, zuweisen lassen kannst. Attributzuweisung wird zusammen mit dem Klassensystem beim Erreichen von Level 10 freigeschaltet.",
"webFaqAnswer71": "Die automatische Attributverteilung weist die erhaltenen Attributpunkte nach einer der folgenden Methoden zu:\n\n* Gleichmäßig - weist jedem Attribut die gleiche Menge an Punkten zu\n* Anhand der Klasse - weist den Attributen, die für deine Klasse wichtig sind, mehr Punkte zu\n* Anhand der Aufgabenaktivität - weist die Punkte anhand der Kategorie der erledigten Aufgaben auf alle Werte zu\n\nWenn du dich dafür entscheidest, die Punkte nicht automatisch verteilen zu lassen, kannst du dies manuell unter \"Attributwerte\" bei deinem Profil tun."
"webFaqAnswer68": "Wenn du häufig LP verlierst, probiere diese Tipps aus:\n\n Pausiere deine täglichen Aufgaben. Die Schaltfläche „Schaden pausieren“ in den Einstellungen verhindert, dass du HP für verpasste Aufgaben verlierst.\n Passe den Zeitplan deiner täglichen Aufgaben an. Indem du sie so einstellst, dass sie nie fällig sind, kannst du sie trotzdem abschließen und Belohnungen erhalten, ohne HP zu verlieren.\n Versuche, Klassenfertigkeiten einzusetzen:\n Schurken können „Schleichen“ einsetzen, um Schaden durch verpasste tägliche Aufgaben zu vermeiden.\n Krieger können „Gewaltschlag“ einsetzen, um die Röte einer täglichen Aufgabe zu verringern und so den erlittenen Schaden beim Verpassen zu reduzieren.\n Heiler können „Brennende Helle“ einsetzen, um die Röte einer täglichen Aufgabe zu verringern und so den erlittenen Schaden beim Verpassen zu reduzieren"
}
+1 -1
View File
@@ -124,7 +124,7 @@
"passwordReset": "Wenn wir Deine E-Mail-Adresse oder Deinen Benutzernamen kennen, wurden Anweisungen zum Passwort-Zurücksetzen dorthin verschickt.",
"invalidLoginCredentialsLong": "Deine E-Mail-Adresse, deine Benutzername oder Passwort sind nicht korrekt. Bitte versuche es erneut oder wähle \"Passwort vergessen.\"",
"invalidCredentials": "Es gibt kein Konto, das diese Anmeldedaten verwendet.",
"accountSuspended": "Dieser Account \"<%= username %>\" wurde gesperrt. Für weitere Informationen oder um Widerspruch einzulegen, sende bitte eine E-Mail an admin@habitica.com mit deinem Habitica Benutzernamen oder deiner User-ID.",
"accountSuspended": "Dieser Account \"<%= userId %>\", wurde gesperrt. Für weitere Informationen oder um Widerspruch einzulegen, sende bitte eine E-Mail an admin@habitica.com mit deinem Habitica-Benutzernamen oder User-ID.",
"accountSuspendedTitle": "Dieser Account wurde suspendiert",
"unsupportedNetwork": "Dieses Netzwerk wird aktuell nicht unterstützt.",
"cantDetachSocial": "Der Account hat nur noch diese Authentifizierung, sie kann nicht getrennt werden.",
+12 -39
View File
@@ -246,7 +246,7 @@
"weaponSpecialWinter2018WarriorText": "Festtags-Schleifchen-Hammer",
"weaponSpecialWinter2018WarriorNotes": "Die funkelnde Erscheinung dieser strahlenden Waffe wird deine Feinde blenden, wenn du sie schwingst! Erhöht Stärke um <%= str %>. Limitierte Ausgabe 2017-2018 Winterausrüstung.",
"weaponSpecialWinter2018MageText": "Feiertagskonfetti",
"weaponSpecialWinter2018MageNotes": "Magie und Glitzerliegt in der Luft! Erhöht Intelligenz um <%= int %> und Wahrnehmung um <%= per %>. Limitierte Ausgabe 2017-2018 Winterausrüstung.",
"weaponSpecialWinter2018MageNotes": "Magie und Glitzer liegt in der Luft! Erhöht Intelligenz um <%= int %> und Wahrnehmung um<%= per %>. Limitierte Ausgabe 2017-2018 Winterausrüstung.",
"weaponSpecialWinter2018HealerText": "Mistelzauberstab",
"weaponSpecialWinter2018HealerNotes": "Dieser Mistelball wird mit Sicherheit alle Passanten verzaubern und betören. Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe 2017-2018 Winterausrüstung.",
"weaponSpecialSpring2018RogueText": "Putziger Rohrkolben",
@@ -326,7 +326,7 @@
"weaponArmoireBasicLongbowText": "Einfacher Langbogen",
"weaponArmoireBasicLongbowNotes": "Ein nützlicher, gebrauchter Bogen. Erhöht Stärke um <%= str %>. Verzauberter Schrank: Standard-Bogenschützenset (Gegenstand 1 von 3).",
"weaponArmoireHabiticanDiplomaText": "Habiticaner-Diplom",
"weaponArmoireHabiticanDiplomaNotes": "Ein wohlverdientes Zertifikatgut gemacht! Erhöht Intelligenz um <%= int %>. Verzauberter Schrank: Doktoranden-Set (Gegenstand 1 von 3).",
"weaponArmoireHabiticanDiplomaNotes": "Ein wohlverdientes Zertifikat -- gut gemacht! Erhöht Intelligenz um <%= int %>. Verzauberter Schrank: Doktoranden-Set (Gegenstand 1 von 3).",
"weaponArmoireSandySpadeText": "Sandiger Spaten",
"weaponArmoireSandySpadeNotes": "Ein Werkzeug, um zu graben, und um Sand in die Augen feindlicher Monster zu streuen. Erhöht Stärke um <%= str %>. Verzauberter Schrank: Strandset (Gegenstand 1 von 3).",
"weaponArmoireCannonText": "Kanone",
@@ -806,7 +806,7 @@
"armorArmoireCoverallsOfBookbindingText": "Overall der Buchbinderei",
"armorArmoireCoverallsOfBookbindingNotes": "Alles, was Du in einem Set von Overalls brauchst, inklusive Taschen für alles. Eine Brille, Kleingeld, ein goldener Ring... Erhöht Ausdauer um <%= con %> und Wahrnehmung um <%= per %>. Verzauberter Schrank: Buchbinder-Set (Gegenstand 2 von 4).",
"armorArmoireRobeOfSpadesText": "Pik-Roben",
"armorArmoireRobeOfSpadesNotes": "Diese luxuriösen Gewänder verbergen geheime Taschen für Schätze oder Waffen Du hast die Wahl! Erhöht Stärke um <%= str %>. Verzauberter Schrank: Pik-Ass-Set (Gegenstand 2 von 3).",
"armorArmoireRobeOfSpadesNotes": "Diese üppigen Gewänder verbergen geheime Taschen für Schätze oder Waffen - Du hast die Wahl! Erhöht Stärke um <%= str %>. Verzauberter Schrank: Pik-Ass-Set (Gegenstand 2 von 3).",
"armorArmoireSoftBlueSuitText": "Weicher Blauer Anzug",
"armorArmoireSoftBlueSuitNotes": "Blau ist eine beruhigende Farbe. So beruhigend, dass einige sogar dieses weiche Outfit zum Schlafen tragen... zZz. Erhöht Intelligenz um <%= int %> und Wahrnehmung um <%= per %>. Verzauberter Schrank: Blaues Loungewear-Set (Gegenstand 2 von 3).",
"armorArmoireSoftGreenSuitText": "Weicher Grüner Anzug",
@@ -876,7 +876,7 @@
"headSpecialLunarWarriorHelmText": "Mondkriegerhelm",
"headSpecialLunarWarriorHelmNotes": "Die Kraft des Mondes wird Dich im Kampf stärken! Erhöht die Stärke und Intelligenz um jeweils <%= attrs %>.",
"headSpecialMammothRiderHelmText": "Mammutreiter-Helm",
"headSpecialMammothRiderHelmNotes": "Lass dich nicht von der Flauschigkeit täuschen der Helm wird dir die durchdringende Macht der Wahrnehmung verleihen! Erhöht Wahrnehmung um <%= per %>.",
"headSpecialMammothRiderHelmNotes": "Lass Dich nicht von der Flauschigkeit täuschen - der Helm wird Dir die durchdringende Macht der Wahrnehmung verleihen! Erhöht Wahrnehmung um <%= per %>.",
"headSpecialPageHelmText": "Pagen-Helm",
"headSpecialPageHelmNotes": "Kettenrüstung: für die Stilbewussten UND die Praktischen. Erhöht Wahrnehmung um <%= per %>.",
"headSpecialRoguishRainbowMessengerHoodText": "Kapuze des Ruchlosen Regenbogenbotens",
@@ -960,7 +960,7 @@
"headSpecialFall2015RogueText": "Geflügelter Kampfhelm",
"headSpecialFall2015RogueNotes": "Orte Deine Feinde mit diesem mächtigen Helm durch Echos! Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe 2015 Herbstausrüstung.",
"headSpecialFall2015WarriorText": "Vogelscheuchenhut",
"headSpecialFall2015WarriorNotes": "Jeder würde diesen Hut wollenwenn sie denn nur ein Gehirn hätten. Erhöht Stärke um <%= str %>. Limitierte Ausgabe 2015 Herbstausrüstung.",
"headSpecialFall2015WarriorNotes": "Jeder würde diesen Hut wollen wenn sie denn nur ein Gehirn hätten. Erhöht Stärke um <%= str %>. Limitierte Ausgabe 2015 Herbstausrüstung.",
"headSpecialFall2015MageText": "Genähter Hut",
"headSpecialFall2015MageNotes": "Dieser Hut wurde mit jedem Nadelstich stärker. Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe 2015 Herbstausrüstung.",
"headSpecialFall2015HealerText": "Froschhut",
@@ -1435,7 +1435,7 @@
"shieldArmoireMushroomDruidShieldText": "Pilzdruiden-Schild",
"shieldArmoireMushroomDruidShieldNotes": "Obwohl er aus einem Pilz gefertigt ist, ist nichts schimmlig an diesem harten Schild! Erhöht Ausdauer um <%= con %> und Stärke um <%= str %>. Verzauberter Schrank: Pilzdruiden-Set (Gegenstand 3 von 3).",
"shieldArmoireFestivalParasolText": "Festival-Sonnenschirm",
"shieldArmoireFestivalParasolNotes": "Dieser leichte Sonnenschirm schützt Dich vor grellem Lichtsei es von der Sonne oder von dunkelroten Tagesaufgaben! Erhöht Ausdauer um <%= con %>. Verzauberter Schrank: Festival-Tracht Set (Gegenstand 2 von 3).",
"shieldArmoireFestivalParasolNotes": "Dieser leichte Sonnenschirm schützt Dich vor grellem Licht sei es von der Sonne oder von dunkelroten Tagesaufgaben! Erhöht Ausdauer um <%= con %>. Verzauberter Schrank: Festival-Tracht Set (Gegenstand 2 von 3).",
"shieldArmoireVikingShieldText": "Wikingerschild",
"shieldArmoireVikingShieldNotes": "Dieser robuste hölzerne Schild hält auch den einschüchterndsten Feinden stand. Erhöht Wahrnehmung um <%= per %> und Intelligenz um <%= int %>. Verzauberter Schrank: Wikingerset (Gegenstand 3 von 3).",
"shieldArmoireSwanFeatherFanText": "Schwanenfederfächer",
@@ -2047,7 +2047,7 @@
"headSpecialSpring2020MageText": "Tropfkantenhut",
"headSpecialSpring2020WarriorNotes": "Die Schläge Deiner Gegener werden von diesem durch Käfer inspirierten Helm abprallen! Erhöht Stärke um <%= str %>. Limitierte Ausgabe 2020 Frühlingsausrüstung.",
"headSpecialSpring2020RogueNotes": "So knallig und kostbar, dass Du in Versuchung kommen wirst, ihn von Deinem eigenen Kopf zu stehlen. Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe 2020 Frühlingsausrüstung.",
"headAccessoryMystery202004Notes": "Sie zucken leicht sobald süßer Blumenduft vorbeiziehtmit Ihnen findest Du immer einen hübschen Garten! Gewährt keinen Attributbonus. Abonnentengegenstand, April 2020.",
"headAccessoryMystery202004Notes": "Sie zucken leicht sobald süßer Blumenduft vorbeizieht mit Ihnen findest Du immer einen hübschen Garten! Gewährt keinen Attributbonus. Abonnentengegenstand, April 2020.",
"backMystery202004Notes": "Flattere mal kurz zur nächsten Blumenwiese oder ziehe über den ganzen Kontinent mit diesen wunderschönen Flügeln! Gewährt keinen Attributbonus. Abonentengegenstand, April 2020.",
"shieldArmoireHobbyHorseNotes": "Reite auf Deinem stattlichen Steckenpferd zu Deinen verdienten Belohnungen! Erhöht Wahrnehmung und Ausdauer um je <%= attrs %>. Verzauberter Schrank: Papierritter-Set (Gegenstand 2 von 3).",
"shieldSpecialSpring2020HealerNotes": "Wehre die muffigen, alten To-Dos mit dem süßen Duft dieses Schilds ab. Erhöht Ausdauer um <%= con %>. Limitierte Ausgabe 2020 Frühlingsausrüstung.",
@@ -2085,7 +2085,7 @@
"headSpecialSummer2020RogueText": "Krokodilhelm",
"armorSpecialSummer2020MageText": "Riemenfisch",
"armorSpecialSummer2020WarriorText": "Regenbogenforellenschwanz",
"armorSpecialSummer2020RogueNotes": "Ein Krokodil ist ein geborener Schurke, so wie es auf den perfekten Moment wartet, um zuzuschlagen. Leihe Dir ihre Fähigkeiten und ihre explosive Geschwindigkeit. Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe 2020 Sommerausrüstung.",
"armorSpecialSummer2020RogueNotes": "Ein Krokodil ist ein geborener Schurke, so wie es auf den perfekten Moment wartet, um zuzuschlagen. Leihe Dir ihre Fähigkeiten - und ihre explosive Geschwindigkeit. Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe 2020 Sommerausrüstung.",
"headMystery202007Text": "Spektakulärer Schwertwalhelm",
"armorMystery202007Text": "Spektakuläres Schwertwalkostüm",
"shieldArmoirePiratesCompanionNotes": "Perfekt, wenn Du Deine Gegner totquatschen willst, denn dieser Papagei hält nie den Schnabel. Vielleicht wird er Dich auch an Deine Aufgaben erinnern! Erhöht Wahrnehmung um <%= per %>. Verzauberter Schrank: Piraten-Set (Gegenstand 3 von 3).",
@@ -2348,7 +2348,7 @@
"weaponSpecialSummer2021RogueText": "Anemonententakel",
"headSpecialSummer2021WarriorText": "Fischhelm",
"headSpecialSummer2021RogueText": "Clownfisch Haube",
"armorArmoireBathtubNotes": "Zeit für eine kleine Auszeit? Hier ist Ihre ganz persönliche Badewanneund eine Garantie, dass das Wasser immer die richtige Temperatur hat! Erhöht Ausdauer um <%= con %>. Verzauberter Schrank: Schaumbad-Set (Artikel 2 von 4).",
"armorArmoireBathtubNotes": "Zeit für eine kleine Auszeit? Hier ist Ihre ganz persönliche Badewanne - und eine Garantie, dass das Wasser immer die richtige Temperatur hat! Erhöht Ausdauer um <%= con %>. Verzauberter Schrank: Bubble Bath Set (Artikel 2 von 4).",
"armorArmoireBathtubText": "Badewanne",
"armorSpecialSummer2021HealerNotes": "Deine Feinde könnten vermuten, dass Du ein Federgewicht bist, aber diese Rüstung wird Dich schützen, während Du Deiner Party hilfst. Erhöht Ausdauer um <%= con %>. Limiterte Ausgabe 2021, Sommerausrüstung.",
"armorSpecialSummer2021HealerText": "Papageiengefieder",
@@ -2456,7 +2456,7 @@
"armorMystery202112Text": "Antarktischer Nixenschwanz",
"armorMystery202112Notes": "Gleite mit diesem schimmerden Schwanz durch eisige Gewässser ohne jegliche Kälte zu spühren. Gewährt keinen Attributbonus. Dezember 2021 Abonnentengegenstand.",
"headArmoireGlengarryText": "Hochlandmütze",
"shieldArmoireBagpipesNotes": "Unbarmherzige mögen sagen, Du planst mit diesem Dudelsack die Toten zu weckenaber Du weißt, dass Du lediglich Deine Party zum Erfolg motivierst! Erhöht Stärke um <%= str %>. Verzauberter Schrank: Dudelsackpfeifenset (Gegenstand 3 von 3).",
"shieldArmoireBagpipesNotes": "Unbarmherzige mögen sagen, Du planst mit diesem Dudelsack die Toten zu wecken aber Du weißt, dass Du lediglich Deine Party zum Erfolg motivierst! Erhöht Stärke um <%= str %>. Verzauberter Schrank: Dudelsackpfeifenset (Gegenstand 3 von 3).",
"weaponArmoireRegalSceptreText": "Majestätisches Szepter",
"headArmoireRegalCrownText": "Majestätische Krone",
"headArmoireBlackFloppyHatNotes": "Viele Zauber wurden in diese einfache Mütze genäht, um diese schwungvolle schwarze Farbe zu erreichen. Erhöht Ausdauer, Wahrnehmung und Sträke um jeweils <%= attrs %>. Verzauberter Schrank: Schwarzes Wohlfühl-Set (Gegenstand 1 von 3).",
@@ -2807,7 +2807,7 @@
"weaponArmoireMopNotes": "Schritt 1: Tauche den Mopp in einen Eimer mit Wasser und Schaum. Schritt 2: Ziehe den Mopp über den Boden. Schritt 3: Tu so, als wäre das Ende des Mopp Stiels ein Mikrofon und singe mit voller Inbrunst. Schritt 4: Wiederhole Schritte 1-3, bis der Boden sauber ist. Erhöht Ausdauer und Wahrnehmung um jeweils <%= attrs %>. Reinigungs-Set Zwei (Gegenstand 2 von 3)",
"weaponArmoireCleaningClothNotes": "Nimm dieses Putzwerkzeug auf deine Abenteuer mit und sei immer bereit, eine hübsche Gedenktafel zu polieren oder eine hölzerne Fensterbank zu wischen. Erhöht Stärke und Ausdauer um jeweils <%= attrs %>. Verzauberter Schrank: Reinigungs-Set Zwei (Gegenstand 3 von 3)",
"weaponArmoireRidingBroomText": "Reitbesen",
"weaponArmoireRidingBroomNotes": "Reite auf diesem feinen Besen zu all deinen magischsten Besorgungen oder nimm ihn für eine Spritztour durch die Nachbarschaft. Wuui! Erhöht Stärke um <%= str %> und Intelligenz um <%= int %>. Verzauberter Schrank: Spukhaftes Zauberer Set (Gegenstand 1 von 3)",
"weaponArmoireRidingBroomNotes": "Reite auf diesem feinen Besen zu all deinen magischsten Besorgungen--oder nimm ihn für eine Spritztour durch die Nachbarschaft. Wuui! Erhöht Stärke um <%= str %> und Intelligenz um <%= int %>. Verzauberter Schrank: Spukhaftes Zauberer Set (Gegenstand 1 von 3)",
"weaponArmoireHattersShearsText": "Scharfe Scheren",
"weaponArmoireScholarlyTextbooksNotes": "Hier ist deine Chance, tief einzusteigen, und über jedes Thema, das dich interessiert, zu lernen. Was ist deine momentane Hyperfixation? Erhöht Intelligenz um <%= int %>. Verzauberter Schrank: Schuluniform Set (Gegenstand 3 von 4).",
"weaponArmoireScholarlyTextbooksText": "Wissenschaftliche Lehrbücher",
@@ -3470,32 +3470,5 @@
"armorSpecialWinter2026MageNotes": "Gleite geschmeidig wie Wachs über Deinen Weg, um Deine täglichen Aufgaben zu erledigen. Erhöht die Intelligenz um <%= int %>. Limitierte Auflage Winter 2025-2026 Ausrüstung.",
"armorMystery202512Text": "Keks-Champion-Rüstung",
"headSpecialWinter2026WarriorText": "Frostsichel-Helm",
"headSpecialWinter2026RogueText": "Skimaske und Schutzbrille",
"headSpecialWinter2026HealerNotes": "Erhalte deinen Fokus und deine Klarheit, wenn du in dieser Jahreszeit deine Aufmerksamkeit auf größere Ziele richtest. Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe Winterausrüstung 2025-2026.",
"headSpecialWinter2026RogueNotes": "Erhalte deinen Fokus und deinen Weitblick, wenn du in dieser Jahreszeit deine Aufmerksamkeit auf größere Ziele richtest. Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe Winterausrüstung 2025-2026.",
"headSpecialWinter2026HealerText": "Eisbär Maske",
"headSpecialWinter2026MageNotes": "Erhalte deinen Fokus und deine Erleuchtung, wenn du in dieser Jahreszeit deine Aufmerksamkeit auf größere Ziele richtest. Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe Winterausrüstung 2025-2026.",
"headSpecialWinter2026MageText": "Wintersonnenwende Kerzenhut",
"headMystery202512Notes": "Der mit vorzeitlicher Magie geschmiedete Lebkuchen wird dich beschützen, solange du deine Gelüste, einen Bissen zu probieren, beherrschen kannst! Gewährt keinen Attributbonus. Dezember 2025 Abonnentengegenstand.",
"headMystery202512Text": "Keks-Champion Helm",
"shieldArmoirePrettyPinkGiftBoxText": "Hübsches rosa Geschenk",
"shieldArmoirePrettyPinkGiftBoxNotes": "Ist dieses Geschenk von einem lieben Freund? Einem fürsorglichen Verwandten? Einem heimlichen Verehrer? Wer auch immer es dir geschickt hat, weiß, dass du dich über den Inhalt freuen wirst. Erhöht alle Werte um jeweils <%= attrs %> . Verzauberter Schrank: Pretty in Pink-Set (Gegenstand 2 von 2)",
"headArmoireLoneCowpokeHatText": "Einsamer Cowboy Hut",
"shieldSpecialWinter2026WarriorText": "Raureif Schild",
"shieldSpecialWinter2026WarriorNotes": "Stoppe eiskalt Hindernisse mit diesem praktischen, pieksigen Schild. Erhöht Ausdauer um %= con %>. Limitierte Ausgabe Winterausrüstung 2025-2026.",
"headMystery202602Text": "Kirschblüte Fuchsohren",
"headMystery202602Notes": " Diese Ohren schärfen dein Gehör so sehr, dass du im nahenden Frühling das Wachsen der Blütenknospen an den Zweigen der Bäume hören kannst. Gewährt keinen Attributbonus. Februar 2026 Abonnentengegenstand.",
"headArmoireLoneCowpokeHatNotes": "Howdy Kumpel! Hasst dus auch so, wenn du draußen auf dem Schießstand bist, an Aufgaben arbeitest und dir die Sonne in die Augen scheint? Also, gute Sache, dass du dafür jetzt nen Hut hast. Erhöht deine Wahrnehmung um <%= per %>. Verzauberter Schrank: Einsamer Cowboy Set (Item 1 of 2)",
"shieldSpecialWinter2026HealerText": "Sternenexplosion",
"shieldArmoireDoubleBassNotes": "Bom doo bom brrrr brr brr brrrr! Versammle deine Party, um euch zu erden oder zu tanzen, während ihr euch Musik von dieser tiefen Double Bass anhört. Erhört Ausdauer und Stärke um jeweils <%= attrs %>. Verzauberter Schwank: Musikinstrumente Set 2 (Gegenstand 3 von 3)",
"backArmoireHarpsichordNotes": "Pting! Ptiiing! Versammle deine Party für ein Abendessen oder Picknick und lauscht einer leisen Melodie of diesem Cembalo. Erhöht Wahrnehmung und Intelligenz jeweils um <%= attrs %> . Verzauberter Schrank: Musikinstrumente Set 2 (Gegenstand 1 von 3)",
"shieldSpecialWinter2026HealerNotes": "Sterne helfen dabei den Weg zu finden und sie geben Energie und Licht—als Dinge, die dir dabei helfen eine Aufgabenliste zu bezwingen. Erhöht Ausdauer um<%= con %>. Limitierte Ausgabe Winterausrüstung 2025-2026.",
"shieldArmoireDoubleBassText": "Double Bass",
"backMystery202601Text": "Wintersiegel",
"backMystery202601Notes": "Dieses Zeichen gewährt dem Anwender die Kontrolle über die Elemente der Jahreszeit von Kälte und Frost. Gewährt keinen Attributbonus. Januar 2026 Abonnentengegenstand.",
"backMystery202602Text": "Fünf Schweife der Sakura",
"backMystery202602Notes": "Diese flauschigen Schweife haben die Farbe der Kirschblüte, eine Erinnerung, dass der Frühling auf dem Weg ist. Gewährt keinen Autobusbonus. Februar 2026 Abonnentengegenstand.",
"backArmoireHarpsichordText": "Cembalo",
"weaponSpecialSpring2026HealerText": "Schneeglöckchen Stab",
"weaponSpecialSpring2026HealerNotes": "Eine Gelegenheit für einen Neuanfang liegt direkt vor dir, und mit diesem prächtigen Stab wirst du bereit sein! Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe Frühlingsausrüstung 2026."
"headSpecialWinter2026RogueText": "Skimaske und Schutzbrille"
}
+1 -2
View File
@@ -242,6 +242,5 @@
"targetUserNotExist": "Zielbenutzer: '<%= userName %>' existiert nicht.",
"newMessage": "Neue Nachricht",
"rememberToBeKind": "Bitte sei freundlich, respektvoll, und folge den <a href='/static/community-guidelines' target='_blank'>Community-Richtlinien</a>.",
"gem": "Edelstein",
"confirmPurchase": "Kauf bestätigen"
"gem": "Edelstein"
}
+1 -5
View File
@@ -428,9 +428,5 @@
"groupManager": "Nutzung für die Arbeit",
"groupFriends": "Nutzung mit Freunden",
"groupPlanBillingFYIShort": "Gruppenpläne verlängern sich automatisch, sofern du sie nicht mindestens 24 Stunden vor Ablauf des aktuellen Zeitraums kündigst. Die Abbuchung erfolgt innerhalb von 24 Stunden vor der Verlängerung deines Abos, basierend auf der Anzahl der Mitglieder in deinem Gruppenplan zu diesem Zeitpunkt. Wenn du zwischen den Abrechnungszeiträumen Mitglieder hinzufügst, wird dir deren Leistung anteilig in deinem nächsten Abrechnungszeitraum in Rechnung gestellt.",
"groupPlanBillingFYI": "Gruppenpläne verlängern sich automatisch, sofern du sie nicht mindestens 24 Stunden vor Ablauf des aktuellen Zeitraums kündigst. Die Kündigung kann über den Tab „Gruppen-Abrechnung“ deines Gruppenplans erfolgen. Die Abbuchung erfolgt innerhalb von 24 Stunden vor der Verlängerung deines Abos, basierend auf der Anzahl der Mitglieder in deinem Gruppenplan zu diesem Zeitpunkt. Wenn du zwischen den Abrechnungszeiträumen Mitglieder hinzufügst, wird dir deren Leistung anteilig in deinem nächsten Abrechnungszeitraum in Rechnung gestellt.",
"chooseAnOption": "Wähle eine Option",
"upgradeExistingGroup": "Eine bestehende Gruppe upgraden",
"createNewGroup": "Eine neue Gruppe erstellen",
"yourParty": "Deine Party"
"groupPlanBillingFYI": "Gruppenpläne verlängern sich automatisch, sofern du sie nicht mindestens 24 Stunden vor Ablauf des aktuellen Zeitraums kündigst. Die Kündigung kann über den Tab „Gruppen-Abrechnung“ deines Gruppenplans erfolgen. Die Abbuchung erfolgt innerhalb von 24 Stunden vor der Verlängerung deines Abos, basierend auf der Anzahl der Mitglieder in deinem Gruppenplan zu diesem Zeitpunkt. Wenn du zwischen den Abrechnungszeiträumen Mitglieder hinzufügst, wird dir deren Leistung anteilig in deinem nächsten Abrechnungszeitraum in Rechnung gestellt."
}
+1 -4
View File
@@ -286,8 +286,5 @@
"winter2026RimeReaperWarriorSet": "Frostschnitter Krieger Set",
"winter2026SkiRogueSet": "Ski Schurken Set",
"winter2026PolarBearHealerSet": "Eisbär Heiler Set",
"winter2026MidwinterCandleMageSet": "Mittwinterkerzen Magier Set",
"spring2026FrogWarriorSet": "Frosch Set (Krieger)",
"spring2026SnowdropHealerSet": "Schneeglöckchen Set (Heiler)",
"spring2026MaypoleMageSet": "Maibaum Set (Magier)"
"winter2026MidwinterCandleMageSet": "Mittwinterkerzen Magier Set"
}
+1 -7
View File
@@ -137,11 +137,5 @@
"taskAliasPopover": "Dieser Aufgaben-Alias kann für die Integrierung in Drittanbieter-Integrationen verwendet werden. Nur Bindestriche, Unterstriche und alphanumerische Zeichen werden unterstützt. Der Aufgaben-Alias muss über alle deine Aufgaben eindeutig sein.",
"taskAliasPlaceholder": "Dein-Aufgaben-Alias-hier",
"scoreUp": "Score hoch",
"scoreDown": "Score runter",
"sureDeleteType": "Bist du sicher, dass du diese Aufgabe löschen möchtest?",
"deleteTask": "Aufgabe löschen",
"deleteXTasks": "<%= count %> Aufgaben löschen",
"confirmDeleteTasks": "Möchtest du diese Aufgaben löschen?",
"deleteType": "Lösche <%= type %>",
"brokenChallengeTaskCount": "Das ist eine von <%= count %> Aufgaben, die Teil einer Herausforderung sind, die nicht mehr existiert."
"scoreDown": "Score runter"
}
@@ -1063,18 +1063,6 @@
"backgroundElegantPalaceText": "Elegant Palace",
"backgroundElegantPalaceNotes": "Admire the colorful halls of an Elegant Palace.",
"backgrounds032026": "SET 142: Released March 2026",
"backgroundWaterfallWithRainbowText": "Waterfall with Rainbow",
"backgroundWaterfallWithRainbowNotes": "Admire the breathtaking beauty of a Waterfall with a Rainbow.",
"backgrounds042026": "SET 143: Released April 2026",
"backgroundRidingACometText": "Riding a Comet",
"backgroundRidingACometNotes": "Travel through space while Riding a Comet!",
"backgrounds052026": "SET 144: Released May 2026",
"backgroundElvenCitadelText": "Elven Citadel",
"backgroundElvenCitadelNotes": "Take the scenic journey to an Elven Citadel.",
"timeTravelBackgrounds": "Steampunk Backgrounds",
"backgroundAirshipText": "Airship",
"backgroundAirshipNotes": "Become a sky sailor on board your very own Airship.",
@@ -1086,8 +1074,6 @@
"eventBackgrounds": "Event Backgrounds",
"backgroundBirthdayBashText": "Birthday Bash",
"backgroundBirthdayBashNotes": "Habitica's having a birthday party, and everyone's invited!",
"backgroundOnAStrangePlanetText": "On a Strange Planet",
"backgroundOnAStrangePlanetNotes": "Venture where no Habitican has gone before: On a Strange Planet.",
"monthlyBackgrounds": "Monthly Backgrounds"
}
-1
View File
@@ -356,7 +356,6 @@
"hatchingPotionBalloon": "Balloon",
"hatchingPotionCryptid": "Cryptid",
"hatchingPotionOpal": "Opal",
"hatchingPotionAlien": "Alien",
"hatchingPotionNotes": "Pour this on an egg, and it will hatch as a <%= potText %> Pet.",
"premiumPotionUnlimitedNotes": "Not usable on Quest Pet eggs.",
+1 -59
View File
@@ -578,15 +578,6 @@
"weaponSpecialWinter2026MageText": "Candelabra Staff",
"weaponSpecialWinter2026MageNotes": "Candelabras help by holding multiple candles at a time—follow its lead the next time you need to multitask. Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition Winter 2025-2026 Gear.",
"weaponSpecialSpring2026WarriorText": "Mighty Froggy Foil",
"weaponSpecialSpring2026WarriorNotes": "An opportunity to duel might present itself at any moment, and with this formidable foil, you will be ready! Increases Strength by <%= str %>. Limited Edition Spring 2026 Gear.",
"weaponSpecialSpring2026RogueText": "Spring Branch",
"weaponSpecialSpring2026RogueNotes": "An opportunity to grow is nearly upon you, and with these budding branches, you will be ready! Increases Strength by <%= str %>. Limited Edition Spring 2026 Gear.",
"weaponSpecialSpring2026HealerText": "Snowdrop Staff",
"weaponSpecialSpring2026HealerNotes": "An opportunity to begin anew with a fresh start is right up ahead, and with this splendid staff, you will be ready! Increases Intelligence by <%= int %>. Limited Edition Spring 2026 Gear.",
"weaponSpecialSpring2026MageText": "Maypole Parasol",
"weaponSpecialSpring2026MageNotes": "An opportunity to celebrate approaches, and with this pretty parasol pole, you will be ready! Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition Spring 2026 Gear.",
"weaponMystery201411Text": "Pitchfork of Feasting",
"weaponMystery201411Notes": "Stab your enemies or dig in to your favorite foods - this versatile pitchfork does it all! Confers no benefit. November 2014 Subscriber Item.",
"weaponMystery201502Text": "Shimmery Winged Staff of Love and Also Truth",
@@ -635,8 +626,6 @@
"weaponMystery202512Notes": "A shining sword cast from sugar, mint, and arcane enchantments. Confers no benefit. December 2025 Subscriber Item.",
"weaponMystery202601Text": "Winter's Aegis",
"weaponMystery202601Notes": "An icy bubble shield that grants magical protection from opposing elements. Confers no benefit. January 2026 Subscriber Item.",
"weaponMystery202603Text": "Wisteria Wizard Staff",
"weaponMystery202603Notes": "Cast spells to warm the spring air and encourage the blossoms to bud! Confers no benefit. March 2026 Subscriber Item.",
"weaponMystery301404Text": "Steampunk Cane",
"weaponMystery301404Notes": "Excellent for taking a turn about town. March 3015 Subscriber Item. Confers no benefit.",
@@ -1423,15 +1412,6 @@
"armorSpecialWinter2026MageText": "Midwinter Candle Robe",
"armorSpecialWinter2026MageNotes": "Glide smoothly along your path like wax on your way to completing your Dailies. Increases Intelligence by <%= int %>. Limited Edition Winter 2025-2026 Gear.",
"armorSpecialSpring2026WarriorText": "Frog Armor",
"armorSpecialSpring2026WarriorNotes": "Spring into action just as soon as the snow begins to thaw. Increases Constitution by <%= con %>. Limited Edition Spring 2026 Gear.",
"armorSpecialSpring2026RogueText": "Birch Bark Armor",
"armorSpecialSpring2026RogueNotes": "Withstand inevitable spring rains as well as light breezes. Increases Perception by <%= per %>. Limited Edition Spring 2026 Gear.",
"armorSpecialSpring2026HealerText": "Snowdrop Gown",
"armorSpecialSpring2026HealerNotes": "Glide gracefully from a cold, dark winter into glorious spring. Increases Constitution by <%= con %>. Limited Edition Spring 2026 Gear.",
"armorSpecialSpring2026MageText": "Maypole Dancer Outfit",
"armorSpecialSpring2026MageNotes": "Arrive ready to dance, picnic, and enjoy the warm weather spring brings. Increases Intelligence by <%= int %>. Limited Edition Spring 2026 Gear.",
"armorMystery201402Text": "Messenger Robes",
"armorMystery201402Notes": "Shimmering and strong, these robes have many pockets to carry letters. Confers no benefit. February 2014 Subscriber Item.",
"armorMystery201403Text": "Forest Walker Armor",
@@ -1570,8 +1550,6 @@
"armorMystery202509Notes": "Bright silks protect you from the weather, hot or cold. Confers no benefit. September 2025 Subscriber Item.",
"armorMystery202512Text": "Cookie Champion Armor",
"armorMystery202512Notes": "Ready for battle in this plate that is both sweet and strong. Confers no benefit. December 2025 Subscriber Item.",
"armorMystery202604Text": "Audacious Astronaut Spacesuit",
"armorMystery202604Notes": "One small step for your To Do list, one giant leap for your sense of accomplishment! Confers no benefit. April 2026 Subscriber Item.",
"armorMystery301404Text": "Steampunk Suit",
"armorMystery301404Notes": "Dapper and dashing, wot! Confers no benefit. February 3015 Subscriber Item.",
@@ -1822,10 +1800,6 @@
"armorArmoireBlackPartyDressNotes": "Youre strong, smart, hearty, and so fashionable! Increases Strength, Intelligence, and Constitution by <%= attrs %> each. Enchanted Armoire: Black Hairbow Set (Item 2 of 2).",
"armorArmoireLoneCowpokeOutfitText": "Lone Cowpoke Outfit",
"armorArmoireLoneCowpokeOutfitNotes": "Whoa, there! Want to make a statement when you ride into town as a mysterious stranger ready to be productive? Heres the perfect outfit, complete with chaps and a shining, silver belt buckle. Increases Constitution by <%= con %>. Enchanted Armoire: Lone Cowpoke Set (Item 2 of 2)",
"armorArmoireSoftYellowSuitText": "Soft Yellow Suit",
"armorArmoireSoftYellowSuitNotes": "Yellow is an energetic color. Wear this to bed, and you will wake up with the sun the next morning ready to tackle a day full of tasks. Increases Constitution and Strength by <%= attrs %> each. Enchanted Armoire: Yellow Loungewear Set (Item 2 of 3).",
"armorArmoireHandstandOutfitText": "Handstand",
"armorArmoireHandstandOutfitNotes": "Things sure do look different when youre upside-down, dont they? If youre feeling stuck, its time for a fresh perspective! Increases Perception by <%= per %>. Enchanted Armoire: Handstand Set (Item 1 of 1).",
"headgear": "helm",
"headgearCapitalized": "Headgear",
@@ -2378,15 +2352,6 @@
"headSpecialWinter2026MageText": "Midwinter Candle Hat",
"headSpecialWinter2026MageNotes": "Maintain focus and illumination as you set your sights on greater goals this season. Increases Perception by <%= per %>. Limited Edition 2025-2026 Winter Gear.",
"headSpecialSpring2026WarriorText": "Frog Warrior Helm",
"headSpecialSpring2026WarriorNotes": "Frogs are well-known for their resistance to corruption. This helm will grant you their noble qualities! Increases Strength by <%= str %>. Limited Edition Spring 2026 Gear.",
"headSpecialSpring2026RogueText": "Spring Branch Helm",
"headSpecialSpring2026RogueNotes": "Make a striking statement with twigs and buds growing wild in all directions. Increases Perception by <%= per %>. Limited Edition Spring 2026 Gear.",
"headSpecialSpring2026HealerText": "Snowdrop Helm",
"headSpecialSpring2026HealerNotes": "Make a hopeful statement with these beautiful, resilient petals. Increases Intelligence by <%= int %>. Limited Edition Spring 2026 Gear.",
"headSpecialSpring2026MageText": "Mayflower Crown",
"headSpecialSpring2026MageNotes": "Make a joyous statement with bright blooms encircling your head. Increases Perception by <%= per %>. Limited Edition Spring 2026 Gear.",
"headSpecialGaymerxText": "Rainbow Warrior Helm",
"headSpecialGaymerxNotes": "In celebration of the GaymerX Conference, this special helmet is decorated with a radiant, colorful rainbow pattern! GaymerX is a game convention celebrating LGTBQ and gaming and is open to everyone.",
@@ -2573,11 +2538,7 @@
"headMystery202512Text": "Cookie Champion Helm",
"headMystery202512Notes": "Gingerbread forged with ancient magic will protect you as long as you can hold off your urge to try a bite! Confers no benefit. December 2025 Subscriber Item.",
"headMystery202602Text": "Sakura Fox Ears",
"headMystery202602Notes": "Your hearing will be sharpened by these ears such that you can hear the buds of blossoms growing on tree branches as spring approaches. Confers no benefit. February 2026 Subscriber Item.",
"headMystery202603Text": "Wisteria Wizard Hat",
"headMystery202603Notes": "This jaunty hat not only enhances your magical ability, it also has a lovely spring scent! Confers no benefit. March 2026 Subscriber Item.",
"headMystery202604Text": "Audacious Astronaut Helmet",
"headMystery202604Notes": "In space, no one can hear you check off your To Dos. But the real reward is your sense of personal accomplishment! Confers no benefit. April 2026 Subscriber Item.",
"headMystery202602Notes": " Your hearing will be sharpened by these ears such that you can hear the buds of blossoms growing on tree branches as spring approaches. Confers no benefit. February 2026 Subscriber Item.",
"headMystery301404Text": "Fancy Top Hat",
"headMystery301404Notes": "A fancy top hat for the finest of gentlefolk! January 3015 Subscriber Item. Confers no benefit.",
@@ -2808,10 +2769,6 @@
"headArmoireBlacksmithsGogglesNotes": "Shatter and heat-resistant ocular protection is yours when youre working in a forge. Increases Perception by <%= per %>. Enchanted Armoire: Blacksmith Set (Item 1 of 3).",
"headArmoireLoneCowpokeHatText": "Lone Cowpoke Hat",
"headArmoireLoneCowpokeHatNotes": "Howdy there, pardner! Dyou hate when youre out on the range, workin on tasks, and sun gets in your eyes? Well, good thing youve got a hat for that now. Increases Perception by <%= per %>. Enchanted Armoire: Lone Cowpoke Set (Item 1 of 2)",
"headArmoireFloppyYellowHatText": "Yellow Floppy Hat",
"headArmoireFloppyYellowHatNotes": "Many spells have been sewn into this simple hat, giving it a youthful yellow color. Increases all stats by <%= attrs %> each. Enchanted Armoire: Yellow Loungewear Set (Item 1 of 3).",
"headArmoireVerdantArmingCapText": "Verdant Page Arming Cap",
"headArmoireVerdantArmingCapNotes": "This comfy, cushioned coif makes you battle-ready and helps you withstand anything heavy that could come your way. Increases Perception and Constitution by <%= attrs %> each. Enchanted Armoire: Verdant Page Set (Item 1 of 2).",
"offhand": "off-hand item",
"offHandCapitalized": "Off-Hand Item",
@@ -3129,13 +3086,6 @@
"shieldSpecialWinter2026HealerText": "Starburst",
"shieldSpecialWinter2026HealerNotes": "Stars help with wayfinding, energy, and illumination—all things that help you better conquer a task list. Increases Constitution by <%= con %>. Limited Edition Winter 2025-2026 Gear.",
"shieldSpecialSpring2026WarriorText": "Frog Warrior Candelabra",
"shieldSpecialSpring2026WarriorNotes": "Not only can this candelabra light your way, you can use it to melt any lingering snow and ice. Increases Constitution by <%= con %>. Limited Edition Spring 2026 Gear.",
"shieldSpecialSpring2026RogueText": "Spring Branch",
"shieldSpecialSpring2026RogueNotes": "Reach out and reach high with these branches. They double as a back scratcher in a pinch. Increases Strength by <%= str %>. Limited Edition Spring 2026 Gear.",
"shieldSpecialSpring2026HealerText": "Snowdrop Leaf",
"shieldSpecialSpring2026HealerNotes": "Create a light breeze with this fan as the days grow warmer. It doubles as a writing utensil in a pinch. Increases Constitution by <%= con %>. Limited Edition Spring 2026 Gear.",
"shieldMystery201601Text": "Resolution Slayer",
"shieldMystery201601Notes": "This blade can be used to parry away all distractions. Confers no benefit. January 2016 Subscriber Item.",
"shieldMystery201701Text": "Time-Freezer Shield",
@@ -3166,8 +3116,6 @@
"shieldMystery202508Notes": "If you thought one spinning blade was cool looking, try two! Confers no benefit. August 2025 Subscriber Item.",
"shieldMystery202511Text": "Frost Shield",
"shieldMystery202511Notes": "This rugged shield of icy rock protects you from bad Habits but won't freeze your hands. Confers no benefit. November 2025 Subscriber Item.",
"shieldMystery202605Text": "Nightfall Shield",
"shieldMystery202605Notes": "Let the moons shining light protect you from dangers in the dark. Confers no benefit. May 2026 Subscriber Item.",
"shieldMystery301405Text": "Clock Shield",
"shieldMystery301405Notes": "Time is on your side with this towering clock shield! Confers no benefit. June 3015 Subscriber Item.",
@@ -3350,10 +3298,6 @@
"shieldArmoireDoubleBassNotes": "Bom doo bom brrrr brr brr brrrr! Gather your party for some grounding or dancing as you listen to music on this deep double bass. Increases Constitution and Strength by <%= attrs %> each. Enchanted Armoire: Musical Instrument Set 2 (Item 3 of 3)",
"shieldArmoirePrettyPinkGiftBoxText": "Pretty Pink Present",
"shieldArmoirePrettyPinkGiftBoxNotes": "Is this gift from a dear friend? A caring relative? A true love? A secret admirer? Whoever sent it knows youll be pleased with whats inside. Increases all stats by <%= attrs %> each. Enchanted Armoire: Pretty in Pink Set (Item 2 of 2)",
"shieldArmoireSoftYellowPillowText": "Soft Yellow Pillow",
"shieldArmoireSoftYellowPillowNotes": "The experienced warrior packs a pillow for any expedition. Grow and shine as you consolidate all youve learned during past adventures… even while you nap. Increases Intelligence and Perception by <%= attrs %> each. Enchanted Armoire: Yellow Loungewear Set (Item 3 of 3).",
"shieldArmoireVerdantBannerText": "Verdant Page Banner",
"shieldArmoireVerdantBannerNotes": "Wave your banner high to signal friends its time to rally together! Intelligence by <%= int %>. Enchanted Armoire: Verdant Page Set (Item 2 of 2).",
"back": "Back Accessory",
"backBase0Text": "No Back Accessory",
@@ -3448,8 +3392,6 @@
"backMystery202601Notes": "This mark grants the user control over the elements of the season of cold and frost. Confers no benefit. January 2026 Subscriber Item.",
"backMystery202602Text": "Five Tails of Sakura",
"backMystery202602Notes": "These fluffy tails are the color of cherry blossoms, a reminder that spring is on the way! Confers no benefit. February 2026 Subscriber Item.",
"backMystery202605Text": "Nightfall Nimbus",
"backMystery202605Notes": "A glowing aureole of moonlight and starlight to illuminate the darkest night. Confers no benefit. May 2026 Subscriber Item.",
"backArmoireHarpsichordText": "Harpsichord",
"backArmoireHarpsichordNotes": "Pting! Ptiiing! Gather your party for a dinner or picnic and listen to a tinny melody on this harpsichord. Increases Perception and Intelligence by <%= attrs %> each. Enchanted Armoire: Musical Instrument Set 2 (Item 1 of 3)",
+1 -13
View File
@@ -428,17 +428,5 @@
"interestedLearningMore": "Interested in Learning More?",
"checkGroupPlanFAQ": "Check out the <a href='/static/faq#what-is-group-plan'>Group Plans FAQ</a> to learn how to get the most out of your shared task experience.",
"groupPlanBillingFYI": "Group Plan subscriptions automatically renew unless you cancel at least 24 hours before the end of your current period. You can cancel from the Group Billing tab of your Group Plan. You will be charged within 24 hours before your subscription renews, based on the number of members in your Group Plan at that time. If you add members between payment periods, you'll see an additional prorated charge for their benefits at your next billing cycle.",
"groupPlanBillingFYIShort": "Group Plan subscriptions automatically renew unless you cancel at least 24 hours before the end of your current period. You will be charged within 24 hours before your subscription renews, based on the number of members in your Group Plan at that time. If you add members between payment periods, you'll see an additional prorated charge for their benefits at your next billing cycle.",
"chooseAnOption": "Choose an Option",
"upgradeExistingGroup": "Upgrade an Existing Group",
"createNewGroup": "Create a New Group",
"yourParty": "Your Party",
"previouslyUpgradedGroup": "Previously upgraded Group",
"inviteOthersForAdditional": "Invite others to your Group for an additional",
"perMember": "per member",
"additionalMembersProrated": "Additional members invited during the month will be added to the next billing cycle's total as a pro-rated charge.",
"oneMember": "1 member",
"membersCount": "<%= count %> members",
"pendingCount": "(<%= count %> pending)",
"upgradeCancelsPendingInvites": "Upgrading your Party will cancel all pending invites"
"groupPlanBillingFYIShort": "Group Plan subscriptions automatically renew unless you cancel at least 24 hours before the end of your current period. You will be charged within 24 hours before your subscription renews, based on the number of members in your Group Plan at that time. If you add members between payment periods, you'll see an additional prorated charge for their benefits at your next billing cycle."
}
+20 -24
View File
@@ -223,30 +223,26 @@
"fall2024UnderworldSorcerorMageSet": "Underworld Sorceror Set (Mage)",
"fall2024SpaceInvaderHealerSet": "Space Invader Set (Healer)",
"fall2024BlackCatRogueSet": "Black Cat Set (Rogue)",
"winter2025MooseWarriorSet": "Moose Set (Warrior)",
"winter2025AuroraMageSet": "Aurora Set (Mage)",
"winter2025StringLightsHealerSet": "String Lights Set (Healer)",
"winter2025SnowRogueSet": "Snow Set (Rogue)",
"spring2025SunshineWarriorSet": "Sunshine Set (Warrior)",
"spring2025CrystalPointRogueSet": "Crystal Point Set (Rogue)",
"spring2025PlumeriaHealerSet": "Plumeria Set (Healer)",
"spring2025MantisMageSet": "Mantis Set (Mage)",
"summer2025ScallopWarriorSet": "Scallop Set (Warrior)",
"summer2025SquidRogueSet": "Squid Set (Rogue)",
"summer2025SeaAngelHealerSet": "Sea Angel Set (Healer)",
"summer2025FairyWrasseMageSet": "Fairy Wrasse Set (Mage)",
"fall2025SasquatchWarriorSet": "Sasquatch Set (Warrior)",
"fall2025SkeletonRogueSet": "Skeleton Set (Rogue)",
"fall2025KoboldHealerSet": "Kobold Set (Healer)",
"fall2025MaskedGhostMageSet": "Masked Ghost Set (Mage)",
"winter2026RimeReaperWarriorSet": "Rime Reaper Set (Warrior)",
"winter2026SkiRogueSet": "Ski Set (Rogue)",
"winter2026PolarBearHealerSet": "Polar Bear Set (Healer)",
"winter2026MidwinterCandleMageSet": "Midwinter Candle Set (Mage)",
"spring2026FrogWarriorSet": "Frog Set (Warrior)",
"spring2026BranchRogueSet": "Spring Branch Set (Rogue)",
"spring2026SnowdropHealerSet": "Snowdrop Set (Healer)",
"spring2026MaypoleMageSet": "Maypole Set (Mage)",
"winter2025MooseWarriorSet": "Moose Warrior Set",
"winter2025AuroraMageSet": "Aurora Mage Set",
"winter2025StringLightsHealerSet": "String Lights Healer Set",
"winter2025SnowRogueSet": "Snow Rogue Set",
"spring2025SunshineWarriorSet": "Sunshine Warrior Set",
"spring2025CrystalPointRogueSet": "Crystal Point Rogue Set",
"spring2025PlumeriaHealerSet": "Plumeria Healer Set",
"spring2025MantisMageSet": "Mantis Mage Set",
"summer2025ScallopWarriorSet": "Scallop Warrior Set",
"summer2025SquidRogueSet": "Squid Rogue Set",
"summer2025SeaAngelHealerSet": "Sea Angel Healer Set",
"summer2025FairyWrasseMageSet": "Fairy Wrasse Mage Set",
"fall2025SasquatchWarriorSet": "Sasquatch Warrior Set",
"fall2025SkeletonRogueSet": "Skeleton Rogue Set",
"fall2025KoboldHealerSet": "Kobold Healer Set",
"fall2025MaskedGhostMageSet": "Masked Ghost Mage Set",
"winter2026RimeReaperWarriorSet": "Rime Reaper Warrior Set",
"winter2026SkiRogueSet": "Ski Rogue Set",
"winter2026PolarBearHealerSet": "Polar Bear Healer Set",
"winter2026MidwinterCandleMageSet": "Midwinter Candle Mage Set",
"winterPromoGiftHeader": "GIFT A SUBSCRIPTION, GET ONE 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",
+12 -22
View File
@@ -221,7 +221,7 @@
"questTRexUndeadBoss": "Skeletal Tyrannosaur",
"questTRexUndeadRageTitle": "Skeleton Healing",
"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!",
"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 Tyrannosaur Eggs for purchase in the Market",
@@ -282,7 +282,7 @@
"questDilatoryDistress2Boss": "Water Skull Swarm",
"questDilatoryDistress2RageTitle": "Swarm Respawn",
"questDilatoryDistress2RageDescription": "Swarm Respawn: This bar fills when you don't complete your Dailies. When it is full, the Water Skull Swarm will heal 30% of its remaining health!",
"questDilatoryDistress2RageEffect": "Water Skull Swarm uses SWARM RESPAWN!\n\nEmboldened by their victories, more skulls pour forth from the crevasse, bolstering the swarm!",
"questDilatoryDistress2RageEffect": "`Water Skull Swarm uses SWARM RESPAWN!`\n\nEmboldened by their victories, more skulls pour forth from the crevasse, bolstering the swarm!",
"questDilatoryDistress2DropSkeletonPotion": "Skeleton Hatching Potion",
"questDilatoryDistress2DropCottonCandyBluePotion": "Cotton Candy Blue Hatching Potion",
"questDilatoryDistress2DropHeadgear": "Fire Coral Circlet (Headgear)",
@@ -398,7 +398,7 @@
"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\nA curtain of colorful bubbles obscures the monster for a moment, and when it clears, some of its wounds have vanished!",
"questAxolotlRageEffect": "`Magical Axolotl uses AXOLOTL REGENERATION!`\n\n`A curtain of colorful bubbles obscures the monster for a moment, and when it clears, some of its wounds have vanished!`",
"questTurtleText": "Guide the Turtle",
"questTurtleNotes": "Help! This giant sea turtle cannot find her way to her nesting beach. She returns there every year to lay her eggs, but this year Inkomplete Bay is filled with toxic Task Flotsam made of red Dailies and unchecked To Do's. \"She's thrashing in a panic!\" @JessicaChase says.<br><br>@UncommonCriminal nods. \"It's because her guiding senses are fogged and confused.\"<br><br>@Scarabsi grabs your arm. \"Can you help clear the Task Flotsam blocking her path? It may be hazardous, but we have to help her!\"",
@@ -435,7 +435,7 @@
"questTaskwoodsTerror1Boss": "Fire Skull Swarm",
"questTaskwoodsTerror1RageTitle": "Swarm Respawn",
"questTaskwoodsTerror1RageDescription": "Swarm Respawn: This bar fills when you don't complete your Dailies. When it is full, the Fire Skull Swarm will heal 30% of its remaining health!",
"questTaskwoodsTerror1RageEffect": "Fire Skull Swarm uses SWARM RESPAWN!\n\nEmboldened by their victories, more skulls swirl around you in a gout of flame!",
"questTaskwoodsTerror1RageEffect": "`Fire Skull Swarm uses SWARM RESPAWN!`\n\nEmboldened by their victories, more skulls swirl around you in a gout of flame!",
"questTaskwoodsTerror1DropSkeletonPotion": "Skeleton Hatching Potion",
"questTaskwoodsTerror1DropRedPotion": "Red Hatching Potion",
"questTaskwoodsTerror1DropHeadgear": "Pyromancer's Turban (Headgear)",
@@ -507,7 +507,7 @@
"questStoikalmCalamity1Boss": "Earth Skull Swarm",
"questStoikalmCalamity1RageTitle": "Swarm Respawn",
"questStoikalmCalamity1RageDescription": "Swarm Respawn: This bar fills when you don't complete your Dailies. When it is full, the Earth Skull Swarm will heal 30% of its remaining health!",
"questStoikalmCalamity1RageEffect": "Earth Skull Swarm uses SWARM RESPAWN!\n\nMore skulls break free from the ground, their teeth chattering in the cold!",
"questStoikalmCalamity1RageEffect": "`Earth Skull Swarm uses SWARM RESPAWN!`\n\nMore skulls break free from the ground, their teeth chattering in the cold!",
"questStoikalmCalamity1DropSkeletonPotion": "Skeleton Hatching Potion",
"questStoikalmCalamity1DropDesertPotion": "Desert Hatching Potion",
"questStoikalmCalamity1DropArmor": "Mammoth Rider Armor",
@@ -554,7 +554,7 @@
"questMayhemMistiflying1Boss": "Air Skull Swarm",
"questMayhemMistiflying1RageTitle": "Swarm Respawn",
"questMayhemMistiflying1RageDescription": "Swarm Respawn: This bar fills when you don't complete your Dailies. When it is full, the Air Skull Swarm will heal 30% of its remaining health!",
"questMayhemMistiflying1RageEffect": "Air Skull Swarm uses SWARM RESPAWN!\n\nEmboldened by their victories, more skulls come whirling out of the clouds!",
"questMayhemMistiflying1RageEffect": "`Air Skull Swarm uses SWARM RESPAWN!`\n\nEmboldened by their victories, more skulls come whirling out of the clouds!",
"questMayhemMistiflying1DropSkeletonPotion": "Skeleton Hatching Potion",
"questMayhemMistiflying1DropWhitePotion": "White Hatching Potion",
"questMayhemMistiflying1DropArmor": "Roguish Rainbow Messenger Robes (Armor)",
@@ -623,7 +623,7 @@
"questLostMasterclasser3Boss": "Void Skull Swarm",
"questLostMasterclasser3RageTitle": "Swarm Respawn",
"questLostMasterclasser3RageDescription": "Swarm Respawn: This bar fills when you don't complete your Dailies. When it is full, the Void Skull Swarm will heal 30% of its remaining health!",
"questLostMasterclasser3RageEffect": "Void Skull Swarm uses SWARM RESPAWN!\n\nEmboldened by their victories, more skulls scream down from the heavens, bolstering the swarm!",
"questLostMasterclasser3RageEffect": "`Void Skull Swarm uses SWARM RESPAWN!`\n\nEmboldened by their victories, more skulls scream down from the heavens, bolstering the swarm!",
"questLostMasterclasser3DropBodyAccessory": "Aether Amulet (Body Accessory)",
"questLostMasterclasser3DropBasePotion": "Base Hatching Potion",
"questLostMasterclasser3DropGoldenPotion": "Golden Hatching Potion",
@@ -637,7 +637,7 @@
"questLostMasterclasser4Boss": "Anti'zinnya",
"questLostMasterclasser4RageTitle": "Siphoning Void",
"questLostMasterclasser4RageDescription": "Siphoning Void: This bar fills when you don't complete your Dailies. When it is full, Anti'zinnya will remove the party's Mana!",
"questLostMasterclasser4RageEffect": "Anti'zinnya uses SIPHONING VOID! In a twisted inversion of the Ethereal Surge spell, you feel your magic drain away into the darkness!",
"questLostMasterclasser4RageEffect": "`Anti'zinnya uses SIPHONING VOID!` In a twisted inversion of the Ethereal Surge spell, you feel your magic drain away into the darkness!",
"questLostMasterclasser4DropBackAccessory": "Aether Cloak (Back Accessory)",
"questLostMasterclasser4DropWeapon": "Aether Crystals (Two-Handed Weapon)",
"questLostMasterclasser4DropMount": "Invisible Aether Mount",
@@ -804,7 +804,7 @@
"questWaffleBoss": "Awful Waffle",
"questWaffleRageTitle": "Maple Mire",
"questWaffleRageDescription": "Maple Mire: This bar fills when you don't complete your Dailies. When it is full, the Awful Waffle will subtract from the pending damage that party members have built up!",
"questWaffleRageEffect": "Awful Waffle uses MAPLE MIRE! Sticky sappy syrup slows your swings and spells! Pending damage reduced.",
"questWaffleRageEffect": "`Awful Waffle uses MAPLE MIRE!` Sticky sappy syrup slows your swings and spells! Pending damage reduced.",
"questWaffleDropDessertPotion": "Confection Hatching Potion",
"questWaffleUnlockText": "Unlocks Confection Hatching Potions for purchase in the Market",
@@ -875,7 +875,7 @@
"questVirtualPetBoss": "Wotchimon",
"questVirtualPetRageTitle": "The Beepening",
"questVirtualPetRageDescription": "This bar fills when you don't complete your Dailies. When it is full, the Wotchimon will take away some of your party's pending damage!",
"questVirtualPetRageEffect": "Wotchimon uses Bothersome Beep! Wotchimon sounds a bothersome beep, and its happiness bar suddenly disappears! Pending damage reduced.",
"questVirtualPetRageEffect": "`Wotchimon uses Bothersome Beep!` Wotchimon sounds a bothersome beep, and its happiness bar suddenly disappears! Pending damage reduced.",
"questVirtualPetDropVirtualPetPotion": "Virtual Pet Hatching Potion",
"questVirtualPetUnlockText": "Unlocks Virtual Pet Hatching Potion for purchase in the Market",
@@ -885,7 +885,7 @@
"questPinkMarbleBoss": "Cupido",
"questPinkMarbleRageTitle": "Pink Punch",
"questPinkMarbleRageDescription": "This bar fills when you don't complete your Dailies. When it is full, Cupido will take away some of your party's pending damage!",
"questPinkMarbleRageEffect": "Cupido uses Pink Punch! That wasn't affectionate at all! Your partymates are taken aback. Pending damage reduced.",
"questPinkMarbleRageEffect": "`Cupido uses Pink Punch!` That wasn't affectionate at all! Your partymates are taken aback. Pending damage reduced.",
"questPinkMarbleDropPinkMarblePotion": "Pink Marble Hatching Potion",
"questPinkMarbleUnlockText": "Unlocks Pink Marble Hatching Potions for purchase in the Market.",
@@ -997,15 +997,5 @@
"questFungiRageDescription": "This bar fills when you don't complete your Dailies. When it's full, the Moody Mushroom will take away some of your party's pending damage",
"questFungiRageEffect": "A Mist emanates from the Moody Mushroom and surrounds your party, dampening the mood and subduing your magic. The party's MP is reduced!",
"questFungiDropFungiPotion": "Fungi Hatching Potion",
"questFungiUnlockText": "Unlocks Fungi Hatching Potions for purchase in the Market.",
"questAlienText": "Invasion of the Motivation Snatchers",
"questAlienNotes": "Its been a strange few days in Habitica. The great flying saucer still hovers near the Flourishing Fields. It hums oddly. Why is it lingering? April Fools Day has passed, and the Master of Rogues' time in the spotlight has ended.<br><br>You wander toward the light of the space ship. You may as well check it out and get a few steps in while youre at it.<br><br>As you get closer you see the April Fool, looking a bit grim. His face appears greenish in the light of the ships beam.<br><br>”'Twas my plan to get some potions for everyone, a little gift so all can enjoy their little extraterrestrial pals again! But I just cant work up the gumption… I do believe I know why,” the Fool says, nodding toward the beam.<br><br>Little symbols are being sucked up into the ship. Its all your checked off tasks! No wonder your motivations been lackluster.<br><br>”Our motivation is being abducted!” you exclaim. “We have to rescue it before it ends up in deep space somewhere!”<br><br>The Fool smiles. “Concentrate your thoughts on the tasks you know you need to finish! Ill do the rest with a bit of magic.”",
"questAlienCompletion": "Youve managed to wrestle back the stolen motivation with your determination and the Fools magic power. As you feel your drive returning, the UFO descends, and a ramp slowly comes out along with a large, green, one-eyed creature. While strange-looking, it doesnt seem threatening.<br><br>“Looks like we went a little far trying to harvest a little extra encouragement from your fine city,” it says. “Apologies for that, and fantastic work getting it back. The extra aura of your efforts actually charged up the ships engine enough to get us home! Please, take these with our thanks.”<br><br>“Ooh potions,” says the Fool, “how delightful, and how convenient for me that you have them all ready to go!”",
"questAlienBoss": "Encouragement Thief, the Extraterrestrial",
"questAlienRageTitle": "Intergalactic Impediment",
"questAlienRageDescription": "This bar fills when you don't complete your Dailies. When it is full, the Extraterrestrial will discourage you by recovering some of its Health!",
"questAlienRageEffect": "Encouragement Thief uses Intergalactic Impediment! You've backslid right through hyperspace. Your opponent recovers HP!",
"questAlienDropAlienPotion": "Alien Hatching Potion",
"questAlienUnlockText": "Unlocks Alien Hatching Potion for purchase in the Market"
"questFungiUnlockText": "Unlocks Fungi Hatching Potions for purchase in the Market."
}
+2 -9
View File
@@ -1,15 +1,8 @@
{
"rebirthNew": "Rebirth: New Adventure Available!",
"rebirthUnlock": "You've unlocked Rebirth! This special Market item allows you to begin a new game at level 1 while keeping your tasks, achievements, pets, and more. Use it to breathe new life into Habitica if you feel you've achieved it all, or to experience new features with the fresh eyes of a beginning character!",
"rebirthUnlockedNewItem": "Orb of Rebirth Unlocked",
"rebirthUnlockedOrb": "A new adventure is available!",
"rebirthUnlockedDesc": "Use the Orb of Rebirth to breathe new life into your Habitica adventure once you feel you've achieved it all! Begin again at level 1 while keeping your tasks, Achievements, and Pets with this special item found in the Market.",
"rebirthNewAchievement": "New Achievement",
"rebirthNewAdventure": "A new adventure begins now!",
"rebirthAchievement": "You've used the Orb of Rebirth <strong><%= number %></strong> time, and your highest level reached is <strong><%= level %></strong>.",
"rebirthAchievementPlural": "You've used the Orb of Rebirth <strong><%= number %></strong> times, and your highest level reached is <strong><%= level %></strong>.",
"rebirthAchievement100": "You've used the Orb of Rebirth <strong><%= number %></strong> times, and your highest level reached is <strong>100</strong> or higher.",
"rebirthStackInfo": "This achievement will stack each time you use the Orb of Rebirth.",
"rebirthAchievement": "You've begun a new adventure! This is Rebirth <%= number %> for you, and the highest Level you've attained is <%= level %>. To stack this Achievement, begin your next new adventure when you've reached an even higher Level!",
"rebirthAchievement100": "You've begun a new adventure! This is Rebirth <%= number %> for you, and the highest Level you've attained is 100 or higher. To stack this Achievement, begin your next new adventure when you've reached at least 100!",
"rebirthBegan": "Began a New Adventure",
"rebirthText": "Began <%= rebirths %> New Adventures",
"rebirthOrb": "Used an Orb of Rebirth to start over after attaining Level <%= level %>.",
@@ -183,9 +183,6 @@
"mysterySet202512": "Cookie Champion Set",
"mysterySet202601": "Winter's Aegis Set",
"mysterySet202602": "Sakura Fox Set",
"mysterySet202603": "Wisteria Wizard Set",
"mysterySet202604": "Audacious Astronaut Set",
"mysterySet202605": "Nightfall Nimbus Set",
"mysterySet301404": "Steampunk Standard Set",
"mysterySet301405": "Steampunk Accessories Set",
"mysterySet301703": "Peacock Steampunk Set",
-7
View File
@@ -123,13 +123,6 @@
"dayOfMonth": "Day of the Month",
"month": "Month",
"months": "Months",
"every": "every",
"everyDay": "every day",
"everyWeek": "every week",
"everyMonth": "every Month",
"everyXMonths": "every <%= count %> Months",
"everyYear": "every year",
"fifthWeekWarning": "This task will not appear due during months with less <%= day %>s.",
"week": "Week",
"weeks": "Weeks",
"year": "Year",
+1 -2
View File
@@ -108,6 +108,5 @@
"cannotClose": "This Challenge cannot be closed because one or more players have reported it as inappropriate. A staff members will contact you shortly with instructions. If over 48 hours have passed and you have not heard from them, please email admin@habitica.com for assistance.",
"abuseFlagModalBodyChallenge": "You should only report a Challenge that violates the <%= firstLinkStart %>Community Guidelines<%= linkEnd %> and/or <%= secondLinkStart %>Terms of Service<%= linkEnd %>. Submitting a false report is a violation of Habitica's Community Guidelines.",
"cannotMakeChallenge": "You are unable to create public Challenges as your account currently does not have chat privileges. Please contact admin@habitica.com for more information.",
"deleteChallengeRefundDescription": "If you delete this Challenge, you will be refunded the Gem prize and the Challenge tasks will remain on the participants' task boards.",
"brokenTask": "Broken Challenge Link"
"deleteChallengeRefundDescription": "If you delete this Challenge, you will be refunded the Gem prize and the Challenge tasks will remain on the participants' task boards."
}
+1 -3
View File
@@ -191,7 +191,5 @@
"titleHaircolor": "Hair Colours",
"titleHairbase": "Hair Styles",
"customizations": "Customisations",
"skins": "Skins",
"pointsAvailable": "Points Available",
"assignedStat": "Assigned Stat"
"skins": "Skins"
}
+1 -2
View File
@@ -2556,6 +2556,5 @@
"weaponMystery202111Notes": "Shape the flow of time with this mysterious and powerful staff. Confers no benefit. November 2021 Subscriber Item.",
"weaponMystery202212Text": "Glacial Wand",
"weaponSpecialWinter2024MageNotes": "Thanks to a generous, magical narwhal that sensed your great abilities, you have been gifted a tusk that lets you sense changes happening around you. Increases Intelligence by <%= int %>. Limited Edition Winter 2023-2024 Gear.",
"weaponSpecialSpring2024RogueNotes": "Challenges that are as hard as ice can be sliced into smaller pieces. Increases Strength by <%= str %>. Limited Edition Spring 2024 Gear.",
"backMystery202602Notes": "These fluffy tails are the colour of cherry blossoms, a reminder that spring is on the way! Confers no benefit. February 2026 Subscriber Item."
"weaponSpecialSpring2024RogueNotes": "Challenges that are as hard as ice can be sliced into smaller pieces. Increases Strength by <%= str %>. Limited Edition Spring 2024 Gear."
}
+1 -2
View File
@@ -242,6 +242,5 @@
"newMessage": "New Message",
"targetUserNotExist": "Target User: '<%= userName %>' does not exist.",
"rememberToBeKind": "Please remember to be kind, respectful, and follow the <a href='/static/community-guidelines' target='_blank'>Community Guidelines</a>.",
"gem": "Gem",
"confirmPurchase": "Confirm Purchase"
"gem": "Gem"
}
+1 -5
View File
@@ -137,9 +137,5 @@
"taskAliasPopover": "This task alias can be used when integrating with 3rd party integrations. Only dashes, underscores, and alphanumeric characters are supported. The task alias must be unique among all your tasks.",
"taskAliasPlaceholder": "your-task-alias-here",
"scoreUp": "Score up",
"scoreDown": "Score down",
"deleteType": "Delete <%= type %>",
"deleteTask": "Delete Task",
"deleteXTasks": "Delete <%= count %> Tasks",
"sureDeleteType": "Are you sure you want to delete this task?"
"scoreDown": "Score down"
}
+82 -82
View File
@@ -3,9 +3,9 @@
"onwards": "¡Adelante!",
"levelup": "Al cumplir tus objetivos en la vida real, ¡has subido de nivel y has recuperado toda tu salud!",
"reachedLevel": "Has Alcanzado el Nivel <%= level %>",
"achievementLostMasterclasser": "Completista de Aventuras: Serie Arquimaestra",
"achievementLostMasterclasser": "Completador de Aventuras: Serie Arquimaestra",
"achievementLostMasterclasserText": "¡Ha completado las dieciséis misiones en la Serie Arquimaestra y resuelto el misterio de la Arquimaestra Perdida!",
"achievementLostMasterclasserModalText": "¡Completaste las dieciséis misiones en la Serie Arquimaestra y resolviste el misterio de la Arquimaestra Perdida!",
"achievementLostMasterclasserModalText": "¡Completaste las dieciséis misiones en la Serie Maestro de Clases y resolviste el misterio de la Arquimaestra Perdida!",
"achievementMindOverMatter": "La mente sobre la materia",
"achievementMindOverMatterText": "Ha completado las misiones de la Roca, el Limo y el Hilo.",
"achievementMindOverMatterModalText": "¡Completaste las misiones de mascotas de la Roca, el Limo y el Hilo!",
@@ -24,106 +24,106 @@
"achievementAridAuthorityText": "Por domar todas las Monturas Desérticas.",
"achievementAridAuthority": "Autoridad Árida",
"achievementDustDevilModalText": "¡Conseguiste todas las Mascotas Desérticas!",
"achievementDustDevilText": "Ha conseguido todas las Mascotas Desérticas.",
"achievementDustDevilText": "Por conseguir todas las Mascotas Desérticas.",
"achievementDustDevil": "Demonio de Polvo",
"achievementMonsterMagus": "Monstruo Magus",
"achievementUndeadUndertakerModalText": "¡Has domado todas las Monturas Zombi!",
"achievementUndeadUndertakerText": "Ha domado todas las Monturas Zombi.",
"achievementUndeadUndertakerText": "Por domar todas las Monturas Zombie.",
"achievementUndeadUndertaker": "Sepulturero de Muertos Vivientes",
"achievementMonsterMagusModalText": "¡Has conseguido todas las Mascotas Zombi!",
"achievementMonsterMagusText": "Ha conseguido todas las Mascotas Zombi.",
"achievementMonsterMagusText": "Por conseguir todas las Mascotas Zombi.",
"achievementPartyOn": "¡Tu equipo llegó a 4 miembros!",
"achievementPartyUp": "¡Formaste un equipo con alguien más!",
"achievementPearlyProModalText": "¡Has domado todas las Monturas Blancas!",
"achievementPearlyProText": "Ha domado todas las Monturas Blancas.",
"achievementPearlyProModalText": "¡Has domado todas las Mascotas Blancas!",
"achievementPearlyProText": "Ha domado Todas las Mascotas Blancas.",
"achievementPrimedForPaintingModalText": "¡Has conseguido todas las Mascotas Blancas!",
"achievementPrimedForPaintingText": "Ha conseguido todas las Mascotas Blancas.",
"achievementPrimedForPainting": "Preparado para Pintar",
"achievementPrimedForPainting": "Preparado para pintar",
"hideAchievements": "Ocultar <%= category %>",
"showAllAchievements": "Mostrar Todos <%= category %>",
"onboardingCompleteDesc": "Has ganado <strong>5 Logros</strong> y <strong class=\"gold-amount\">100 de Oro</strong> por completar la lista.",
"showAllAchievements": "Mostrar todo <%= category %>",
"onboardingCompleteDesc": "Has ganado <strong>5 logros</strong> y <strong class=\"gold-amount\">100 de oro</strong> por completar la lista.",
"earnedAchievement": "¡Has conseguido un logro!",
"viewAchievements": "Ver Logros",
"letsGetStarted": "¡Comencemos!",
"onboardingProgress": "<%= percentage %> % de progreso",
"gettingStartedDesc": "¡Completa estas tareas de introducción y ganarás <strong>5 Logros</strong> y <strong class=\"gold-amount\">100 de Oro</strong> una vez hayas terminado!",
"gettingStartedDesc": "¡Completa estas tareas de incorporación y ganarás <strong>5 logros</strong> y <strong class=\"gold-amount\">100 de oro</strong> una vez hayas terminado!",
"achievementCreatedTaskText": "Creó su primera tarea.",
"achievementCreatedTask": "Crea tu primera tarea",
"achievementFedPet": "Alimenta a una Mascota",
"achievementFedPetModalText": "Hay muchos tipos diferentes de alimentos, pero las Mascotas pueden ser selectivas",
"achievementFedPet": "Alimenta a una mascota",
"achievementFedPetModalText": "Hay muchos tipos diferentes de alimentos, pero las mascotas pueden ser exigentes",
"achievementHatchedPetModalText": "Dirígete a tu inventario y prueba a combinar una poción de eclosión y un huevo",
"achievementCompletedTaskText": "Ha completado su primera tarea.",
"achievementPurchasedEquipmentModalText": "El Equipamiento es una forma de personalizar tu avatar y mejorar tus Estadísticas",
"achievementPurchasedEquipment": "Compra una pieza de Equipamiento",
"achievementCompletedTaskModalText": "Marca como completada cualquier tarea para conseguir recompensas",
"achievementCompletedTaskText": "Has completado tu primera tarea.",
"achievementPurchasedEquipmentModalText": "El equipamiento es una forma de personalizar tu avatar y mejorar tus estadísticas",
"achievementPurchasedEquipment": "Compra una pieza de equipamiento",
"achievementCompletedTaskModalText": "Marca alguna de tus tareas para conseguir recompensas",
"achievementCompletedTask": "Completa una tarea",
"achievementCreatedTaskModalText": "Añade una tarea para algo que te gustaría cumplir esta semana",
"achievementFedPetText": "Alimentó a su primera mascota.",
"achievementPurchasedEquipmentText": "Adquirió su primera pieza de equipamento.",
"achievementPurchasedEquipmentText": "Adquirió su primera pieza de equipo.",
"achievementHatchedPetText": "Eclosionó su primera mascota.",
"achievementHatchedPet": "Eclosiona una Mascota",
"achievementHatchedPet": "Eclosiona una mascota",
"achievementPearlyPro": "Coleccionista de Perlas",
"achievementTickledPinkModalText": "¡Has conseguido todas las mascotas de Algodón de Azúcar Rosa!",
"achievementTickledPinkText": "Ha conseguido todas las mascotas de Algodón de Azúcar Rosa.",
"achievementTickledPinkModalText": "¡Has conseguido todas las mascotas de algodón de azúcar rosa!",
"achievementTickledPinkText": "Ha conseguido todas las mascotas de algodón de azúcar rosa.",
"achievementTickledPink": "cosquillas rosa",
"foundNewItemsCTA": "¡Dirígete a tu Inventario e intenta combinar tu nueva poción de eclosión y un huevo!",
"foundNewItemsCTA": "¡Dirígete a tu Inventario e intenta combinar tu nueva poción para incubar y un huevo!",
"foundNewItemsExplanation": "Completar tareas te da la oportunidad de encontrar objetos, como Huevos, Pociones de Eclosión y Alimento para Mascotas.",
"foundNewItems": "¡Encontraste nuevos artículos!",
"onboardingCompleteDescSmall": "¡Si quieres aún más, mira tus Logros y empieza a coleccionarlos!",
"yourProgress": "Tu Progreso",
"onboardingComplete": "¡Has completado tus tareas de introducción!",
"achievementRosyOutlookModalText": "¡Has domado todas las Monturas de Algodón de Azúcar Rosa!",
"achievementRosyOutlookText": "Ha domado todas las Monturas de Algodón de Azúcar Rosa.",
"achievementRosyOutlook": "Perspectiva Optimista",
"achievementBareNecessities": "Necesidades Básicas",
"achievementBugBonanzaModalText": "¡Has completado las misiones de las mascotas Escarabajo, Mariposa, Caracol y Araña!",
"achievementBugBonanzaText": "Ha completado las misiones de las mascotas Escarabajo, Mariposa, Caracol y Araña.",
"achievementBareNecessitiesModalText": "¡Has completado las misiones de las mascotas Mono, Perezoso y Brote!",
"achievementBareNecessitiesText": "Ha completado las misiones de las mascotas Mono, Perezoso y Brote.",
"onboardingComplete": "¡Has completado tus tareas de incorporación!",
"achievementRosyOutlookModalText": "¡Has domado todas las monturas de algodón de azúcar rosa!",
"achievementRosyOutlookText": "Ha domado todas las monturas de algodón de azúcar rosa.",
"achievementRosyOutlook": "Perspectiva optimista",
"achievementBareNecessities": "Necesidades básicas",
"achievementBugBonanzaModalText": "¡Has completado las misiones de las mascotas escarabajo, mariposa, caracol y araña!",
"achievementBugBonanzaText": "Ha completado las misiones de las mascotas escarabajo, mariposa, caracol y araña.",
"achievementBareNecessitiesModalText": "¡Has completado las misiones de las mascotas mono, perezoso y brote!",
"achievementBareNecessitiesText": "Ha completado las misiones de las mascotas mono, perezoso y brote.",
"achievementBugBonanza": "Bonanza insectil",
"achievementFreshwaterFriendsModalText": "¡Has completado las misiones de las mascotas Ajolote, Rana e Hipopótamo!",
"achievementFreshwaterFriendsText": "Ha completado las misiones de las mascotas Ajolote, Rana, e Hipopótamo.",
"achievementFreshwaterFriends": "Amigos de Agua Dulce",
"achievementFreshwaterFriendsModalText": "¡Has completado las misiones de las mascotas ajolote, rana e hipopótamo!",
"achievementFreshwaterFriendsText": "Ha completado las misiones de las mascotas ajolote, rana, e hipopótamo.",
"achievementFreshwaterFriends": "Amigos de agua dulce",
"achievementAllThatGlittersModalText": "¡Has domado todas las Monturas Doradas!",
"achievementAllThatGlittersText": "Ha domado todas las Monturas Doradas.",
"achievementGoodAsGoldModalText": "¡Has conseguido todas las Mascotas Doradas!",
"achievementGoodAsGoldText": "Ha conseguido todas las Mascotas Doradas.",
"achievementGoodAsGold": "Corazón de Oro",
"achievementGoodAsGoldText": "Ha conseguido todas las Mascotas doradas.",
"achievementGoodAsGold": "Más Bueno que el Pan",
"yourRewards": "Tus Recompensas",
"achievementAllThatGlitters": "Todo lo que Brilla",
"achievementBoneCollector": "Coleccionista de Huesos",
"achievementBoneCollectorText": "Ha conseguido todas las Mascotas Esqueleto.",
"achievementAllThatGlitters": "Todo lo que brilla",
"achievementBoneCollector": "Coleccionista de huesos",
"achievementBoneCollectorText": "Ha conseguido todas las Mascotas esqueléticas.",
"achievementSeeingRed": "Rojo de Ira",
"achievementSkeletonCrewModalText": "¡Has domado todas las Monturas Esqueleto!",
"achievementSkeletonCrewText": "Ha domado todas las Monturas Esqueleto.",
"achievementSkeletonCrew": "Ejército Huesudo",
"achievementBoneCollectorModalText": "¡Has conseguido todas las Mascotas Esqueleto!",
"achievementSeeingRedText": "Ha conseguido todas las Mascotas Rojas.",
"achievementSeeingRedModalText": "¡Has conseguido todas las Mascotas Rojas!",
"achievementRedLetterDayModalText": "¡Has domado todas las Monturas Rojas!",
"achievementRedLetterDayText": "Ha domado todas las Monturas Rojas.",
"achievementSkeletonCrewModalText": "¡Has domado todas las monturas esqueléticas!",
"achievementSkeletonCrewText": "Ha domado todas las monturas esqueléticas.",
"achievementSkeletonCrew": "Equipo esquelético",
"achievementBoneCollectorModalText": "¡Has conseguido todas las mascotas esqueléticas!",
"achievementSeeingRedText": "Ha conseguido todas las Mascotas rojas.",
"achievementSeeingRedModalText": "¡Has conseguido todas las mascotas rojas!",
"achievementRedLetterDayModalText": "¡Has domado todas las monturas rojas!",
"achievementRedLetterDayText": "Ha domado todas las monturas rojas.",
"achievementRedLetterDay": "Día señalado",
"achievementLegendaryBestiaryModalText": "¡Has conseguido todas las mascotas míticas!",
"achievementLegendaryBestiaryText": "¡Ha eclosionado todos los colores estándar de todas las mascotas míticas: Dragón, Cerdo Volador, Grifo, Serpiente Marina y Unicornio!",
"achievementLegendaryBestiary": "Bestiario Legendario",
"achievementLegendaryBestiary": "Bestiario legendario",
"achievementSeasonalSpecialistModalText": "¡Completaste todas las misiones estacionales!",
"achievementSeasonalSpecialistText": "Ha completado todas las misiones estacionales de Primavera e Invierno: ¡Búsqueda de Huevos, Santa Trampero, y Encuentra al Cachorro!",
"achievementSeasonalSpecialist": "Especialista Estacional",
"achievementVioletsAreBlue": "Las Violetas son Azules",
"achievementVioletsAreBlue": "Las violetas son azules",
"achievementWildBlueYonderModalText": "¡Has domado todas las monturas de Algodon de Azúcar Azul!",
"achievementWildBlueYonderText": "Ha domado todas las monturas de Algodon de Azúcar Azul.",
"achievementWildBlueYonder": "La Salvaje y Azul Lejanía",
"achievementWildBlueYonder": "La salvaje y azul lejanía",
"achievementVioletsAreBlueModalText": "¡Has conseguido todas las mascotas de Algodon de Azúcar Azul!",
"achievementVioletsAreBlueText": "Ha conseguido todas las mascotas de Algodon de Azúcar Azul.",
"achievementDomesticatedText": "¡Ha eclosionado todos los colores de mascotas domésticas: Hurón, Cobaya, Gallo, Cerdo Volador, Rata, Conejito, Caballo y Vaca!",
"achievementDomesticated": "I-A-I-A-O",
"achievementDomesticatedText": "¡Has criado todos los colores de mascotas domésticas: hurón, cobaya, gallo, cerdo volador, rata, conejito, caballo y vaca!",
"achievementDomesticated": "E-I-E-I-O",
"achievementDomesticatedModalText": "¡Has conseguido todas las mascotas domesticadas!",
"achievementShadyCustomerModalText": "¡Has conseguido todas las Mascotas Sombrías!",
"achievementShadeOfItAll": "A la Sombra de Todo",
"achievementShadeOfItAllText": "Ha domado todas las Monturas Sombrías.",
"achievementShadeOfItAllModalText": "¡Has domado todas las Monturas Sombrías!",
"achievementShadyCustomerText": "Ha conseguido todas las Mascotas Sombrías.",
"achievementShadyCustomer": "Cliente Sombrío",
"achievementShadyCustomerModalText": "¡Has conseguido todas las mascotas sombrías!",
"achievementShadeOfItAll": "La sombra de todo ello",
"achievementShadeOfItAllText": "Ha domado todas las monturas sombrías.",
"achievementShadeOfItAllModalText": "¡Has domado todas las monturas sombrías!",
"achievementShadyCustomerText": "Ha conseguido todas las mascotas sombrías.",
"achievementShadyCustomer": "Cliente sombrío",
"achievementZodiacZookeeper": "Cuidador del Zodiaco",
"achievementZodiacZookeeperText": "¡Ha eclosionado todas las mascotas del zodíaco de color básico: Rata, Vaca, Conejo, Serpiente, Caballo, Oveja, Mono, Gallo, Lobo, Tigre, Cerdo Volador y Dragón!",
"achievementZodiacZookeeperModalText": "¡Has conseguido todas las mascotas del zodíaco!",
@@ -131,39 +131,39 @@
"achievementBirdsOfAFeatherModalText": "¡Has conseguido todas las mascotas voladoras!",
"achievementBirdsOfAFeather": "Aves de Pluma",
"achievementReptacularRumbleModalText": "¡Has coleccionado todas las mascotas reptiles!",
"achievementReptacularRumbleText": "¡Ha eclosionado todos los colores estándar de las mascotas reptiles: Caimán, Pterodáctilo, Serpiente, Triceratops, Tortuga, Tiranosaurio Rex y Velociraptor!",
"achievementGroupsBeta2022": "Probador Beta Interactivo",
"achievementGroupsBeta2022Text": "Tú y tu grupo proporcionaron comentarios invaluables para ayudar a probar Habitica.",
"achievementReptacularRumbleText": "!Has incubado todos los colores estándar de las mascotas reptiles: caimán, pterodáctilo, serpiente, triceratops, tortuga, tiranosaurio rex y velociraptor!",
"achievementGroupsBeta2022": "Probador Beta interactivo",
"achievementGroupsBeta2022Text": "Tú y tu grupo habéis proporcionado comentarios invaluables para ayudar a probar Habitica.",
"achievementGroupsBeta2022ModalText": "¡Usted y sus grupos ayudaron a Habitica probando y proporcionando comentarios!",
"achievementReptacularRumble": "Rumble reptacular",
"achievementWoodlandWizard": "Mago del Bosque",
"achievementWoodlandWizardModalText": "¡Has conseguido todas las mascotas del bosque!",
"achievementWoodlandWizardText": "¡Ha eclosionado todos los colores estándar de las criaturas del bosque: Tejón, Oso, Ciervo, Zorro, Rana, Erizo, Búho, Caracol, Ardilla y Brote!",
"achievementBoneToPick": "Un Hueso Duro de Roer",
"achievementBoneToPickText": "¡Ha eclosionado todas las Mascotas Esqueleto, Clásicas y de Misión!",
"achievementWoodlandWizard": "Mago del bosque",
"achievementWoodlandWizardModalText": "¡Has recogido todas las mascotas del bosque!",
"achievementWoodlandWizardText": "Ha incubado todos los colores estándar de las criaturas del bosque: Tejón, Oso, Ciervo, Zorro, Rana, Erizo, Búho, Caracol, Ardilla y Treeling!",
"achievementBoneToPick": "Un hueso duro de roer",
"achievementBoneToPickText": "¡Ha eclosionado todas las mascotas Clásicas y de Misión Esqueléticas!",
"achievementPolarPro": "Experto Polar",
"achievementPolarProModalText": "¡Has conseguido todas las Mascotas Polares!",
"achievementBoneToPickModalText": "¡Has coleccionado todas las Mascotas Esqueleto, Clásicas y de Misión!",
"achievementPolarProModalText": "¡Has coleccionado todas las mascotas Polares!",
"achievementBoneToPickModalText": "¡Has coleccionado todas las mascotas clásicas y de misiones esqueléticas!",
"achievementPolarProText": "¡Ha eclosionado todos los colores estándar para mascotas Polares: Osos, Zorros, Pinguinos, Ballenas y Lobos!",
"achievementPlantParent": "Cuidador de Plantas",
"achievementPlantParentText": "¡Ha eclosionado todos los colores estándar de mascotas vegetales: Cactus y Brote!",
"achievementPlantParentModalText": "¡Has conseguido todas las Mascotas Planta!",
"achievementPlantParentText": "¡Ha eclosionado todos los colores estándar de mascotas vegetales: Cactus y Árbolito!",
"achievementPlantParentModalText": "¡Has coleccionado todas las Mascotas Planta!",
"achievementDinosaurDynasty": "Dinastía de Dinosaurios",
"achievementDinosaurDynastyModalText": "¡Has conseguido todas las mascotas ave y dinosaurio!",
"achievementDinosaurDynastyText": "Ha eclosionado todos los colores estándar de mascotas ave y dinosaurio: Halcón, Búho, Loro, Pavo Real, Pingüino, Gallo, Pterodáctilo, Tiranosaurio rex, Triceratops y Velociraptor!",
"achievementDinosaurDynastyModalText": "¡Has recogido todas las mascotas de pájaros y dinosaurios!",
"achievementDinosaurDynastyText": "Ha eclosionado todos los colores estándar de mascotas, de aves y dinosaurios: halcón, búho, loro, pavo real, pingüino, gallo, pterodáctilo, tiranosaurio rex, triceratops y velociraptor!",
"achievementRoughRider": "Jinete tosco",
"achievementRoughRiderText": "¡Ha eclosionado todos los colores estándar de mascotas y monturas incómodas: Cactus, Erizo y Piedra!",
"achievementBonelessBossModalText": Has conseguido todas las mascotas invertebradas!",
"achievementBonelessBossText": "¡Ha eclosionado todos los colores estándar de mascotas invertebradas: Escarabajo, Mariposa, Calamar, Nudibranquio, Pulpo, Caracol y Araña!",
"achievementBonelessBoss": "Jefe Deshuesado",
"achievementDuneBuddyText": "¡Ha eclosionado todos los colores estándar de mascotas de clima desértico: Armadillo, Cactus, Zorro, Rana, Serpiente y Araña!",
"achievementBonelessBossModalText": Tienes todas las mascotas invertebradas en tu colección!",
"achievementBonelessBossText": "Ha eclosionado todos los colores estándar de mascotas invertebradas: escarabajo, mariposa calamar, nudibranquio, pulpo, caracol y araña!",
"achievementBonelessBoss": "Jefe deshuesado",
"achievementDuneBuddyText": "¡Ha eclosionado todos los colores estándar de mascotas de clima desértico: armadillo, cactus, zorro, rana, serpiente y araña!",
"achievementDuneBuddy": "Amigo de médano",
"achievementDuneBuddyModalText": "¡Has conseguido todas las mascotas de desierto!",
"achievementRoughRiderModalText": "¡Has conseguido todos los colores básicos de mascotas y monturas incómodas!",
"achievementRodentRuler": "Rey Roedor",
"achievementRodentRulerText": "¡Ha eclosionado todos los colores estándar de mascotas roedores: Conejillo de Indias, Rata y Ardilla!",
"achievementRodentRulerModalText": "¡Has conseguido todos las mascotas roedores!",
"achievementCats": "Señora de los Gatos",
"achievementCatsText": "¡Ha eclosionado todos los colores estándar de mascotas felinas: Guepardo, León, Tigre Dientes de Sable y Tigre!",
"achievementRoughRiderModalText": "¡Has conseguido todos los colores básicos de las mascotas y monturas incómodas!",
"achievementRodentRuler": "Gobernante Roedor",
"achievementRodentRulerText": "¡Ha eclosionado todos los colores estándar de las mascotas roedores: Conejillo de Indias, Rata y Ardilla!",
"achievementRodentRulerModalText": "¡Has conseguido todos las roedores mascota!",
"achievementCats": "Pastor de Gatos",
"achievementCatsText": "¡Ha eclosionado todos los colores estándar de las mascotas felinas: Guepardo, León, Tigre Dientes de Sable y Tigre!",
"achievementCatsModalText": "¡Has conseguido todas las mascotas felinas!"
}
+114 -125
View File
@@ -1,203 +1,203 @@
{
"backgrounds": "Fondos",
"background": "Fondo",
"backgroundShop": "Tienda de Fondos",
"noBackground": "Ningún Fondo Seleccionado",
"backgroundShop": "Tienda de fondos",
"noBackground": "Ningún fondo seleccionado",
"backgrounds062014": "1.ª serie: publicada en junio de 2014",
"backgroundBeachText": "Playa",
"backgroundBeachNotes": "Relájate en una cálida playa.",
"backgroundFairyRingText": "Anillo de Hadas",
"backgroundFairyRingText": "Anillo de hadas",
"backgroundFairyRingNotes": "Baila en un anillo de hadas.",
"backgroundForestText": "Bosque",
"backgroundForestNotes": "Pasea por un bosque estival.",
"backgrounds072014": "2.ª serie: publicada en julio de 2014",
"backgroundCoralReefText": "Arrecife de Coral",
"backgroundCoralReefText": "Arrecife de coral",
"backgroundCoralReefNotes": "Nada en un arrecife de coral.",
"backgroundOpenWatersText": "Aguas Abiertas",
"backgroundOpenWatersText": "Aguas abiertas",
"backgroundOpenWatersNotes": "Disfruta de las aguas abiertas.",
"backgroundSeafarerShipText": "Bajel de Marineros",
"backgroundSeafarerShipNotes": "Navega a bordo de un Barco Marinero.",
"backgroundSeafarerShipText": "Bajel de marineros",
"backgroundSeafarerShipNotes": "Navega a bordo de un barco marinero.",
"backgrounds082014": "3.ª serie: publicada en agosto de 2014",
"backgroundCloudsText": "Nubes",
"backgroundCloudsNotes": "Planea entre las nubes.",
"backgroundDustyCanyonsText": "Cañón Polvoriento",
"backgroundDustyCanyonsText": "Cañón polvoriento",
"backgroundDustyCanyonsNotes": "Pasea por un cañón polvoriento.",
"backgroundVolcanoText": "Volcán",
"backgroundVolcanoNotes": "Entra en calor dentro de un volcán.",
"backgrounds092014": "4.ª serie: publicada en septiembre de 2014",
"backgroundThunderstormText": "Tormenta Eléctrica",
"backgroundThunderstormText": "Tormenta eléctrica",
"backgroundThunderstormNotes": "Conduce rayos en la tormenta eléctrica.",
"backgroundAutumnForestText": "Bosque Otoñal",
"backgroundAutumnForestText": "Bosque otoñal",
"backgroundAutumnForestNotes": "Pasea por un bosque otoñal.",
"backgroundHarvestFieldsText": "Campos de Cultivo",
"backgroundHarvestFieldsText": "Campos de cultivo",
"backgroundHarvestFieldsNotes": "Labra tus campos de cultivo.",
"backgrounds102014": "5.ª serie: publicada en octubre de 2014",
"backgroundGraveyardText": "Cementerio",
"backgroundGraveyardNotes": "Visita un espeluznante cementerio.",
"backgroundHauntedHouseText": "Casa Encantada",
"backgroundHauntedHouseText": "Casa encantada",
"backgroundHauntedHouseNotes": "Entra a hurtadillas en una casa encantada.",
"backgroundPumpkinPatchText": "Campo de Calabazas",
"backgroundPumpkinPatchNotes": "Talla tus calabazas en este campo de calabazas.",
"backgroundPumpkinPatchText": "Terreno de calabazas",
"backgroundPumpkinPatchNotes": "Talla tu calabaza en este terreno.",
"backgrounds112014": "6.ª serie: publicada en noviembre de 2014",
"backgroundHarvestFeastText": "Festín de la Cosecha",
"backgroundHarvestFeastNotes": "Disfruta del Banquete de la Cosecha.",
"backgroundStarrySkiesText": "Cielos Estrellados",
"backgroundHarvestFeastText": "Festín de la cosecha",
"backgroundHarvestFeastNotes": "Disfruta del banquete de la cosecha.",
"backgroundStarrySkiesText": "Cielos estrellados",
"backgroundStarrySkiesNotes": "Contempla los cielos repletos de estrellas.",
"backgroundSunsetMeadowText": "Atardecer en la Pradera",
"backgroundSunsetMeadowText": "Atardecer en la pradera",
"backgroundSunsetMeadowNotes": "Admira un atardecer en la pradera.",
"backgrounds122014": "7.ª serie: publicada en diciembre de 2014",
"backgroundIcebergText": "Témpano de Hielo",
"backgroundIcebergNotes": "Flota a la deriva sobre un Témpano de Hielo.",
"backgroundTwinklyLightsText": "Luces Brillantes de Invierno",
"backgroundIcebergText": "Iceberg",
"backgroundIcebergNotes": "Flota a la deriva sobre un iceberg.",
"backgroundTwinklyLightsText": "Luces brillantes de invierno",
"backgroundTwinklyLightsNotes": "Camina entre árboles engalanados con luces festivas.",
"backgroundSouthPoleText": "Polo Sur",
"backgroundSouthPoleNotes": "Visita el gélido Polo Sur.",
"backgrounds012015": "8.ª serie: publicada en enero de 2015",
"backgroundIceCaveText": "Cueva de Hielo",
"backgroundIceCaveNotes": "Desciende y adéntrate en una Cueva de Hielo.",
"backgroundFrigidPeakText": "Cima Glacial",
"backgroundIceCaveText": "Cueva de hielo",
"backgroundIceCaveNotes": "Desciende y adéntrate en una cueva de hielo.",
"backgroundFrigidPeakText": "Cima glacial",
"backgroundFrigidPeakNotes": "Escala una cima glacial.",
"backgroundSnowyPinesText": "Pinos Nevados",
"backgroundSnowyPinesText": "Pinos nevados",
"backgroundSnowyPinesNotes": "Refúgiate entre pinos nevados.",
"backgrounds022015": "9.ª serie: publicada en febrero de 2015",
"backgroundBlacksmithyText": "Forja",
"backgroundBlacksmithyNotes": "Trabaja en la forja.",
"backgroundCrystalCaveText": "Cueva de Cristal",
"backgroundCrystalCaveText": "Cueva de cristal",
"backgroundCrystalCaveNotes": "Explora una cueva de cristal.",
"backgroundDistantCastleText": "Castillo Distante",
"backgroundDistantCastleText": "Castillo distante",
"backgroundDistantCastleNotes": "Defiende un castillo distante.",
"backgrounds032015": "10.ª serie: publicada en marzo de 2015",
"backgroundSpringRainText": "Lluvia Primaveral",
"backgroundSpringRainText": "Lluvia primaveral",
"backgroundSpringRainNotes": "Baila bajo la lluvia de primavera.",
"backgroundStainedGlassText": "Vidriera",
"backgroundStainedGlassNotes": "Contempla las vidrieras.",
"backgroundRollingHillsText": "Colinas Ondulantes",
"backgroundRollingHillsText": "Colinas ondulantes",
"backgroundRollingHillsNotes": "Corretea por las colinas ondulantes.",
"backgrounds042015": "11.ª serie: publicada en abril de 2015",
"backgroundCherryTreesText": "Cerezos",
"backgroundCherryTreesNotes": "Admira los cerezos en flor.",
"backgroundFloralMeadowText": "Prado Floreciente",
"backgroundFloralMeadowText": "Prado floreciente",
"backgroundFloralMeadowNotes": "Ve de pícnic a un prado floreciente.",
"backgroundGumdropLandText": "País de las Gominolas",
"backgroundGumdropLandNotes": "Mordisquea el paisaje del País de las Gominolas.",
"backgrounds052015": "12.ª serie: publicada en mayo de 2015",
"backgroundMarbleTempleText": "Templo de Mármol",
"backgroundMarbleTempleText": "Templo de mármol",
"backgroundMarbleTempleNotes": "Posa delante de un templo de mármol.",
"backgroundMountainLakeText": "Lago de Montaña",
"backgroundMountainLakeText": "Lago de montaña",
"backgroundMountainLakeNotes": "Atrévete a sumergir la punta del pie en este lago de montaña.",
"backgroundPagodasText": "Pagodas",
"backgroundPagodasNotes": "Sube a lo alto de las Pagodas.",
"backgroundPagodasNotes": "Sube a lo alto de las pagodas.",
"backgrounds062015": "13.ª serie: publicada en junio de 2015",
"backgroundDriftingRaftText": "Balsa a la Deriva",
"backgroundDriftingRaftText": "Balsa a la deriva",
"backgroundDriftingRaftNotes": "Rema sobre una balsa a la deriva.",
"backgroundShimmeryBubblesText": "Burbujas Relucientes",
"backgroundShimmeryBubblesText": "Burbujas relucientes",
"backgroundShimmeryBubblesNotes": "Flota a través de un mar de burbujas relucientes.",
"backgroundIslandWaterfallsText": "Cascadas Isleñas",
"backgroundIslandWaterfallsText": "Cascadas isleñas",
"backgroundIslandWaterfallsNotes": "Haz un pícnic junto a las cascadas de esta isla.",
"backgrounds072015": "14.ª serie: publicada en julio de 2015",
"backgroundDilatoryRuinsText": "Ruinas de Dilatoria",
"backgroundDilatoryRuinsNotes": "Sumérgete en las ruinas de Dilatoria.",
"backgroundGiantWaveText": "Ola Gigante",
"backgroundGiantWaveText": "Ola gigante",
"backgroundGiantWaveNotes": "¡Surfea una ola gigante!",
"backgroundSunkenShipText": "Barco Hundido",
"backgroundSunkenShipText": "Barco hundido",
"backgroundSunkenShipNotes": "Explora un barco hundido.",
"backgrounds082015": "15.ª serie: publicada en agosto de 2015",
"backgroundPyramidsText": "Pirámides",
"backgroundPyramidsNotes": "Admira las pirámides.",
"backgroundSunsetSavannahText": "Ocaso en la Sabana",
"backgroundSunsetSavannahText": "Ocaso en la sabana",
"backgroundSunsetSavannahNotes": "Acecha a tus presas al atardecer en la sabana.",
"backgroundTwinklyPartyLightsText": "Luces Parpadeantes de Fiesta",
"backgroundTwinklyPartyLightsText": "Luces parpadeantes de fiesta",
"backgroundTwinklyPartyLightsNotes": "¡Baila bajo las luces festivas centelleantes!",
"backgrounds092015": "16.ª serie: publicada en septiembre de 2015",
"backgroundMarketText": "Mercado de Habitica",
"backgroundMarketNotes": "Compra en el Mercado de Habitica.",
"backgroundMarketNotes": "Compra en el mercado de Habitica.",
"backgroundStableText": "Establo de Habitica",
"backgroundStableNotes": "Cuida a tus monturas en el Establo de Habitica.",
"backgroundStableNotes": "Cuida a tus monturas en el establo de Habitica.",
"backgroundTavernText": "Taberna de Habitica",
"backgroundTavernNotes": "Visita la Taberna de Habitica.",
"backgrounds102015": "17.ª serie: publicada en octubre de 2015",
"backgroundHarvestMoonText": "Luna de Cosecha",
"backgroundHarvestMoonText": "Luna de cosecha",
"backgroundHarvestMoonNotes": "Ríete a carcajadas bajo la luna de cosecha.",
"backgroundSlimySwampText": "Pantano Lodoso",
"backgroundSlimySwampText": "Pantano lodoso",
"backgroundSlimySwampNotes": "Cruza con esfuerzo el pantano lodoso.",
"backgroundSwarmingDarknessText": "Criaturas de la Oscuridad",
"backgroundSwarmingDarknessText": "Criaturas de la oscuridad",
"backgroundSwarmingDarknessNotes": "Tiembla entre las criaturas de la oscuridad.",
"backgrounds112015": "18.ª serie: publicada en noviembre de 2015",
"backgroundFloatingIslandsText": "Islas Flotantes",
"backgroundFloatingIslandsText": "Islas flotantes",
"backgroundFloatingIslandsNotes": "Salta entre las islas flotantes.",
"backgroundNightDunesText": "Dunas Nocturnas",
"backgroundNightDunesText": "Dunas nocturnas",
"backgroundNightDunesNotes": "Camina tranquilamente por las dunas nocturnas.",
"backgroundSunsetOasisText": "Oasis al Atardecer",
"backgroundSunsetOasisText": "Oasis al atardecer",
"backgroundSunsetOasisNotes": "Disfruta del oasis al atardecer.",
"backgrounds122015": "19.ª serie: publicada en diciembre de 2015",
"backgroundAlpineSlopesText": "Laderas Alpinas",
"backgroundAlpineSlopesText": "Laderas alpinas",
"backgroundAlpineSlopesNotes": "Esquía en las laderas alpinas.",
"backgroundSnowySunriseText": "Amanecer Nevado",
"backgroundSnowySunriseText": "Amanecer nevado",
"backgroundSnowySunriseNotes": "Contempla el amanecer nevado.",
"backgroundWinterTownText": "Pueblo Invernal",
"backgroundWinterTownText": "Pueblo invernal",
"backgroundWinterTownNotes": "Camina deprisa por el pueblo invernal.",
"backgrounds012016": "20.ª serie: publicada en enero de 2016",
"backgroundFrozenLakeText": "Lago Congelado",
"backgroundFrozenLakeText": "Lago congelado",
"backgroundFrozenLakeNotes": "Patina sobre un lago congelado.",
"backgroundSnowmanArmyText": "Ejército de Muñecos de Nieve",
"backgroundSnowmanArmyText": "Ejército de muñecos de nieve",
"backgroundSnowmanArmyNotes": "Lidera un ejército de muñecos de nieve.",
"backgroundWinterNightText": "Noche de Invierno",
"backgroundWinterNightText": "Noche de invierno",
"backgroundWinterNightNotes": "Mira las estrellas de una noche de invierno.",
"backgrounds022016": "21.ª serie: publicada en febrero de 2016",
"backgroundBambooForestText": "Bosque de Bambú",
"backgroundBambooForestText": "Bosque de bambú",
"backgroundBambooForestNotes": "Pasea por el bosque de bambú.",
"backgroundCozyLibraryText": "Biblioteca Acogedora",
"backgroundCozyLibraryText": "Biblioteca acogedora",
"backgroundCozyLibraryNotes": "Lee en esta acogedora biblioteca.",
"backgroundGrandStaircaseText": "Gran Escalinata",
"backgroundGrandStaircaseText": "Gran escalinata",
"backgroundGrandStaircaseNotes": "Desciende por la gran escalinata.",
"backgrounds032016": "22.ª serie: publicada en marzo de 2016",
"backgroundDeepMineText": "Mina Profunda",
"backgroundDeepMineText": "Mina profunda",
"backgroundDeepMineNotes": "Encuentra metales preciosos en esta mina profunda.",
"backgroundRainforestText": "Selva Tropical",
"backgroundRainforestText": "Selva tropical",
"backgroundRainforestNotes": "Adéntrate en la selva tropical.",
"backgroundStoneCircleText": "Crómlech",
"backgroundStoneCircleNotes": "Lanza hechizos en este crómlech.",
"backgrounds042016": "23.ª serie: publicada en abril de 2016",
"backgroundArcheryRangeText": "Campo de Tiro con Arco",
"backgroundArcheryRangeText": "Campo de tiro con arco",
"backgroundArcheryRangeNotes": "Practica en este campo de tiro con arco.",
"backgroundGiantFlowersText": "Flores Gigantes",
"backgroundGiantFlowersText": "Flores gigantes",
"backgroundGiantFlowersNotes": "Diviértete sobre estas gigantescas flores.",
"backgroundRainbowsEndText": "Final del Arcoíris",
"backgroundRainbowsEndText": "Final del arcoíris",
"backgroundRainbowsEndNotes": "Encuentra oro al final del arcoíris.",
"backgrounds052016": "24.ª serie: publicada en mayo de 2016",
"backgroundBeehiveText": "Colmena",
"backgroundBeehiveNotes": "Zumba y baila en una colmena.",
"backgroundGazeboText": "Kiosko",
"backgroundGazeboNotes": "Pelea en un kiosko.",
"backgroundTreeRootsText": "Raíces de Árbol",
"backgroundTreeRootsText": "Raíces de árbol",
"backgroundTreeRootsNotes": "Explora las raíces del árbol.",
"backgrounds062016": "25.ª serie: publicada en junio de 2016",
"backgroundLighthouseShoreText": "Costa con Faro",
"backgroundLighthouseShoreText": "Costa con faro",
"backgroundLighthouseShoreNotes": "Pasea por la costa junto al faro.",
"backgroundLilypadText": "Nenúfar",
"backgroundLilypadNotes": "Salta sobre un nenúfar.",
"backgroundWaterfallRockText": "Roca de Cascada",
"backgroundWaterfallRockText": "Roca de cascada",
"backgroundWaterfallRockNotes": "Chapotea junto a la roca de la cascada.",
"backgrounds072016": "26.ª serie: publicada en julio de 2016",
"backgroundAquariumText": "Acuario",
"backgroundAquariumNotes": "Sube y baja dentro de este acuario.",
"backgroundDeepSeaText": "Mar Profundo",
"backgroundDeepSeaText": "Profundidades del mar",
"backgroundDeepSeaNotes": "Bucea hasta las profundidades del mar.",
"backgroundDilatoryCastleText": "Castillo de Dilatoria",
"backgroundDilatoryCastleNotes": "Nada junto al Castillo de Dilatoria.",
"backgrounds082016": "27.ª serie: publicada en agosto de 2016",
"backgroundIdyllicCabinText": "Cabaña Idílica",
"backgroundIdyllicCabinNotes": "Retírate a una cabaña idílica.",
"backgroundMountainPyramidText": "Pirámide de Montaña",
"backgroundIdyllicCabinText": "Cabaña bucólica",
"backgroundIdyllicCabinNotes": "Retírate a una cabaña bucólica.",
"backgroundMountainPyramidText": "Pirámide de montaña",
"backgroundMountainPyramidNotes": "Sube los incontables peldaños de esta pirámide de montaña.",
"backgroundStormyShipText": "Barco Tormentoso",
"backgroundStormyShipText": "Barco tormentoso",
"backgroundStormyShipNotes": "Agárrate fuerte contra viento y marea a bordo de un barco tormentoso.",
"backgrounds092016": "28.ª serie: publicada en septiembre de 2016",
"backgroundCornfieldsText": "Campos de Maíz",
"backgroundCornfieldsText": "Campos de maíz",
"backgroundCornfieldsNotes": "Disfruta de un bonito día en los campos de maíz.",
"backgroundFarmhouseText": "Casa de Granja",
"backgroundFarmhouseText": "Casa de granja",
"backgroundFarmhouseNotes": "Saluda a los animales de camino a la casa de la granja.",
"backgroundOrchardText": "Huerto de Árboles Frutales",
"backgroundOrchardText": "Huerto de árboles frutales",
"backgroundOrchardNotes": "Coge fruta madura en el huerto.",
"backgrounds102016": "29.ª serie: publicada en octubre de 2016",
"backgroundSpiderWebText": "Telaraña",
@@ -207,14 +207,14 @@
"backgroundRainyCityText": "Ciudad Lluviosa",
"backgroundRainyCityNotes": "Chapotea a través de una Ciudad Lluviosa.",
"backgrounds112016": "30.ª serie: publicada en noviembre de 2016",
"backgroundMidnightCloudsText": "Nubes de Medianoche",
"backgroundMidnightCloudsNotes": "Vuela a través de las nubes de medianoche.",
"backgroundStormyRooftopsText": "Techos Tormentosos",
"backgroundStormyRooftopsNotes": "Deslízate a través de los techos tormentosos.",
"backgroundMidnightCloudsText": "Media noche nublada",
"backgroundMidnightCloudsNotes": "Vuela a través de la Media noche nublada.",
"backgroundStormyRooftopsText": "Tempestuoso Techo",
"backgroundStormyRooftopsNotes": "Deslízate a través del Tempestuoso Techo.",
"backgroundWindyAutumnText": "Otoño Ventoso",
"backgroundWindyAutumnNotes": "Persigue las hojas durante el otoño ventoso.",
"backgroundWindyAutumnNotes": "Caza las hojas durante el Otoño Ventoso.",
"incentiveBackgrounds": "Fondos Estándar",
"backgroundVioletText": "Violeta",
"backgroundVioletText": "violeta",
"backgroundVioletNotes": "Un vibrante fondo violeta.",
"backgroundBlueText": "Azul",
"backgroundBlueNotes": "Un fondo básico azul.",
@@ -228,16 +228,16 @@
"backgroundYellowNotes": "Un agradable fondo amarillo.",
"backgrounds122016": "31.ª serie: publicada en diciembre de 2016",
"backgroundShimmeringIcePrismText": "Prismas de Hielo Relucientes",
"backgroundShimmeringIcePrismNotes": "Baila junto a los prismas de hielo relucientes.",
"backgroundShimmeringIcePrismNotes": "Baila junto a los Prismas de Hielo Relucientes.",
"backgroundWinterFireworksText": "Fuegos Artificiales de Invierno",
"backgroundWinterFireworksNotes": "Lanza los Fuegos Artificiales de Invierno.",
"backgroundWinterStorefrontText": "Tienda Invernal",
"backgroundWinterStorefrontNotes": "Compra regalos en la Tienda Invernal.",
"backgrounds012017": "32.ª serie: publicada en enero de 2017",
"backgroundBlizzardText": "Tormenta de Nieve",
"backgroundBlizzardNotes": "Enfréntate a una terrible tormenta de nieve.",
"backgroundBlizzardNotes": "Enfréntate a una terrible Tormenta de Nieve.",
"backgroundSparklingSnowflakeText": "Copo de Nieve Chispeante",
"backgroundSparklingSnowflakeNotes": "Deslízate en un copo de nieve chispeante.",
"backgroundSparklingSnowflakeNotes": "Deslízate en un Copo de Nieve Chispeante.",
"backgroundStoikalmVolcanoesText": "Volcanes Stoïkalm",
"backgroundStoikalmVolcanoesNotes": "Explora los Volcanes Stoïkalm.",
"backgrounds022017": "33.ª serie: publicada en febrero de 2017",
@@ -246,10 +246,10 @@
"backgroundTreasureRoomText": "Sala del Tesoro",
"backgroundTreasureRoomNotes": "Disfruta de la riqueza de la Sala del Tesoro.",
"backgroundWeddingArchText": "Arco de Boda",
"backgroundWeddingArchNotes": "Posa bajo el arco de boda.",
"backgroundWeddingArchNotes": "Posa bajo el Arco de Boda.",
"backgrounds032017": "34.ª serie: publicada en marzo de 2017",
"backgroundMagicBeanstalkText": "Tallo de Judía Mágico",
"backgroundMagicBeanstalkNotes": "Sube por un tallo de judía mágico.",
"backgroundMagicBeanstalkNotes": "Sube por un Tallo de Judía Mágico.",
"backgroundMeanderingCaveText": "Cuerva Serpenteante",
"backgroundMeanderingCaveNotes": "Explora la Cueva Serpenteante.",
"backgroundMistiflyingCircusText": "Desconcertante Circo Volador",
@@ -260,47 +260,47 @@
"backgroundGiantBirdhouseText": "Casa de Pájaros Gigante",
"backgroundGiantBirdhouseNotes": "Posarse sobre la Casa de Pájaros Gigante.",
"backgroundMistShroudedMountainText": "Montaña Envuelta en Niebla",
"backgroundMistShroudedMountainNotes": "Escala la montaña envuelta en niebla.",
"backgroundMistShroudedMountainNotes": "Escala la Montaña Envuelta en Niebla.",
"backgrounds052017": "36.ª serie: publicada en mayo de 2017",
"backgroundGuardianStatuesText": "Estatuas Guardianes",
"backgroundGuardianStatuesNotes": "Quédate en vigilia frente a Estatuas Guardianes.",
"backgroundHabitCityStreetsText": "Calles de la Ciudad de los Hábitos",
"backgroundHabitCityStreetsNotes": "Explora las Calles de la Ciudad de los Hábitos.",
"backgroundOnATreeBranchText": "Sobre Una Rama de un Árbol",
"backgroundOnATreeBranchNotes": "Pósate sobre una rama de un árbol.",
"backgroundOnATreeBranchNotes": "Pósate sobre una Rama de un Árbol.",
"backgrounds062017": "37.ª serie: publicada en junio de 2017",
"backgroundBuriedTreasureText": "Tesoro Enterrado",
"backgroundBuriedTreasureNotes": "Desentierra el tesoro enterrado.",
"backgroundBuriedTreasureNotes": "Desentierra el Tesoro Enterrado.",
"backgroundOceanSunriseText": "Amanecer Oceánico",
"backgroundOceanSunriseNotes": "Admira el amanecer oceánico.",
"backgroundOceanSunriseNotes": "Admira el Amanecer Oceánico.",
"backgroundSandcastleText": "Castillo de Arena",
"backgroundSandcastleNotes": "Rige sobre el castillo de arena.",
"backgroundSandcastleNotes": "Rige sobre el Castillo de Arena.",
"backgrounds072017": "38.ª serie: publicada en julio de 2017",
"backgroundGiantSeashellText": "Concha Gigante",
"backgroundGiantSeashellNotes": "Reposa en la concha gigante.",
"backgroundGiantSeashellNotes": "Reposa en la Concha Gigante.",
"backgroundKelpForestText": "Bosque de Algas Marinas",
"backgroundKelpForestNotes": "Nada a través del bosque de algas marinas.",
"backgroundKelpForestNotes": "Nada a través del Bosque de Algas Marinas.",
"backgroundMidnightLakeText": "Lago Medianoche",
"backgroundMidnightLakeNotes": "Descansa junto al Lago Medianoche.",
"backgrounds082017": "39.ª serie: publicada en agosto de 2017",
"backgroundBackOfGiantBeastText": "Espalda de una Bestia Gigante",
"backgroundBackOfGiantBeastNotes": "Cabalga en la espalda de una bestia gigante.",
"backgroundBackOfGiantBeastNotes": "Cabalga en la Espalda de una Bestia Gigante.",
"backgroundDesertDunesText": "Dunas del Desierto",
"backgroundDesertDunesNotes": "Explora valientemente las dunas del desierto.",
"backgroundDesertDunesNotes": "Explora valientemente las Dunas del Desierto.",
"backgroundSummerFireworksText": "Fuegos Artificiales de Verano",
"backgroundSummerFireworksNotes": "¡Celebra el Día del Nombramiento de Habitica con Fuegos Artificiales de Verano!",
"backgrounds092017": "40.ª serie: publicada en septiembre de 2017",
"backgroundBesideWellText": "Al lado de un Pozo",
"backgroundBesideWellNotes": "Paseo junto a un pozo.",
"backgroundBesideWellNotes": "Paseo junto a un Pozo.",
"backgroundGardenShedText": "Cobertizo de Jardín",
"backgroundGardenShedNotes": "Trabaja en un cobertizo de jardín.",
"backgroundGardenShedNotes": "Trabajo en un Cobertizo de Jardín.",
"backgroundPixelistsWorkshopText": "Taller de Pixelist",
"backgroundPixelistsWorkshopNotes": "Crea obras maestras en el Taller de Pixelist.",
"backgrounds102017": "41.ª serie: publicada en octubre de 2017",
"backgroundMagicalCandlesText": "Velas Mágicas",
"backgroundMagicalCandlesNotes": "Déjate acariciar por la luz de velas mágicas.",
"backgroundMagicalCandlesNotes": "Déjate acariciar por la luz de Velas Mágicas.",
"backgroundSpookyHotelText": "Hotel Escalofriante",
"backgroundSpookyHotelNotes": "Infíltrate por el vestíbulo de un hotel escalofriante.",
"backgroundSpookyHotelNotes": "Infíltrate por el vestíbulo de un Hotel Escalofriante.",
"backgroundTarPitsText": "Pozos de Alquitrán",
"backgroundTarPitsNotes": "Pasa de puntillas por los Pozos de Alquitrán.",
"backgrounds112017": "42.ª serie: publicada en noviembre de 2017",
@@ -314,16 +314,16 @@
"backgroundCrosscountrySkiTrailText": "Ruta de Ski Todo-Terreno",
"backgroundCrosscountrySkiTrailNotes": "Planea sobre la Ruta de Ski Todo-Terreno.",
"backgroundStarryWinterNightText": "Noche de Invierno Estrellada",
"backgroundStarryWinterNightNotes": "Admira una noche de invierno estrellada.",
"backgroundStarryWinterNightNotes": "Noche de Invierno Estrellada.",
"backgroundToymakersWorkshopText": "Taller del Fabricante de Juguetes",
"backgroundToymakersWorkshopNotes": "Disfrutar las maravillas del Taller del Fabricante de Juguetes.",
"backgrounds012018": "44.ª serie: publicada en enero de 2018",
"backgroundAuroraText": "Aurora",
"backgroundAuroraNotes": "Disfruta del brillo invernal de la aurora.",
"backgroundAuroraNotes": "Disfrutar del brillo invernal de la Aurora.",
"backgroundDrivingASleighText": "Trineo",
"backgroundDrivingASleighNotes": "Conduce un trineo sobre terreno nevado.",
"backgroundDrivingASleighNotes": "Conduce un Trineo sobre terreno nevado.",
"backgroundFlyingOverIcySteppesText": "Estepas heladas",
"backgroundFlyingOverIcySteppesNotes": "Vuela sobre las estepas heladas.",
"backgroundFlyingOverIcySteppesNotes": "Volar sobre las Estepas Heladas.",
"backgrounds022018": "45.ª serie: publicada en febrero de 2018",
"backgroundChessboardLandText": "Tierra de Tablero de Ajedrez",
"backgroundChessboardLandNotes": "Juega una partida en la Tierra de Tablero de Ajedrez.",
@@ -333,16 +333,16 @@
"backgroundRoseGardenNotes": "Pasear por el Jardín de Rosas.",
"backgrounds032018": "45.ª serie: publicada en marzo de 2018",
"backgroundGorgeousGreenhouseText": "Espléndido Invernadero",
"backgroundGorgeousGreenhouseNotes": "Camina entre la flora que se cuida en un espléndido invernadero.",
"backgroundGorgeousGreenhouseNotes": "Camina entre la flora que se cuida en el Espléndido Invernadero.",
"backgroundElegantBalconyText": "Elegante Balcón",
"backgroundElegantBalconyNotes": "Admira el paisaje desde un elegante balcón.",
"backgroundElegantBalconyNotes": "Admira el paisaje desde un Elegante Balcón.",
"backgroundDrivingACoachText": "Conduciendo una Carroza",
"backgroundDrivingACoachNotes": "Disfruta conducir una carroza por campos de flores.",
"backgroundDrivingACoachNotes": "Disfruta Conducir una Carroza por campos de flores.",
"backgrounds042018": "47.ª serie: publicada en abril de 2018",
"backgroundTulipGardenText": "Jardín de Tulipanes",
"backgroundTulipGardenNotes": "Pasa de puntillas por un jardín de tulipanes.",
"backgroundTulipGardenNotes": "Pasa de puntillas por un Jardín de Tulipanes.",
"backgroundFlyingOverWildflowerFieldText": "Campo de Flores silvestres",
"backgroundFlyingOverWildflowerFieldNotes": "Elévate por encima de un campo de flores silvestres.",
"backgroundFlyingOverWildflowerFieldNotes": "Elévate por encima de un Campo de Flores silvestres.",
"backgroundFlyingOverAncientForestText": "Bosque Antiguo",
"backgroundFlyingOverAncientForestNotes": "Vuela por encima de las copas de los árboles de un bosque antiguo.",
"backgrounds052018": "48.ª serie: publicada en mayo de 2018",
@@ -355,19 +355,19 @@
"backgrounds062018": "49.ª serie: publicada en junio de 2018",
"backgroundDocksText": "Muelle",
"backgroundDocksNotes": "Pescado de lo alto del muelle.",
"backgroundRowboatText": "Bote de Remos",
"backgroundRowboatText": "Bote de remos",
"backgroundRowboatNotes": "Canta en un bote de remos.",
"backgroundPirateFlagText": "Bandera Pirata",
"backgroundPirateFlagText": "Bandera pirata",
"backgroundPirateFlagNotes": "Cuelga una temible bandera pirata.",
"backgrounds072018": "50.ª serie: publicada en julio de 2018",
"backgroundDarkDeepText": "Oscuras Profundidades",
"backgroundDarkDeepText": "Oscuras profundidades",
"backgroundDarkDeepNotes": "Nada en las oscuras profundidades entre bichos bioluminiscentes.",
"backgroundDilatoryCityText": "Ciudad de Dilatoria",
"backgroundDilatoryCityNotes": "Deambula a través de la ciudad submarina de Dilatoria.",
"backgroundTidePoolText": "Poza de Marea",
"backgroundTidePoolText": "Poza de marea",
"backgroundTidePoolNotes": "Observa la vida del océano cerca de una poza de marea.",
"backgrounds082018": "51.ª serie: publicada en agosto de 2018",
"backgroundTrainingGroundsText": "Campos de Entrenamiento",
"backgroundTrainingGroundsText": "Campos de entrenamiento",
"backgroundTrainingGroundsNotes": "Practica en los campos de entrenamiento.",
"backgroundFlyingOverRockyCanyonText": "Cañón Rocoso",
"backgroundFlyingOverRockyCanyonNotes": "Contempla un escenario que quita el aliento mientras vuelas sobre un Cañón rocoso.",
@@ -375,9 +375,9 @@
"backgroundBridgeNotes": "Cruza un Puente encantador.",
"backgrounds092018": "52.ª serie: publicada en septiembre de 2018",
"backgroundApplePickingText": "Colecta de Manzanas",
"backgroundApplePickingNotes": "Ve a recolectar manzanas y trae a casa unas cuantas.",
"backgroundApplePickingNotes": "Ve a Recolectar Manzanas y trae a casa unas cuantas.",
"backgroundGiantBookText": "Libro Gigante",
"backgroundGiantBookNotes": "Lee mientras paseas por las páginas de un libro gigante.",
"backgroundGiantBookNotes": "Lee mientras paseas por las páginas de un Libro Gigante.",
"backgroundCozyBarnText": "Granero Confortable",
"backgroundCozyBarnNotes": "Relájate con tus mascotas y monturas en su Confortable Granero.",
"backgrounds102018": "53.ª serie: publicada en octubre de 2018",
@@ -930,16 +930,5 @@
"backgroundWinterDesertWithSaguarosNotes": "Exalta tus sentidos entre los Cactus en Desierto Invernal.",
"backgrounds022026": "CONJUNTO 141: Publicado en Febrero 2026",
"backgroundElegantPalaceText": "Palacio Elegante",
"backgroundElegantPalaceNotes": "Quédate obnubilado por las coloridas salas del Palacio Elegante.",
"backgrounds032026": "142.ª serie: publicada en marzo de 2026",
"backgroundWaterfallWithRainbowText": "Cascada y Arcoíris",
"backgroundWaterfallWithRainbowNotes": "Admira la belleza cautivadora de una cascada con un arcoíris.",
"backgrounds042026": "143.ª serie: publicada en abril de 2026",
"backgroundRidingACometText": "Montando un Cometa",
"backgroundRidingACometNotes": "¡Viaja a través del espacio mientras montas un cometa!",
"backgrounds052026": "144.ª serie: publicada en mayo de 2026",
"backgroundElvenCitadelText": "Ciudadela Élfica",
"backgroundElvenCitadelNotes": "Toma un pintoresto recorrido en una ciudadela élfica.",
"backgroundOnAStrangePlanetText": "En un Extraño Planeta",
"backgroundOnAStrangePlanetNotes": "Aventúrate allá donde ningun Habiticano ha viajado antes: hacia un extraño planeta."
"backgroundElegantPalaceNotes": "Quédate obnubilado por las coloridas salas del Palacio Elegante."
}
+3 -7
View File
@@ -4,8 +4,8 @@
"brokenChaLink": "El enlace al desafío no funciona",
"keepIt": "Conservarla",
"removeIt": "Eliminarla",
"brokenChallenge": "Enlace de desafío roto",
"challengeCompleted": "¡Desafío Completado!",
"brokenChallenge": "Enlace al desafío interrumpido: esta tarea formaba parte de un desafío, pero el desafío (o el grupo) se ha eliminado. ¿Qué hacemos con las tareas del desafío?",
"challengeCompleted": "Este desafío ha finalizado y el ganador es ¡<span class=\"badge\"><%= user %></span>! ¿Qué hacemos con las tareas del desafío?",
"unsubChallenge": "Enlace al desafío interrumpido: esta tarea formaba parte de un desafío, pero ya no participas en él. ¿Qué hacemos con las tareas del desafío?",
"challenges": "Desafíos",
"endDate": "Concluye",
@@ -108,9 +108,5 @@
"cannotClose": "Este Desafío no puede cerrarse porque uno o más jugadores lo han marcado como inapropiado. Un miembro del Personal te contactará pronto con instrucciones. Si han pasado más de 48 horas y no has recibido noticias de ellos, envía un correo a admin@habitica.com para solicitar ayuda.",
"cannotMakeChallenge": "No puedes crear un Desafío público porque tu cuenta no tiene privilegios de chat en este momento. Envía un mensaje a admin@habitica.com para obtener más información.",
"messageChallengeFlagOfficial": "Los Desafíos Oficiales no se pueden notificar.",
"deleteChallengeRefundDescription": "Si cancelas este Desafío, recuperarás las Gemas de la recompensa y las tareas del Desafío permanecerán en los listados de tareas de los participantes.",
"brokenTaskDescription": "Esta tarea formaba parte de un desafío, pero se ha eliminado. ¿Qué te gustaría hacer?",
"brokenChallengeDescription": "Esta tarea formaba parte de un desafío, pero el desafío (o grupo) se ha eliminado. ¿Qué hacer con las tareas huérfanas?",
"challengeCompletedDescription": "¡El ganador fue <%= user %>! ¿Qué hacer con las tareas huérfanas?",
"brokenTask": "Enlace de desafío roto"
"deleteChallengeRefundDescription": "Si cancelas este Desafío, recuperarás las Gemas de la recompensa y las tareas del Desafío permanecerán en los listados de tareas de los participantes."
}
+9 -18
View File
@@ -83,7 +83,7 @@
"allocatePerPop": "Añadir un punto a Percepción",
"allocateInt": "Puntos asignados a Inteligencia:",
"allocateIntPop": "Añade un punto de inteligencia",
"noMoreAllocate": "Ahora que has alcanzado el nivel 100, no ganarás más Puntos de Atributo. Puedes continuar subiendo de nivel, o empezar una nueva aventura en el nivel 1 usando el <a href='/shops/market'> Orbe del Renacimiento</a>.",
"noMoreAllocate": "Ahora que has alcanzado el nivel 100, no ganarás más Puntos de Atributo. ¡Puedes continuar subiendo de nivel, o empezar una nueva aventura en el nivel 1 usando el <a href='/shops/market'> Orbe del Renacimiento</a>!",
"stats": "Atributos",
"strength": "Fuerza",
"strText": "Fuerza aumenta la posibilidad de \"golpes críticos\" y el Oro, la Experiencia y la posibilidad de que caigan objetos aumentan con ellos. Además, ayuda a lidiar con el daño de los Jefes.",
@@ -114,12 +114,12 @@
"unallocated": "Puntos de atributo no asignados",
"autoAllocation": "Asignación Automática",
"autoAllocationPop": "Asigna puntos en los atributos de acuerdo a tus preferencias cuando subes de nivel.",
"evenAllocation": "Distribuir uniformemente",
"evenAllocationPop": "Asigna el mismo número de puntos a cada atributo",
"classAllocation": "Distribuir según la clase",
"classAllocationPop": "Asigna más puntos a los atributos importantes para tu clase",
"taskAllocation": "Distribuir en función de la actividad de la tarea",
"taskAllocationPop": "Asigna Puntos basado en las categorías de Fuerza, Inteligencia, Constitución y Percepción asociadas con las tareas que completas",
"evenAllocation": "Distribuir Puntos de Atributo equitativamente",
"evenAllocationPop": "Asigna el mismo número de puntos a cada atributo.",
"classAllocation": "Distribuir los puntos en base a tu clase",
"classAllocationPop": "Asignar más puntos a los atributos importantes para tu clase.",
"taskAllocation": "Distribuye Puntos basándote en la actividad de tus tareas",
"taskAllocationPop": "Asigna Puntos basado en las categorías de Fuerza, Inteligencia, Constitución y Percepción asociadas con las tareas que completas.",
"distributePoints": "Distribuir Puntos no Asignados",
"distributePointsPop": "Asigna todos los Puntos no asignados de acuerdo con el esquema de asignación seleccionado.",
"warriorText": "Los Guerreros consiguen más y mejores «golpes críticos», los cuales otorgan bonus de Oro, Experiencia y probabilidad de botín al completar una tarea. También hacen mucho daño a mounstros jefe. ¡Juega como un Guerrero si te motivan las recompensas impredecibles como en un casino o si deseas ser la fuente de daño en las Misiones!",
@@ -178,7 +178,7 @@
"mainHand": "Mano dominante",
"offHand": "Mano secundaria",
"statPoints": "Puntos de Atributo",
"pts": "PTS",
"pts": "puntos",
"chatCastSpellUser": "<%= username %> lanza <%= spell %> sobre <%= target %>.",
"chatCastSpellParty": "<%= username %> lanza <%= spell %> para el equipo.",
"purchasePetItemConfirm": "Esta compra supera el número que necesitas para eclosionar todos los <%= itemText %> . ¿Quieres hacerla?",
@@ -191,14 +191,5 @@
"titleHaircolor": "Colores de Pelo",
"titleHairbase": "Estilos de Peinado",
"customizations": "Personalizaciones",
"skins": "Pieles",
"perTaskText": "Aumenta la probabilidad de obtener objetos, el límite diario de objetos obtenidos, las bonificaciones por rachas de tareas y el oro ganado al completar tareas.",
"autoAllocate": "Asignación automática",
"pointsAvailable": "Puntos disponibles",
"allocationMethod": "Método de asignación",
"statAllocationInfo": "Cada nivel te otorga un punto que puedes asignar a la estadística que prefieras. Puedes hacerlo manualmente o dejar que el juego lo haga automáticamente mediante una de las opciones de asignación automática.",
"assignedStat": "Estadística asignada",
"strTaskText": "Aumenta la probabilidad y el daño de los golpes críticos al completar tareas. También aumenta el daño infligido a los jefes de las misiones.",
"intTaskText": "Aumenta la experiencia obtenida al completar tareas. También aumenta tu límite de maná y la velocidad de regeneración de maná.",
"conTaskText": "Reduce el daño recibido por no completar las tareas diarias y por los hábitos negativos. No reduce el daño de los jefes de las misiones."
"skins": "Pieles"
}
+1 -7
View File
@@ -245,11 +245,5 @@
"faqQuestion67": "¿Cuales son las profesiones en Habitica?",
"webFaqAnswer67": "La Profesiones son los diferentes roles con los que juegas con tu personaje. Cada profesión tiene un conjunto único de beneficios y habilidades que puedes potenciar cuando vas subiendo de nivel. Estas habilidades pueden modificar la forma en que interactúas con tus tareas o ayudarte, contribuyendo a completar Misiones con tu Equipo.\n\nTu profesión también determina el equipamiento que tendrás disponible para comprar en las Recompensas, el Mercado y la Tienda Estacional.\n\nAquí tienes un resumen de cada profesión para ayudarte a elegir cuál se ajusta mejor a tu estilo de juego:\n#### **Guerrero**\n*Los guerreros son los mejores preparados para dañar a los monstruos y tienen muchas oportunidades de lanzar golpes críticos al completar tareas, recompensándote con Experiencia y Oro extra.\n* La Fuerza es su característica principal, incrementando así el daño que causas.\n* Constitución es su habilidad secundaria, reduciendo el daño que recibes.\n* Las habilidades de los guerreros mejoran la constitución y la fuerza de sus compañeros de Equipo.\n* Elige Guerrero como profesión si te gusta luchar contra los monstruos, pero también si piensas que vas a necesitar protección extra contra la pérdida de vida debida a fallos ocasionales en tus Tareas.\n#### **Sanador**\n* Los Sanadores tienen una elevada resistencia al daño y pueden curarse a ellos mismos y también a los miembros de su Equipo.\n* Como Sanador tu característica principal es la Constitución, incrementando la velocidad de curación y reduciendo el daño que recibes.\n* La Inteligencia es tu característica secundaria, incrementando tus valores de Maná y Experiencia.\n* Tus habilidades como Sanador ayudan a que tus tareas tiendan menos hacia el rojo y mejoran la Constitución de los miembros de tu Equipo.\n* Elige Sanador como profesión si piensas que vas a fallar frecuentemente con algunas de tus tareas y vas a necesitar la habilidad especial de sanación en ti o en los compañeros de Equipo. También los Sanadores suben de nivel muy rápido.\n#### **Mago**\n* Los Magos suben de nivel muy rápido, obtienen más Maná y dañan severamente a los monstruos en las Misiones.\n* La Inteligencia es tu característica principal que incrementa tu nivel de Maná y tu Experincia.\n* La Percepción es tu característica secundaria, incrementando la cantidad de oro y objetos que obtienes.\n* Con tus habilidades puedes congelar los contadores de tus tareas, restaurar el Maná le tus compañeros de Equipo y mejorar su Inteligencia.\n* Elige Mago como profesión si lo que te mantiene motivado es progresar rápidamente con respecto a subir de nivel y contribuir significativamente al daño producido a los monstruos en las Misiones.\n#### **Pícaro**\n* Los Pícaros son los que más oro y objetos obtienen al completar tareas y tienen muchas oportunidades de lanzar golpes críticos obteniendo así más Experiencia y Oro.\n* Tu característica principal como Pícaro es la Percepción incrementando la cantidad de objetos y Oro que obtienes.\n* La Fuerza es tu característica secundaria, elevando el daño que produces.\n* Tus habilidades como Pícaro te ayudan a esquivar los fallos en tus Tareas Diarias, robar Oro y mejorar la Percepción de los miembros de tu Equipo.\n* Si lo que te mantiene motivado es obtener muchos objetos y recompensas elige Pícaro como tu profesión.",
"faqQuestion68": "¿Cómo puedo evitar perder PV?",
"webFaqAnswer68": "Si sueles perder PV con frecuencia, prueba los siguientes consejos:\n\n- Pausa tus Tareas Diarias. El botón “Pausar Daño” en los Ajustes evitará que pierdas PV por las Tareas Diarias no completadas.\n- Ajusta el horario de tus Tareas Diarias. Al ajustarlas como nunca pendientes, puedes completarlas solo por loas recompensas sin riesgo a perder PV.\n- Intenta usar las habilidades de tu clase:\n\t- Los Pícaros pueden lanzar Sigilo para evitar daño de las Tareas Diarias no completadas\n\t- Los Guerreros pueden lanzar Golpe Brutal para reducir el color rojo y así también reducir el daño causado por las no completadas\n\t- Los Sanadores pueden lanzar Claridad Abrasadora para reducir el color rojo y así también reducir el daño por las no completadas",
"faqQuestion69": "¿Qué son las estadísticas de personaje?",
"faqQuestion70": "¿Qué son los puntos de atributo?",
"webFaqAnswer70": "Los puntos de atributo te permiten incrementar las estadísticas principales de tu personaje. Ganas un punto de atributo cada vez que subes de nivel (hasta el nivel 100), los cuales puedes asignar de forma manual o automática mediante la función de Localización Automática. La asignación de atributos se desbloquea junto con el Sistema de Clases al alcanzar el nivel 10.",
"faqQuestion71": "¿Cómo funciona la Localización Automática?",
"webFaqAnswer69": "Todos los jugadores tienen cuatro estadísticas de personaje que otorgan diferentes beneficios:\n\n*Fuerza: Aumenta la probabilidad de golpe crítico y el daño al completar tareas. También incrementa el daño infligido a los jefes de las misiones.\n*Inteligencia: Aumenta la Experiencia obtenida de las tareas. También incrementa tu límite máximo de Mana y la tasa de regeneración de Mana.\n*Constitución: Reduce el daño recibido por tareas diarias incumplidas y hábitos negativos. No reduce el daño de los jefes de las misiones.\n*Percepción: Aumenta la probabilidad de encontrar objetos, el límite diario de obtención de objetos, los bonos por racha de tareas y el Oro ganado al completar tareas.\n\nLas estadísticas pueden incrementarse mediante la asignación de puntos de atributo, el equipamiento, las habilidades de clase y al subir de nivel. También obtienes un punto de bonificación en todas las estadísticas cada dos niveles, hasta alcanzar el nivel 100.",
"webFaqAnswer71": "La función de Localización Automática asigna automáticamente los puntos de atributo de acuerdo con uno de los siguientes métodos de distribución:\n\n* Distribuir equitativamente: Asigna la misma cantidad de puntos a cada atributo.\n* Distribuir según la clase: Asigna más puntos a los atributos importantes para tu clase.\n* Distribuir según la actividad de las tareas: Asigna puntos según las categorías de Fuerza, Inteligencia, Constitución y Percepción asociadas a las tareas que completas.\n\nSi eliges no utilizar la Localización Automática, puedes asignar manualmente tus puntos de atributo desde la sección de Estadísticas."
"webFaqAnswer68": "Si sueles perder PV con frecuencia, prueba los siguientes consejos:\n\n- Pausa tus Tareas Diarias. El botón “Pausar Daño” en los Ajustes evitará que pierdas PV por las Tareas Diarias no completadas.\n- Ajusta el horario de tus Tareas Diarias. Al ajustarlas como nunca pendientes, puedes completarlas solo por loas recompensas sin riesgo a perder PV.\n- Intenta usar las habilidades de tu clase:\n\t- Los Pícaros pueden lanzar Sigilo para evitar daño de las Tareas Diarias no completadas\n\t- Los Guerreros pueden lanzar Golpe Brutal para reducir el color rojo y así también reducir el daño causado por las no completadas\n\t- Los Sanadores pueden lanzar Claridad Abrasadora para reducir el color rojo y así también reducir el daño por las no completadas"
}
+15 -69
View File
@@ -3,14 +3,14 @@
"equipmentType": "Tipo",
"klass": "Clase",
"groupBy": "Agrupar por <%= type %>",
"classBonus": "(Este equipamiento es de tu clase por lo que gana un multiplicador adicional de 1.5 a sus atributos)",
"classArmor": "Armadura de Clase",
"featuredset": "Conjunto Destacado: <%= name %>",
"mysterySets": "Conjuntos Misteriosos",
"classBonus": "(Este equipamiento es de tu clase por lo que gana un multiplicador de 1,5 a sus atributos)",
"classArmor": "Armadura de clase",
"featuredset": "Conjunto destacado: <%= name %>",
"mysterySets": "Conjuntos misteriosos",
"gearNotOwned": "No tienes este objeto.",
"noGearItemsOfType": "No tienes ninguno de estos.",
"classLockedItem": "Este equipamiento solo está disponible para una clase específica. ¡A partir del nivel 10, puedes cambiar tu clase pulsando: Icono de Usuario > Ajustes > Creación de personaje!",
"tierLockedItem": "Este objeto solo estará disponible una vez hayas comprado los anteriores en orden. ¡Sigue trabajando duro para llegar hasta él!",
"classLockedItem": "Este equipamiento solo está disponible para una clase específica. ¡A partir del nivel 10, cambia tu clase pulsando: Icono de Usuario > Ajustes > Creación de personaje!",
"tierLockedItem": "Este objeto solo estará disponible una vez hayas comprado los anteriores de la secuencia. ¡Sigue trabajando duro para llegar hasta él!",
"sortByType": "Tipo",
"sortByPrice": "Precio",
"sortByCon": "CON",
@@ -18,16 +18,16 @@
"sortByStr": "FUE",
"sortByInt": "INT",
"weapon": "arma",
"weaponCapitalized": "Objeto Mano Dominante",
"weaponBase0Text": "Sin Arma",
"weaponBase0Notes": "Sin Arma.",
"weaponWarrior0Text": "Espada de Entrenamiento",
"weaponCapitalized": "Objeto de la mano dominante",
"weaponBase0Text": "Sin arma",
"weaponBase0Notes": "Sin arma.",
"weaponWarrior0Text": "Espada de entrenamiento",
"weaponWarrior0Notes": "Arma de práctica. No otorga ningún beneficio.",
"weaponWarrior1Text": "Espada",
"weaponWarrior1Notes": "Espada común de un soldado. Aumenta la Fuerza en <%= str %>.",
"weaponWarrior2Text": "Hacha",
"weaponWarrior2Notes": "Arma cortante de doble filo. Aumenta la fuerza en <%= str %>.",
"weaponWarrior3Text": "Lucero del Alba",
"weaponWarrior3Text": "Lucero del alba",
"weaponWarrior3Notes": "Maza pesada con brutales espinas. Aumenta la Fuerza en <%= str %>.",
"weaponWarrior4Text": "Espada de Zafiro",
"weaponWarrior4Notes": "Espada cuyos filos cortan como el viento del norte. Aumenta la Fuerza en <%= str %>.",
@@ -3108,9 +3108,9 @@
"headSpecialSummer2024MageNotes": "Este sombrero se mece suavemente en las corrientes del océano a la vez que te asiste para canalizar tu gran sabiduría. Aumenta la percepcion en <%= per %>. Equipamiento de edición limitada Verano 2024.",
"headArmoireCorsairsBandanaNotes": "Este pañuelo badana es esencial ya sea que desees mantener tu cabeza protegida de alguna gaviota que volando sobre ella suelte la carga o por que no quieras que la tripulación vea que estas sudando nerviosamente y decida amotinarse. Eso si, añade una cuenta decorativa cada vez que completes una de tus aventuras. Aumenta la Inteligencia en <%= int %>. Armario Encantado: Conjunto de Corsario (Artículo 2 de 3)",
"shieldSpecialSummer2024WarriorNotes": "Jajaja, para todos aquellos que dicen que no eres capaz de alcanzar tus objetivos, mirad: ¡decídselo a mi mano, quiero decir, jeje, aleta! Aumenta la Constitución en <%= con %>. Equipamiento de edición limitada Verano 2024.",
"gearItemsCompleted": "¡Ya tienes todo el equipamiento de <%= klass %>! Nuevo equipamiento se publica durante las Galas estaciónales.",
"gearItemsCompleted": "¡Ya tienes todo el equipamiento de <%= klass %>! Se publicará nuevo equipamiento en las Galas estaciónales.",
"moreArmoireGearAvailable": "¡Hasta entonces, hay aún <%= armoireCount %> piezas de equipamiento que puedes encontrar en el Armario Encantado!",
"moreArmoireGearComing": El Armario Encantado también obtiene objetos nuevos cada mes!",
"moreArmoireGearComing": También en el Armario Encantado tienes nuevos objetos cada mes!",
"weaponSpecialSummer2024RogueText": "Tridente de Nudibranquio",
"weaponSpecialSummer2024MageText": "Varita de Anémona de Mar",
"weaponSpecialSummer2024MageNotes": "Estos tentáculos terroríficos poseen la habilidad de disipar, desviar y dirigir la magia indistintamente. Aumenta la inteligencia en <%= int %> y la percepción en <%= per %>. Equipamiento de edición limitada Verano 2024.",
@@ -3484,7 +3484,7 @@
"headMystery202512Text": "Yelmo de Galleta Ganadora",
"headMystery202512Notes": "Pan de jengibre forjado con números hechizos arcanos que acabaron con la cordura de sus conjuradores, protección mística ¡siempre y cuando no te lo comas! No otorga ningún beneficio. Artículo de Suscriptor Diciembre 2025.",
"headMystery202602Text": "Orejas de Zorro del Sakura",
"headMystery202602Notes": "Con estas orejas tu oído se afilará tanto que podrás escuchar el brote de las flores en las ramas de los árboles al acercarse la primavera. No otorga ningún beneficio. Artículo de Suscriptor de febrero 2026.",
"headMystery202602Notes": " Tu percepción de los sonidos será tan aguzada debido a estas orejas, que podrás escuchar no solo una mano aplaudiendo sola, si no también el florecimiento de las hermosas florecillas cuando la primavera se vaya acercando, florecilla. No otorga ningún beneficio. Artículo de Suscriptor Febrero 2026.",
"headArmoireLoneCowpokeHatText": "Sombrero de Vaquero Solitario",
"shieldSpecialWinter2026WarriorText": "Escudo Escarcha",
"shieldSpecialWinter2026HealerText": "Explosión Estelar",
@@ -3495,59 +3495,5 @@
"backMystery202601Text": "Símbolo Invernal",
"backMystery202602Text": "Las Cinco Colas de Sakura",
"backArmoireHarpsichordText": "Clavicémbalo",
"backArmoireHarpsichordNotes": "¡Duing! ¡Ding! Reúne a tu equipo ya sea para un almuerzo campestre o un picnic, algo totalmente diferente a lo anterior, y una vez allí deleita sus pabellones auditivos mientras interpretas Highway to Hell en tu clavicémbalo. Aumenta la Percepción y la Inteligencia en <%= attrs %> cada uno.Armario Encantado: Conjunto Instrumentos Musicales 2 (Artículo 1 de 3)",
"weaponSpecialSpring2026WarriorText": "Florete de la Poderosa Rana",
"weaponSpecialSpring2026RogueText": "Rama Primaveral",
"weaponSpecialSpring2026HealerText": "Bastón de Campanilla de Invierno",
"weaponSpecialSpring2026MageText": "Parasol Palo de Mayo",
"weaponSpecialSpring2026MageNotes": "Se acerca una ocasión para celebrar, ¡y con este bonito palo-parasol estarás preparado! Aumenta la Inteligencia en <%= int %> y la Percepción en <%= per %>. Equipamiento de Edición Limitada de Primavera 2026.",
"armorSpecialSpring2026WarriorText": "Armadura Rana",
"armorSpecialSpring2026WarriorNotes": "Salta a la acción tan pronto como la nieve empieza a derretirse. Aumenta la Constitución en <%= con %>. Equipamiento de Edición Limitada de Primavera 2026.",
"armorSpecialSpring2026RogueText": "Armadura de Corteza de Abedul",
"armorSpecialSpring2026RogueNotes": "Resiste las inevitables lluvias primaverales y las brisas ligeras. Aumenta la Percepción en <%= per %>. Equipamiento de Edición Limitada de Primavera 2026.",
"armorSpecialSpring2026HealerText": "Vestido de Campanilla de Invierno",
"armorSpecialSpring2026MageText": "Traje de Bailarín del Palo de Mayo",
"armorSpecialSpring2026MageNotes": "Llega preparado para bailar, hacer un picnic y disfrutar del clima cálido que trae la primavera. Aumenta la Inteligencia en <%= int %>. Equipamiento de Edición Limitada de Primavera 2026.",
"armorMystery202604Text": "Traje Espacial del Audaz Astronauta",
"armorMystery202604Notes": "Un pequeño paso para tus Tareas Pendientes, ¡un gran salto para tu satisfacción personal! No otorga ningún beneficio. Artículo de Suscriptor de abril de 2026.",
"armorArmoireHandstandOutfitText": "Parado de manos",
"armorArmoireHandstandOutfitNotes": "Las cosas definitvamente se ven de otra manera cuando estás boca abajo, no es así? Si te sientes atrapado, ¡es tiempo de una nueva perspectiva! Aumenta la Percepción en <%= per %>. Armario Encantado: Conjunto Parado de Manos (Artículo 1 de 1).",
"headSpecialSpring2026RogueText": "Casco Rama Primaveral",
"headSpecialSpring2026HealerText": "Casco de Campanilla de Invierno",
"headSpecialSpring2026HealerNotes": "Haz una esperanzadora declaración con estos hermosos, resistentes pétalos. Aumenta la Inteligencia en <%= int %>. Equipamiento de Edición Limitada de Primavera 2026.",
"headSpecialSpring2026MageText": "Corona de Flor de Mayo",
"headMystery202603Text": "Sombrero de Mago de las Glicinias",
"headMystery202604Text": "Casco del Audaz Astronauta",
"headArmoireFloppyYellowHatText": "Sombrero Flexible Amarillo",
"headArmoireVerdantArmingCapText": "Cofia Acolchada del Paje Verdoso",
"shieldSpecialSpring2026RogueText": "Rama Primaveral",
"shieldSpecialSpring2026RogueNotes": "Alcanza tus límites con estas ramas. También sirven como rascador de espalda en caso de necesitarlo. Aumenta la Fuerza en <%= str %>. Equipamiento de Edición Limitada de Primavera 2026.",
"shieldSpecialSpring2026HealerText": "Hoja de Campanilla de Invierno",
"shieldMystery202605Text": "Escudo del Anochecer",
"shieldArmoireSoftYellowPillowText": "Almohada Amarillo Suave",
"shieldArmoireVerdantBannerText": "Estandarte del Paje Verde",
"shieldArmoireVerdantBannerNotes": "¡Ondea alto tu estandarte para indicar a tus amigos que es hora de reunirse! Aumenta la Inteligencia en <%= int %>. Armario Encantado: Conjunto del Paje Verdoso (Artículo 2 de 2).",
"backMystery202605Text": "Nimbus del Anochecer",
"weaponSpecialSpring2026RogueNotes": "Se acerca una gran oportunidad para crecer, ¡y con estas ramas en ciernes estarás preparado! Aumenta la Fuerza en <%= str %>. Equipamiento de Edición Limitada de Primavera 2026.",
"weaponSpecialSpring2026WarriorNotes": "Puede que se presente una oportunidad para batirse en duelo en cualquier momento, ¡y con este formidable florete estarás preparado! Aumenta la Fuerza en <%= str %>. Equipamiento de Edición Limitada de Primavera 2026.",
"weaponSpecialSpring2026HealerNotes": "Se presenta una oportunidad para empezar de nuevo con un fresco comienzo, ¡y con este espléndido bastón estarás preparado! Aumenta la Inteligencia en <%= int %>. Equipamiento de Edición Limitada de Primavera 2026.",
"weaponMystery202603Text": "Bastón de Mago de las Glicinias",
"weaponMystery202603Notes": "¡Lanza hechizos para calentar el aire primaveral y favorecer la floración! No otorga ningún beneficio. Artículo de Suscriptor de marzo de 2026.",
"armorSpecialSpring2026HealerNotes": "Deslízate con gracia desde un invierno frío y oscuro hasta una primavera gloriosa. Aumenta la Constitución en <%= con %>. Equipamiento de Edición Limitada de Primavera 2026.",
"armorArmoireSoftYellowSuitText": "Traje Amarillo Suave",
"armorArmoireSoftYellowSuitNotes": "El amarillo es un color energético. Ponte esto a la hora de dormir, y te despertarás con el Sol, listo para enfrentarte a un día atareado. Aumenta la Constitución y la Fuerza en <%= attrs %>. Armario Encantado: Conjunto Ropa de Casa Amarilla (Artículo 2 de 3).",
"headSpecialSpring2026WarriorText": "Casco del Guerrero Rana",
"headSpecialSpring2026WarriorNotes": "Las ranas son famosas por su resistencia a la corrupción. ¡Este casco te otorgará sus nobles cualidades! Aumenta la Fuerza en <%= str %>. Equipamiento de Edición Limitada de Primavera 2026.",
"headSpecialSpring2026RogueNotes": "Haz una notable declaración con ramitas y brotes creciendo de forma salvaje en todas direcciones. Aumenta la Percepción en <%= per %>. Equipamiento de Edición Limitada de Primavera 2026.",
"headSpecialSpring2026MageNotes": "Haz una alegre declaración con brillantes flores rodeando tu cabeza. Aumenta la Percepción en <%= per %>. Equipamiento de Edición Limitada de Primavera 2026.",
"headMystery202603Notes": "Este coqueto sombrero no solo potencia tus habilidades mágicas, ¡sino que además tiene un adorable aroma primaveral! No otorga ningún beneficio. Artículo de Suscriptor de marzo 2026.",
"headMystery202604Notes": "En el espacio, nadie puede oirte completando tus Tareas Pendientes. ¡Pero la verdadera recompensa es la satisfacción personal! No otorga ningún beneficio. Artículo de Suscriptor de abril 2026.",
"backMystery202605Notes": "Un halo resplandeciente de luz de luna y estrellas para iluminar la noche más oscura. No confiere ningún beneficio. Artículo de Suscriptor de mayo 2026.",
"headArmoireFloppyYellowHatNotes": "Muchos encantamientos han sido cosidos a este simple sombrero, confiriéndole un juvenil color amarillo. Aumenta todas las estadísticas en <%= attrs %>. Armario Encantado: Conjunto Ropa de Casa Amarilla (Artículo 1 de 3).",
"headArmoireVerdantArmingCapNotes": "Esta cómoda, acolchada cofia te prepara para la batalla y te ayuda a resistir cualquier cosa pesada que se te presente. Aumenta la Percepción y la Constitución en <%= attrs %>. Armario Encantado: Conjunto del Paje Verdoso (Artículo 1 de 2).",
"shieldSpecialSpring2026WarriorText": "Candelabro del Guerrero Rana",
"shieldSpecialSpring2026WarriorNotes": "Este candelabro no sólo puede iluminar tu camino; también puedes usarlo para derretir cualquier resto de nieve y hielo. Aumenta la Constitución en <%= con %>. Equipamiento de Edición Limitada de Primavera 2026.",
"shieldSpecialSpring2026HealerNotes": "Crea una brisa suave con este ventilador a medida que suben las temperaturas. También sirve como bolígrafo en caso de necesitarlo. Aumenta la Constitución en <%= con %>. Equipamiento de Edición Limitada de Primavera 2026.",
"shieldMystery202605Notes": "Deja que la brillante luz de luna te proteja de los peligros en la oscuridad. No otorga ningún beneficio. Artículo de Suscriptor de mayo 2026.",
"shieldArmoireSoftYellowPillowNotes": "El guerrero experimentado lleva una almohada en cada expedición. Crece y brilla mientras consolidas todo lo aprendido en aventuras pasadas… incluso mientras duermes la siesta. Aumenta la Inteligencia y la Percepción en <%= attrs %>. Armario Encantado: Conjunto Ropa de Casa Amarilla (Artículo 3 de 3)."
"backArmoireHarpsichordNotes": "¡Duing! ¡Ding! Reúne a tu equipo ya sea para un almuerzo campestre o un picnic, algo totalmente diferente a lo anterior, y una vez allí deleita sus pabellones auditivos mientras interpretas Highway to Hell en tu clavicémbalo. Aumenta la Percepción y la Inteligencia en <%= attrs %> cada uno.Armario Encantado: Conjunto Instrumentos Musicales 2 (Artículo 1 de 3)"
}
+1 -2
View File
@@ -242,6 +242,5 @@
"newMessage": "Nuevo Mensaje",
"targetUserNotExist": "Usuario objetivo: '<%= userName %>' no existe.",
"rememberToBeKind": "Por favor recuerda ser bondadoso, respetuoso y seguir las <a href='/static/community-guidelines' target='_blank'>Normas de la Comunidad</a>.",
"gem": "Gema",
"confirmPurchase": "Confirmar Compra"
"gem": "Gema"
}
+1 -13
View File
@@ -428,17 +428,5 @@
"groupTeacher": "Usándolo para dar clase",
"groupParentChildren": "Usándolo con mi familia",
"groupPlanBillingFYI": "Las suscripciones de Planes de Grupo se renuevan automáticamente a no ser que la canceles al menos 24 horas antes del fin del periodo en curso. Puedes cancelarla desde la pestaña Facturación de Grupo en tu Plan de Grupo. Se te cargará dentro de las 24 horas en las que renueva la suscripción y basado en el número de miembros de tu grupo en el Plan de Grupo en ese mismo momento. Si añades miembros entre períodos de pago, habrá un cargo adicional prorrateado por los beneficios obtenidos en tu siguiente ciclo de facturación.",
"groupPlanBillingFYIShort": "Las suscripciones de Plan de Grupo se renuevan automáticamente a no ser que se cancelen 24 horas antes del fin del periodo actual. Se te cargará dentro de las 24 horas antes de la renovación de la suscripción, basado en el número de miembros de tu Plan de Grupo en ese mismo momento. Si añades miembros entre períodos de pago, se te aplicará un pago adicional prorrateado por los beneficios obtenidos en tu siguiente ciclo de facturación.",
"createNewGroup": "Crear un Nuevo Grupo",
"upgradeExistingGroup": "Mejorar un Grupo Existente",
"chooseAnOption": "Elegir una Opción",
"yourParty": "Tu Equipo",
"previouslyUpgradedGroup": "Grupo previamente mejorado",
"inviteOthersForAdditional": "Invita a otros a tu Grupo por un adicional de",
"perMember": "por miembro",
"oneMember": "1 miembro",
"membersCount": "<%= count %> miembros",
"pendingCount": "(<%= count %> pendiente)",
"upgradeCancelsPendingInvites": "Mejorar tu Equipo cancelará todas las invitaciones pendientes",
"additionalMembersProrated": "Miembros adicionales invitados durante el mes se añadirán al total del siguiente ciclo de facturación como cargo prorrateado."
"groupPlanBillingFYIShort": "Las suscripciones de Plan de Grupo se renuevan automáticamente a no ser que se cancelen 24 horas antes del fin del periodo actual. Se te cargará dentro de las 24 horas antes de la renovación de la suscripción, basado en el número de miembros de tu Plan de Grupo en ese mismo momento. Si añades miembros entre períodos de pago, se te aplicará un pago adicional prorrateado por los beneficios obtenidos en tu siguiente ciclo de facturación."
}
+20 -24
View File
@@ -267,28 +267,24 @@
"fall2024SpaceInvaderHealerSet": "Conjunto de Invasor del Espacio (Sanador)",
"fall2024BlackCatRogueSet": "Conjunto Gato Negro (Pícaro)",
"fall2024FieryImpWarriorSet": "Conjunto de Balrog Menor (Guerrero)",
"winter2025StringLightsHealerSet": "Conjunto Tira de Luces (Sanador)",
"winter2025SnowRogueSet": "Conjunto Muñeco de Nieve (Pícaro)",
"winter2025MooseWarriorSet": "Conjunto Alce (Guerrero)",
"winter2025AuroraMageSet": "Conjunto Aurora (Mago)",
"spring2025CrystalPointRogueSet": "Conjunto Punta de Cristal (Pícaro)",
"spring2025PlumeriaHealerSet": "Conjunto Plumeria (Sanador)",
"spring2025MantisMageSet": "Conjunto Mantis (Mago)",
"spring2025SunshineWarriorSet": "Conjunto Rayo de Sol (Guerrero)",
"summer2025ScallopWarriorSet": "Conjunto Vieira (Guerrero)",
"summer2025SquidRogueSet": "Conjunto Calamar (Pícaro)",
"summer2025SeaAngelHealerSet": "Conjunto Ángel de Mar (Sanador)",
"summer2025FairyWrasseMageSet": "Conjunto Pez Lábrido Hada (Mago)",
"fall2025SasquatchWarriorSet": "Conjunto Pie Grande (Guerrero)",
"fall2025SkeletonRogueSet": "Conjunto Esqueleto (Pícaro)",
"fall2025KoboldHealerSet": "Conjunto Kobold (Sanador)",
"fall2025MaskedGhostMageSet": "Conjunto Fantasma Enmascarado (Mago)",
"winter2026RimeReaperWarriorSet": "Conjunto Destripador Escarcha (Guerrero)",
"winter2026SkiRogueSet": "Conjunto Esquí (Pícaro)",
"winter2026PolarBearHealerSet": "Conjunto Oso Polar (Sanador)",
"winter2026MidwinterCandleMageSet": "Conjunto Vela Invernal (Mago)",
"spring2026FrogWarriorSet": "Conjunto Rana (Guerrero)",
"spring2026BranchRogueSet": "Conjunto Rama Primaveral (Pícaro)",
"spring2026SnowdropHealerSet": "Conjunto Campanilla de Invierno (Sanador)",
"spring2026MaypoleMageSet": "Conjunto Palo de Mayo (Mago)"
"winter2025StringLightsHealerSet": "Conjunto de Sanador Tira de Luces",
"winter2025SnowRogueSet": "Conjunto Pícaro Muñeco de Nieve",
"winter2025MooseWarriorSet": "Conjunto de Guerrero Alce",
"winter2025AuroraMageSet": "Conjunto de Mago de la Aurora",
"spring2025CrystalPointRogueSet": "Conjunto Pícaro Puntas de Cristal",
"spring2025PlumeriaHealerSet": "Conjunto Sanador Flor Plumaria",
"spring2025MantisMageSet": "Conjunto Mago Mantis",
"spring2025SunshineWarriorSet": "Conjunto Guerrero Brillo Solar",
"summer2025ScallopWarriorSet": "Conjunto Guerrero Vieira",
"summer2025SquidRogueSet": "Conjunto Pícaro Calamar",
"summer2025SeaAngelHealerSet": "Conjunto Sanador Ángel de Mar",
"summer2025FairyWrasseMageSet": "Conjunto Mago Pez Lábrido Hada",
"fall2025SasquatchWarriorSet": "Conjunto de Guerrero Bigfoot",
"fall2025SkeletonRogueSet": "Conjunto de Esqueleto Pícaro",
"fall2025KoboldHealerSet": "Conjunto de Sanador Kobold",
"fall2025MaskedGhostMageSet": "Conjunto de Mago Fantasma Enmascarado",
"winter2026RimeReaperWarriorSet": "Conjunto de Guerrero Destripador Escarcha",
"winter2026SkiRogueSet": "Conjunto de Esquiador Pícaro",
"winter2026PolarBearHealerSet": "Conjunto de Sanador Oso Polar",
"winter2026MidwinterCandleMageSet": "Conjunto de Mago Vela Invernal"
}
+9 -18
View File
@@ -189,7 +189,7 @@
"questTRexUndeadBoss": "Tiranosaurio Esqueleto",
"questTRexUndeadRageTitle": "Sanación de Esqueleto",
"questTRexUndeadRageDescription": "Esta barra se llena cuando no completas tus tareas Diarias. Cuando esté completa, ¡el Tiranosaurio Esqueleto va a sanar un 30 por ciento de su salud restante!",
"questTRexUndeadRageEffect": "¡Tiranosaurio Esqueleto usa SANACIÓN DE ESQUELETO!\n\n¡El monstruo deja salir un rugido sobrenatural, y algunos de sus huesos dañados vuelven a unirse!",
"questTRexUndeadRageEffect": "`¡Tiranosaurio Esqueleto usa SANACIÓN DE ESQUELETO!`\n\n¡El monstruo deja salir un rugido sobrenatural, y algunos de sus huesos dañados vuelven a unirse!",
"questTRexDropTRexEgg": "Tiranosaurio (Huevo)",
"questTRexUnlockText": "Desbloquea la compra de huevos de tiranosaurio en el Mercado",
"questRockText": "Escapa de la Cueva Viviente",
@@ -241,7 +241,7 @@
"questDilatoryDistress2Boss": "Enjambre de Carabelas Aquaticas",
"questDilatoryDistress2RageTitle": "Regeneración de Enjambre",
"questDilatoryDistress2RageDescription": "Regeneración de Enjambre: Esta barra se va llenando cuando no completas tus Diarias. Cuando se llene completamente, ¡el Enjambre de Calaveras Acuáticas sanará el 30% de su salud restante!",
"questDilatoryDistress2RageEffect": "¡El Enjambre de Calaveras Acuáticas usa REGENERACIÓN DE ENJAMBRE!\n\n¡Incentivadas por sus victorias, más calaveras salen de la grieta, fortaleciendo al enjambre!",
"questDilatoryDistress2RageEffect": "`¡El Enjambre de Calaveras Acuáticas usa REGENERACIÓN DE ENJAMBRE!`\n\n¡Incentivadas por sus victorias, más calaveras salen de la grieta, fortaleciendo al enjambre!",
"questDilatoryDistress2DropSkeletonPotion": "Poción de Eclosión Esquelética",
"questDilatoryDistress2DropCottonCandyBluePotion": "Poción de Eclosión Algodón de Azúcar Azul",
"questDilatoryDistress2DropHeadgear": "Diadema de coral de fuego (equipo de cabeza)",
@@ -437,7 +437,7 @@
"questStoikalmCalamity1Boss": "Enjambre de Calaveras Terrestres",
"questStoikalmCalamity1RageTitle": "Reaparición del Enjambre",
"questStoikalmCalamity1RageDescription": "Regeneración de Enjambre: Esta barra se va llenando cuando no completas tus Diarias. Cuando se llene completamente, ¡el Enjambre de Calaveras Terrestres sanará el 30% o de su salud restante!",
"questStoikalmCalamity1RageEffect": "¡El Enjambre de Calaveras de Tierra usa REGENERACIÓN DE ENJAMBRE!\n\n¡Más calaveras salen de la tierra, chasqueando sus dientes en el frío!",
"questStoikalmCalamity1RageEffect": "`¡El Enjambre de Calaveras de Tierra usa REGENERACIÓN DE ENJAMBRE!`\n\n¡Más calaveras salen de la tierra, chasqueando sus dientes en el frío!",
"questStoikalmCalamity1DropSkeletonPotion": "Poción de eclosión de esqueleto",
"questStoikalmCalamity1DropDesertPotion": "Poción de eclosión del desierto",
"questStoikalmCalamity1DropArmor": "Armadura de jinete de mamut",
@@ -478,7 +478,7 @@
"questMayhemMistiflying1Boss": "Enjambre de Calaveras Aéreas",
"questMayhemMistiflying1RageTitle": "Reaparición del Enjambre",
"questMayhemMistiflying1RageDescription": "Reaparición del Enjambre: Esta barra se llena cuando no completas tus Tareas Diarias. Cuando está llena, ¡el Enjambre de Calaveras Aéreas recuperará el 30% de su salud restante!",
"questMayhemMistiflying1RageEffect": "¡El Enjambre de Calaveras Aéreas utiliza REAPARICIÓN DEL ENJAMBRE!\n\n¡Envalentonadas por sus victorias, más calaveras aparecen girando de entre las nubes!",
"questMayhemMistiflying1RageEffect": "`El Enjambre de Calaveras Aéreas utiliza REAPARICIÓN DEL ENJAMBRE`\n\n¡Envalentonadas por sus victorias, más calaveras aparecen girando de entre las nubes!",
"questMayhemMistiflying1DropSkeletonPotion": "Poción de Eclosión Esquelética",
"questMayhemMistiflying1DropWhitePotion": "Poción de Eclosión Blanca",
"questMayhemMistiflying1DropArmor": "Túnicas del Mensajero Picaresco Arcoiris (Armadura)",
@@ -548,7 +548,7 @@
"questLostMasterclasser4Boss": "Anti'zinnya",
"questLostMasterclasser4RageTitle": "Vacío Sifónico",
"questLostMasterclasser4RageDescription": "Vacío Sifónico: Esta barra se llena cuando no completas tus Tareas Diarias. ¡Cuando esté llena, Anti'zinnya eliminará el Maná del Equipo!",
"questLostMasterclasser4RageEffect": "¡'Anti'zinnya usa VACÍO SIFÓNICO! ¡En una inversión del hechizo Oleada Etérea, sientes que tu magia se escurre hacia la oscuridad!",
"questLostMasterclasser4RageEffect": "'Anti'zinnya usa VACÍO SIFÓNICO! ¡En una inversión del hechizo Oleada Etérea, sientes que tu magia se escurre entre la oscuridad!",
"questLostMasterclasser4DropBackAccessory": "Capa de Éter (Accesorio en la Espalda)",
"questLostMasterclasser4DropWeapon": "Cristales de Éter (Arma de dos manos)",
"questLostMasterclasser4DropMount": "Montura Invisible de Éter",
@@ -693,7 +693,7 @@
"jungleBuddiesText": "Paquete de misiones Colegas de la Jungla",
"questWaffleUnlockText": "Desbloquea la compra de la poción de eclosión de confitería en el Mercado",
"questWaffleDropDessertPotion": "Poción de eclosión de confitería",
"questWaffleRageEffect": "¡Tortita Terrible usa CIENAGA DE ARCE! ¡Un sirope pegajoso de savia ralentiza tus golpes y hechizos! Daño pendiente reducido.",
"questWaffleRageEffect": "`¡Tortita Terrible usa CIENAGA DE ARCE!` ¡Un sirope pegajoso de savia ralentiza tus golpes y hechizos! Daño pendiente reducido.",
"questWaffleRageDescription": "Cienaga de Arce: Esta barra se llena cuando no completas tus Tareas Diarias. ¡Cuando esté llena, la Tortita Terrible restará del daño pendiente que los miembros del Equipo hayan acumulado!",
"questBlackPearlUnlockText": "Desbloquea Pociones de Eclosión de Perla Negra para comprar en el Mercado",
"questBlackPearlDropBlackPearlPotion": "Poción de Eclosión de Perla Negra",
@@ -749,7 +749,7 @@
"questVirtualPetNotes": "Es una tranquila y agradable mañana de primavera en Habitica, una semana después de un memorable Día de los Inocentes. Tú y @Beffymaroo estáis en los establos atendiendo a vuestras mascotas (¡quienes todavía están un poco confundidas por el tiempo que pasaron virtualmente!).<br><br>A lo lejos escuchas un estruendo y un pitido, suave al principio pero aumentando en volumen como si estuviera cada vez más cerca. Aparece una forma de huevo en el horizonte y, a medida que se acerca, con un pitido cada vez más fuerte, ¡ves que es una mascota virtual gigantesca!<br><br>“Oh, no”, exclama @Beffymaroo, “Creo que Santo Inocente dejó asuntos pendientes con este tipo grande aquí, ¡parece querer atención!”<br><br>La mascota virtual emite un pitido enfadado, lanzando una rabieta virtual y gritando cada vez más cerca.",
"questVirtualPetBoss": "Tamagotchi",
"questVirtualPetRageTitle": "El pitido",
"questVirtualPetRageEffect": "¡Wotchimon usa Pitido Molesto!\" ¡Wotchimon emite un pitido molesto y su barra de felicidad desaparece repentinamente! Daño pendiente reducido.",
"questVirtualPetRageEffect": "\"¡Wotchimon usa un pitido molesto!\" ¡Wotchimon emite un pitido molesto y su barra de felicidad desaparece repentinamente! Daño pendiente reducido.",
"questVirtualPetRageDescription": "Esta barra se llena cuando no completas tus Diarios. ¡Cuando esté lleno, Wotchimon eliminará algunos de los daños causados de tu grupo!",
"questVirtualPetDropVirtualPetPotion": "Poción virtual para incubar mascotas",
"questVirtualPetText": "El Caos Virtual con Santo Inocente: El Pitido",
@@ -760,7 +760,7 @@
"questPinkMarbleBoss": "Cupido",
"questPinkMarbleRageTitle": "Ponche Rosa",
"questPinkMarbleRageDescription": "Esta barra se llena cuando no completas tus Tareas Diarias. ¡Cuando esté llena, Cupido eliminará algunos daños causados por tu grupo!",
"questPinkMarbleRageEffect": "¡Cupido usa Ponche Rosa! ¡No ha sido nada afectuoso! Tus compañeros de equipo están desconcertados. El daño pendiente se ha reducido.",
"questPinkMarbleRageEffect": "\"¡Cupido usa Ponche Rosa!\" ¡No ha sido nada afectuoso! Tus compañeros de equipo están desconcertados. El daño pendiente se ha reducido.",
"questPinkMarbleDropPinkMarblePotion": "Poción de eclosión de mármol rosa",
"questPinkMarbleUnlockText": "Desbloquea Poción de eclosión de mármol rosa para comprarla en el Mercado.",
"questFungiNotes": "Ha sido una primavera lluviosa y la tierra alrededor de los establos está esponjosa y húmeda. Te das cuenta que bastantes setas han crecido cerca de las paredes de madera y en las vallas. Hay una niebla que impide que el sol brille con fuerza y esto crea un paisaje muy desalentador. <br><br>Entre la espesura de la bruma ves la silueta del Bromista de Abril, pero no parece que esté en su habitual estado divertido y saltarín.<br><br>”Esperaba traeros algunas divertidas pociones de eclosión de Setas Mágicas para que pudierais disfrutar de vuestras amigas setas desde mi día especial y para siempre” dice, con una expresión alarmantemente seria. “Pero esta fría niebla me está afectando, me hace sentirme demasiado cansado y triste y hace que mi magia no funcione.”<br><br>”Oh no, siento escuchar eso,” le dices, notando tu también tu propio estado de ánimo muy afectado y apagado. “Esta extraña niebla esta haciendo que el día se vuelva sombrío. Me pregunto cuál será su procedencia...”<br><br>Un estruendo apenas audible resuena por entre los campos y puedes ver una silueta emergiendo de la bruma. La sensación de peligro que notas se hace más intensa al ver una gigantesca criatura parecida a una seta con cara de pocos amigos, y la bruma parece que procede de ella.<br><br>”Vale,” dice el Bromista, “Creo que este colega micológico puede ser el origen de nuestra súbita tristeza. Veamos si una buena trifulca nos ameniza el día mientras le abrimos otra sonrisa al bicho.”",
@@ -860,14 +860,5 @@
"questOpalCollectMercuryRunes": "Runa de Mercurio",
"questOpalCollectOpalGems": "Gema de Ópalo",
"questOpalDropOpalPotion": "Poción de eclosión Ópalo",
"questOpalUnlockText": "Desbloquea pociones de eclosión Ópalo para comprarlas en la Tienda",
"questAlienText": "Invasión de los Ladrones de Motivación",
"questAlienNotes": "Han sido días extraños en Habitica. El gran platillo volador aún flota cerca de los Campos Florecientes. Zumba extrañamente. ¿Por qué sigue ahí? El Día de los Santos Inocentes ha pasado, y el tiempo de protagonismo del Maestro de los Pícaros ha terminado.<br><br>Deambulas hacia la luz de la nave espacial. Podrías echarle un vistazo y adentrarte un poco, de paso.<br><br>Mientras te acercas, ves al Bromista de Abril, con aspecto algo sombrío. Su rostro luce verdoso a la luz del rayo de la nave.<br><br>\"'¡Era mi plan conseguir algunas pociones para todos, un pequeño regalo para que todos puedan disfrutar de sus pequeños amigos extraterrestres de nuevo! Pero simplemente no puedo reunir el valor... Creo que sé por qué\", dice el Bromista, asintiendo hacia el rayo.<br><br>Pequeños símbolos están siendo absorbidos por la nave. ¡Son todas tus tareas marcadas! No me extraña que tu motivación haya estado tan baja.<br><br>”¡Nuestra motivación está siendo abducida!” exclamas. “¡Tenemos que rescatarla antes de que acabe perdida en el espacio profundo!”<br><br>El Bromista sonríe. “¡Concentra tus pensamientos en las tareas que sabes que debes terminar! Yo haré el resto con un poco de magia.”",
"questAlienBoss": "Ladrón de Ánimo, el Extraterrestre",
"questAlienRageTitle": "Impedimento Intergaláctico",
"questAlienRageEffect": "¡Ladrón de Ánimo usa Impedimento Intergaláctico! Has retrocedido a través del hiperespacio. ¡Tu oponente recupera PV!",
"questAlienDropAlienPotion": "Poción de eclosión alien",
"questAlienUnlockText": "Desbloque la Poción de Eclosión Alien para comprar en el Mercado",
"questAlienRageDescription": "Esta barra se llena cuando no completas tus Tareas Diarias. ¡Cuando está llena, el Extraterrestre te desanimará recuperando parte de su Salud!",
"questAlienCompletion": "Has logrado recuperar la motivación robada con tu determinación y el poder mágico del Bromista. Mientras sientes regresar tus fuerzas, el OVNI desciende y una rampa emerge lentamente junto con una criatura grande, verde y de un solo ojo. Aunque de aspecto extraño, no parece amenazante.<br><br>“Parece que fuimos un poco demasiado lejos al intentar obtener un poco de ánimo extra de tu hermosa ciudad”, dice. “Disculpas por eso, y fantástico trabajo al recuperarlo. ¡El aura extra de tus esfuerzos, de hecho, cargó el motor de la nave lo suficiente como para llevarnos a casa! Por favor, toma esto en señal de agradecimiento.”<br><br>“¡Oh, pociones!”, dice el Bromista, “¡qué encantador, y qué conveniente para mí que las tengas todas listas!”"
"questOpalUnlockText": "Desbloquea pociones de eclosión Ópalo para comprarlas en la Tienda"
}
+3 -10
View File
@@ -1,8 +1,8 @@
{
"rebirthNew": "Renacimiento: ¡Nueva aventura disponible!",
"rebirthUnlock": "¡Has desbloqueado el Renacimiento! Este objeto especial del Mercado te permite empezar un juego nuevo en el nivel 1, manteniendo tus tareas, logros, mascotas, y más. Úsalo para comenzar una nueva vida en Habitica por si sientes que ya lo lograste todo, o para experimentar nuevas funciones con la perspectiva de un personaje nuevo.",
"rebirthAchievement": "Has utilizado el Orbe del Renacimiento <strong><%= number %></strong> vez, y el nivel más alto que has conseguido <strong><%= level %></strong>.",
"rebirthAchievement100": "Has utilizado el Orbe del Renacimiento <strong><%= number %></strong> veces, y el nivel más alto que has conseguido es <strong>100</strong> o superior.",
"rebirthAchievement": "¡Has comenzado una nueva aventura! Este es tu renacimiento número <%= number %>, y el nivel más alto que has conseguido es <%= level %>. Para apilar este logro, ¡empieza tu siguiente aventura después de haber conseguido un nivel más alto!",
"rebirthAchievement100": "¡Has comenzado una nueva aventura! Este es el Renacimiento <%= number %> para ti, y el Nivel más alto que has conseguido es 100 o superior. Para acumular este Logro, ¡empieza tu aventura siguiente después de haber conseguido al menos el nivel 100!",
"rebirthBegan": "Comienza una nueva aventura",
"rebirthText": "Has comenzado <%= rebirths %> nuevas aventuras",
"rebirthOrb": "Usó un Orbe de Renacimiento para comenzar de nuevo después de alcanzar el Nivel <%= level %>.",
@@ -11,12 +11,5 @@
"rebirthPop": "Reinicia instantáneamente tu personaje como un Guerrero de Nivel 1, manteniendo logros, colecciones y equipamiento. Tus tareas y su historial se mantendrán, pero volverán a ser amarillas. Tus rachas desaparecerán excepto por tareas pertenecientes a Desafíos y Planes Grupales activos. Tu Oro, Experiencia, Maná y los efectos de todas tus habilidades desaparecerán. Todo esto tendrá efecto inmediato.",
"rebirthName": "Esfera de Renacimiento",
"rebirthComplete": "¡Has vuelto a nacer!",
"nextFreeRebirth": "<strong><%= days %> días</strong> hasta la Orbe de Renacimiento <strong>GRATIS</strong>",
"rebirthUnlockedOrb": "¡Una nueva aventura está disponible!",
"rebirthNewAchievement": "Nuevo Logro",
"rebirthNewAdventure": "¡Una nueva aventura comienza!",
"rebirthAchievementPlural": "Has utilizado el Orbe del Renacimiento <strong><%= number %></strong> veces, y el nivel más alto que has conseguido <strong><%= level %></strong>.",
"rebirthStackInfo": "Este logro se acumulará cada vez que uses el Orbe del Renacimiento.",
"rebirthUnlockedNewItem": "Orbe del Renacimiento Desbloqueado",
"rebirthUnlockedDesc": "¡Usa el Orbe del Renacimiento para darle nuevo significado a tu aventura en Habitica cuando sientas que ya has logrado todo! Vuelve a empezar desde el nivel 1 conservando tus tareas, Logros y Mascotas con este objeto especial que encontrarás en el Mercado."
"nextFreeRebirth": "<strong><%= days %> días</strong> hasta la Orbe de Renacimiento <strong>GRATIS</strong>"
}
+1 -5
View File
@@ -273,9 +273,5 @@
"mysterySet202512": "Conjunto de Galleta Ganadora",
"mysterySet202601": "Conjunto Égida de Invierno",
"mysterySet202602": "Conjunto Zorro del Sakura",
"subscriptionBillingFYI": "Las suscripciones se renuevan automáticamente a no ser que se cancelen con 24 horas de antelación antes de que finalice el periodo en curso. Puedes modificar tu suscripción desde la pestaña Suscripción en los ajustes. Se te cargará a tu cuenta dentro de las 24 horas de la fecha de renovación, al mismo precio que pagaste inicialmente.",
"mysterySet202603": "Conjunto de Mago de las Glicinias",
"mysterySet202604": "Conjunto Astronauta Audaz",
"mysterySet202605": "Conjunto Nimbus del Anochecer",
"subscriptionBillingFYIShort": "Las suscripciones se renuevan automáticamente a menos que las canceles al menos 24 horas antes de que finalice el período actual. Se te cobrará el importe correspondiente en las 24 horas siguientes a la fecha de renovación, al mismo precio que pagaste inicialmente."
"subscriptionBillingFYI": "Las suscripciones se renuevan automáticamente a no ser que se cancelen con 24 horas de antelación antes de que finalice el periodo en curso. Puedes modificar tu suscripción desde la pestaña Suscripción en los ajustes. Se te cargará a tu cuenta dentro de las 24 horas de la fecha de renovación, al mismo precio que pagaste inicialmente."
}
+1 -7
View File
@@ -137,11 +137,5 @@
"taskAliasPopover": "El alias de tarea puede usarse al conectar con integraciones de terceros. Solo se admiten guiones, guiones bajos y caracteres alfanuméricos. El alias de la tarea debe ser único entre todas tus tareas.",
"taskAliasPlaceholder": "tu-alias-de-tarea-aquí",
"scoreUp": "Puntuar positivamente",
"scoreDown": "Puntuar negativamente",
"deleteType": "Eliminar <%= type %>",
"deleteTask": "Eliminar tarea",
"deleteXTasks": "Eliminar <%= count %> tareas",
"confirmDeleteTasks": "¿Quieres eliminar las tareas?",
"brokenChallengeTaskCount": "Esta es una de las <%= count %> tareas que forman parte de un desafío que ya no existe.",
"sureDeleteType": "¿Estás seguro que deseas eliminar esta tarea?"
"scoreDown": "Puntuar negativamente"
}

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