mirror of
https://github.com/HabitRPG/habitica.git
synced 2026-04-22 11:28:25 -05:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8a317c269e |
@@ -37,7 +37,6 @@
|
||||
"NODE_DB_URI": "mongodb://localhost:27017/habitica-dev?replicaSet=rs",
|
||||
"TEST_DB_URI": "mongodb://localhost:27017/habitica-test?replicaSet=rs",
|
||||
"MONGODB_POOL_SIZE": "10",
|
||||
"MONGODB_SOCKET_TIMEOUT": "20000",
|
||||
"NODE_ENV": "development",
|
||||
"PATH": "bin:node_modules/.bin:/usr/local/bin:/usr/bin:/bin",
|
||||
"PAYPAL_BILLING_PLANS_basic_12mo": "basic_12mo",
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const MIGRATION_NAME = '2024_purge_invite_accepted';
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUsers (userIds) {
|
||||
count += userIds.length;
|
||||
if (count % progressCount === 0) console.warn(`${count} ${userIds[0]}`);
|
||||
|
||||
return await User.updateMany(
|
||||
{ _id: { $in: userIds } },
|
||||
{ $pull: { notifications: { type: 'GROUP_INVITE_ACCEPTED' } } },
|
||||
).exec();
|
||||
}
|
||||
|
||||
export default async function processUsers () {
|
||||
let query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
'notifications.type': 'GROUP_INVITE_ACCEPTED',
|
||||
'auth.timestamps.loggedin': { $gt: new Date('2024-06-25') },
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({ _id: 1 })
|
||||
.select({ _id: 1 })
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
const userIds = users.map(user => user._id);
|
||||
|
||||
await updateUsers(userIds); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
Generated
+10
-822
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "habitica",
|
||||
"version": "5.27.3",
|
||||
"version": "5.27.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "habitica",
|
||||
"version": "5.27.3",
|
||||
"version": "5.27.0",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.22.10",
|
||||
@@ -20,7 +20,6 @@
|
||||
"amplitude": "^6.0.0",
|
||||
"apidoc": "^0.54.0",
|
||||
"apple-auth": "^1.0.9",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
"bcrypt": "^5.1.1",
|
||||
"body-parser": "^1.20.2",
|
||||
"bootstrap": "^4.6.2",
|
||||
@@ -81,7 +80,6 @@
|
||||
"useragent": "^2.1.9",
|
||||
"uuid": "^9.0.0",
|
||||
"validator": "^13.11.0",
|
||||
"webpack-bundle-analyzer": "^4.10.2",
|
||||
"winston": "^3.10.0",
|
||||
"winston-loggly-bulk": "^3.3.0",
|
||||
"xml2js": "^0.6.2"
|
||||
@@ -3257,11 +3255,6 @@
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"node_modules/@polka/url": {
|
||||
"version": "1.0.0-next.25",
|
||||
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz",
|
||||
"integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ=="
|
||||
},
|
||||
"node_modules/@protobufjs/aspromise": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||
@@ -3923,17 +3916,6 @@
|
||||
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn-walk": {
|
||||
"version": "8.3.3",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz",
|
||||
"integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==",
|
||||
"dependencies": {
|
||||
"acorn": "^8.11.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/agent-base": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||
@@ -4795,195 +4777,6 @@
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-code-frame": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
|
||||
"integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==",
|
||||
"dependencies": {
|
||||
"chalk": "^1.1.3",
|
||||
"esutils": "^2.0.2",
|
||||
"js-tokens": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-code-frame/node_modules/ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-code-frame/node_modules/ansi-styles": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-code-frame/node_modules/chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-code-frame/node_modules/js-tokens": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
|
||||
"integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg=="
|
||||
},
|
||||
"node_modules/babel-code-frame/node_modules/strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-helper-builder-binary-assignment-operator-visitor": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
|
||||
"integrity": "sha512-gCtfYORSG1fUMX4kKraymq607FWgMWg+j42IFPc18kFQEsmtaibP4UrqsXt8FlEJle25HUd4tsoDR7H2wDhe9Q==",
|
||||
"dependencies": {
|
||||
"babel-helper-explode-assignable-expression": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-helper-call-delegate": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz",
|
||||
"integrity": "sha512-RL8n2NiEj+kKztlrVJM9JT1cXzzAdvWFh76xh/H1I4nKwunzE4INBXn8ieCZ+wh4zWszZk7NBS1s/8HR5jDkzQ==",
|
||||
"dependencies": {
|
||||
"babel-helper-hoist-variables": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-traverse": "^6.24.1",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-helper-define-map": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz",
|
||||
"integrity": "sha512-bHkmjcC9lM1kmZcVpA5t2om2nzT/xiZpo6TJq7UlZ3wqKfzia4veeXbIhKvJXAMzhhEBd3cR1IElL5AenWEUpA==",
|
||||
"dependencies": {
|
||||
"babel-helper-function-name": "^6.24.1",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"babel-types": "^6.26.0",
|
||||
"lodash": "^4.17.4"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-helper-explode-assignable-expression": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz",
|
||||
"integrity": "sha512-qe5csbhbvq6ccry9G7tkXbzNtcDiH4r51rrPUbwwoTzZ18AqxWYRZT6AOmxrpxKnQBW0pYlBI/8vh73Z//78nQ==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-traverse": "^6.24.1",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-helper-function-name": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
|
||||
"integrity": "sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q==",
|
||||
"dependencies": {
|
||||
"babel-helper-get-function-arity": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-template": "^6.24.1",
|
||||
"babel-traverse": "^6.24.1",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-helper-get-function-arity": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz",
|
||||
"integrity": "sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-helper-hoist-variables": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz",
|
||||
"integrity": "sha512-zAYl3tqerLItvG5cKYw7f1SpvIxS9zi7ohyGHaI9cgDUjAT6YcY9jIEH5CstetP5wHIVSceXwNS7Z5BpJg+rOw==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-helper-optimise-call-expression": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz",
|
||||
"integrity": "sha512-Op9IhEaxhbRT8MDXx2iNuMgciu2V8lDvYCNQbDGjdBNCjaMvyLf4wl4A3b8IgndCyQF8TwfgsQ8T3VD8aX1/pA==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-helper-regex": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz",
|
||||
"integrity": "sha512-VlPiWmqmGJp0x0oK27Out1D+71nVVCTSdlbhIVoaBAj2lUgrNjBCRR9+llO4lTSb2O4r7PJg+RobRkhBrf6ofg==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.26.0",
|
||||
"babel-types": "^6.26.0",
|
||||
"lodash": "^4.17.4"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-helper-remap-async-to-generator": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz",
|
||||
"integrity": "sha512-RYqaPD0mQyQIFRu7Ho5wE2yvA/5jxqCIj/Lv4BXNq23mHYu/vxikOy2JueLiBxQknwapwrJeNCesvY0ZcfnlHg==",
|
||||
"dependencies": {
|
||||
"babel-helper-function-name": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-template": "^6.24.1",
|
||||
"babel-traverse": "^6.24.1",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-helper-replace-supers": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
|
||||
"integrity": "sha512-sLI+u7sXJh6+ToqDr57Bv973kCepItDhMou0xCP2YPVmR1jkHSCY+p1no8xErbV1Siz5QE8qKT1WIwybSWlqjw==",
|
||||
"dependencies": {
|
||||
"babel-helper-optimise-call-expression": "^6.24.1",
|
||||
"babel-messages": "^6.23.0",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-template": "^6.24.1",
|
||||
"babel-traverse": "^6.24.1",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-messages": {
|
||||
"version": "6.23.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
|
||||
"integrity": "sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-check-es2015-constants": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz",
|
||||
"integrity": "sha512-B1M5KBP29248dViEo1owyY32lk1ZSH2DaNNrXLGt8lyjjHm7pBqAdQ7VKUPR6EEDO323+OvT3MQXbCin8ooWdA==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-polyfill-corejs2": {
|
||||
"version": "0.4.8",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz",
|
||||
@@ -5035,451 +4828,6 @@
|
||||
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-syntax-async-functions": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
|
||||
"integrity": "sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw=="
|
||||
},
|
||||
"node_modules/babel-plugin-syntax-exponentiation-operator": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
|
||||
"integrity": "sha512-Z/flU+T9ta0aIEKl1tGEmN/pZiI1uXmCiGFRegKacQfEJzp7iNsKloZmyJlQr+75FCJtiFfGIK03SiCvCt9cPQ=="
|
||||
},
|
||||
"node_modules/babel-plugin-syntax-trailing-function-commas": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
|
||||
"integrity": "sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ=="
|
||||
},
|
||||
"node_modules/babel-plugin-transform-async-to-generator": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
|
||||
"integrity": "sha512-7BgYJujNCg0Ti3x0c/DL3tStvnKS6ktIYOmo9wginv/dfZOrbSZ+qG4IRRHMBOzZ5Awb1skTiAsQXg/+IWkZYw==",
|
||||
"dependencies": {
|
||||
"babel-helper-remap-async-to-generator": "^6.24.1",
|
||||
"babel-plugin-syntax-async-functions": "^6.8.0",
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-arrow-functions": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
|
||||
"integrity": "sha512-PCqwwzODXW7JMrzu+yZIaYbPQSKjDTAsNNlK2l5Gg9g4rz2VzLnZsStvp/3c46GfXpwkyufb3NCyG9+50FF1Vg==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-block-scoped-functions": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz",
|
||||
"integrity": "sha512-2+ujAT2UMBzYFm7tidUsYh+ZoIutxJ3pN9IYrF1/H6dCKtECfhmB8UkHVpyxDwkj0CYbQG35ykoz925TUnBc3A==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-block-scoping": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz",
|
||||
"integrity": "sha512-YiN6sFAQ5lML8JjCmr7uerS5Yc/EMbgg9G8ZNmk2E3nYX4ckHR01wrkeeMijEf5WHNK5TW0Sl0Uu3pv3EdOJWw==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.26.0",
|
||||
"babel-template": "^6.26.0",
|
||||
"babel-traverse": "^6.26.0",
|
||||
"babel-types": "^6.26.0",
|
||||
"lodash": "^4.17.4"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-classes": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz",
|
||||
"integrity": "sha512-5Dy7ZbRinGrNtmWpquZKZ3EGY8sDgIVB4CU8Om8q8tnMLrD/m94cKglVcHps0BCTdZ0TJeeAWOq2TK9MIY6cag==",
|
||||
"dependencies": {
|
||||
"babel-helper-define-map": "^6.24.1",
|
||||
"babel-helper-function-name": "^6.24.1",
|
||||
"babel-helper-optimise-call-expression": "^6.24.1",
|
||||
"babel-helper-replace-supers": "^6.24.1",
|
||||
"babel-messages": "^6.23.0",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-template": "^6.24.1",
|
||||
"babel-traverse": "^6.24.1",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-computed-properties": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz",
|
||||
"integrity": "sha512-C/uAv4ktFP/Hmh01gMTvYvICrKze0XVX9f2PdIXuriCSvUmV9j+u+BB9f5fJK3+878yMK6dkdcq+Ymr9mrcLzw==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-template": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-destructuring": {
|
||||
"version": "6.23.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz",
|
||||
"integrity": "sha512-aNv/GDAW0j/f4Uy1OEPZn1mqD+Nfy9viFGBfQ5bZyT35YqOiqx7/tXdyfZkJ1sC21NyEsBdfDY6PYmLHF4r5iA==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-duplicate-keys": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz",
|
||||
"integrity": "sha512-ossocTuPOssfxO2h+Z3/Ea1Vo1wWx31Uqy9vIiJusOP4TbF7tPs9U0sJ9pX9OJPf4lXRGj5+6Gkl/HHKiAP5ug==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-for-of": {
|
||||
"version": "6.23.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz",
|
||||
"integrity": "sha512-DLuRwoygCoXx+YfxHLkVx5/NpeSbVwfoTeBykpJK7JhYWlL/O8hgAK/reforUnZDlxasOrVPPJVI/guE3dCwkw==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-function-name": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz",
|
||||
"integrity": "sha512-iFp5KIcorf11iBqu/y/a7DK3MN5di3pNCzto61FqCNnUX4qeBwcV1SLqe10oXNnCaxBUImX3SckX2/o1nsrTcg==",
|
||||
"dependencies": {
|
||||
"babel-helper-function-name": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-literals": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz",
|
||||
"integrity": "sha512-tjFl0cwMPpDYyoqYA9li1/7mGFit39XiNX5DKC/uCNjBctMxyL1/PT/l4rSlbvBG1pOKI88STRdUsWXB3/Q9hQ==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-modules-amd": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz",
|
||||
"integrity": "sha512-LnIIdGWIKdw7zwckqx+eGjcS8/cl8D74A3BpJbGjKTFFNJSMrjN4bIh22HY1AlkUbeLG6X6OZj56BDvWD+OeFA==",
|
||||
"dependencies": {
|
||||
"babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-template": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-modules-commonjs": {
|
||||
"version": "6.26.2",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz",
|
||||
"integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==",
|
||||
"dependencies": {
|
||||
"babel-plugin-transform-strict-mode": "^6.24.1",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"babel-template": "^6.26.0",
|
||||
"babel-types": "^6.26.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-modules-systemjs": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz",
|
||||
"integrity": "sha512-ONFIPsq8y4bls5PPsAWYXH/21Hqv64TBxdje0FvU3MhIV6QM2j5YS7KvAzg/nTIVLot2D2fmFQrFWCbgHlFEjg==",
|
||||
"dependencies": {
|
||||
"babel-helper-hoist-variables": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-template": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-modules-umd": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz",
|
||||
"integrity": "sha512-LpVbiT9CLsuAIp3IG0tfbVo81QIhn6pE8xBJ7XSeCtFlMltuar5VuBV6y6Q45tpui9QWcy5i0vLQfCfrnF7Kiw==",
|
||||
"dependencies": {
|
||||
"babel-plugin-transform-es2015-modules-amd": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-template": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-object-super": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz",
|
||||
"integrity": "sha512-8G5hpZMecb53vpD3mjs64NhI1au24TAmokQ4B+TBFBjN9cVoGoOvotdrMMRmHvVZUEvqGUPWL514woru1ChZMA==",
|
||||
"dependencies": {
|
||||
"babel-helper-replace-supers": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-parameters": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz",
|
||||
"integrity": "sha512-8HxlW+BB5HqniD+nLkQ4xSAVq3bR/pcYW9IigY+2y0dI+Y7INFeTbfAQr+63T3E4UDsZGjyb+l9txUnABWxlOQ==",
|
||||
"dependencies": {
|
||||
"babel-helper-call-delegate": "^6.24.1",
|
||||
"babel-helper-get-function-arity": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-template": "^6.24.1",
|
||||
"babel-traverse": "^6.24.1",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-shorthand-properties": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz",
|
||||
"integrity": "sha512-mDdocSfUVm1/7Jw/FIRNw9vPrBQNePy6wZJlR8HAUBLybNp1w/6lr6zZ2pjMShee65t/ybR5pT8ulkLzD1xwiw==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-spread": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz",
|
||||
"integrity": "sha512-3Ghhi26r4l3d0Js933E5+IhHwk0A1yiutj9gwvzmFbVV0sPMYk2lekhOufHBswX7NCoSeF4Xrl3sCIuSIa+zOg==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-sticky-regex": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz",
|
||||
"integrity": "sha512-CYP359ADryTo3pCsH0oxRo/0yn6UsEZLqYohHmvLQdfS9xkf+MbCzE3/Kolw9OYIY4ZMilH25z/5CbQbwDD+lQ==",
|
||||
"dependencies": {
|
||||
"babel-helper-regex": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-template-literals": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz",
|
||||
"integrity": "sha512-x8b9W0ngnKzDMHimVtTfn5ryimars1ByTqsfBDwAqLibmuuQY6pgBQi5z1ErIsUOWBdw1bW9FSz5RZUojM4apg==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-typeof-symbol": {
|
||||
"version": "6.23.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz",
|
||||
"integrity": "sha512-fz6J2Sf4gYN6gWgRZaoFXmq93X+Li/8vf+fb0sGDVtdeWvxC9y5/bTD7bvfWMEq6zetGEHpWjtzRGSugt5kNqw==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-unicode-regex": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz",
|
||||
"integrity": "sha512-v61Dbbihf5XxnYjtBN04B/JBvsScY37R1cZT5r9permN1cp+b70DY3Ib3fIkgn1DI9U3tGgBJZVD8p/mE/4JbQ==",
|
||||
"dependencies": {
|
||||
"babel-helper-regex": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"regexpu-core": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-unicode-regex/node_modules/jsesc": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
|
||||
"integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==",
|
||||
"bin": {
|
||||
"jsesc": "bin/jsesc"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-unicode-regex/node_modules/regexpu-core": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz",
|
||||
"integrity": "sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ==",
|
||||
"dependencies": {
|
||||
"regenerate": "^1.2.1",
|
||||
"regjsgen": "^0.2.0",
|
||||
"regjsparser": "^0.1.4"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-es2015-unicode-regex/node_modules/regjsparser": {
|
||||
"version": "0.1.5",
|
||||
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
|
||||
"integrity": "sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw==",
|
||||
"dependencies": {
|
||||
"jsesc": "~0.5.0"
|
||||
},
|
||||
"bin": {
|
||||
"regjsparser": "bin/parser"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-exponentiation-operator": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz",
|
||||
"integrity": "sha512-LzXDmbMkklvNhprr20//RStKVcT8Cu+SQtX18eMHLhjHf2yFzwtQ0S2f0jQ+89rokoNdmwoSqYzAhq86FxlLSQ==",
|
||||
"dependencies": {
|
||||
"babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1",
|
||||
"babel-plugin-syntax-exponentiation-operator": "^6.8.0",
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-regenerator": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz",
|
||||
"integrity": "sha512-LS+dBkUGlNR15/5WHKe/8Neawx663qttS6AGqoOUhICc9d1KciBvtrQSuc0PI+CxQ2Q/S1aKuJ+u64GtLdcEZg==",
|
||||
"dependencies": {
|
||||
"regenerator-transform": "^0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-regenerator/node_modules/regenerator-transform": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz",
|
||||
"integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.18.0",
|
||||
"babel-types": "^6.19.0",
|
||||
"private": "^0.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-strict-mode": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
|
||||
"integrity": "sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-preset-env": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz",
|
||||
"integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==",
|
||||
"dependencies": {
|
||||
"babel-plugin-check-es2015-constants": "^6.22.0",
|
||||
"babel-plugin-syntax-trailing-function-commas": "^6.22.0",
|
||||
"babel-plugin-transform-async-to-generator": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-block-scoping": "^6.23.0",
|
||||
"babel-plugin-transform-es2015-classes": "^6.23.0",
|
||||
"babel-plugin-transform-es2015-computed-properties": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-destructuring": "^6.23.0",
|
||||
"babel-plugin-transform-es2015-duplicate-keys": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-for-of": "^6.23.0",
|
||||
"babel-plugin-transform-es2015-function-name": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-literals": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-modules-amd": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-modules-commonjs": "^6.23.0",
|
||||
"babel-plugin-transform-es2015-modules-systemjs": "^6.23.0",
|
||||
"babel-plugin-transform-es2015-modules-umd": "^6.23.0",
|
||||
"babel-plugin-transform-es2015-object-super": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-parameters": "^6.23.0",
|
||||
"babel-plugin-transform-es2015-shorthand-properties": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-spread": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-sticky-regex": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-template-literals": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-typeof-symbol": "^6.23.0",
|
||||
"babel-plugin-transform-es2015-unicode-regex": "^6.22.0",
|
||||
"babel-plugin-transform-exponentiation-operator": "^6.22.0",
|
||||
"babel-plugin-transform-regenerator": "^6.22.0",
|
||||
"browserslist": "^3.2.6",
|
||||
"invariant": "^2.2.2",
|
||||
"semver": "^5.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-preset-env/node_modules/browserslist": {
|
||||
"version": "3.2.8",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz",
|
||||
"integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==",
|
||||
"dependencies": {
|
||||
"caniuse-lite": "^1.0.30000844",
|
||||
"electron-to-chromium": "^1.3.47"
|
||||
},
|
||||
"bin": {
|
||||
"browserslist": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-preset-env/node_modules/semver": {
|
||||
"version": "5.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||
"bin": {
|
||||
"semver": "bin/semver"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-runtime": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
|
||||
"integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==",
|
||||
"dependencies": {
|
||||
"core-js": "^2.4.0",
|
||||
"regenerator-runtime": "^0.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-template": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
|
||||
"integrity": "sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.26.0",
|
||||
"babel-traverse": "^6.26.0",
|
||||
"babel-types": "^6.26.0",
|
||||
"babylon": "^6.18.0",
|
||||
"lodash": "^4.17.4"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-traverse": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
|
||||
"integrity": "sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==",
|
||||
"dependencies": {
|
||||
"babel-code-frame": "^6.26.0",
|
||||
"babel-messages": "^6.23.0",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"babel-types": "^6.26.0",
|
||||
"babylon": "^6.18.0",
|
||||
"debug": "^2.6.8",
|
||||
"globals": "^9.18.0",
|
||||
"invariant": "^2.2.2",
|
||||
"lodash": "^4.17.4"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-traverse/node_modules/debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-traverse/node_modules/globals": {
|
||||
"version": "9.18.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
|
||||
"integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-traverse/node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||
},
|
||||
"node_modules/babel-types": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
|
||||
"integrity": "sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==",
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.26.0",
|
||||
"esutils": "^2.0.2",
|
||||
"lodash": "^4.17.4",
|
||||
"to-fast-properties": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-types/node_modules/to-fast-properties": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
|
||||
"integrity": "sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babylon": {
|
||||
"version": "6.18.0",
|
||||
"resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
|
||||
"integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
|
||||
"bin": {
|
||||
"babylon": "bin/babylon.js"
|
||||
}
|
||||
},
|
||||
"node_modules/bach": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz",
|
||||
@@ -6631,9 +5979,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001639",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001639.tgz",
|
||||
"integrity": "sha512-eFHflNTBIlFwP2AIKaYuBQN/apnUoKNhBdza8ZnW/h2di4LCZ4xFqYlxUxo+LQ76KFI1PGcC1QDxMbxTZpSCAg==",
|
||||
"version": "1.0.30001585",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001585.tgz",
|
||||
"integrity": "sha512-yr2BWR1yLXQ8fMpdS/4ZZXpseBgE7o4g41x3a6AJOqZuOi+iE/WdJYAuZ6Y95i4Ohd2Y+9MzIWRR+uGABH4s3Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -7463,13 +6811,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/core-js": {
|
||||
"version": "2.6.12",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
|
||||
"integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
|
||||
"deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.",
|
||||
"hasInstallScript": true
|
||||
},
|
||||
"node_modules/core-js-compat": {
|
||||
"version": "3.35.1",
|
||||
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.35.1.tgz",
|
||||
@@ -7643,11 +6984,6 @@
|
||||
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-0.0.3.tgz",
|
||||
"integrity": "sha512-Cp+jOa8QJef5nXS5hU7M1DWzXPEIoVR3kbV0dQuVGwROZg8bGf1DcCnkmajBTnvghTtSNMUdRrPjgaT6ZQucbw=="
|
||||
},
|
||||
"node_modules/debounce": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
|
||||
"integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug=="
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
@@ -12391,20 +11727,6 @@
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/gzip-size": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz",
|
||||
"integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==",
|
||||
"dependencies": {
|
||||
"duplexer": "^0.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/habitica-markdown": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/habitica-markdown/-/habitica-markdown-3.0.0.tgz",
|
||||
@@ -12505,6 +11827,7 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
|
||||
"integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
},
|
||||
@@ -12516,6 +11839,7 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -12760,7 +12084,8 @@
|
||||
"node_modules/html-escaper": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
|
||||
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="
|
||||
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/http-cache-semantics": {
|
||||
"version": "4.1.1",
|
||||
@@ -13326,14 +12651,6 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/invert-kv": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
|
||||
@@ -14654,17 +13971,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||
"dependencies": {
|
||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"loose-envify": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/loud-rejection": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
|
||||
@@ -15766,14 +15072,6 @@
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/mrmime": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz",
|
||||
"integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
@@ -17117,14 +16415,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/opener": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
|
||||
"integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
|
||||
"bin": {
|
||||
"opener": "bin/opener-bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/optional-require": {
|
||||
"version": "1.1.8",
|
||||
"resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.1.8.tgz",
|
||||
@@ -18067,14 +17357,6 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/private": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
|
||||
"integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
@@ -18526,11 +17808,6 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/regenerator-runtime": {
|
||||
"version": "0.11.1",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
|
||||
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
|
||||
},
|
||||
"node_modules/regenerator-transform": {
|
||||
"version": "0.15.2",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz",
|
||||
@@ -18591,11 +17868,6 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/regjsgen": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
|
||||
"integrity": "sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g=="
|
||||
},
|
||||
"node_modules/regjsparser": {
|
||||
"version": "0.9.1",
|
||||
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz",
|
||||
@@ -19679,19 +18951,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/sirv": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz",
|
||||
"integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==",
|
||||
"dependencies": {
|
||||
"@polka/url": "^1.0.0-next.24",
|
||||
"mrmime": "^2.0.0",
|
||||
"totalist": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/slash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
@@ -20598,6 +19857,7 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
@@ -21213,14 +20473,6 @@
|
||||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/totalist": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
|
||||
"integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/touch": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
|
||||
@@ -22253,50 +21505,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-bundle-analyzer": {
|
||||
"version": "4.10.2",
|
||||
"resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz",
|
||||
"integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==",
|
||||
"dependencies": {
|
||||
"@discoveryjs/json-ext": "0.5.7",
|
||||
"acorn": "^8.0.4",
|
||||
"acorn-walk": "^8.0.0",
|
||||
"commander": "^7.2.0",
|
||||
"debounce": "^1.2.1",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"gzip-size": "^6.0.0",
|
||||
"html-escaper": "^2.0.2",
|
||||
"opener": "^1.5.2",
|
||||
"picocolors": "^1.0.0",
|
||||
"sirv": "^2.0.3",
|
||||
"ws": "^7.3.1"
|
||||
},
|
||||
"bin": {
|
||||
"webpack-bundle-analyzer": "lib/bin/analyzer.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-bundle-analyzer/node_modules/commander": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
|
||||
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-bundle-analyzer/node_modules/escape-string-regexp": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-cli": {
|
||||
"version": "4.10.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz",
|
||||
@@ -22662,26 +21870,6 @@
|
||||
"typedarray-to-buffer": "^3.1.5"
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "7.5.10",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
|
||||
"integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
|
||||
"engines": {
|
||||
"node": ">=8.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": "^5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/xml-crypto": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-0.10.1.tgz",
|
||||
|
||||
+1
-3
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "habitica",
|
||||
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
|
||||
"version": "5.27.3",
|
||||
"version": "5.27.0",
|
||||
"main": "./website/server/index.js",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.22.10",
|
||||
@@ -15,7 +15,6 @@
|
||||
"amplitude": "^6.0.0",
|
||||
"apidoc": "^0.54.0",
|
||||
"apple-auth": "^1.0.9",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
"bcrypt": "^5.1.1",
|
||||
"body-parser": "^1.20.2",
|
||||
"bootstrap": "^4.6.2",
|
||||
@@ -76,7 +75,6 @@
|
||||
"useragent": "^2.1.9",
|
||||
"uuid": "^9.0.0",
|
||||
"validator": "^13.11.0",
|
||||
"webpack-bundle-analyzer": "^4.10.2",
|
||||
"winston": "^3.10.0",
|
||||
"winston-loggly-bulk": "^3.3.0",
|
||||
"xml2js": "^0.6.2"
|
||||
|
||||
@@ -54,7 +54,6 @@ describe('rateLimiter middleware', () => {
|
||||
|
||||
it('does not throw when there are available points', async () => {
|
||||
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
||||
nconfGetStub.withArgs('RATE_LIMITER_IP_COST').returns(1);
|
||||
const attachRateLimiter = requireAgain(pathToRateLimiter).default;
|
||||
await attachRateLimiter(req, res, next);
|
||||
|
||||
@@ -72,7 +71,6 @@ describe('rateLimiter middleware', () => {
|
||||
|
||||
it('does not throw when an unknown error is thrown by the rate limiter', async () => {
|
||||
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
||||
nconfGetStub.withArgs('RATE_LIMITER_IP_COST').returns(1);
|
||||
sandbox.stub(logger, 'error');
|
||||
sandbox.stub(RateLimiterMemory.prototype, 'consume')
|
||||
.returns(Promise.reject(new Error('Unknown error.')));
|
||||
@@ -106,7 +104,6 @@ describe('rateLimiter middleware', () => {
|
||||
it('limits when LIVELINESS_PROBE_KEY is incorrect', async () => {
|
||||
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
||||
nconfGetStub.withArgs('LIVELINESS_PROBE_KEY').returns('abc');
|
||||
nconfGetStub.withArgs('RATE_LIMITER_IP_COST').returns(1);
|
||||
const attachRateLimiter = requireAgain(pathToRateLimiter).default;
|
||||
|
||||
req.query.liveliness = 'das';
|
||||
@@ -123,7 +120,6 @@ describe('rateLimiter middleware', () => {
|
||||
it('limits when LIVELINESS_PROBE_KEY is not set', async () => {
|
||||
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
||||
nconfGetStub.withArgs('LIVELINESS_PROBE_KEY').returns(undefined);
|
||||
nconfGetStub.withArgs('RATE_LIMITER_IP_COST').returns(1);
|
||||
const attachRateLimiter = requireAgain(pathToRateLimiter).default;
|
||||
|
||||
await attachRateLimiter(req, res, next);
|
||||
@@ -139,7 +135,6 @@ describe('rateLimiter middleware', () => {
|
||||
it('throws when LIVELINESS_PROBE_KEY is blank', async () => {
|
||||
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
||||
nconfGetStub.withArgs('LIVELINESS_PROBE_KEY').returns('');
|
||||
nconfGetStub.withArgs('RATE_LIMITER_IP_COST').returns(1);
|
||||
const attachRateLimiter = requireAgain(pathToRateLimiter).default;
|
||||
|
||||
req.query.liveliness = '';
|
||||
@@ -155,7 +150,6 @@ describe('rateLimiter middleware', () => {
|
||||
|
||||
it('throws when there are no available points remaining', async () => {
|
||||
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
||||
nconfGetStub.withArgs('RATE_LIMITER_IP_COST').returns(1);
|
||||
const attachRateLimiter = requireAgain(pathToRateLimiter).default;
|
||||
|
||||
// call for 31 times
|
||||
@@ -179,7 +173,6 @@ describe('rateLimiter middleware', () => {
|
||||
|
||||
it('uses the user id if supplied or the ip address', async () => {
|
||||
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
||||
nconfGetStub.withArgs('RATE_LIMITER_IP_COST').returns(1);
|
||||
const attachRateLimiter = requireAgain(pathToRateLimiter).default;
|
||||
|
||||
req.ip = 1;
|
||||
@@ -206,51 +199,4 @@ describe('rateLimiter middleware', () => {
|
||||
'X-RateLimit-Reset': sinon.match(Date),
|
||||
});
|
||||
});
|
||||
|
||||
it('applies increased cost for registration calls with and without user id', async () => {
|
||||
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
||||
nconfGetStub.withArgs('RATE_LIMITER_REGISTRATION_COST').returns(3);
|
||||
const attachRateLimiter = requireAgain(pathToRateLimiter).default;
|
||||
req.path = '/api/v4/user/auth/local/register';
|
||||
|
||||
req.ip = 1;
|
||||
await attachRateLimiter(req, res, next);
|
||||
|
||||
req.headers['x-api-user'] = 'user-1';
|
||||
await attachRateLimiter(req, res, next);
|
||||
await attachRateLimiter(req, res, next);
|
||||
|
||||
// user id an ip are counted as separate sources
|
||||
expect(res.set).to.have.been.calledWithMatch({
|
||||
'X-RateLimit-Limit': 30,
|
||||
'X-RateLimit-Remaining': 27, // 2 calls with user id
|
||||
'X-RateLimit-Reset': sinon.match(Date),
|
||||
});
|
||||
|
||||
req.headers['x-api-user'] = undefined;
|
||||
await attachRateLimiter(req, res, next);
|
||||
await attachRateLimiter(req, res, next);
|
||||
|
||||
expect(res.set).to.have.been.calledWithMatch({
|
||||
'X-RateLimit-Limit': 30,
|
||||
'X-RateLimit-Remaining': 24, // 3 calls with only ip
|
||||
'X-RateLimit-Reset': sinon.match(Date),
|
||||
});
|
||||
});
|
||||
|
||||
it('applies increased cost for unauthenticated API calls', async () => {
|
||||
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
||||
nconfGetStub.withArgs('RATE_LIMITER_IP_COST').returns(10);
|
||||
const attachRateLimiter = requireAgain(pathToRateLimiter).default;
|
||||
|
||||
req.ip = 1;
|
||||
await attachRateLimiter(req, res, next);
|
||||
await attachRateLimiter(req, res, next);
|
||||
|
||||
expect(res.set).to.have.been.calledWithMatch({
|
||||
'X-RateLimit-Limit': 30,
|
||||
'X-RateLimit-Remaining': 10,
|
||||
'X-RateLimit-Reset': sinon.match(Date),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -34,11 +34,9 @@ describe('POST /debug/jump-time', () => {
|
||||
expect(resultDate.getMonth()).to.eql(today.getMonth());
|
||||
expect(resultDate.getFullYear()).to.eql(today.getFullYear());
|
||||
const newResultDate = new Date((await user.post('/debug/jump-time', { offsetDays: 1 })).time);
|
||||
const tomorrow = new Date(today.valueOf());
|
||||
tomorrow.setDate(today.getDate() + 1);
|
||||
expect(newResultDate.getDate()).to.eql(tomorrow.getDate());
|
||||
expect(newResultDate.getMonth()).to.eql(tomorrow.getMonth());
|
||||
expect(newResultDate.getFullYear()).to.eql(tomorrow.getFullYear());
|
||||
expect(newResultDate.getDate()).to.eql(today.getDate() + 1);
|
||||
expect(newResultDate.getMonth()).to.eql(today.getMonth());
|
||||
expect(newResultDate.getFullYear()).to.eql(today.getFullYear());
|
||||
});
|
||||
|
||||
it('jumps back', async () => {
|
||||
@@ -47,11 +45,9 @@ describe('POST /debug/jump-time', () => {
|
||||
expect(resultDate.getMonth()).to.eql(today.getMonth());
|
||||
expect(resultDate.getFullYear()).to.eql(today.getFullYear());
|
||||
const newResultDate = new Date((await user.post('/debug/jump-time', { offsetDays: -1 })).time);
|
||||
const yesterday = new Date(today.valueOf());
|
||||
yesterday.setDate(today.getDate() - 1);
|
||||
expect(newResultDate.getDate()).to.eql(yesterday.getDate());
|
||||
expect(newResultDate.getMonth()).to.eql(yesterday.getMonth());
|
||||
expect(newResultDate.getFullYear()).to.eql(yesterday.getFullYear());
|
||||
expect(newResultDate.getDate()).to.eql(today.getDate() - 1);
|
||||
expect(newResultDate.getMonth()).to.eql(today.getMonth());
|
||||
expect(newResultDate.getFullYear()).to.eql(today.getFullYear());
|
||||
});
|
||||
|
||||
it('can jump a lot', async () => {
|
||||
|
||||
@@ -85,6 +85,22 @@ describe('POST /group/:groupId/join', () => {
|
||||
await expect(user.get('/user')).to.eventually.have.nested.property('items.quests.basilist', 1);
|
||||
});
|
||||
|
||||
it('notifies inviting user that their invitation was accepted', async () => {
|
||||
await invitedUser.post(`/groups/${guild._id}/join`);
|
||||
|
||||
const inviter = await user.get('/user');
|
||||
const expectedData = {
|
||||
headerText: t('invitationAcceptedHeader'),
|
||||
bodyText: t('invitationAcceptedBody', {
|
||||
username: invitedUser.auth.local.username,
|
||||
groupName: guild.name,
|
||||
}),
|
||||
};
|
||||
|
||||
expect(inviter.notifications[1].type).to.eql('GROUP_INVITE_ACCEPTED');
|
||||
expect(inviter.notifications[1].data).to.eql(expectedData);
|
||||
});
|
||||
|
||||
it('awards Joined Guild achievement', async () => {
|
||||
await invitedUser.post(`/groups/${guild._id}/join`);
|
||||
|
||||
@@ -139,6 +155,23 @@ describe('POST /group/:groupId/join', () => {
|
||||
await expect(invitedUser.get('/user')).to.eventually.have.nested.property('party._id', party._id);
|
||||
});
|
||||
|
||||
it('notifies inviting user that their invitation was accepted', async () => {
|
||||
await invitedUser.post(`/groups/${party._id}/join`);
|
||||
|
||||
const inviter = await user.get('/user');
|
||||
|
||||
const expectedData = {
|
||||
headerText: t('invitationAcceptedHeader'),
|
||||
bodyText: t('invitationAcceptedBody', {
|
||||
username: invitedUser.auth.local.username,
|
||||
groupName: party.name,
|
||||
}),
|
||||
};
|
||||
|
||||
expect(inviter.notifications[0].type).to.eql('GROUP_INVITE_ACCEPTED');
|
||||
expect(inviter.notifications[0].data).to.eql(expectedData);
|
||||
});
|
||||
|
||||
it('clears invitation from user when joining party', async () => {
|
||||
await invitedUser.post(`/groups/${party._id}/join`);
|
||||
|
||||
|
||||
@@ -47,9 +47,9 @@ describe('shops', () => {
|
||||
|
||||
describe('premium hatching potions', () => {
|
||||
it('contains current scheduled premium hatching potions', async () => {
|
||||
clock = sinon.useFakeTimers(new Date('2024-04-01T09:00:00.000Z'));
|
||||
clock = sinon.useFakeTimers(new Date('2024-04-01'));
|
||||
const potions = shared.shops.getMarketCategories(user).find(x => x.identifier === 'premiumHatchingPotions');
|
||||
expect(potions.items.length).to.eql(3);
|
||||
expect(potions.items.length).to.eql(2);
|
||||
});
|
||||
|
||||
it('does not contain past scheduled premium hatching potions', async () => {
|
||||
@@ -73,9 +73,9 @@ describe('shops', () => {
|
||||
});
|
||||
|
||||
it('does not contain locked quest premium hatching potions', async () => {
|
||||
clock = sinon.useFakeTimers(new Date('2024-04-01T09:00:00.000Z'));
|
||||
clock = sinon.useFakeTimers(new Date('2024-04-01'));
|
||||
const potions = shared.shops.getMarketCategories(user).find(x => x.identifier === 'premiumHatchingPotions');
|
||||
expect(potions.items.length).to.eql(3);
|
||||
expect(potions.items.length).to.eql(2);
|
||||
expect(potions.items.filter(x => x.key === 'Bronze' || x.key === 'BlackPearl').length).to.eql(0);
|
||||
});
|
||||
|
||||
|
||||
@@ -18,19 +18,12 @@ function validateMatcher (matcher, checkedDate) {
|
||||
|
||||
describe('Content Schedule', () => {
|
||||
let switchoverTime;
|
||||
let clock;
|
||||
|
||||
beforeEach(() => {
|
||||
switchoverTime = nconf.get('CONTENT_SWITCHOVER_TIME_OFFSET') || 0;
|
||||
clearCachedMatchers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
if (clock) {
|
||||
clock.restore();
|
||||
}
|
||||
});
|
||||
|
||||
it('assembles scheduled items on january 15th', () => {
|
||||
const date = new Date('2024-01-15');
|
||||
const matchers = getAllScheduleMatchingGroups(date);
|
||||
@@ -112,14 +105,8 @@ describe('Content Schedule', () => {
|
||||
expect(matchers.backgrounds.end).to.eql(moment.utc(`2024-05-07T${String(switchoverTime).padStart(2, '0')}:00:00.000Z`).toDate());
|
||||
});
|
||||
|
||||
it('sets the end date if its on the release day before switchover', () => {
|
||||
const date = new Date('2024-05-07T07:00:00.000+00:00');
|
||||
const matchers = getAllScheduleMatchingGroups(date);
|
||||
expect(matchers.backgrounds.end).to.eql(moment.utc(`2024-05-07T${String(switchoverTime).padStart(2, '0')}:00:00.000Z`).toDate());
|
||||
});
|
||||
|
||||
it('sets the end date if its on the release day after switchover', () => {
|
||||
const date = new Date('2024-05-07T09:00:00.000+00:00');
|
||||
it('sets the end date if its on the release day', () => {
|
||||
const date = new Date('2024-05-07T07:00:00.000Z');
|
||||
const matchers = getAllScheduleMatchingGroups(date);
|
||||
expect(matchers.backgrounds.end).to.eql(moment.utc(`2024-06-07T${String(switchoverTime).padStart(2, '0')}:00:00.000Z`).toDate());
|
||||
});
|
||||
@@ -142,42 +129,6 @@ describe('Content Schedule', () => {
|
||||
expect(matchers.seasonalGear.end).to.eql(moment.utc(`2025-03-21T${String(switchoverTime).padStart(2, '0')}:00:00.000Z`).toDate());
|
||||
});
|
||||
|
||||
it('uses correct date for first hours of the month', () => {
|
||||
// if the date is checked before CONTENT_SWITCHOVER_TIME_OFFSET,
|
||||
// it should be considered the previous month
|
||||
const date = new Date('2024-05-01T02:00:00.000Z');
|
||||
const matchers = getAllScheduleMatchingGroups(date);
|
||||
expect(matchers.petQuests.items).to.contain('snake');
|
||||
expect(matchers.petQuests.items).to.not.contain('horse');
|
||||
expect(matchers.timeTravelers.match('202304'), '202304').to.be.true;
|
||||
expect(matchers.timeTravelers.match('202404'), '202404').to.be.false;
|
||||
expect(matchers.timeTravelers.match('202305'), '202305').to.be.false;
|
||||
});
|
||||
|
||||
it('uses correct date after switchover time', () => {
|
||||
// if the date is checked after CONTENT_SWITCHOVER_TIME_OFFSET,
|
||||
// it should be considered the current
|
||||
const date = new Date('2024-05-01T09:00:00.000Z');
|
||||
const matchers = getAllScheduleMatchingGroups(date);
|
||||
expect(matchers.petQuests.items).to.contain('snake');
|
||||
expect(matchers.petQuests.items).to.not.contain('horse');
|
||||
expect(matchers.timeTravelers.match('202304'), '202304').to.be.false;
|
||||
expect(matchers.timeTravelers.match('202305'), '202305').to.be.true;
|
||||
expect(matchers.timeTravelers.match('202405'), '202405').to.be.false;
|
||||
});
|
||||
|
||||
it('uses UTC timezone', () => {
|
||||
// if the date is checked after CONTENT_SWITCHOVER_TIME_OFFSET,
|
||||
// it should be considered the current
|
||||
clock = sinon.useFakeTimers(new Date('2024-05-01T05:00:00.000-04:00'));
|
||||
const matchers = getAllScheduleMatchingGroups();
|
||||
expect(matchers.petQuests.items).to.contain('snake');
|
||||
expect(matchers.petQuests.items).to.not.contain('horse');
|
||||
expect(matchers.timeTravelers.match('202304'), '202304').to.be.false;
|
||||
expect(matchers.timeTravelers.match('202305'), '202305').to.be.true;
|
||||
expect(matchers.timeTravelers.match('202405'), '202405').to.be.false;
|
||||
});
|
||||
|
||||
it('contains content for repeating events', () => {
|
||||
const date = new Date('2024-04-15');
|
||||
const matchers = getAllScheduleMatchingGroups(date);
|
||||
|
||||
@@ -45,7 +45,7 @@ describe('time-travelers store', () => {
|
||||
|
||||
describe('on may 1st', () => {
|
||||
beforeEach(() => {
|
||||
date = new Date('2024-05-01T09:00:00.000Z');
|
||||
date = new Date('2024-05-01');
|
||||
});
|
||||
it('returns the correct gear', () => {
|
||||
const items = timeTravelers.timeTravelerStore(user, date);
|
||||
|
||||
+282
-24
@@ -27,15 +27,73 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<snackbars />
|
||||
<router-view v-if="!isUserLoggedIn || isStaticPage" />
|
||||
<user-main v-else />
|
||||
<div
|
||||
id="app"
|
||||
:class="{
|
||||
'casting-spell': castingSpell,
|
||||
}"
|
||||
>
|
||||
<!-- <banned-account-modal /> -->
|
||||
<amazon-payments-modal v-if="!isStaticPage" />
|
||||
<payments-success-modal />
|
||||
<sub-cancel-modal-confirm v-if="isUserLoaded" />
|
||||
<sub-canceled-modal v-if="isUserLoaded" />
|
||||
<bug-report-modal v-if="isUserLoaded" />
|
||||
<bug-report-success-modal v-if="isUserLoaded" />
|
||||
<external-link-modal />
|
||||
<birthday-modal />
|
||||
<snackbars />
|
||||
<router-view v-if="!isUserLoggedIn || isStaticPage" />
|
||||
<template v-else>
|
||||
<template v-if="isUserLoaded">
|
||||
<chat-banner />
|
||||
<damage-paused-banner />
|
||||
<gems-promo-banner />
|
||||
<gift-promo-banner />
|
||||
<birthday-banner />
|
||||
<notifications-display />
|
||||
<app-menu />
|
||||
<div
|
||||
class="container-fluid"
|
||||
:class="{'no-margin': noMargin}"
|
||||
>
|
||||
<app-header />
|
||||
<buyModal
|
||||
:item="selectedItemToBuy || {}"
|
||||
:with-pin="true"
|
||||
:generic-purchase="genericPurchase(selectedItemToBuy)"
|
||||
@buyPressed="customPurchase($event)"
|
||||
/>
|
||||
<selectMembersModal
|
||||
:item="selectedSpellToBuy || {}"
|
||||
:group="user.party"
|
||||
@memberSelected="memberSelected($event)"
|
||||
/>
|
||||
<div :class="{sticky: user.preferences.stickyHeader}">
|
||||
<router-view />
|
||||
</div>
|
||||
</div>
|
||||
<app-footer v-if="!hideFooter" />
|
||||
<audio
|
||||
id="sound"
|
||||
ref="sound"
|
||||
autoplay="autoplay"
|
||||
></audio>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
@import '~@/assets/scss/colors.scss';
|
||||
|
||||
#app {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
#loading-screen-inapp {
|
||||
#melior {
|
||||
color: $white;
|
||||
@@ -105,20 +163,68 @@
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
import { loadProgressBar } from 'axios-progress-bar';
|
||||
|
||||
import * as Analytics from '@/libs/analytics';
|
||||
import birthdayModal from '@/components/news/birthdayModal';
|
||||
import AppMenu from './components/header/menu';
|
||||
import AppHeader from './components/header/index';
|
||||
import ChatBanner from './components/header/banners/chatBanner';
|
||||
import DamagePausedBanner from './components/header/banners/damagePaused';
|
||||
import GemsPromoBanner from './components/header/banners/gemsPromo';
|
||||
import GiftPromoBanner from './components/header/banners/giftPromo';
|
||||
import BirthdayBanner from './components/header/banners/birthdayBanner';
|
||||
import AppFooter from './components/appFooter';
|
||||
import notificationsDisplay from './components/notifications';
|
||||
import snackbars from './components/snackbars/notifications';
|
||||
import { mapState } from '@/libs/store';
|
||||
import userMain from '@/pages/user-main';
|
||||
import snackbars from '@/components/snackbars/notifications';
|
||||
import * as Analytics from '@/libs/analytics';
|
||||
import BuyModal from './components/shops/buyModal.vue';
|
||||
import SelectMembersModal from '@/components/selectMembersModal.vue';
|
||||
import notifications from '@/mixins/notifications';
|
||||
import { setup as setupPayments } from '@/libs/payments';
|
||||
import amazonPaymentsModal from '@/components/payments/amazonModal';
|
||||
import paymentsSuccessModal from '@/components/payments/successModal';
|
||||
import subCancelModalConfirm from '@/components/payments/cancelModalConfirm';
|
||||
import subCanceledModal from '@/components/payments/canceledModal';
|
||||
import externalLinkModal from '@/components/externalLinkModal.vue';
|
||||
|
||||
import spellsMixin from '@/mixins/spells';
|
||||
import {
|
||||
CONSTANTS,
|
||||
getLocalSetting,
|
||||
removeLocalSetting,
|
||||
} from '@/libs/userlocalManager';
|
||||
|
||||
const bugReportModal = () => import(/* webpackChunkName: "bug-report-modal" */'@/components/bugReportModal');
|
||||
const bugReportSuccessModal = () => import(/* webpackChunkName: "bug-report-success-modal" */'@/components/bugReportSuccessModal');
|
||||
|
||||
const COMMUNITY_MANAGER_EMAIL = process.env.EMAILS_COMMUNITY_MANAGER_EMAIL; // eslint-disable-line
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
AppMenu,
|
||||
AppHeader,
|
||||
AppFooter,
|
||||
birthdayModal,
|
||||
ChatBanner,
|
||||
DamagePausedBanner,
|
||||
GemsPromoBanner,
|
||||
GiftPromoBanner,
|
||||
BirthdayBanner,
|
||||
notificationsDisplay,
|
||||
snackbars,
|
||||
userMain,
|
||||
BuyModal,
|
||||
SelectMembersModal,
|
||||
amazonPaymentsModal,
|
||||
paymentsSuccessModal,
|
||||
subCancelModalConfirm,
|
||||
subCanceledModal,
|
||||
bugReportModal,
|
||||
bugReportSuccessModal,
|
||||
externalLinkModal,
|
||||
},
|
||||
mixins: [notifications, spellsMixin],
|
||||
data () {
|
||||
return {
|
||||
selectedItemToBuy: null,
|
||||
@@ -132,25 +238,71 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(['isUserLoggedIn', 'isUserLoaded', 'notificationsRemoved']),
|
||||
...mapState(['isUserLoggedIn', 'browserTimezoneUtcOffset', 'isUserLoaded', 'notificationsRemoved']),
|
||||
...mapState({ user: 'user.data' }),
|
||||
isStaticPage () {
|
||||
return this.$route.meta.requiresLogin === false;
|
||||
},
|
||||
castingSpell () {
|
||||
return this.$store.state.spellOptions.castingSpell;
|
||||
},
|
||||
noMargin () {
|
||||
return ['privateMessages'].includes(this.$route.name);
|
||||
},
|
||||
hideFooter () {
|
||||
return ['privateMessages'].includes(this.$route.name);
|
||||
},
|
||||
},
|
||||
created () {
|
||||
// Setup listener for title
|
||||
this.$store.watch(state => state.title, title => {
|
||||
document.title = title;
|
||||
this.$root.$on('playSound', sound => {
|
||||
const theme = this.user.preferences.sound;
|
||||
|
||||
if (!theme || theme === 'off') {
|
||||
return;
|
||||
}
|
||||
|
||||
const file = `/static/audio/${theme}/${sound}`;
|
||||
|
||||
if (this.audioSuffix === null) {
|
||||
this.audioSource = document.createElement('source');
|
||||
if (this.$refs.sound.canPlayType('audio/ogg')) {
|
||||
this.audioSuffix = '.ogg';
|
||||
this.audioSource.type = 'audio/ogg';
|
||||
} else {
|
||||
this.audioSuffix = '.mp3';
|
||||
this.audioSource.type = 'audio/mp3';
|
||||
}
|
||||
this.audioSource.src = file + this.audioSuffix;
|
||||
this.$refs.sound.appendChild(this.audioSource);
|
||||
} else {
|
||||
this.audioSource.src = file + this.audioSuffix;
|
||||
}
|
||||
|
||||
this.$refs.sound.load();
|
||||
});
|
||||
this.$store.watch(state => state.isUserLoaded, () => {
|
||||
if (this.isUserLoaded) {
|
||||
this.hideLoadingScreen();
|
||||
|
||||
// @TODO: I'm not sure these should be at the app level.
|
||||
// Can we move these back into shop/inventory or maybe they need a lateral move?
|
||||
this.$root.$on('buyModal::showItem', item => {
|
||||
this.selectedItemToBuy = item;
|
||||
this.$root.$emit('bv::show::modal', 'buy-modal');
|
||||
});
|
||||
|
||||
this.$root.$on('bv::modal::hidden', event => {
|
||||
if (event.componentId === 'buy-modal') {
|
||||
this.$root.$emit('buyModal::hidden', this.selectedItemToBuy.key);
|
||||
}
|
||||
});
|
||||
this.$nextTick(() => {
|
||||
// Load external scripts after the app has been rendered
|
||||
Analytics.load();
|
||||
|
||||
this.$root.$on('selectMembersModal::showItem', item => {
|
||||
this.selectedSpellToBuy = item;
|
||||
this.$root.$emit('bv::show::modal', 'select-member-modal');
|
||||
});
|
||||
|
||||
// @TODO split up this file, it's too big
|
||||
|
||||
loadProgressBar({
|
||||
showSpinner: false,
|
||||
});
|
||||
|
||||
axios.interceptors.response.use(response => { // Set up Response interceptors
|
||||
@@ -262,20 +414,79 @@ export default {
|
||||
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
// Setup listener for title
|
||||
this.$store.watch(state => state.title, title => {
|
||||
document.title = title;
|
||||
});
|
||||
this.$nextTick(() => {
|
||||
// Load external scripts after the app has been rendered
|
||||
Analytics.load();
|
||||
});
|
||||
|
||||
if (this.isUserLoggedIn && !this.isStaticPage) {
|
||||
// Load the user and the user tasks
|
||||
Promise.all([
|
||||
this.$store.dispatch('user:fetch'),
|
||||
this.$store.dispatch('tasks:fetchUserTasks'),
|
||||
]).then(() => {
|
||||
this.$store.state.isUserLoaded = true;
|
||||
Analytics.setUser();
|
||||
Analytics.updateUser();
|
||||
return axios.get(
|
||||
'/api/v4/i18n/browser-script',
|
||||
{
|
||||
language: this.user.preferences.language,
|
||||
headers: {
|
||||
'Cache-Control': 'no-cache',
|
||||
Pragma: 'no-cache',
|
||||
Expires: '0',
|
||||
},
|
||||
},
|
||||
);
|
||||
}).then(() => {
|
||||
const i18nData = window && window['habitica-i18n'];
|
||||
this.$loadLocale(i18nData);
|
||||
this.hideLoadingScreen();
|
||||
|
||||
// Adjust the timezone offset
|
||||
const browserTimezoneOffset = -this.browserTimezoneUtcOffset;
|
||||
if (this.user.preferences.timezoneOffset !== browserTimezoneOffset) {
|
||||
this.$store.dispatch('user:set', {
|
||||
'preferences.timezoneOffset': browserTimezoneOffset,
|
||||
});
|
||||
}
|
||||
|
||||
let appState = getLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE);
|
||||
if (appState) {
|
||||
appState = JSON.parse(appState);
|
||||
if (appState.paymentCompleted) {
|
||||
removeLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE);
|
||||
this.$root.$emit('habitica:payment-success', appState);
|
||||
}
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
// Load external scripts after the app has been rendered
|
||||
setupPayments();
|
||||
});
|
||||
}).catch(err => {
|
||||
console.error('Impossible to fetch user. Clean up localStorage and refresh.', err); // eslint-disable-line no-console
|
||||
});
|
||||
} else {
|
||||
this.hideLoadingScreen();
|
||||
}
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.$root.$off('playSound');
|
||||
this.$root.$off('buyModal::showItem');
|
||||
this.$root.$off('selectMembersModal::showItem');
|
||||
},
|
||||
mounted () {
|
||||
// Remove the index.html loading screen and now show the inapp loading
|
||||
const loadingScreen = document.getElementById('loading-screen');
|
||||
if (loadingScreen) document.body.removeChild(loadingScreen);
|
||||
|
||||
if (this.isStaticPage || !this.isUserLoggedIn) {
|
||||
this.hideLoadingScreen();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
hideLoadingScreen () {
|
||||
this.loading = false;
|
||||
},
|
||||
checkForBannedUser (error) {
|
||||
const AUTH_SETTINGS = localStorage.getItem('habit-mobile-settings');
|
||||
const parseSettings = JSON.parse(AUTH_SETTINGS);
|
||||
@@ -296,10 +507,57 @@ export default {
|
||||
this.$store.dispatch('auth:logout', { redirectToLogin: true });
|
||||
return true;
|
||||
},
|
||||
itemSelected (item) {
|
||||
this.selectedItemToBuy = item;
|
||||
},
|
||||
genericPurchase (item) {
|
||||
if (!item) return false;
|
||||
|
||||
if (['card', 'debuffPotion'].includes(item.purchaseType)) return false;
|
||||
|
||||
return true;
|
||||
},
|
||||
customPurchase (item) {
|
||||
if (item.purchaseType === 'card') {
|
||||
this.selectedSpellToBuy = item;
|
||||
|
||||
// hide the dialog
|
||||
this.$root.$emit('bv::hide::modal', 'buy-modal');
|
||||
// remove the dialog from our modal-stack,
|
||||
// the default hidden event is delayed
|
||||
this.$root.$emit('bv::modal::hidden', {
|
||||
target: {
|
||||
id: 'buy-modal',
|
||||
},
|
||||
});
|
||||
|
||||
this.$root.$emit('bv::show::modal', 'select-member-modal');
|
||||
}
|
||||
|
||||
if (item.purchaseType === 'debuffPotion') {
|
||||
this.castStart(item, this.user);
|
||||
}
|
||||
},
|
||||
async memberSelected (member) {
|
||||
await this.castStart(this.selectedSpellToBuy, member);
|
||||
|
||||
this.selectedSpellToBuy = null;
|
||||
|
||||
if (this.user.party._id) {
|
||||
this.$store.dispatch('party:getMembers', { forceLoad: true });
|
||||
}
|
||||
|
||||
this.$root.$emit('bv::hide::modal', 'select-member-modal');
|
||||
},
|
||||
hideLoadingScreen () {
|
||||
this.loading = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style src="intro.js/minified/introjs.min.css"></style>
|
||||
<style src="axios-progress-bar/dist/nprogress.css"></style>
|
||||
<style src="@/assets/scss/index.scss" lang="scss"></style>
|
||||
<style src="@/assets/scss/sprites.scss" lang="scss"></style>
|
||||
<style src="smartbanner.js/dist/smartbanner.min.css"></style>
|
||||
|
||||
@@ -224,7 +224,7 @@
|
||||
<script>
|
||||
import hello from 'hellojs';
|
||||
import debounce from 'lodash/debounce';
|
||||
import isEmail from 'validator/es/lib/isEmail';
|
||||
import isEmail from 'validator/lib/isEmail';
|
||||
import { MINIMUM_PASSWORD_LENGTH } from '@/../../common/script/constants';
|
||||
import { setUpAxios, buildAppleAuthUrl } from '@/libs/auth';
|
||||
import googleIcon from '@/assets/svg/google.svg';
|
||||
|
||||
@@ -607,7 +607,7 @@
|
||||
import axios from 'axios';
|
||||
import hello from 'hellojs';
|
||||
import debounce from 'lodash/debounce';
|
||||
import isEmail from 'validator/es/lib/isEmail';
|
||||
import isEmail from 'validator/lib/isEmail';
|
||||
import DOMPurify from 'dompurify';
|
||||
import { MINIMUM_PASSWORD_LENGTH } from '@/../../common/script/constants';
|
||||
import { buildAppleAuthUrl } from '../../libs/auth';
|
||||
|
||||
@@ -167,7 +167,7 @@ label {
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
import isEmail from 'validator/es/lib/isEmail';
|
||||
import isEmail from 'validator/lib/isEmail';
|
||||
import closeX from '@/components/ui/closeX';
|
||||
import { mapState } from '@/libs/store';
|
||||
import { MODALS } from '@/libs/consts';
|
||||
|
||||
@@ -122,8 +122,8 @@
|
||||
<script>
|
||||
import clone from 'lodash/clone';
|
||||
import debounce from 'lodash/debounce';
|
||||
import isEmail from 'validator/es/lib/isEmail';
|
||||
import isUUID from 'validator/es/lib/isUUID';
|
||||
import isEmail from 'validator/lib/isEmail';
|
||||
import isUUID from 'validator/lib/isUUID';
|
||||
import { mapState } from '@/libs/store';
|
||||
import notifications from '@/mixins/notifications';
|
||||
import positiveIcon from '@/assets/svg/positive.svg';
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
class="brand"
|
||||
aria-label="Habitica"
|
||||
>
|
||||
<router-link to="/">
|
||||
<router-link to="/">
|
||||
<div
|
||||
class="logo svg-icon svg color gryphon pl-2 mr-3"
|
||||
v-html="icons.melior"
|
||||
class="logo svg-icon svg color gryphon"
|
||||
v-html="icons.melior"
|
||||
></div>
|
||||
<div class="svg-icon"></div>
|
||||
</router-link>
|
||||
@@ -297,7 +297,7 @@
|
||||
<div class="topbar-dropdown">
|
||||
<router-link
|
||||
v-if="user.permissions.fullAccess ||
|
||||
user.permissions.userSupport || user.permissions.newsPoster"
|
||||
user.permissions.userSupport"
|
||||
class="topbar-dropdown-item dropdown-item"
|
||||
:to="{name: 'adminPanel'}"
|
||||
>
|
||||
@@ -349,15 +349,15 @@
|
||||
>
|
||||
<div
|
||||
v-b-tooltip.hover.bottom="$t('mysticHourglassesTooltip')"
|
||||
class="top-menu-icon svg-icon mr-1"
|
||||
class="top-menu-icon svg-icon"
|
||||
v-html="icons.hourglasses"
|
||||
></div>
|
||||
<span>{{ userHourglasses }}</span>
|
||||
</div>
|
||||
<div class="item-with-icon gem">
|
||||
<div class="item-with-icon">
|
||||
<a
|
||||
v-b-tooltip.hover.bottom="$t('gems')"
|
||||
class="top-menu-icon svg-icon gem mr-2"
|
||||
class="top-menu-icon svg-icon gem"
|
||||
:aria-label="$t('gems')"
|
||||
href="#buy-gems"
|
||||
@click.prevent="showBuyGemsModal()"
|
||||
@@ -368,7 +368,7 @@
|
||||
<div class="item-with-icon gold">
|
||||
<div
|
||||
v-b-tooltip.hover.bottom="$t('gold')"
|
||||
class="top-menu-icon svg-icon mr-2"
|
||||
class="top-menu-icon svg-icon"
|
||||
:aria-label="$t('gold')"
|
||||
v-html="icons.gold"
|
||||
></div>
|
||||
@@ -409,180 +409,6 @@ body.modal-open #habitica-menu {
|
||||
@import '~@/assets/scss/utils.scss';
|
||||
@import '~@/assets/scss/variables.scss';
|
||||
|
||||
.menu-toggle {
|
||||
border: none;
|
||||
}
|
||||
|
||||
#menu_collapse {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
z-index: 1080;
|
||||
background: $purple-100 url(~@/assets/svg/for-css/bits.svg) right top no-repeat;
|
||||
min-height: 56px;
|
||||
box-shadow: 0 1px 2px 0 rgba($black, 0.24);
|
||||
|
||||
a {
|
||||
color: white !important;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
color: $white;
|
||||
height: 32px;
|
||||
object-fit: contain;
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.quick-menu {
|
||||
display: flex;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.currency-tray {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.topbar-item {
|
||||
font-size: 16px;
|
||||
color: $white !important;
|
||||
font-weight: bold;
|
||||
transition: none;
|
||||
|
||||
.topbar-dropdown {
|
||||
overflow: hidden;
|
||||
max-height: 0;
|
||||
|
||||
.topbar-dropdown-item {
|
||||
line-height: 1.5;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
>a {
|
||||
padding: .8em 1em !important;
|
||||
}
|
||||
|
||||
&.down {
|
||||
color: $white !important;
|
||||
background: $purple-200;
|
||||
|
||||
.topbar-dropdown {
|
||||
margin-top: 0; // Remove gap between navbar and drop-down.
|
||||
background: $purple-200;
|
||||
border-radius: 0px;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
padding: 0px;
|
||||
|
||||
border-bottom-right-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
|
||||
.topbar-dropdown-item {
|
||||
font-size: 16px;
|
||||
box-shadow: none;
|
||||
color: $white;
|
||||
border: none;
|
||||
line-height: 1.5;
|
||||
display: list-item;
|
||||
|
||||
&.active {
|
||||
background: $purple-300;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $purple-300;
|
||||
text-decoration: none;
|
||||
|
||||
&:last-child {
|
||||
border-bottom-right-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown + .dropdown {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.item-with-icon {
|
||||
color: $white;
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
white-space: nowrap;
|
||||
|
||||
span {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&.gem {
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
&.gold {
|
||||
margin-left: 12px;
|
||||
margin-right: 36px;
|
||||
}
|
||||
|
||||
&:focus ::v-deep .top-menu-icon.svg-icon,
|
||||
&:hover ::v-deep .top-menu-icon.svg-icon {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
& ::v-deep .top-menu-icon.svg-icon {
|
||||
color: $header-color;
|
||||
vertical-align: bottom;
|
||||
display: inline-block;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 12px;
|
||||
margin-left: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
a.item-with-icon:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
@keyframes rotateGemColors {
|
||||
/* Gems are green by default, so we rotate through ROYGBIV starting with green. */
|
||||
20% {
|
||||
fill: #46A7D9; /* Blue */
|
||||
}
|
||||
40% {
|
||||
fill: #925CF3; /* Purple */
|
||||
}
|
||||
60% {
|
||||
fill: #DE3F3F; /* Red */
|
||||
}
|
||||
80% {
|
||||
fill: #FA8537; /* Orange */
|
||||
}
|
||||
100% {
|
||||
fill: #FFB445; /* Yellow */
|
||||
}
|
||||
}
|
||||
|
||||
.gem:hover {
|
||||
cursor: pointer;
|
||||
|
||||
& ::v-deep path:nth-child(1) {
|
||||
animation: rotateGemColors 3s linear infinite alternate;
|
||||
}
|
||||
}
|
||||
|
||||
.message-count.top-count {
|
||||
background-color: $red-50;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: -0.5em;
|
||||
padding: .2em;
|
||||
}
|
||||
@media only screen and (max-width: 1200px) {
|
||||
.chevron {
|
||||
display: none
|
||||
@@ -590,13 +416,12 @@ body.modal-open #habitica-menu {
|
||||
|
||||
.gryphon {
|
||||
background-size: cover;
|
||||
color: $white;
|
||||
height: 32px;
|
||||
color: $white;
|
||||
margin: 0 auto;
|
||||
top: -10px;
|
||||
padding-left: 8px;
|
||||
position: relative;
|
||||
width: 32px;
|
||||
top: -10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.logo {
|
||||
@@ -720,23 +545,193 @@ body.modal-open #habitica-menu {
|
||||
.desktop-only {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-toggler {
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
.menu-toggle {
|
||||
border: none;
|
||||
}
|
||||
|
||||
#menu_collapse {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
z-index: 1080;
|
||||
background: $purple-100 url(~@/assets/svg/for-css/bits.svg) right top no-repeat;
|
||||
min-height: 56px;
|
||||
box-shadow: 0 1px 2px 0 rgba($black, 0.24);
|
||||
|
||||
a {
|
||||
color: white !important;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
color: $white;
|
||||
height: 32px;
|
||||
object-fit: contain;
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.quick-menu {
|
||||
display: flex;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.currency-tray {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.topbar-item {
|
||||
font-size: 16px;
|
||||
color: $white !important;
|
||||
font-weight: bold;
|
||||
transition: none;
|
||||
|
||||
.topbar-dropdown {
|
||||
overflow: hidden;
|
||||
max-height: 0;
|
||||
|
||||
.topbar-dropdown-item {
|
||||
line-height: 1.5;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-with-icon {
|
||||
margin-left: 0px;
|
||||
margin-right: 16px;
|
||||
>a {
|
||||
padding: .8em 1em !important;
|
||||
}
|
||||
|
||||
& ::v-deep .top-menu-icon.svg-icon {
|
||||
margin-right: 0px;
|
||||
margin-left: 0px;
|
||||
&.down {
|
||||
color: $white !important;
|
||||
background: $purple-200;
|
||||
|
||||
.topbar-dropdown {
|
||||
margin-top: 0; // Remove gap between navbar and drop-down.
|
||||
background: $purple-200;
|
||||
border-radius: 0px;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
padding: 0px;
|
||||
|
||||
border-bottom-right-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
|
||||
.topbar-dropdown-item {
|
||||
font-size: 16px;
|
||||
box-shadow: none;
|
||||
color: $white;
|
||||
border: none;
|
||||
line-height: 1.5;
|
||||
display: list-item;
|
||||
|
||||
&.active {
|
||||
background: $purple-300;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $purple-300;
|
||||
text-decoration: none;
|
||||
|
||||
&:last-child {
|
||||
border-bottom-right-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown + .dropdown {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.item-with-icon {
|
||||
color: $white;
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
white-space: nowrap;
|
||||
|
||||
span {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&.gold {
|
||||
margin-right: 24px;
|
||||
}
|
||||
|
||||
&:focus ::v-deep .top-menu-icon.svg-icon,
|
||||
&:hover ::v-deep .top-menu-icon.svg-icon {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
& ::v-deep .top-menu-icon.svg-icon {
|
||||
color: $header-color;
|
||||
vertical-align: bottom;
|
||||
display: inline-block;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 12px;
|
||||
margin-left: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
a.item-with-icon:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
margin-left: 24px;
|
||||
}
|
||||
|
||||
@keyframes rotateGemColors {
|
||||
/* Gems are green by default, so we rotate through ROYGBIV starting with green. */
|
||||
20% {
|
||||
fill: #46A7D9; /* Blue */
|
||||
}
|
||||
40% {
|
||||
fill: #925CF3; /* Purple */
|
||||
}
|
||||
60% {
|
||||
fill: #DE3F3F; /* Red */
|
||||
}
|
||||
80% {
|
||||
fill: #FA8537; /* Orange */
|
||||
}
|
||||
100% {
|
||||
fill: #FFB445; /* Yellow */
|
||||
}
|
||||
}
|
||||
|
||||
.gem:hover {
|
||||
cursor: pointer;
|
||||
|
||||
& ::v-deep path:nth-child(1) {
|
||||
animation: rotateGemColors 3s linear infinite alternate;
|
||||
}
|
||||
}
|
||||
|
||||
.message-count {
|
||||
background-color: $blue-50;
|
||||
border-radius: 50%;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
float: right;
|
||||
color: $white;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.message-count.top-count {
|
||||
background-color: $red-50;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: -0.5em;
|
||||
padding: .2em;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
.message-count {
|
||||
background-color: $red-50;
|
||||
border-radius: 50%;
|
||||
color: $white;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
height: 20px;
|
||||
left: 24px;
|
||||
text-align: center;
|
||||
width: 20px;
|
||||
float: right;
|
||||
color: $white;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
|
||||
svg {
|
||||
width: 12px;
|
||||
@@ -36,11 +36,4 @@
|
||||
.message-count.top-count-gray {
|
||||
background-color: $gray-200;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 992px) {
|
||||
|
||||
.message-count {
|
||||
left: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
:top="true"
|
||||
/>
|
||||
<div
|
||||
class="top-menu-icon svg-icon mr-2"
|
||||
class="top-menu-icon svg-icon user"
|
||||
v-html="icons.user"
|
||||
></div>
|
||||
</div>
|
||||
@@ -105,11 +105,6 @@
|
||||
|
||||
<style lang='scss' scoped>
|
||||
@import '~@/assets/scss/colors.scss';
|
||||
@media only screen and (max-width: 992px) {
|
||||
.item-with-icon.item-user {
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.user-dropdown {
|
||||
width: 14.75em;
|
||||
|
||||
@@ -107,7 +107,7 @@ export default {
|
||||
if (lastPublishedPost) this.posts.push(lastPublishedPost);
|
||||
|
||||
// If the user is authorized, show any draft
|
||||
if (this.user && this.user.contributor.newsPoster) {
|
||||
if (this.user && (this.user.permissions.news || this.user.permissions.fullAccess)) {
|
||||
this.posts.unshift(
|
||||
...postsFromServer
|
||||
.filter(p => !p.published || moment().isBefore(p.publishDate)),
|
||||
|
||||
@@ -295,7 +295,7 @@ h2 {
|
||||
// import { nextTick } from 'vue'; // may not need this? I don't know!
|
||||
import debounce from 'lodash/debounce';
|
||||
import find from 'lodash/find';
|
||||
import isUUID from 'validator/es/lib/isUUID';
|
||||
import isUUID from 'validator/lib/isUUID';
|
||||
import moment from 'moment';
|
||||
import { mapState } from '@/libs/store';
|
||||
import closeIcon from '@/assets/svg/close.svg';
|
||||
|
||||
@@ -139,6 +139,13 @@
|
||||
<style lang='scss' scoped>
|
||||
@import '~@/assets/scss/colors.scss';
|
||||
|
||||
@media only screen and (max-width : 750px) {
|
||||
.login-button {
|
||||
margin: 0 auto !important;
|
||||
margin-top: 18px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.habitica-logo {
|
||||
height: 64px;
|
||||
margin: 28px auto 0px auto;
|
||||
@@ -158,7 +165,7 @@
|
||||
|
||||
nav.navbar {
|
||||
background: $purple-100 url(~@/assets/svg/for-css/bits.svg) right no-repeat;
|
||||
padding-left: 24px;
|
||||
padding-left: 25px;
|
||||
padding-right: 12.5px;
|
||||
height: 56px;
|
||||
box-shadow: 0 1px 2px 0 rgba($black, 0.24);
|
||||
@@ -258,16 +265,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width : 750px) {
|
||||
.login-button {
|
||||
margin: 0 auto !important;
|
||||
margin-top: 18px !important;
|
||||
}
|
||||
.habitica-logo {
|
||||
margin: 4px auto 0px auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -781,7 +781,7 @@
|
||||
<script>
|
||||
import hello from 'hellojs';
|
||||
import debounce from 'lodash/debounce';
|
||||
import isEmail from 'validator/es/lib/isEmail';
|
||||
import isEmail from 'validator/lib/isEmail';
|
||||
import { MINIMUM_PASSWORD_LENGTH } from '@/../../common/script/constants';
|
||||
import { buildAppleAuthUrl } from '../../libs/auth';
|
||||
import googlePlay from '@/assets/images/home/google-play-badge.svg';
|
||||
|
||||
@@ -1,16 +1,6 @@
|
||||
import Vue from 'vue';
|
||||
import axios from 'axios';
|
||||
import {
|
||||
ModalPlugin,
|
||||
DropdownPlugin,
|
||||
PopoverPlugin,
|
||||
FormPlugin,
|
||||
FormInputPlugin,
|
||||
FormRadioPlugin,
|
||||
TooltipPlugin,
|
||||
NavbarPlugin,
|
||||
CollapsePlugin,
|
||||
} from 'bootstrap-vue';
|
||||
import BootstrapVue from 'bootstrap-vue';
|
||||
import Fragment from 'vue-fragment';
|
||||
import AppComponent from './app';
|
||||
import {
|
||||
@@ -39,15 +29,7 @@ Vue.config.productionTip = IS_PRODUCTION;
|
||||
// window['habitica-i18n] is injected by the server
|
||||
Vue.use(i18n, { i18nData: window && window['habitica-i18n'] });
|
||||
Vue.use(StoreModule);
|
||||
Vue.use(ModalPlugin);
|
||||
Vue.use(DropdownPlugin);
|
||||
Vue.use(PopoverPlugin);
|
||||
Vue.use(FormPlugin);
|
||||
Vue.use(FormInputPlugin);
|
||||
Vue.use(FormRadioPlugin);
|
||||
Vue.use(TooltipPlugin);
|
||||
Vue.use(NavbarPlugin);
|
||||
Vue.use(CollapsePlugin);
|
||||
Vue.use(BootstrapVue);
|
||||
Vue.use(Fragment.Plugin);
|
||||
|
||||
setUpLogging();
|
||||
|
||||
@@ -131,7 +131,7 @@ input {
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
import isEmail from 'validator/es/lib/isEmail';
|
||||
import * as validator from 'validator';
|
||||
import debounce from 'lodash/debounce';
|
||||
import { mapState } from '@/libs/store';
|
||||
|
||||
@@ -162,7 +162,7 @@ export default {
|
||||
user: 'user.data',
|
||||
}),
|
||||
validEmail () {
|
||||
return isEmail(this.updates.newEmail);
|
||||
return validator.isEmail(this.updates.newEmail);
|
||||
},
|
||||
allowedToSave () {
|
||||
return !this.validEmail || this.updates.password.length === 0;
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
import isEmail from 'validator/es/lib/isEmail';
|
||||
import * as validator from 'validator';
|
||||
import { mapState } from '@/libs/store';
|
||||
|
||||
import SaveCancelButtons from '../components/saveCancelButtons.vue';
|
||||
@@ -99,7 +99,7 @@ export default {
|
||||
return this.previousEmail !== this.updates.newEmail;
|
||||
},
|
||||
validEmail () {
|
||||
return isEmail(this.updates.newEmail);
|
||||
return validator.isEmail(this.updates.newEmail);
|
||||
},
|
||||
disallowedToSave () {
|
||||
return !this.emailChanged
|
||||
|
||||
@@ -208,7 +208,7 @@ table {
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import isURL from 'validator/es/lib/isURL';
|
||||
import * as validator from 'validator';
|
||||
import uuid from '@/../../common/script/libs/uuid';
|
||||
import { mapState } from '@/libs/store';
|
||||
|
||||
@@ -247,7 +247,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
isValidUrl (url) {
|
||||
return isURL(url, {
|
||||
return validator.isURL(url, {
|
||||
require_tld: true,
|
||||
require_protocol: true,
|
||||
protocols: ['http', 'https'],
|
||||
|
||||
@@ -1,388 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
id="app"
|
||||
:class="{
|
||||
'casting-spell': castingSpell,
|
||||
}"
|
||||
>
|
||||
<!-- <banned-account-modal /> -->
|
||||
<amazon-payments-modal v-if="!isStaticPage" />
|
||||
<payments-success-modal />
|
||||
<sub-cancel-modal-confirm v-if="isUserLoaded" />
|
||||
<sub-canceled-modal v-if="isUserLoaded" />
|
||||
<bug-report-modal v-if="isUserLoaded" />
|
||||
<bug-report-success-modal v-if="isUserLoaded" />
|
||||
<external-link-modal />
|
||||
<birthday-modal />
|
||||
<template v-if="isUserLoaded">
|
||||
<chat-banner />
|
||||
<damage-paused-banner />
|
||||
<gems-promo-banner />
|
||||
<gift-promo-banner />
|
||||
<birthday-banner />
|
||||
<notifications-display />
|
||||
<app-menu />
|
||||
<div
|
||||
class="container-fluid"
|
||||
:class="{'no-margin': noMargin}"
|
||||
>
|
||||
<app-header />
|
||||
<buyModal
|
||||
:item="selectedItemToBuy || {}"
|
||||
:with-pin="true"
|
||||
:generic-purchase="genericPurchase(selectedItemToBuy)"
|
||||
@buyPressed="customPurchase($event)"
|
||||
/>
|
||||
<selectMembersModal
|
||||
:item="selectedSpellToBuy || {}"
|
||||
:group="user.party"
|
||||
@memberSelected="memberSelected($event)"
|
||||
/>
|
||||
<div :class="{sticky: user.preferences.stickyHeader}">
|
||||
<router-view />
|
||||
</div>
|
||||
</div>
|
||||
<app-footer v-if="!hideFooter" />
|
||||
<audio
|
||||
id="sound"
|
||||
ref="sound"
|
||||
autoplay="autoplay"
|
||||
></audio>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
@import '~@/assets/scss/colors.scss';
|
||||
|
||||
#app {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.casting-spell {
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.container-fluid {
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
|
||||
.no-margin {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.notification {
|
||||
border-radius: 1000px;
|
||||
background-color: $green-10;
|
||||
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
|
||||
padding: .5em 1em;
|
||||
color: $white;
|
||||
margin-top: .5em;
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang='scss'>
|
||||
@import '~@/assets/scss/colors.scss';
|
||||
|
||||
.modal-backdrop {
|
||||
opacity: .9 !important;
|
||||
background-color: $purple-100 !important;
|
||||
}
|
||||
|
||||
/* Push progress bar above modals */
|
||||
#nprogress .bar {
|
||||
z-index: 1600 !important; /* Must stay above nav bar */
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
import { loadProgressBar } from 'axios-progress-bar';
|
||||
|
||||
import birthdayModal from '@/components/news/birthdayModal';
|
||||
import AppMenu from '@/components/header/menu';
|
||||
import AppHeader from '@/components/header/index';
|
||||
import ChatBanner from '@/components/header/banners/chatBanner';
|
||||
import DamagePausedBanner from '@/components/header/banners/damagePaused';
|
||||
import GemsPromoBanner from '@/components/header/banners/gemsPromo';
|
||||
import GiftPromoBanner from '@/components/header/banners/giftPromo';
|
||||
import BirthdayBanner from '@/components/header/banners/birthdayBanner';
|
||||
import AppFooter from '@/components/appFooter';
|
||||
import notificationsDisplay from '@/components/notifications';
|
||||
import { mapState } from '@/libs/store';
|
||||
import * as Analytics from '@/libs/analytics';
|
||||
import BuyModal from '@/components/shops/buyModal.vue';
|
||||
import SelectMembersModal from '@/components/selectMembersModal.vue';
|
||||
import notifications from '@/mixins/notifications';
|
||||
import { setup as setupPayments } from '@/libs/payments';
|
||||
import amazonPaymentsModal from '@/components/payments/amazonModal';
|
||||
import paymentsSuccessModal from '@/components/payments/successModal';
|
||||
import subCancelModalConfirm from '@/components/payments/cancelModalConfirm';
|
||||
import subCanceledModal from '@/components/payments/canceledModal';
|
||||
import externalLinkModal from '@/components/externalLinkModal.vue';
|
||||
|
||||
import spellsMixin from '@/mixins/spells';
|
||||
import {
|
||||
CONSTANTS,
|
||||
getLocalSetting,
|
||||
removeLocalSetting,
|
||||
} from '@/libs/userlocalManager';
|
||||
|
||||
const bugReportModal = () => import(/* webpackChunkName: "bug-report-modal" */'@/components/bugReportModal');
|
||||
const bugReportSuccessModal = () => import(/* webpackChunkName: "bug-report-success-modal" */'@/components/bugReportSuccessModal');
|
||||
|
||||
const COMMUNITY_MANAGER_EMAIL = process.env.EMAILS_COMMUNITY_MANAGER_EMAIL; // eslint-disable-line
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
AppMenu,
|
||||
AppHeader,
|
||||
AppFooter,
|
||||
birthdayModal,
|
||||
ChatBanner,
|
||||
DamagePausedBanner,
|
||||
GemsPromoBanner,
|
||||
GiftPromoBanner,
|
||||
BirthdayBanner,
|
||||
notificationsDisplay,
|
||||
BuyModal,
|
||||
SelectMembersModal,
|
||||
amazonPaymentsModal,
|
||||
paymentsSuccessModal,
|
||||
subCancelModalConfirm,
|
||||
subCanceledModal,
|
||||
bugReportModal,
|
||||
bugReportSuccessModal,
|
||||
externalLinkModal,
|
||||
},
|
||||
mixins: [notifications, spellsMixin],
|
||||
data () {
|
||||
return {
|
||||
selectedItemToBuy: null,
|
||||
selectedSpellToBuy: null,
|
||||
|
||||
audioSource: null,
|
||||
audioSuffix: null,
|
||||
|
||||
loading: true,
|
||||
bannerHidden: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(['isUserLoggedIn', 'browserTimezoneUtcOffset', 'isUserLoaded']),
|
||||
...mapState({ user: 'user.data' }),
|
||||
isStaticPage () {
|
||||
return this.$route.meta.requiresLogin === false;
|
||||
},
|
||||
castingSpell () {
|
||||
return this.$store.state.spellOptions.castingSpell;
|
||||
},
|
||||
noMargin () {
|
||||
return ['privateMessages'].includes(this.$route.name);
|
||||
},
|
||||
hideFooter () {
|
||||
return ['privateMessages'].includes(this.$route.name);
|
||||
},
|
||||
},
|
||||
created () {
|
||||
this.$root.$on('playSound', sound => {
|
||||
const theme = this.user.preferences.sound;
|
||||
|
||||
if (!theme || theme === 'off') {
|
||||
return;
|
||||
}
|
||||
|
||||
const file = `https://habitica-assets.s3.amazonaws.com/mobileApp/sounds/${theme}/${sound}`;
|
||||
|
||||
if (this.audioSuffix === null) {
|
||||
this.audioSource = document.createElement('source');
|
||||
if (this.$refs.sound.canPlayType('audio/ogg')) {
|
||||
this.audioSuffix = '.ogg';
|
||||
this.audioSource.type = 'audio/ogg';
|
||||
} else {
|
||||
this.audioSuffix = '.mp3';
|
||||
this.audioSource.type = 'audio/mp3';
|
||||
}
|
||||
this.audioSource.src = file + this.audioSuffix;
|
||||
this.$refs.sound.appendChild(this.audioSource);
|
||||
} else {
|
||||
this.audioSource.src = file + this.audioSuffix;
|
||||
}
|
||||
|
||||
this.$refs.sound.load();
|
||||
});
|
||||
|
||||
this.$root.$on('buyModal::showItem', item => {
|
||||
this.selectedItemToBuy = item;
|
||||
this.$root.$emit('bv::show::modal', 'buy-modal');
|
||||
});
|
||||
|
||||
this.$root.$on('bv::modal::hidden', event => {
|
||||
if (event.componentId === 'buy-modal') {
|
||||
this.$root.$emit('buyModal::hidden', this.selectedItemToBuy.key);
|
||||
}
|
||||
});
|
||||
|
||||
this.$root.$on('selectMembersModal::showItem', item => {
|
||||
this.selectedSpellToBuy = item;
|
||||
this.$root.$emit('bv::show::modal', 'select-member-modal');
|
||||
});
|
||||
|
||||
// @TODO split up this file, it's too big
|
||||
|
||||
loadProgressBar({
|
||||
showSpinner: false,
|
||||
});
|
||||
|
||||
// Setup listener for title
|
||||
this.$store.watch(state => state.title, title => {
|
||||
document.title = title;
|
||||
});
|
||||
|
||||
// Load the user and the user tasks
|
||||
Promise.all([
|
||||
this.$store.dispatch('user:fetch'),
|
||||
this.$store.dispatch('tasks:fetchUserTasks'),
|
||||
]).then(() => {
|
||||
this.$store.state.isUserLoaded = true;
|
||||
Analytics.setUser();
|
||||
Analytics.updateUser();
|
||||
if (window && window['habitica-i18n']) {
|
||||
if (this.user.preferences.language === window['habitica-i18n'].language.code) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (window && window['habitica-i18n']) {
|
||||
if (this.user.preferences.language === window['habitica-i18n'].language.code) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return axios.get(
|
||||
'/api/v4/i18n/browser-script',
|
||||
{
|
||||
language: this.user.preferences.language,
|
||||
headers: {
|
||||
'Cache-Control': 'no-cache',
|
||||
Pragma: 'no-cache',
|
||||
Expires: '0',
|
||||
},
|
||||
},
|
||||
);
|
||||
}).then(() => {
|
||||
const i18nData = window && window['habitica-i18n'];
|
||||
this.$loadLocale(i18nData);
|
||||
this.hideLoadingScreen();
|
||||
|
||||
// Adjust the timezone offset
|
||||
const browserTimezoneOffset = -this.browserTimezoneUtcOffset;
|
||||
if (this.user.preferences.timezoneOffset !== browserTimezoneOffset) {
|
||||
this.$store.dispatch('user:set', {
|
||||
'preferences.timezoneOffset': browserTimezoneOffset,
|
||||
});
|
||||
}
|
||||
|
||||
let appState = getLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE);
|
||||
if (appState) {
|
||||
appState = JSON.parse(appState);
|
||||
if (appState.paymentCompleted) {
|
||||
removeLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE);
|
||||
this.$root.$emit('habitica:payment-success', appState);
|
||||
}
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
// Load external scripts after the app has been rendered
|
||||
setupPayments();
|
||||
});
|
||||
}).catch(err => {
|
||||
console.error('Impossible to fetch user. Clean up localStorage and refresh.', err); // eslint-disable-line no-console
|
||||
});
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.$root.$off('playSound');
|
||||
this.$root.$off('buyModal::showItem');
|
||||
this.$root.$off('selectMembersModal::showItem');
|
||||
},
|
||||
mounted () {
|
||||
// Remove the index.html loading screen and now show the inapp loading
|
||||
const loadingScreen = document.getElementById('loading-screen');
|
||||
if (loadingScreen) document.body.removeChild(loadingScreen);
|
||||
},
|
||||
methods: {
|
||||
checkForBannedUser (error) {
|
||||
const AUTH_SETTINGS = localStorage.getItem('habit-mobile-settings');
|
||||
const parseSettings = JSON.parse(AUTH_SETTINGS);
|
||||
const errorMessage = error.response.data.message;
|
||||
|
||||
// Case where user is not logged in
|
||||
if (!parseSettings) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const bannedMessage = this.$t('accountSuspended', {
|
||||
communityManagerEmail: COMMUNITY_MANAGER_EMAIL,
|
||||
userId: parseSettings.auth.apiId,
|
||||
});
|
||||
|
||||
if (errorMessage !== bannedMessage) return false;
|
||||
|
||||
this.$store.dispatch('auth:logout', { redirectToLogin: true });
|
||||
return true;
|
||||
},
|
||||
itemSelected (item) {
|
||||
this.selectedItemToBuy = item;
|
||||
},
|
||||
genericPurchase (item) {
|
||||
if (!item) return false;
|
||||
|
||||
if (['card', 'debuffPotion'].includes(item.purchaseType)) return false;
|
||||
|
||||
return true;
|
||||
},
|
||||
customPurchase (item) {
|
||||
if (item.purchaseType === 'card') {
|
||||
this.selectedSpellToBuy = item;
|
||||
|
||||
// hide the dialog
|
||||
this.$root.$emit('bv::hide::modal', 'buy-modal');
|
||||
// remove the dialog from our modal-stack,
|
||||
// the default hidden event is delayed
|
||||
this.$root.$emit('bv::modal::hidden', {
|
||||
target: {
|
||||
id: 'buy-modal',
|
||||
},
|
||||
});
|
||||
|
||||
this.$root.$emit('bv::show::modal', 'select-member-modal');
|
||||
}
|
||||
|
||||
if (item.purchaseType === 'debuffPotion') {
|
||||
this.castStart(item, this.user);
|
||||
}
|
||||
},
|
||||
async memberSelected (member) {
|
||||
await this.castStart(this.selectedSpellToBuy, member);
|
||||
|
||||
this.selectedSpellToBuy = null;
|
||||
|
||||
if (this.user.party._id) {
|
||||
this.$store.dispatch('party:getMembers', { forceLoad: true });
|
||||
}
|
||||
|
||||
this.$root.$emit('bv::hide::modal', 'select-member-modal');
|
||||
},
|
||||
hideLoadingScreen () {
|
||||
this.loading = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style src="intro.js/minified/introjs.min.css"></style>
|
||||
<style src="axios-progress-bar/dist/nprogress.css"></style>
|
||||
@@ -189,7 +189,6 @@ const router = new VueRouter({
|
||||
meta: {
|
||||
privilegeNeeded: [ // any one of these is enough to give access
|
||||
'userSupport',
|
||||
'newsPoster',
|
||||
],
|
||||
},
|
||||
children: [
|
||||
|
||||
@@ -76,9 +76,6 @@ const webpackPlugins = [
|
||||
if ((context.includes('sinon') || resource.includes('sinon') || context.includes('nise')) && nconf.get('TIME_TRAVEL_ENABLED') !== 'true') {
|
||||
return true;
|
||||
}
|
||||
if (context.includes('yargs')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
}),
|
||||
@@ -94,28 +91,6 @@ module.exports = {
|
||||
dependency: { not: ['url'] },
|
||||
type: 'asset/source',
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
// Exclude transpiling `node_modules`, except `bootstrap-vue/src`
|
||||
exclude: /node_modules\/(?!bootstrap-vue\/src\/)/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
presets: ['@babel/preset-env'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
// Exclude transpiling `node_modules`, except `bootstrap-vue/src`
|
||||
exclude: /node_modules\/(?!validator)/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
presets: ['@babel/preset-env'],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
@@ -127,10 +102,6 @@ module.exports = {
|
||||
stream: false,
|
||||
timers: require.resolve('timers-browserify'),
|
||||
},
|
||||
alias: {
|
||||
// Alias for using source of BootstrapVue
|
||||
'bootstrap-vue$': 'bootstrap-vue/src/index.js',
|
||||
},
|
||||
},
|
||||
plugins: webpackPlugins,
|
||||
},
|
||||
|
||||
@@ -878,8 +878,5 @@
|
||||
"backgrounds072024": "SET 122: Veröffentlicht im Juli 2024",
|
||||
"backgroundRiverBottomText": "Flussgrund",
|
||||
"backgroundRiverBottomNotes": "Erkunde den Grund eines Flusses.",
|
||||
"monthlyBackgrounds": "Hintergrund des Monats",
|
||||
"backgrounds082024": "Set 123: Veröffentlicht im August 2024",
|
||||
"backgroundSavannaText": "Dunstiges Grasland",
|
||||
"backgroundSavannaNotes": "Wandere durch Dunstiges Grasland."
|
||||
"monthlyBackgrounds": "Hintergrund des Monats"
|
||||
}
|
||||
|
||||
@@ -383,7 +383,5 @@
|
||||
"hatchingPotionKoi": "Koi",
|
||||
"questEggGiraffeText": "Giraffe",
|
||||
"questEggGiraffeAdjective": "eine riesengroße",
|
||||
"questEggChameleonAdjective": "ein chaotisches",
|
||||
"questEggCrabText": "Krabbe",
|
||||
"questEggCrabMountText": "Krabbe"
|
||||
"questEggChameleonAdjective": "ein chaotisches"
|
||||
}
|
||||
|
||||
@@ -2925,9 +2925,5 @@
|
||||
"armorSpecialSpring2024HealerNotes": "Diese fabelhaften Federn werden helfen, deinen glücklichsten Träumen Flügel zu verleihen. Erhöht Ausdauer um <%= con %>. Limitierte Ausgabe 2024 Frühlingsausrüstung.",
|
||||
"armorSpecialSummer2024RogueText": "Nacktkiemerschnecken-Schwanz",
|
||||
"armorSpecialSummer2024RogueNotes": "Du magst vielleicht eine Seeschnecke ohne Schneckenhaus sein, aber du bist eine Seeschnecke mit See-Schwingen! Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe 2024 Sommerausrüstung.",
|
||||
"armorSpecialSpring2024HealerText": "Blaukehlchen Anzug",
|
||||
"weaponMystery202408Text": "Arkanes Aegis",
|
||||
"weaponMystery202408Notes": "Ein magisches Bläschen-Schild, das dich vor gegnerischen Zaubersprüchen schützt, oder dir hilft, im Wasser oder in der Luft zu schweben. Gewährt keinen Attributbonus. August 2024 Abonnentengegenstand.",
|
||||
"weaponArmoireDragonKnightsLanceText": "Drachenritter Lanze",
|
||||
"weaponArmoireDragonKnightsLanceNotes": "Diese rot-silberne Lanze hat so manchen Gegner aus dem Sattel seines Reittiers gehoben. Erhöht Ausdauer um <%= con %>. Verzauberter Schrank: Drachenritter Set (Gegenstand 3 von 3)"
|
||||
"armorSpecialSpring2024HealerText": "Blaukehlchen Anzug"
|
||||
}
|
||||
|
||||
@@ -778,7 +778,5 @@
|
||||
"questChameleonBoss": "Chaotisches Chamäleon",
|
||||
"questChameleonDropChameleonEgg": "Chamäleon (Ei)",
|
||||
"QuestChameleonUnlockText": "Schält Chamäleon Eier zum Kauf im Marktplatz frei",
|
||||
"questGiraffeDropGiraffeEgg": "Giraffe (Ei)",
|
||||
"questGiraffeUnlockText": "Schält Giraffen Eier zum Kauf im Marktplatz frei.",
|
||||
"questChameleonUnlockText": "Schält Chamäleon Eier zum Kauf im Marktplatz frei"
|
||||
"questGiraffeDropGiraffeEgg": "Giraffe (Ei)"
|
||||
}
|
||||
|
||||
@@ -241,6 +241,5 @@
|
||||
"mysterySet202403": "Glückliches Legenden Set",
|
||||
"mysterySet202405": "Vergoldetes Drachen Set",
|
||||
"mysterySet202406": "Phantom-Seeräuber Set",
|
||||
"mysterySet202407": "Liebenswertes Axolotl Set",
|
||||
"mysterySet202408": "Arkanes Aegis Set"
|
||||
"mysterySet202407": "Liebenswertes Axolotl Set"
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
"commonQuestions": "Common Questions",
|
||||
|
||||
"faqQuestion25": "What are the different task types?",
|
||||
"webFaqAnswer25": "Habitica uses three different task types to accommodate your needs: Habits, Dailies, and To Do’s.\n\nHabits can be positive or negative and represent something you may want to track multiple times per day, or on an unset schedule. Positive Habits will provide you with rewards, like Gold and Experience (Exp), while Negative Habits will cause you to lose health points (HP).\n\nDailies are repeated tasks you want to complete on a more structured schedule. For example, once per day, three times a week, or four times a month. Missing Dailies causes you to lose HP, but the more difficult they are, the better the rewards!\n\nTo Do’s are one-off tasks that provide rewards after you complete them. To Do’s can have a due date, but you won’t lose HP if you miss it.\n\nPick the task type that best fits what you want to achieve!",
|
||||
"webFaqAnswer25": "Habitica uses three different task types to accommodate your needs: Habits, Dailies, and To Do’s.\n\nHabits can be positive or negative and represent something you may want to track multiple times per day, or on an unset schedule. Positive Habits will provide you with rewards, like Gold and Experience (Exp), while Negative Habits will cause you to lose health points (HP).\n\nDailies are repeated tasks you want to complete on a more structured schedule. E.g. Once per day, three times a week, or four times a month. Missing Dailies causes you to lose HP, but the more difficult they are, the better the rewards!\n\nTo Do’s are one-off tasks that provide rewards after you complete them. To Do’s can have a due date, but you won’t lose HP if you miss it.\n\nPick the task type that best fits what you want to achieve!",
|
||||
|
||||
"faqQuestion26": "What are some sample tasks?",
|
||||
"webFaqAnswer26": "Positive Habits (Behaviors you want to encourage; should have a plus button)\n\n * Take vitamins\n * Floss teeth\n * One hour of studying\n\nNegative Habits (Behaviors you want to limit or avoid; should have a minus button)\n\n * Smoking\n * Doom scrolling\n * Biting nails\n\nDual Habits (Habits that involve a positive vs. negative option; should have both plus and minus buttons)\n\n * Drink water vs. drink soda\n * Study vs. procrastinate\n\nSample Dailies (Tasks you want to repeat on a regular schedule)\n * Wash dishes\n * Water plants\n * 30 minutes of physical activity\n\nSample To Do’s (Tasks you only need to do once)\n\n * Schedule appointment\n * Organize closet\n * Finish essay",
|
||||
|
||||
"faqQuestion27": "Why do tasks change color?",
|
||||
"webFaqAnswer27": "The color of a task is a visual representation of the task’s value. All tasks start as yellow for neutral, blue is better, and red is worse. Here’s how each task type determines the task’s value:\n\nHabits become more blue or red based on whether you tap the plus or minus button. Positive and negative Habits degrade to yellow over time if you don’t complete them. Dual Habits only change color based on your inputs.\n\nDailies change color based on how often they are completed, becoming more blue as they’re completed or more red if they’re missed.\n\nTo Do’s gradually get more red the longer they stay incomplete.\n\nThe more red the task, the more Gold and Experience you’ll earn for completing it, so be sure to take on even your toughest tasks!",
|
||||
"webFaqAnswer27": "The color of a task is a visual representation of the task’s value. All tasks start as yellow for neutral, blue is better, and red is worse. Here’s how each task type determines the task’s value:\n\nHabits become more blue or red based on whether you tap the plus or minus button. Positive and negative Habits degrade to yellow over time if you don’t complete them. Dual Habits only change color based on your inputs.\n\nDailies change color based on how often they are completed, becoming more blue as they’re completed or more red if they’re missed.\n\nTo Do’s gradually get more red the longer they stay incomplete.\n\nThe more red the task, the more Gold and Exp you’ll earn for completing it, so be sure to take on even your toughest tasks!",
|
||||
|
||||
"faqQuestion28": "Can I pause my Dailies if I need a break?",
|
||||
"webFaqAnswer28": "Yes! The “Pause Damage” button can be found in Settings. It will prevent you from losing HP for missed Dailies. This is helpful if you are on vacation, need a rest, or for any other reason you might need a break. If you are participating in a Quest, your own pending progress will be paused, but you will still take damage from your Party member’s missed Dailies.\n\nTo pause specific Dailies, you can edit the scheduling to make it due every 0 days until you’re ready to restart it.",
|
||||
@@ -30,16 +30,16 @@
|
||||
"webFaqAnswer33": "After you unlock the Class System, you also unlock Skills that require Mana to be cast. Mana is determined by your INT stat and can be adjusted by Skills and Equipment.",
|
||||
|
||||
"faqQuestion34": "What kind of Food does my Pet like?",
|
||||
"webFaqAnswer34": "Pets like Food that matches their color. Base Pets are the exception, but all Base Pets like the same item. You can see the specific foods each Pet likes below:\n\n * Base Pets like Meat\n * White Pets like Milk\n * Desert Pets like Potatoes\n * Red Pets like Strawberries\n * Shade Pets like Chocolate\n * Skeleton Pets like Fish\n * Zombie Pets like Rotten Meat\n * Cotton Candy Pink Pets like Pink Cotton Candy\n * Cotton Candy Blue Pets like Blue Cotton Candy\n * Golden Pets like Honey",
|
||||
"webFaqAnswer34": "Pets like Food that matches their color. Base Pets are the exception, but all Base Pets like the same item. You can see the specific Foods each Pet likes below:\n\n * Base Pets like Meat\n * White Pets like Milk\n * Desert Pets like Potatoes\n * Red Pets like Strawberries\n * Shade Pets like Chocolate\n * Skeleton Pets like Fish\n * Zombie Pets like Rotten Meat\n * Cotton Candy Pink Pets like Pink Cotton Candy\n * Cotton Candy Blue Pets like Blue Cotton Candy\n * Golden Pets like Honey",
|
||||
|
||||
"faqQuestion35": "I fed my Pet and it disappeared! What happened?",
|
||||
"webFaqAnswer35": "Once you’ve fed your Pet enough to raise it into a Mount, you’ll need to hatch that type of Pet again to have it in your stable.\n\nTo view Mounts on the mobile apps:\n\n * From the Menu, select “Pets & Mounts” and switch to the Mounts tab\n\nTo view Mounts on the website:\n\n * From the Inventory menu, select “Pets and Mounts” and scroll down to the Mounts section",
|
||||
"webFaqAnswer35": "Once you’ve fed your Pet enough to raise it into a Mount, you’ll need to hatch that type of Pet again to have it in your Stable.\n\nTo view Mounts on the mobile apps:\n\n * From the Menu, select “Pets & Mounts” and switch to the Mounts tab\n\nTo view Mounts on the website:\n\n * From the Inventory menu, select “Stable” and scroll down to the Mounts section",
|
||||
|
||||
"faqQuestion36": "How do I change the appearance of my Avatar?",
|
||||
"webFaqAnswer36": "There are endless ways to customize the appearance of your Habitica Avatar! You can change your Avatar’s body shape, hair style and color, skin color, or add glasses or mobility aids by selecting \"Customize Avatar\" from the menu.\n\nTo customize your Avatar on the mobile apps:\n * From the menu, select “Customize Avatar”\n\nTo customize your Avatar on the website:\n * From the user menu in the navigation, select \"Customize Avatar\"",
|
||||
"webFaqAnswer36": "There are endless ways to customize the appearance of your Habitica Avatar! You can change your Avatar’s body shape, hair style and color, skin color, or add glasses or mobility aids by selecting Customize (or Edit) Avatar from the menu.\n\nTo customize your Avatar on the mobile apps:\n * From the menu, select “Customize Avatar”\n\nTo customize your Avatar on the website:\n * From the user menu in the navigation, select \"Edit Avatar\"",
|
||||
|
||||
"faqQuestion37": "Why isn’t my Equipment displaying on my Avatar?",
|
||||
"webFaqAnswer37": "Check to see if the Costume option is toggled on. If your Avatar is wearing a Costume, that set of Equipment will show instead of your Battle Gear.\n\nTo toggle the Costume on the mobile apps:\n * From the menu, select “Equipment” to find the Costume toggle\n\nTo toggle the Costume on the website:\n * From your Inventory, select “Equipment” and locate the Costume toggle in the Costume tab of the Equipment drawer",
|
||||
"webFaqAnswer37": "Check to see if the Costume option is toggled on. If your Avatar is wearing a Costume, that set of Equipment will show instead of your Battle Gear.\n\nTo toggle the Costume on the mobile apps:\n * From the menu, select “Equipment” to find the Costume toggle\n\nTo toggle the Costume on the website:\n * From your Inventory, select “Equipment” and and locate the Costume toggle in the Costume tab of the Equipment drawer",
|
||||
|
||||
"faqQuestion38": "Why can't I purchase certain items?",
|
||||
"webFaqAnswer38": "New Habitica players can only purchase the basic Warrior class Equipment. Players must buy Equipment in sequential order to unlock the next piece.\n\nMany pieces of Equipment are class-specific, which means that a player can only buy Equipment belonging to their current class.",
|
||||
@@ -60,7 +60,7 @@
|
||||
"webFaqAnswer43": "To begin a Quest, you will need to be a member of a Party. Parties can be solo adventures where you challenge Quests alone, or you can invite other Habitica players to tackle Quests at a quicker rate!\n\nChoose a Quest Scroll from your inventory by selecting the “Begin Quest” button from your Party. Complete your tasks as you normally would to progress on the Quest! You’ll either build up damage against a monster if you’re taking on a Boss Quest, or have a chance to find items if you’re taking on a Collection Quest. All pending progress is applied the next day.\n\nWhen you do enough damage or collect all items, the Quest is complete and you will receive your rewards!",
|
||||
|
||||
"faqQuestion44": "How can I delete Challenge tasks?",
|
||||
"webFaqAnswer44": "You will need to leave the Challenge or wait for the Challenge to be closed in order to delete the associated tasks. A red megaphone icon implies the Challenge has been closed and a gray megaphone implies the Challenge is still running.\n\nTo delete Challenge tasks on the **Android** app:\n 1. Tap on a task belonging to the Challenge.\n 2. Tap on \"Delete\" in the upper right corner of the screen.\n 3. Choose to remove the Challenge tasks from your task list.\n\nTo delete Challenge tasks on the **iOS** app:\n 1. Find the Challenge task you wish to delete and look at the megaphone icon.\n 2. If the megaphone icon is red, tap on the task and select \"Delete\" at the bottom\n 3. If the megaphone icon is gray, you’ll need to find the Challenge and leave it to remove the task.\n\nTo delete Challenge tasks on the **website**:\n 1. Find the Challenge task you wish to delete and look at the megaphone icon.\n 2. If the megaphone icon is red, click it then choose to remove the tasks from your task list.\n 3. If the megaphone icon is gray, you'll need to find the Challenge and leave it to remove the task.",
|
||||
"webFaqAnswer44": "You will need to leave the Challenge or wait for the Challenge to be closed in order to delete the associated tasks. A red megaphone icon implies the Challenge has been closed and a gray megaphone implies the Challenge is still running.\n\nTo delete Challenge tasks on the **Android** app:\n 1. Tap on a task belonging to the Challenge. 2. Tap on \"Delete\" in the upper right corner of the screen.\n 3. Choose to remove the Challenge tasks from your task list.\n\nTo delete Challenge tasks on the **iOS** app:\n 1. Find the Challenge task you wish to delete and look at the megaphone icon.\n 2. If the megaphone icon is red, tap on the task and select \"Delete\" at the bottom\n 3. If the megaphone icon is gray, you’ll need to find the Challenge and leave it to remove the task.\n\nTo delete Challenge tasks on the **website**:\n 1. Find the Challenge task you wish to delete and look at the megaphone icon.\n 2. If the megaphone icon is red, click it then choose to remove the tasks from your task list.\n\n If the megaphone icon is gray, you'll need to find the Challenge and leave it to remove the task.",
|
||||
|
||||
"faqQuestion45": "My Avatar transformed into a snowman, starfish, flower, or ghost. How can I change back?",
|
||||
"webFaqAnswer45": "One of your Party members used a Seasonal Shop transformation item on you! Your Avatar will change back to normal the next day. If you want to remove the transformation sooner, you can purchase an antidote (Salt, Sand, Petal-free, or Opaque Potion) from Rewards.",
|
||||
@@ -77,7 +77,7 @@
|
||||
"webFaqAnswer48": "Yes, with Parties! You can start your own Party or join an existing one. Partying with other Habitica players is a great way to take on Quests, receive buffs from Party members’ skills, and boost your motivation with additional accountability.",
|
||||
|
||||
"faqQuestion49": "How do I find a Party when I'm not in one?",
|
||||
"webFaqAnswer49": "If you want to experience Habitica with others but don’t know other players, searching for a Party is your best option! If you already know other players that have a Party, you can share your @username with them to be invited. Alternatively, you can create a new Party and invite them with their @username or email address.\n\nTo create or search for a Party, select “Party” in the navigation menu, then choose the option that works for you.",
|
||||
"webFaqAnswer49": "If you want to experience Habitica with others but don’t know other players, searching for a Party is your best option! If you already know other players that have a Party, you can shareyour @username with them to be invited. Alternatively, you can create a new Party and invite them with their @username or email address.\n\nTo create or search for a Party, select “Party” in the navigation menu, then choose the option that works for you.",
|
||||
|
||||
"faqQuestion50": "How does searching for a Party work?",
|
||||
"webFaqAnswer50": "After selecting \"Look for a Party\", you’ll be added to a list of players that want to join a Party. Party leaders can view this list and send invitations. Once you receive an invitation, you can accept it from your notifications to join the Party of your choosing!\n\nYou may get multiple invitations to different Parties. However, you can only be a member of one Party at a time.",
|
||||
@@ -112,7 +112,7 @@
|
||||
"webFaqAnswer59": "Habitica Group Plans provide a shared experience by allowing members to easily add, assign, and complete tasks from a shared task board. With features like member roles, status view, and task assigning, Group Plans are great for families or teams of colleagues that have shared goals. They’re also a great way to keep each other motivated on your journey to fight monsters and improve your life.",
|
||||
|
||||
"faqQuestion60": "How do I get started with my Group Plan?",
|
||||
"webFaqAnswer60": "Here are some quick tips to get you started with your new Habitica Group Plan:\n\n * Promote a member to a manager to give them the ability to create and edit tasks\n * Leave tasks unassigned if anyone can complete it and it only needs done once\n * Assign a task to one person to make sure no one else can complete their task\n * Assign a task to multiple people if they all need to complete it\n * Toggle the ability to display shared tasks on your personal board to not miss anything\n * You get rewarded for the tasks you complete, even multi-assigned\n * Task completion rewards aren’t split between members\n * Use task color on the team board to judge the average completion rate of tasks\n * Regularly review the tasks on the shared task board to make sure they are still relevant\n * Missing a Daily won’t damage you or your team, but the task will degrade in color",
|
||||
"webFaqAnswer60": "Here are some quick tips to get you started with your new Habitica Group Plan:\n\n * Promote a member to a manager to give them the ability to create and edit tasks\n * Leave tasks unassigned if anyone can complete it and it only needs done once\n * Assign a task to one person to make sure no one else can complete their task\n * Assign a task to multiple people if they all need to complete it * Toggle the ability to display shared tasks on your personal board to not miss anything\n * You get rewarded for the tasks you complete, even multi-assigned\n * Task completion rewards aren’t split between members\n * Use task color on the team board to judge the average completion rate of tasks\n * Regularly review the tasks on the shared task board to make sure they are still relevant\n * Missing a Daily won’t damage you or your team, but the task will degrade in color",
|
||||
|
||||
"faqQuestion61": "Can other Group Plan members create tasks?",
|
||||
"webFaqAnswer61": "Only the Group Plan leader and managers can create shared tasks. If you’d like a member to be able to create tasks, then you should promote them to manager.\n\nTo promote a Group Plan member to a manager on the website:\n 1. Navigate to your Group Plan then switch to the \"Group Information\" tab\n 2. View your Member List and click on the dot icon by the member you want to promote\n 3. Select \"Assign Manager\"",
|
||||
|
||||
@@ -1595,7 +1595,7 @@
|
||||
"armorArmoireTeaGownText": "Tea Party Gown",
|
||||
"armorArmoireTeaGownNotes": "You’re resilient, creative, brilliant, and so fashionable! Increases Strength and Intelligence by <%= attrs %> each. Enchanted Armoire: Tea Party Set (Item 1 of 3).",
|
||||
"armorArmoireBasketballUniformText": "Basketball Uniform",
|
||||
"armorArmoireBasketballUniformNotes": "Wondering what’s printed on the back of this uniform? It’s your lucky number, of course! Increases Perception by <%= per %>. Enchanted Armoire: Old Timey Basketball Set (Item 1 of 2).",
|
||||
"armorArmoireBasketballUniformNotes": "Wondering what’s printed on the back of this uniform? It’s your lucky number, of course! Increases Perception by <% per %>. Enchanted Armoire: Old Timey Basketball Set (Item 1 of 2).",
|
||||
"armorArmoirePaintersApronText": "Painter's Apron",
|
||||
"armorArmoirePaintersApronNotes": "This apron can protect your clothes from paint and your creative projects from harsh critiques. Increases Constitution by <%= con %>. Enchanted Armoire: Painter Set (Item 1 of 4).",
|
||||
"armorArmoireStripedRainbowShirtText": "Striped Rainbow Shirt",
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
"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",
|
||||
"viewAchievements": "Ver logros",
|
||||
"letsGetStarted": "¡Comencemos!",
|
||||
"onboardingProgress": "<%= percentage %> % de progreso",
|
||||
"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!",
|
||||
|
||||
@@ -875,7 +875,5 @@
|
||||
"monthlyBackgrounds": "Fondos Mensuales",
|
||||
"backgrounds082024": "CONJUNTO 123: Publicado en Agosto 2024",
|
||||
"backgroundSavannaNotes": "Camina a través de estos Pastizales con Bruma.",
|
||||
"backgroundSavannaText": "Pastizales con Bruma",
|
||||
"backgroundRiverBottomText": "Fondo del Río",
|
||||
"backgroundRiverBottomNotes": "Explora el fondo del río."
|
||||
"backgroundSavannaText": "Pastizales con Bruma"
|
||||
}
|
||||
|
||||
@@ -60,11 +60,11 @@
|
||||
"general": "Información general",
|
||||
"commonQuestions": "Preguntas Comunes",
|
||||
"faqQuestion25": "¿Cuales son los diferentes tipos de tareas?",
|
||||
"webFaqAnswer25": "Habitica usa tres diferentes tipos de tarea que se ajustan a tus necesidades: Hábitos, Tareas Diarias y Tareas Pendientes.\n\nLos Hábitos pueden ser clasificados como positivos o negativos y representan acciones llevadas a cabo en una o más ocasiones a lo largo del día ya sean de forma programada o aleatoria. Los hábitos positivos producen recompensas como por ejemplo Oro y Puntos de Experiencia (Exp), mientras que los Hábitos negativos producen la pérdida de puntos de vida (HP).\n\nLas Tareas Diarias son tareas programadas a realizar durante un periodo de tiempo específico. Por ejemplo, una vez al día, tres veces a la semana o cuatro veces al mes. Las Tareas Diarias no completadas tienen como consecuencia la pérdida de puntos de vida (HP) pero si por el contrario se realizan dentro del periodo de tiempo especificado, dependiendo de la dificultad de estas, producen recompensas más jugosas.\n\nLas Tareas Pendientes, o proyectos a medio-largo plazo, producen recompensas una vez se han logrado. A tener en cuenta es que estas Tareas Pendientes, aunque pueden tener una fecha límite, no conllevan la pérdida de puntos de vida (HP) si no se completan.\n\n¡Simplemente selecciona el tipo de tarea que más se ajuste a tus objetivos!",
|
||||
"webFaqAnswer25": "Habitica usa tres diferentes tipos de tarea que se ajustan a tus necesidades: Hábitos, Tareas Diarias y Tareas Pendientes.\n\nLos Hábitos pueden ser clasificados como positivos o negativos y representan acciones llevadas a cabo en una o más ocasiones a lo largo del día ya sean de forma programada o aleatoria. Los hábitos positivos producen recompensas como por ejemplo Oro y Puntos de Experiencia (Exp), mientras que los Hábitos negativos producen la pérdida de puntos de vida (HP).\n\nLas Tareas Diarias son tareas programadas a realizar durante un periodo de tiempo específico. Por ejemplo: Una vez al día, tres veces a la semana o cuatro veces al mes. Las Tareas Diarias no completadas tienen como consecuencia la pérdida de puntos de vida (HP) pero si por el contrario se realizan dentro del periodo de tiempo especificado, dependiendo de la dificultad de estas, producen recompensas más jugosas.\n\nLas Tareas Pendientes, o proyectos a medio-largo plazo, producen recompensas una vez se han logrado. A tener en cuenta es que estas Tareas Pendientes, aunque pueden tener una fecha límite, no conllevan la pérdida de puntos de vida (HP) si no se completan.\n\n¡Simplemente selecciona el tipo de tarea que más se ajuste a tus objetivos!",
|
||||
"faqQuestion26": "Por ejemplo, ¿qué tareas puedes añadir?",
|
||||
"webFaqAnswer26": "Hábitos Positivos (Comportamientos o acciones que te gustaría hacer más; deberían tener un botón seleccionable con el símbolo ‘+’)\n\n* Tomar una pieza de fruta\n* Cepillarse los Dientes\n* Sesión de Estudio de una hora\n\nHábitos Negativos (Comportamientos o acciones que te gustaría hacer con menos frecuencia o incluso no hacer; deberían tener un botón seleccionable con el símbolo ‘-‘)\n\n* Fumar un cigarillo \n* Mal uso de las Redes Sociales\n* Morderse las uñas\n\nHábitos contrapuestos (Hábitos que pueden tener una opción positiva y una negativa; deberían tener dos botones seleccionables uno con el símbolo ‘+’ y otro con el símbolo ‘-‘)\n\n* Beber agua (+) contra Beber refrescos azucarados (-)\n* Estudiar (+) contra Perder el Tiempo (-)\n\nEjemplos de Tareas Diarias (Tareas que quieras añadir a tu rutina)\n* Lavar los platos\n* Regar las plantas\n* 30 minutos de ejercicio\n\nEjemplos de Tareas Pendientes (Proyectos a medio-largo plazo)\n\n* Cita a la que tengas que acudir\n* Ordenar tu armario o tu habitación \n* Terminar un proyecto o un trabajo",
|
||||
"faqQuestion27": "¿Porqué cambian las tareas de color?",
|
||||
"webFaqAnswer27": "El color de una tarea es una representación visual del valor de la tarea en sí misma. Todas las tareas empiezan en color amarillo, que es el que denominaremos, color neutral, la tendencia hacia el azul significa que estamos mejorando y la tendencia hacia el rojo significa que estamos empeorando. A continuación veamos cómo en cada tipo de tarea se determina el valor de esta.\n\nLos hábitos van cambiando de color (hacia el azul o hacia el rojo) dependiendo de si seleccionamos el botón con el símbolo ‘+’ o ‘-‘. Los hábitos tanto positivos como negativos se van degradando hacia el amarillo y después el rojo con el paso de los períodos de tiempo si no los practicamos. Los hábitos contrapuestos cambian de color basándose en los avances (+), tendencia al azul y fracasos (-) tendencia al rojo.\n\nLas Tareas Diarias cambian de color en base a la frecuencia con las que las completamos, tendiendo al azul si las logramos y hacia el rojo si no hemos podido realizarlas.\n\nLas Tareas Pendientes tienden hacia el rojo a medida que pasan los periodos de tiempo sin que se completen.\n\nCuanto más cerca del rojo este una tarea más Oro y Experiencia te proporcionará el completarla así que ¡ponte manos a la obra y trata de completar inclusos las tareas que te resulten más difíciles!",
|
||||
"webFaqAnswer27": "El color de una tarea es una representación visual del valor de la tarea en sí misma. Todas las tareas empiezan en color amarillo, que es el que denominaremos, color neutral, la tendencia hacia el azul significa que estamos mejorando y la tendencia hacia el rojo significa que estamos empeorando. A continuación veamos cómo en cada tipo de tarea se determina el valor de esta.\n\nLos hábitos van cambiando de color (hacia el azul o hacia el rojo) dependiendo de si seleccionamos el botón con el símbolo ‘+’ o ‘-‘. Los hábitos tanto positivos como negativos se van degradando hacia el amarillo y después el rojo con el paso de los períodos de tiempo si no los practicamos. Los hábitos contrapuestos cambian de color basándose en los avances (+), tendencia al azul y fracasos (-) tendencia al rojo.\n\nLas Tareas Diarias cambian de color en base a la frecuencia con las que las completamos, tendiendo al azul si las logramos y hacia el rojo si no hemos podido realizarlas.\n\nLas Tareas Pendientes tienden hacia el rojo a medida que pasan los periodos de tiempo sin que se completen.\n\nCuanto más cerca del rojo este una tarea más Oro y Puntos de Experiencia te proporcionará el completarla así que ¡ponte manos a la obra y trata de completar inclusos las tareas que te resulten más difíciles!",
|
||||
"faqQuestion28": "¿Puedo poner en “Pausa” las Tareas Diarias para tomarme un descanso y que no me causen pérdida de puntos de vida?",
|
||||
"webFaqAnswer32": "Hay cuatro diferentes profesiones que puedes elegir en Habitica: Guerrero, Mago, Pícaro y Sanador. Todos los jugadores empiezan siendo como base, Guerreros hasta que alcanzan el Nivel 10. Una vez alcanzado este nivel, tienes la opción de elegir entre seguir como Guerrero o elegir otra profesión.\n\nCada profesión tiene un equipamiento y unas habilidades diferentes. Si no quieres elegir profesión, puedes seleccionar “Renunciar”. Si decides renunciar, ten en cuenta, que siempre tendrás la posibilidad en el futuro de elegir una profesión accediendo al Sistema de Profesiones en los Ajustes.",
|
||||
"webFaqAnswer28": "¡Por supuesto! Puedes encontrar el botón “Pausar Daño” en Ajustes. Al activarlo no perderás puntos de vida (HP) si no completas las Tareas Diarias. Usar esta opción puede ser muy útil si estas de vacaciones, necesitas un descanso o si por cualquier otra razón quieres desconectar por un tiempo. Si durante una “Pausa” estas activo en una Misión, también tu progreso en esta quedará en pausa pero, tienes q tener en cuenta, que el daño recibido por tu equipo aún podrá afectarte, en especial debido a las Tareas Diarias incompletas.\n\nUn pequeño truco si quieres “Pausar” Tareas Diarias especificas es; editar la tarea en concreto y programarla a realizar cada 0 días hasta que estés listo para volver a reactivarla.",
|
||||
@@ -78,13 +78,13 @@
|
||||
"faqQuestion33": "¿Qué significa la barra azul que aparece en la plantilla de mi personaje cuando alcanzó el nivel 10?",
|
||||
"webFaqAnswer33": "Cuando desbloqueas el Sistema de Profesiones, también desbloqueas algunas habilidades que requieren Mana para su uso. La cantidad de Mana la determina tu atributo INT (Inteligencia) y puede obtener modificadores debido a Habilidades y Equipo.",
|
||||
"faqQuestion34": "¿Cuál es la comida preferida de mi Mascota?",
|
||||
"webFaqAnswer34": "A las Mascotas les gusta la comida relacionada con su color. Las únicas Mascotas que no siguen esta regla son las Base, pero eso si a todas Base les gusta el mismo Artículo. Aquí tienes una lista de comida específica que le gusta a cada Mascota:\n\n* Mascotas Base les gusta la Carne\n* Mascotas Blancas les gusta la Leche\n* Mascotas del Desierto les gusta las Patatas\n* Mascotas Rojas les gusta las Fresas\n* Mascotas de las Sombras les gusta el Chocolate\n* Mascotas Esqueleto les gusta el Pescado\n* Mascotas Zombi les gusta la Carne Podrida\n* Mascotas Algodón de Azúcar Rosa les gusta el Algodón de Azúcar Rosa\n* Mascotas Algodón de Azúcar Azul les gusta el Algodón de Azúcar Azul\n* Mascotas de Oro les gusta la Miel",
|
||||
"webFaqAnswer34": "A las Mascotas les gusta la comida relacionada con su color. Las únicas Mascotas que no siguen esta regla son las Base, pero eso si a todas Base les gusta el mismo Artículo. Aquí tienes una lista de la comida específica que le gusta a cada Mascota:\n\n* Mascotas Base les gusta la Carne\n* Mascotas Blancas les gusta la Leche\n* Mascotas del Desierto les gusta las Patatas\n* Mascotas Rojas les gusta las Fresas\n* Mascotas de las Sombras les gusta el Chocolate\n* Mascotas Esqueleto les gusta el Pescado\n* Mascotas Zombi les gusta la Carne Podrida\n* Mascotas Algodón de Azúcar Rosa les gusta el Algodón de Azúcar Rosa\n* Mascotas Algodón de Azúcar Azul les gusta el Algodón de Azúcar Azul\n* Mascotas de Oro les gusta la Miel",
|
||||
"faqQuestion35": "Si he alimentado a mi Mascota hasta que ha desaparecido, ¿qué ha pasado?",
|
||||
"webFaqAnswer35": "Cuando hayas alimentado a tu Mascota lo suficiente como para que llegue a ser una Montura, necesitaras incubar ese tipo de Mascota otra vez para poder tenerla en el establo.\n\nPara ver las Monturas en la Aplicación Móvil:\n\n* En el Menú, selecciona “Mascotas y Monturas” y pulsa encima de Monturas\n\nPara ver las Monturas en la Página Web:\n\n* En el Inventario, selecciona “Mascotas y Monturas” y desplaza hacia abajo hasta la sección de Monturas",
|
||||
"webFaqAnswer35": "Cuando hayas alimentado a tu Mascota lo suficiente como para que llegue a ser una Montura, necesitaras incubar ese tipo de Mascota otra vez para poder tenerla en el Establo.\n\nPara ver las Monturas en la Aplicación Móvil:\n\n* En el Menú, selecciona “Mascotas y Monturas” y pulsa encima de Monturas\n\nPara ver las Monturas en la Página Web:\n\n* En el Inventario, selecciona “Establo” y desplaza hacia abajo hasta la sección de Monturas",
|
||||
"faqQuestion36": "¿Cómo cambio la apariencia de mi Avatar?",
|
||||
"webFaqAnswer36": "¡Hay infinitas maneras en las que puedes personalizar la apariencia de tu Avatar en Habitica! Puedes cambiar la forma del cuerpo de tu Avatar, su estilo de peinado y su color, el color de piel o añadir gafas o ayudas para la movilidad, seleccionando “Personalizar Personaje” en el menú.\n\nPara personalizar tu Avatar en la aplicación móvil:\n* En el menú, selecciona “Personalización del Personaje”\n\n* Para personalizar tu Avatar en la página web:\n* En el menú de usuario, icono de persona en la parte arriba a la izquierda, selecciona “Personalizar Personaje”",
|
||||
"webFaqAnswer36": "¡Hay infinitas maneras en las que puedes personalizar la apariencia de tu Avatar en Habitica! Puedes cambiar la forma del cuerpo de tu Avatar, su estilo de peinado y su color, el color de piel o añadir gafas o ayudas para la movilidad, seleccionando “Personalizar/Editar Personaje” en el menú.\n\nPara personalizar tu Avatar en la aplicación móvil:\n* En el menú, selecciona “Personalización del Personaje”\n\n* Para personalizar tu Avatar en la página web:\n* En el menú de usuario, icono de persona en la parte arriba a la izquierda, selecciona “Editar Personaje”",
|
||||
"faqQuestion37": "¿Porqué no puedo ver el Equipo que he puesto en mi Avatar?",
|
||||
"webFaqAnswer37": "Comprueba que la opción “Disfraz” está activada. Si tu Avatar lleva puesto un disfraz, ese Equipo es el que se mostrará en la imagen de tu Avatar en vez del Equipamiento de batalla.\n\nPara activar el “Disfraz” en la aplicación móvil:\n* En el Menú, selecciona “Equipo” para activar la palanca de “Disfraz”\n\nPara activar el “Disfraz” en la página web:\n* Desde el Inventario bajo Equipamiento, en el cuadro inferior que muestra lo que llevas puesto, elige “Disfraz”, activa la palanca que pasará a estar en color verde",
|
||||
"webFaqAnswer37": "Comprueba que la opción “Disfraz” está activada. Si tu Avatar lleva puesto un disfraz, ese Equipo es el que se mostrará en la imagen de tu Avatar en vez del Equipamiento de batalla.\n\nPara activar el “Disfraz” en la aplicación móvil:\n* En el Menú, selecciona “Equipo” para activar la palanca de “Disfraz”\n\nPara activar el “Disfraz” en la página web:\n* Desde el Inventario bajo Equipamiento, en el cuadro inferior que muestra lo que llevas puesto, elige “Disfraz” y activa la palanca que pasará a estar en color verde",
|
||||
"faqQuestion38": "¿Porqué no puedo comprar algunos objetos?",
|
||||
"webFaqAnswer38": "Los nuevos jugadores de Habitica solo pueden comprar el Equipo básico para Guerreros. Además las diferentes piezas de Equipo se deben comprar de forma secuencias para poder desbloquear la siguiente pieza.\n\nMuchas de las piezas de Equipo son específicas de cada profesión, lo que significa que los jugadores solo pueden comprar Equipo que pertenezca a su Profesión actual.",
|
||||
"faqQuestion39": "¿Dónde se puede obtener más Equipo?",
|
||||
@@ -116,7 +116,7 @@
|
||||
"faqQuestion57": "¿Cómo puedo detener las invitaciones indeseadas?",
|
||||
"faqQuestion58": "¿Cómo filtro la lista de miembros que buscan un Equipo?",
|
||||
"parties": "Equipos",
|
||||
"webFaqAnswer44": "Necesitarás abandonar el Desafío o esperar a que cierre el Desafío para eliminar las tareas asociadas. Un ícono de megáfono rojo implica que el Desafío se ha cerrado, y un megáfono gris indica que el Desafío sigue corriendo.\n\nPara eliminar tareas de Desafíos en la app de **Android**:\n 1. Aprieta una tarea de Desafío. \n 2. Aprieta \"Eliminar\" en la esquina superior derecha de la pantalla.\n 3.Escoge eliminar las tareas de Desafío de tu lista de tareas.\n\nPara eliminar tareas de Desafíos en la app de **iOS**:\n 1. Encuentra la tarea de Desafío que deseas eliminar y mira el ícono de megáfono.\n 2. Si el ícono de megáfono es rojo, aprieta la tarea y escoge \"Eliminar\" en la parte inferior.\n 3. Si el ícono de megáfono es gris, necesitarás encontrar el Desafío y abandonarlo para eliminar la tarea.\n\nPara eliminar tareas de Desafíos en la **página web**:\n 1. Encuentra la tarea de Desafío que deseas eliminar y mira el ícono de megáfono.\n 2. Si el ícono de megáfono es rojo, haz click en él para escoger remover la tarea de tu lista de tareas.\n 3. Si el íccono de megáfono es gris, necesitarás encontrar el Desafío y abandonarlo para eliminar la tarea.",
|
||||
"webFaqAnswer44": "Necesitarás abandonar el Desafío o esperar a que cierre el Desafío para eliminar las tareas asociadas. Un ícono de megáfono rojo implica que el Desafío se ha cerrado, y un megáfono gris indica que el Desafío sigue corriendo.\n\nPara eliminar tareas de Desafíos en la app de **Android**:\n 1. Aprieta una tarea de Desafío. 2. Aprieta \"Eliminar\" en la esquina superior derecha de la pantalla.\n 3.Escoge eliminar las tareas de Desafío de tu lista de tareas.\n\nPara eliminar tareas de Desafíos en la app de **iOS**:\n 1. Encuentra la tarea de Desafío que deseas eliminar y mira el ícono de megáfono.\n 2. Si el ícono de megáfono es rojo, aprieta la tarea y escoge \"Eliminar\" en la parte inferior.\n 3. Si el ícono de megáfono es gris, necesitarás encontrar el Desafío y abandonarlo para eliminar la tarea.\n\nPara eliminar tareas de Desafíos en la **página web**:\n 1. Encuentra la tarea de Desafío que deseas eliminar y mira el ícono de megáfono.\n 2. Si el ícono de megáfono es rojo, haz click en él para escoger remover la tarea de tu lista de tareas.\n\n Si el íccono de megáfono es gris, necesitarás encontrar el Desafío y abandonarlo para eliminar la tarea.",
|
||||
"webFaqAnswer48": "¡Sí, con Equipos! Puedes empezar tu propio Equipo o unirte a uno existente. Estar en Equipo con otros jugadores de Habitica es una gran manera de enfrentarte a Misiones, recibir apoyo de habilidades de los miembros de tu Equipo, e impulsar tu motivación al rendir cuentas.",
|
||||
"sunsetFaqPara7": "Los Equipos y Planes de Grupo permanecerán y mantendrán sus espacios de chat. También podrás mandar mensajes privados.",
|
||||
"sunsetFaqHeader4": "¿Dónde puedo pausar mis Tareas Diarias?",
|
||||
@@ -160,7 +160,7 @@
|
||||
"webFaqAnswer63": "Cualquier miembro puede completar las tareas no asignadas. Por ejemplo, sacar la basura. Quien saque la basura podrá completar la tarea no asignada y se mostrará como completada para todos.",
|
||||
"webFaqAnswer64": "Las tareas compartidas se restablecerán al mismo tiempo para que todos mantengan sincronizado el tablero de tareas compartido. Esta hora es visible en el tablero de tareas compartidas y está determinada por la hora de inicio del día del líder del plan de grupo. Debido a que las tareas compartidas se restablecen automáticamente, no tendrás la oportunidad de completar los diarios compartidos incompletos de ayer cuando te registres a la mañana siguiente.\n\nLos diarios compartidos no causarán daño si se pasan por alto, sin embargo, su color se degradará para ayudar a visualizar el progreso.",
|
||||
"faqQuestion65": "¿Los planes grupales son compatibles con las aplicaciones móviles?",
|
||||
"webFaqAnswer60": "Aquí tienes algunas sugerencias para empezar con tu plan grupal:\n * Pide a uno de los miembros del equipo que sea el encargado de permitir que otros tengan la habilidad de crear y editar las tareas.\n * Deja Tareas sin asignar si alguien puede completarlas y solo es necesario hacerlas una vez\n * Asigna una tarea a solo un miembro del equipo para asegurarte que nadie más la completará\n * Asigna una tarea a unos cuantos miembros del equipo que tendrán que completarla \n * Alterna la capacidad de mostrar tareas compartidas en tu tablón personal para no perderte nada\n * Recibes recompensas por las tareas completadas, incluso aquellas q hayas asignado a varios miembros del equipo\n * Las recompensas por tareas completadas no se dividen entre los miembros del equipo\n * Usa el color de la tarea en el tablón del equipo para evaluar el nivel de progreso en la realización de una tarea\n * Revisa de forma regular las tareas en el Tablón de Tareas compartido para asegurarte que todavía están activas\n * No marcar una tarea Diaria no te hará daño ni a ti ni a tu equipo, pero la tarea si cambiará a un color más rojizo",
|
||||
"webFaqAnswer60": "Aquí tienes algunas sugerencias para empezar con tu plan grupal de Habitica:\n\n* Pide a uno de los miembros del equipo que sea el encargado de permitir que otros tengan la habilidad de crear y editar las tareas.\n* Deja Tareas sin asignar si alguien puede completarlas y solo es necesario hacerlas una vez\n* Asigna una tarea a solo un miembro del equipo para asegurarte que nadie más la completará\n* Asigna una tarea a unos cuantos miembros del equipo que tendrán que completarla * Alterna la capacidad de mostrar tareas compartidas en tu tablón personal para no perderte nada\n* Recibes recompensas por las tareas completadas, incluso aquellas q hayas asignado a varios miembros del equipo\n* Las recompensas por tareas completadas no se dividen entre los miembros del equipo\n* Usa el color de la tarea en el tablón del equipo para evaluar el nivel de progreso en la realización de una tarea\n* Revisa de forma regular las tareas en el Tablón de Tareas compartido para asegurarte que todavía están activas\n* No marcar una tarea Diaria no te hará daño ni a ti ni a tu equipo, pero la tarea si cambiará a un color más rojizo",
|
||||
"webFaqAnswer56": "Para cancelar una invitación pendiente en la aplicación del móvil:\n1. Cuando veas tu Equipo, ve hacia abajo hasta el último nombre de los miembros de la lista.\n2. Encuentra al jugador que quieras cancelar y pulsa en “Cancelar Invitación”.\n\nPara cancelar una invitación pendiente en la página web:\n1. Busca en la lista de miembros de tu Equipo y conecta la pestaña “Invitaciones”\n2. Coloca el cursor sobre la invitación del jugador que deseas cancelar\n3. Pulsa en los tres Puntos y elige “Cancelar Invitación”",
|
||||
"webFaqAnswer62": "Los Planes Grupales te dan la habilidad de asignar tareas compartidas a otros miembros de tu Plan Grupal. Cuando compartes una tarea se asigna a uno de los miembros así otros miembros no pueden completarla.\n\nTambién puedes asignar una tarea a cierto número de miembros. Por ejemplo, si todos se tienen que cepillar los dientes, crea una tarea y asignársela a cada miembro de forma individual. Cada uno tendrá que completarla para recibir su recompensa. La tarea principal aparecería como completada sólo cuando todos hayan completados las asignadas de forma individual.",
|
||||
"webFaqAnswer65": "Aunque las Aplicaciones de móvil no tengan un soporte completo a todas las funciones de los planes grupales aún, ¡si puedes completar tareas compartidas desde las aplicaciones de iOS y Android!\n\nEn Android, puedes tocar tu Nombre para mostrar en la parte de arriba de la pantalla cuando ves tus Tareas para accedes al Tablón de Tareas compartido. Desde allí puedes ver los miembros, acceder al chat, y crear, completar o asignar tareas.\n\nTambién puedes activar una de las preferencias para copiar las tareas compartidas en tu tablón de tareas personal y así que puedas ir marcando todas las tareas completadas desde el mismo sitio.\n\nPara hacer esto en la aplicaciones móviles:\n * Ve a Ajustes y activa “Copiar tareas compartidas”\n\nPara hacer esto en la página web de Habitica:\n * Accede a tu Plan de Grupo y activa la palanca “Copiar Tareas” en el Tablón de Tareas compartido",
|
||||
|
||||
@@ -2849,7 +2849,7 @@
|
||||
"armorMystery202310Notes": "Esta prenda espectral danzará grácilmente entre los gases de la ciénaga de los muertos mientras tratas de dar caza al portador del anillo. No otorga ningún beneficio. Artículo de Suscriptor Octubre 2023.",
|
||||
"armorMystery202307Text": "Tentáculos de Kraken",
|
||||
"armorMystery202307Notes": "Las ventosas de tus tentáculos son tan poderosas que te mantienen adherido al lecho marino mientras agarran y succionan el casco de barcos extraviados junto con toda su tripulación hacia las oscuras profundidades. No otorga ningún beneficio. Artículo de Suscriptor Julio 2023.",
|
||||
"armorArmoireBasketballUniformNotes": "¿Te estás preguntando que hay impreso en la espalda de este uniforme? Tu número favorito ¡por supuesto! Aumenta la Percepción en <%= per %>. Armario Encantado: Conjunto Antiguo Jugador de Baloncesto (Artículo 1 de 2).",
|
||||
"armorArmoireBasketballUniformNotes": "¿Te estás preguntando que hay impreso en la espalda de este uniforme? Tu número favorito ¡por supuesto! Aumenta la Percepción en <% per %>. Armario Encantado: Conjunto Antiguo Jugador de Baloncesto (Artículo 1 de 2).",
|
||||
"armorArmoireGreenFluffTrimmedCoatNotes": "Cuentan las leyendas que una vez en cada generación aparece un abrigo llamado a ser el supremo en calidez y comfort. Su pelusa es de filigrana y sus botones abrochables incluso con guantes. Este es EL ABRIGO. Aumenta la fuerza y la inteligencia en <%= attrs %> cada uno. Armario Encantado: Conjunto Sombreo de Trampero (Artículo 2 de 2).",
|
||||
"armorArmoireSchoolUniformPantsNotes": "Ya sea q estés asistiendo a clases para magos, jinetes de dragón, deportistas, artesanos o iniciados en una logia tan secreta que no podamos revelarla aquí, encajarás perfectamente con este uniforme. Aumenta la Inteligencia en <%= int %>. Armario Encantado: Conjunto Uniforme Escolar (Artículo 2 de 4).",
|
||||
"armorArmoireGreenFluffTrimmedCoatText": "Abrigo con Ribete de Pelusa Verde",
|
||||
|
||||
@@ -385,6 +385,5 @@
|
||||
"questEggGiraffeText": "Girafe",
|
||||
"questEggGiraffeAdjective": "un empilement",
|
||||
"questEggCrabText": "Crabe",
|
||||
"questEggCrabMountText": "Crabe",
|
||||
"questEggCrabAdjective": "bouineux"
|
||||
"questEggCrabMountText": "Crabe"
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
"sunsetFaqList9": "Ce <a href='https://habitica.wordpress.com/beginning-adventurers-guide/'>poste de blog (en Anglais)</a> fournit également un guide pratique pour les nouve·aux·elles joueu·r·se·s.",
|
||||
"sunsetFaqList6": "Les Défis actuellement disponibles en Guildes seront toujours accessibles aux participant·e·s dans leur liste de Défis, mais ne seront plus disponibles dans la liste publique pour des raisons de discrétions. Il ne sera plus possible de créer des nouveaux Défis en Guilde.",
|
||||
"sunsetFaqList10": "Les joueu·r·se·s sont aussi encouragé·e·s à adresser un email à <a href='mailto:admin@habitica.com'>admin@habitica.com</a> avec toutes questions pour lesquelles il·elle·s ne trouvent pas réponse dans les liens ci-dessus.",
|
||||
"webFaqAnswer27": "La couleur d'une tâche est une représentation visuelle de sa valeur. Toutes les tâches sont jaune au début pour la neutralité, bleu veut dire mieux, et rouge signifie moins bien. Voilà comment chaque type de tâche détermine la valeur de celle-ci :\n\nLes Habitudes deviennent plus bleues ou rouges selon si vous appuyez sur le bouton \"plus\" ou \"moins\". Les Habitudes positives et négatives redeviennent jaunes au fur et à mesure si vous ne les accomplissez pas. Les Habitudes duelles ne changent de couleur qu'en fonction de vos saisies.\n\nLes Quotidiennes changent de couleurs en fonction du nombre de fois qu'elles sont accomplies, devenant plus bleues quand elles sont accomplies et plus rouge si vous les avez râtées.\n\nLes À Faire deviennent de plus en plus rouge au fur et à mesure du temps, tant qu'elle ne sont pas accomplies.\n\nPlus une tâche est rouge, plus vous allez obtenir de l'Or et de l'Expérience en les accomplissant, donc assurez-vous de faire vos tâches les plus coriaces !",
|
||||
"webFaqAnswer27": "La couleur d'une tâche est une représentation visuelle de sa valeur. Toutes les tâches sont jaune au début pour la neutralité, bleu veut dire mieux, et rouge signifie moins bien. Voilà comment chaque type de tâche détermine la valeur de celle-ci :\n\nLes Habitudes deviennent plus bleues ou rouges selon si vous appuyez sur le bouton \"plus\" ou \"moins\". Les Habitudes positives et négatives redeviennent jaunes au fur et à mesure si vous ne les accomplissez pas. Les Habitudes duelles ne changent de couleur qu'en fonction de vos saisies.\n\nLes Quotidiennes changent de couleurs en fonction du nombre de fois qu'elles sont accomplies, devenant plus bleues quand elles sont accomplies et plus rouge si vous les avez râtées.\n\nLes À Faire deviennent de plus en plus rouge au fur et à mesure du temps, tant qu'elle ne sont pas accomplies.\n\nPlus une tâche est rouge, plus vous allez obtenir de l'Or et de l'XP en les accomplissant, donc assurez-vous de faire vos tâches les plus coriaces !",
|
||||
"commonQuestions": "Questions Fréquemment Posées",
|
||||
"faqQuestion25": "Quels sont les différents types de tâches ?",
|
||||
"faqQuestion26": "Quels sont des exemples de tâches ?",
|
||||
@@ -171,13 +171,13 @@
|
||||
"faqQuestion33": "À quoi sert la barre bleue qui apparaît après le niveau 10 ?",
|
||||
"webFaqAnswer33": "Après avoir débloqué le Système de Classe, vous débloquerez des Compétences qui requièrent du Mana pour être lancées. Le Mana est déterminé par vos statistiques d'INT et peut être ajusté par vos Compétences et votre Équipement.",
|
||||
"faqQuestion34": "Quel type de Nourriture apprécie mon Familier ?",
|
||||
"webFaqAnswer34": "Les Familiers apprécient la Nourriture qui correspond à leur couleur. Les Familiers de Base sont une exception, mais tous les Familiers de Base apprécient la même chose. Vous pouvez voir les nourritures spécifiques appréciées par chaque Familier ci-dessous :\n\n *Les Familiers de Base aiment les Côtelettes\n *Les Familiers des Neiges aiment le Lait\n *Les Familiers du Désert aiment les Pommes de terre\n *Les Familiers Rouges aiment les Fraises\n *Les Familiers Sombres aiment les Tablettes de chocolat\n *Les Familiers Squelettes aiment le Poisson\n *Les Familiers Zombies aiment les Côtelettes avariées\n *Les Familiers Rose Barbe-à-Papa aiment la Barbe-à-papa rose\n *Les Familiers Bleu Barbe-à-Papa aiment la Barbe-à-papa bleue\n *Les Familiers d'Or aiment le Miel",
|
||||
"webFaqAnswer35": "Une fois que vous avez nourri un Familier suffisamment de fois pour qu'il·elle devienne une Monture, vous devrez à nouveau faire éclore ce type de Familier pour qu'il réapparaisse dans votre écurie.\n\nPour voir les Montures dans les application mobile :\n\n * Depuis le menu, choisir \"Familiers et Montures\" et passer sur l'onglet Montures\n\nPour voir les Montures sur le site web :\n\n * Depuis le menu du l'Inventaire, choisir \"Familiers et Montures\" et faire défiler vers la section Montures",
|
||||
"webFaqAnswer37": "Vérifier sur l'option Costume est activée. Si votre Avatar porte un Costume, c'est celui-ci qui va s'afficher et non votre Tenue de Combat.\n\nPour activer le Costume sur les applications mobile :\n * Depuis le menu, choisir \"Équipement\" pour trouver le bouton Costume\n\nPour activer le Costume sur le site web :\n * Depuis votre Inventaire, choisir \"Équipement\", trouver le bouton \"Utiliser un costume\" dans l'onglet Costume du tiroir d'Équipement",
|
||||
"webFaqAnswer34": "Les Familiers apprécient la Nourriture qui correspond à leur couleur. Les Familiers de Base sont une exception, mais tous les Familiers de Base apprécient la même chose. Vous pouvez voir les Nourritures spécifiques appréciées par chaque Familier ci-dessous :\n\n *Les Familiers de Base aiment les Côtelettes\n *Les Familiers des Neiges aiment le Lait\n *Les Familiers du Désert aiment les Pommes de terre\n *Les Familiers Rouges aiment les Fraises\n *Les Familiers Sombres aiment les Tablettes de chocolat\n *Les Familiers Squelettes aiment le Poisson\n *Les Familiers Zombies aiment les Côtelettes avariées\n *Les Familiers Rose Barbe-à-Papa aiment la Barbe-à-papa rose\n *Les Familiers Bleu Barbe-à-Papa aiment la Barbe-à-papa bleue\n *Les Familiers d'Or aiment le Miel",
|
||||
"webFaqAnswer35": "Une fois que vous avez nourri un Familier suffisamment de fois pour qu'il·elle devienne une Monture, vous devrez à nouveau faire éclore ce type de Familier pour qu'il réapparaisse dans votre Écurie.\n\nPour voir les Montures dans les application mobile :\n\n * Depuis le menu, choisir \"Familiers et Montures\" et passer sur l'onglet Montures\n\nPour voir les Montures sur le site web :\n\n * Depuis le menu du l'Inventaire, choisir \"Écurie\" et faire défiler vers la section Montures",
|
||||
"webFaqAnswer37": "Vérifier sur l'option Costume est activée. Si votre Avatar porte un Costume, c'est celui-ci qui va s'afficher et non votre Tenue de Combat.\n\nPour activer le Costume sur les applications mobile :\n * Depuis le menu, choisir \"Équipement\" pour trouver le bouton Costume\n\nPour activer le Costume sur le site web :\n * Depuis votre Inventaire, choisir \"Équipement\" et trouver le bouton \"Utiliser un costume\" dans l'onglet Costume du tiroir d'Équipement",
|
||||
"webFaqAnswer39": "Si vous souhaitez acquérir plus d'Équipement, vous pouvez vous abonner à Habitica, tenter votre chance dans l'Armoire Enchantée, ou faire des folies pendant l'un des Grand Galas d'Habitica.\nBoutique des Voyageu·r·se·s Temporel·le·sBoutique des Voyageu·r·se·s Temporel·le·sBoutique des Voyageu·r·se·s Temporel·le·s\nLes abonné·e·s d'Habitica reçoivent un ensemble d'équipement exclusif tous les mois et des Sabliers Mystiques pour acheter des ensemble d'Équipements du passé dans la Boutique des Voyageu·r·se·s Temporel·le·s.\n\nLe coffre de l'Armoire Enchantée dans vos Récompenses contient plus de 350 morceaux d'Équipement ! Pour 100 Or, vous pourrez recevoir de l'Équipement, de la Nourriture pour élever votre Familier en Monture, ou de l'Expérience pour gagner en niveau !\n\nPendant les quatre Grand Galas saisonniers, de nouveaux Équipements de classe font leur apparition et peuvent être acquis avec de l'Or, et les ensembles de Gala des années précédentes peuvent être acquis avec des Gemmes.",
|
||||
"faqQuestion35": "J'ai nourri mon Familier et il a disparu ! Que s'est-il passé ?",
|
||||
"faqQuestion36": "Comment changer l'apparence de mon Avatar ?",
|
||||
"webFaqAnswer36": "Il y a un nombre infini de possibilités pour customiser l'apparence de votre Avatar Habitica ! Vous pouvez changer la forme du corps de votre Avatar, sa coupe de cheveux et sa couleur, sa couleur de peau, ajouter des lunettes ou une aide à la mobilité en sélectionnant \"Personnaliser votre Avatar\" depuis le menu.\n\nPour customiser votre Avatar sur les applications mobile :\n * Depuis le menu, sélectionner \"Modifier votre Avatar\"\n\nPour customiser votre Avatar sur le site web :\n * Depuis le menu utilisateur dans la barre de navigation, cliquer sur \"Personnaliser votre avatar\"",
|
||||
"webFaqAnswer36": "Il y a un nombre infini de possibilités pour customiser l'apparence de votre Avatar Habitica ! Vous pouvez changer la forme du corps de votre Avatar, sa coupe de cheveux et sa couleur, sa couleur de peau, ajouter des lunettes ou une aide à la mobilité en sélectionnant Modifier votre Avatar depuis le menu.\n\nPour customiser votre Avatar sur les applications mobile :\n * Depuis le menu, sélectionner \"Modifier votre Avatar\"\n\nPour customiser votre Avatar sur le site web :\n * Depuis le menu utilisateur dans la barre de navigation, cliquer sur \"Modifier votre avatar\"",
|
||||
"faqQuestion37": "Pourquoi mon Équipement ne s'affiche pas sur mon Avatar ?",
|
||||
"faqQuestion38": "Pourquoi ne puis-je pas acheter certains objets ?",
|
||||
"webFaqAnswer38": "Les nouve·aux·elles joueu·r·se·s Habitica ne peuvent acheter que des Équipements spécifiques à la classe Guerri·er·ère de base. Les joueu·r·se·s doivent acheter l'Équipement dans un ordre séquentiel pour débloquer l'objet suivant.\n\nBeaucoup d'élément d'Équipement sont spécifiques à une classe, ce qui veut dire qu'un·e joueu·r·se ne peut acheter de l'Équipement qui correspond à sa classe actuelle.",
|
||||
|
||||
@@ -3179,15 +3179,5 @@
|
||||
"shieldSpecialSummer2024HealerText": "Bouclier de l'Escargot de Mer",
|
||||
"shieldSpecialSummer2024HealerNotes": "Ce bouclier brillant est encore plus fort qu'un Bâton d'Escargot de Mer. Augmente la Constitution de <%= con %>. Édition Limitée Équipement Été 2024.",
|
||||
"headSpecialSummer2024RogueNotes": "Ce casque couverts de tentacules aussi pointues que des cornes vous permet de vous cacher pour attaquer quand vous vous sentez prêt·e. Augmente la Perception de <%= per %>. Édition Limitée Équipement Été 2024.",
|
||||
"armorArmoireCorsairsCoatAndCapeNotes": "Que vous attendiez votre moment de gloire sur les quais ou que vous surveilliez les dangers du grand large, ces vêtements vous garderont au sec et vous donneront un air dramatique. Faites juste en sorte de garder votre équilibre sur le pont. Augmente la Constitution de <%= con %>. Armoire Enchantée : Ensemble Corsaire (Objet 1 sur 3)",
|
||||
"weaponMystery202408Text": "Égide des Arcanes",
|
||||
"weaponArmoireDragonKnightsLanceText": "Lance du Chevalier Dragon",
|
||||
"armorArmoireDragonKnightsArmorText": "Armure du Chevalier Dragon",
|
||||
"headArmoireDragonKnightsHelmText": "Heaume du Chevalier Dragon",
|
||||
"shieldMystery202408Text": "Scintillements des Arcanes",
|
||||
"weaponMystery202408Notes": "Une bulle de protection magique qui vous protège des sorts ennemis et vous permet de flotter dans sur l'eau comme dans les airs. Ne confère aucun bonus. Équipement d'Abonnement Août 2024.",
|
||||
"weaponArmoireDragonKnightsLanceNotes": "Cette lance rouge et argent a désarçonner de nombreux opposant·e·s de leur montures. Augmente la Constitution de <%= con %>. Armoire Enchantée : Ensemble Chevalier Dragon (Objet 3 sur 3)",
|
||||
"armorArmoireDragonKnightsArmorNotes": "Canalisez la force et le pouvoir d'un dragon avec cette armure faite d'argent et d'écailles. Augmente la Force de <%= str %>. Armoire Enchantée : Ensemble Chevalier Dragon (Objet 2 sur 3)",
|
||||
"headArmoireDragonKnightsHelmNotes": "Avec ces apparats ardents ornant ce casque, les dragons pourraient vous prendre pour l'un·e des leurs. Augmente l'Intelligence de <%= int %>. Armoire Enchantée : Ensemble Chevalier Dragon (Objet 1 sur 3)",
|
||||
"shieldMystery202408Notes": "De la lumière magique illuminera l'intérieur de votre cachette-bulle, ou dans quel qu'autre endroit nécessitant un peu de lumière ! Ne confère aucun bonus. Équipement d'Abonnement Août 2024."
|
||||
"armorArmoireCorsairsCoatAndCapeNotes": "Que vous attendiez votre moment de gloire sur les quais ou que vous surveilliez les dangers du grand large, ces vêtements vous garderont au sec et vous donneront un air dramatique. Faites juste en sorte de garder votre équilibre sur le pont. Augmente la Constitution de <%= con %>. Armoire Enchantée : Ensemble Corsaire (Objet 1 sur 3)"
|
||||
}
|
||||
|
||||
@@ -784,14 +784,5 @@
|
||||
"QuestChameleonUnlockText": "Débloque la possibilité d'acheter les Œufs de Caméléon au Marché",
|
||||
"questGiraffeBoss": "Girafe Touchatout",
|
||||
"questGiraffeNotes": "Vous vous promenez dans les hautes herbes de la Savane Calméconstante, profitant d'une ballade dans la nature pour prendre une pause. Alors que le paysage défile devant vous, vous remarquez un tas d'objets au loin. Ce sont des instruments de musique, du matériel d'art, des équipements électroniques, et plus encore ! Vous vous en approchez pour en voir un peu plus.<br><br>\"Hey, qu'est-ce que tu crois être en train de faire ?\" crie une voix derrière un acacia. Une grande et imposante girafe en sort, portant une paire de lunettes à la mode, une guitare, et un appareil photo coûteux autour de son long cou. \"C'est tout mon équipement, alors fais attention et ne touche à rien !\"<br><br>Vous remarquez de la poussière sur la majorité des objets. \"Wow, vous avez énormément de loisirs !\" dites-vous. \"Pouvez-vous me montrer vos créations ou me jouer un morceau ?\"<br><br>Le visage de la girafe s'allonge alors qu'il regarde toute sa collection. \"J'ai tant d'affaires, mais je ne sais pas par où commencer ! Tu peux me passer un peu de ta motivation pour que je trouve enfin l'énergie de m'y mettre !\"",
|
||||
"questChameleonNotes": "C'est un belle journée dans un recoin chaud et pluvieux du Bois de Tâches. Vous chercher de nouvelles feuilles pour votre collection quand une branche devant vous se met à changer de couleur d'un coup ! Puis elle se met à bouger !<br><br>Dans un sursaut, vous vous rendez compte que ce n'est pas une branche, mais un énorme caméléon ! Chaque partie de son corps change constamment de couleur et ses yeux dardent dans toutes les directions.<br><br>\"Est-ce que ça va ?\" lui demandez-vous.<br><br>\"Eeuuh, biiin,\" dit-il, l'air perturbé, \"j'essaye de me fondre dans la masse... Mais c'est tellement contraignant... Les couleurs n'arrêtent pas de changer ! C'est difficile de se concentrer sur une seule à la fois...\"<br><br>\"Aha,\" dites-vous, \"Je pense que je peux vous aider. Nous allons améliorer votre concentration avec un petit défi ! Préparez vos couleurs !\"<br><br>\"C'est parti !\" répond le caméléon.",
|
||||
"questGiraffeUnlockText": "Permet de débloquer l'achat des Œufs de Girafe au Marché.",
|
||||
"questChameleonUnlockText": "Permet de débloquer l'achat des Œufs de Caméléon au Marché",
|
||||
"questCrabDropCrabEgg": "Crabe (Œuf)",
|
||||
"questCrabUnlockText": "Permet de débloquer l'achat des Œufs de Crabe au Marché.",
|
||||
"questCrabText": "La Crabe Bouineuse",
|
||||
"questCrabRageEffect": "La Crabe Bouineuse vous distrait avec ses décorations, vous ralentissant dans votre travail, creusant et drainant un peu de votre magie. Les PM de l'équipes sont réduits !",
|
||||
"questCrabBoss": "Crabe Bouineuse",
|
||||
"questCrabRageTitle": "Bouineuse Distrayante",
|
||||
"questCrabRageDescription": "Cette barre se remplit quand vous n'effectuez pas vos Quotidiennes. Quand elle est pleine, La Crabe Bouineuse retirera des PM à toute votre équipe !"
|
||||
"questChameleonNotes": "C'est un belle journée dans un recoin chaud et pluvieux du Bois de Tâches. Vous chercher de nouvelles feuilles pour votre collection quand une branche devant vous se met à changer de couleur d'un coup ! Puis elle se met à bouger !<br><br>Dans un sursaut, vous vous rendez compte que ce n'est pas une branche, mais un énorme caméléon ! Chaque partie de son corps change constamment de couleur et ses yeux dardent dans toutes les directions.<br><br>\"Est-ce que ça va ?\" lui demandez-vous.<br><br>\"Eeuuh, biiin,\" dit-il, l'air perturbé, \"j'essaye de me fondre dans la masse... Mais c'est tellement contraignant... Les couleurs n'arrêtent pas de changer ! C'est difficile de se concentrer sur une seule à la fois...\"<br><br>\"Aha,\" dites-vous, \"Je pense que je peux vous aider. Nous allons améliorer votre concentration avec un petit défi ! Préparez vos couleurs !\"<br><br>\"C'est parti !\" répond le caméléon."
|
||||
}
|
||||
|
||||
@@ -240,6 +240,5 @@
|
||||
"mysterySet202404": "Ensemble du Mage Mycélien",
|
||||
"mysterySet202405": "Ensemble du Dragon Doré",
|
||||
"mysterySet202406": "Ensemble du Spectre Boucanier",
|
||||
"mysterySet202407": "Ensemble de l'Axolotl Aimable",
|
||||
"mysterySet202408": "Ensemble Égide des Arcanes"
|
||||
"mysterySet202407": "Ensemble de l'Axolotl Aimable"
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
"sunsetFaqList8": "<a href='https://habitica.com/static/faq'>FAQ</a> kami yang sudah ada sebelumnya adalah sumber daya yang bagus dan dapat ditemukan dari menu Bantuan, atau Dukungan di ponsel. Kami sedang dalam proses membuat FAQ yang lebih komprehensif dan lebih baik untuk membantu memandu pemain bergerak maju.",
|
||||
"sunsetFaqList9": "<a href='https://habitica.wordpress.com/beginning-adventurers-guide/'>Posting blog</a> ini juga menyediakan panduan praktis untuk pemain baru.",
|
||||
"sunsetFaqHeader11": "Bagaimana hal ini memengaruhi Pedoman Komunitas dan Ketentuan Layanan Habitica?",
|
||||
"anotherQuestion": "Punya pertanyaan lain?",
|
||||
"anotherQuestion": "Ada pertanyaan lain?",
|
||||
"contactAdmin": "Hubungi <a href='mailto:admin@habitica.com'>admin@habitica.com</a>",
|
||||
"sunsetFaqPara4": "Untuk merayakan saat-saat yang kita lalui bersama, kami akan memberi hadiah kepada semua orang Peliharaan Veteran saat kami bergerak maju ke era baru ini. Untuk kontributor kami yang luar biasa, kami juga akan mengirimkan perlengkapan khusus untuk memperingati semua kerja keras mereka di komunitas Habitica.",
|
||||
"sunsetFaqList1": "Tujuan utama Habitica adalah untuk memberikan motivasi melalui pengalaman manajemen tugas tergamifikasi. Guild dan Kedai Minuman digunakan oleh persentase kecil yang tidak proporsional dari basis pemain kami. Mayoritas pemain menggunakan layanan luar yang terutama ditujukan untuk interaksi sosial dan sengaja dirancang dan dipelihara dengan mempertimbangkan kasus penggunaan tersebut.",
|
||||
@@ -173,114 +173,5 @@
|
||||
"faqQuestion35": "Saya memberi makan hewan peliharaan saya dan hewan itu menghilang! Apa yang telah terjadi?",
|
||||
"webFaqAnswer35": "Setelah kamu memberi makan hewan peliharaanmu dalam jumlah yang cukup untuk mengangkatnya menjadi tunggangan, kamu harus menetaskan hewan peliharaan jenis itu lagi agar bisa dimasukkan ke dalam kandangmu.\n\nUntuk melihat Mount di aplikasi seluler:\n\n* Dari Menu, pilih “Hewan Peliharaan & Tunggangan” dan beralih ke tab Tunggangan\n\nUntuk melihat Mount di situs web:\n\n* Dari menu Inventaris, pilih “Stabil” dan gulir ke bawah ke bagian Mount",
|
||||
"faqQuestion36": "Bagaimana cara mengubah tampilan Avatar saya?",
|
||||
"webFaqAnswer36": "Ada banyak cara untuk menyesuaikan tampilan Avatar Habitica Anda! Anda dapat mengubah bentuk tubuh Avatar Anda, gaya dan warna rambut, warna kulit, atau menambahkan kacamata atau alat bantu mobilitas dengan memilih Sesuaikan (atau Edit) Avatar dari menu.\n\nUntuk menyesuaikan Avatar Anda di aplikasi seluler:\n* Dari menu, pilih “Sesuaikan Avatar”\n\nUntuk menyesuaikan Avatar Anda di situs web:\n* Dari menu pengguna di navigasi, pilih \"Edit Avatar\"",
|
||||
"contentReleaseChanges": "Perubahan Rilis Konten",
|
||||
"contentFaqPara1": "Ingin tahu lebih lanjut? Baca terus di bawah ini!",
|
||||
"contentQuestion0": "Apa yang berubah?",
|
||||
"contentAnswer00": "Ramuan Penetasan Ajaib, Latar Belakang yang dirilis ulang, Set Pelanggan terdahulu, dan Misi Hewan Peliharaan akan berganti pada jadwal bulanan yang dapat diprediksi.",
|
||||
"contentAnswer01": "<strong>Grand Galas diperluas</strong> agar aktif sepanjang musim, bersama dengan semua perlengkapan Kelas, Kustomisasi Avatar, dan hadiah lainnya.",
|
||||
"contentAnswer03": "Latar Belakang, Warna Rambut, Gaya Rambut, Kulit, Telinga Hewan, Ekor Hewan, dan Kemeja sekarang dapat dibeli dari <strong>Toko Kustomisasi</strong> yang baru!",
|
||||
"contentQuestion1": "Mengapa Habitica membuat perubahan ini?",
|
||||
"contentAnswer11": "Ketika pemain baru bergabung di Grand Gala, mereka sering kali tidak menyadari adanya acara ini dan kehilangan keseruannya. Kami ingin memastikan semua pemain baru dapat bergabung dalam perayaan musiman kami, kapan pun mereka memilih untuk memulai perjalanan mereka.",
|
||||
"contentAnswer12": "Pemain akan lebih mudah melengkapi koleksinya dengan item yang dirilis pada jadwal yang lebih dapat diprediksi.",
|
||||
"contentQuestion2": "Bagaimana Grand Gala berubah?",
|
||||
"contentAnswer20": "Akan selalu ada Grand Gala yang aktif setiap hari sepanjang tahun ketika perubahan jadwal mulai berlaku.",
|
||||
"contentAnswer200": "<strong>Summer Splash</strong>: 21 Juni hingga 20 September",
|
||||
"contentAnswer202": "<strong>Winter Wonderland</strong>: 21 Desember hingga 20 Maret",
|
||||
"contentAnswer203": "<strong>Spring Fling</strong>: 21 Maret hingga 20 Juni",
|
||||
"contentAnswer22": "Magic Hatching Potions tidak akan lagi terikat dengan Gala, melainkan akan dirilis pada jadwal rilis bulanannya sendiri yang bertemakan perayaan yang sedang berlangsung.",
|
||||
"contentQuestion3": "Bagaimana jadwal rilis konten berubah?",
|
||||
"contentAnswer30": "Toko-toko akan merotasi pilihan item mereka setiap bulan. Ini akan membantu menjaga jumlah konten di toko tetap mudah dikelola dan dijelajahi. Jadwal baru akan menawarkan item-item baru untuk dicoba setiap bulan bagi pemain baru sekaligus menciptakan jadwal yang dapat diprediksi bagi kolektor veteran.",
|
||||
"contentAnswer300": "<strong>Tanggal 1 setiap bulan:</strong> Paket Pelanggan Baru dirilis. Paket Pelanggan yang tersedia di Toko Penjelajah Waktu akan dirotasi.",
|
||||
"contentAnswer301": "<strong>Tanggal 7 setiap bulan:</strong> Item Enchanted Armoire baru dan satu Background baru dirilis. Background yang tersedia di Customization Shop akan berganti-ganti.",
|
||||
"contentAnswer303": "<strong>Tanggal 21 setiap bulannya:</strong> Ramuan Penetasan Ajaib yang tersedia di Pasar akan dirotasi.",
|
||||
"contentQuestion4": "Konten baru apa yang akan hadir?",
|
||||
"contentAnswer40": "Untuk mengisi jadwal baru ini, kami telah bekerja keras menciptakan item baru dalam berbagai kategori termasuk:",
|
||||
"contentAnswer400": "Misi Hewan Peliharaan",
|
||||
"contentAnswer401": "Misi Ramuan Penetasan Ajaib",
|
||||
"contentAnswer402": "Ramuan Penetasan Ajaib",
|
||||
"contentAnswer403": "Warna Rambut Musim Panas",
|
||||
"contentAnswer41": "Apa saja tambahan baru ini?",
|
||||
"contentQuestion5": "Apa itu Toko Kustomisasi?",
|
||||
"contentAnswer50": "Toko Kustomisasi adalah rumah baru untuk semua item Kustomisasi Avatar yang dapat dibeli termasuk:",
|
||||
"contentAnswer501": "Kulit",
|
||||
"contentAnswer502": "Warna dan Gaya Rambut",
|
||||
"contentAnswer52": "Kami berharap perubahan ini akan membantu pemain memilah kustomisasi yang mereka miliki saat mengedit tampilan avatar mereka sambil tetap mempertahankan pengalaman berbelanja yang sudah dikenal untuk item lain yang dapat dibeli.",
|
||||
"contentAnswer53": "Toko Kustomisasi akan ditemukan di samping toko lain di Menu.",
|
||||
"contentAnswer60": "Semua acara terkini lainnya akan tetap berjalan seperti biasa! Semua orang akan tetap mendapatkan hadiah khusus dan makanan bertema seperti yang mereka dapatkan sekarang.",
|
||||
"contentAnswer61": "Kartu ucapan Hari Valentine dan Tahun Baru akan dirilis pada tanggal yang ditentukan.",
|
||||
"contentAnswer63": "Wacky Pets akan tetap tersedia sepanjang sebagian besar bulan April.",
|
||||
"contentQuestion7": "Bagaimana dengan barang lain yang tersedia di Toko Time Travelers selain Set Pelanggan sebelumnya?",
|
||||
"contentAnswer71": "Nantikan informasi terbaru lebih lanjut tentang rencana peningkatan pengalaman berbelanja di Time Travelers Shop.",
|
||||
"contentFaqTitle": "FAQ Perubahan Rilis Konten Habitica",
|
||||
"contentAnswer02": "<strong>Pet Quest, Magic Hatching Potion, dan Magic Hatching Potion</strong> yang baru akan dirilis untuk melengkapi jadwal baru ini!",
|
||||
"contentAnswer10": "Habitica telah ada sejak 2013 (wow!) dan seiring berjalannya waktu, kami telah merilis ribuan item yang dapat dikoleksi oleh para pemain. Hal ini bisa jadi sangat membebani, terutama bagi para pemain baru. Kami ingin memastikan bahwa kami memamerkan semua yang kami tawarkan, dan bahwa item-item luar biasa yang dirilis sebelumnya dalam sejarah kami tidak diabaikan.",
|
||||
"contentAnswer201": "<strong>Festival Musim Gugur</strong>: 21 September hingga 20 Desember",
|
||||
"contentAnswer21": "Semua barang bagus Gala (Perlengkapan Kelas, Kulit dan Warna Rambut, Barang Transformasi, Misi Musiman) akan dirilis saat Gala dimulai dan akan tersedia selama Gala berlangsung.",
|
||||
"contentAnswer302": "<strong>Tanggal 14 setiap bulannya:</strong> Quest Hewan Peliharaan, Quest Ramuan, dan Bundel Quest yang tersedia di Toko Quest akan dirotasi.",
|
||||
"contentAnswer410": "Tetaplah di sini untuk mengetahuinya! Banyak tambahan baru yang sangat diminati dan akan dirilis sepanjang tahun.",
|
||||
"contentFaqPara0": "Habitica menawarkan begitu banyak konten yang menyenangkan dan menarik, dan kami ingin semua orang dapat menikmatinya! Berbagai perubahan akan dilakukan untuk memudahkan pemain baru memulai koleksi mereka dan juga memudahkan pemain lama untuk melengkapi koleksi mereka!",
|
||||
"contentAnswer51": "Kustomisasi yang Anda miliki (baik standar maupun yang dibeli) akan dapat diakses dari antarmuka Kustomisasi Avatar saat ini.",
|
||||
"contentQuestion6": "Apa yang akan terjadi pada acara musiman lainnya, seperti Habitoween, April Mop, dan Ulang Tahun?",
|
||||
"contentAnswer62": "Ramuan Ajaib Penetasan Hari Valentine sekarang dimasukkan ke dalam jadwal bulanan.",
|
||||
"contentAnswer70": "Latar Belakang, Misi, Hewan Peliharaan, dan Tunggangan yang tersedia di Toko Penjelajah Waktu akan tetap tersedia sepanjang tahun.",
|
||||
"contentFaqPara3": "Jika Anda memiliki pertanyaan yang tidak tercakup dalam jawaban di atas, Anda selalu dapat menghubungi tim kami di <%= mailto %>! Kami sangat antusias dengan jadwal rilis konten baru ini dan menantikan lebih banyak proyek di masa mendatang untuk membantu menjadikan Habitica lebih baik bagi semua pemain.",
|
||||
"webFaqAnswer41": "Mystic Hourglasses adalah mata uang eksklusif Pelanggan Habitica yang digunakan di Toko Time Travelers! Hourglass dikirimkan pada jadwal yang ditetapkan berdasarkan paket langganan Anda.\n\nJadwal pengiriman Hourglass:\n* Pelanggan 1 Bulan mendapatkan 1 Hourglass di awal bulan setelah pembayaran ke-3 berturut-turut.\n* Pelanggan 3 Bulan mendapatkan 1 Hourglass segera setelah berlangganan, lalu 1 Hourglass lagi di awal bulan setelah setiap pembaruan.\n* Pelanggan 6 Bulan mendapatkan 2 Hourglass segera setelah berlangganan, lalu 2 Hourglass lagi di awal bulan setelah setiap pembaruan.\n* Pelanggan 12 Bulan mendapatkan 4 Hourglass segera setelah berlangganan, lalu 4 Hourglass lagi di awal bulan setelah setiap pembaruan.",
|
||||
"faqQuestion42": "Apa yang dapat saya lakukan untuk meningkatkan akuntabilitas?",
|
||||
"webFaqAnswer42": "Salah satu cara terbaik untuk memotivasi diri sendiri dan membuat diri Anda bertanggung jawab untuk menyelesaikan tugas adalah dengan bergabung dalam Pesta! Berpesta dengan pemain Habitica lainnya adalah cara yang bagus untuk menyelesaikan Misi untuk menerima Hewan Peliharaan dan Peralatan, menerima buff dari Keterampilan anggota Pesta, dan meningkatkan motivasi Anda.\n\nCara lain untuk meningkatkan akuntabilitas adalah dengan bergabung dalam Tantangan. Tantangan secara otomatis menambahkan tugas yang terkait dengan tujuan tertentu ke daftar Anda! Tantangan juga menambahkan elemen kompetisi melawan pemain Habitica lainnya yang dapat memberi Anda dorongan motivasi saat Anda berjuang untuk mendapatkan hadiah Permata. Ada Tantangan resmi yang dibuat oleh Tim Habitica dan juga Tantangan yang dibuat oleh pemain lain.",
|
||||
"faqQuestion43": "Bagaimana cara saya mengikuti Quest?",
|
||||
"webFaqAnswer43": "Untuk memulai Quest, Anda harus menjadi anggota Party. Party dapat berupa petualangan solo di mana Anda menantang Quest sendirian, atau Anda dapat mengundang pemain Habitica lainnya untuk menyelesaikan Quest dengan lebih cepat!\n\nPilih Quest Scroll dari inventaris Anda dengan memilih tombol \"Begin Quest\" dari Party Anda. Selesaikan tugas Anda seperti biasa untuk melanjutkan Quest! Anda akan membangun damage terhadap monster jika Anda mengambil Boss Quest, atau memiliki kesempatan untuk menemukan item jika Anda mengambil Collection Quest. Semua kemajuan yang tertunda diterapkan pada hari berikutnya.\n\nSaat Anda menghasilkan damage yang cukup atau mengumpulkan semua item, Quest selesai dan Anda akan menerima hadiah!",
|
||||
"faqQuestion44": "Bagaimana saya dapat menghapus tugas Tantangan?",
|
||||
"webFaqAnswer44": "Anda harus meninggalkan Tantangan atau menunggu Tantangan ditutup untuk menghapus tugas terkait. Ikon megafon merah menunjukkan Tantangan telah ditutup dan megafon abu-abu menunjukkan Tantangan masih berjalan.\n\nUntuk menghapus tugas Tantangan di aplikasi **Android**:\n\n1. Ketuk tugas yang termasuk dalam Tantangan. 2. Ketuk \"Hapus\" di sudut kanan atas layar.\n\n3. Pilih untuk menghapus tugas Tantangan dari daftar tugas Anda.\n\nUntuk menghapus tugas Tantangan di aplikasi **iOS**:\n\n1. Temukan tugas Tantangan yang ingin Anda hapus dan lihat ikon megafon.\n\n2. Jika ikon megafon berwarna merah, ketuk tugas dan pilih \"Hapus\" di bagian bawah\n\n3. Jika ikon megafon berwarna abu-abu, Anda harus menemukan Tantangan dan meninggalkannya untuk menghapus tugas.\n\nUntuk menghapus tugas Tantangan di **situs web**:\n\n1. Temukan tugas Tantangan yang ingin Anda hapus dan lihat ikon megafon. 2. Jika ikon megafon berwarna merah, klik ikon tersebut lalu pilih untuk menghapus tugas dari daftar tugas Anda.\n\nJika ikon megafon berwarna abu-abu, Anda harus menemukan Tantangan dan meninggalkannya untuk menghapus tugas.",
|
||||
"faqQuestion45": "Avatar saya berubah menjadi manusia salju, bintang laut, bunga, atau hantu. Bagaimana cara mengubahnya kembali?",
|
||||
"sunsetFaqHeader12": "Apa yang akan terjadi pada Guild Bank Gems?",
|
||||
"sunsetFaqPara21": "Permata di Bank Guild akan dikembalikan kepada pemimpin Guild pada tanggal 8 Agustus saat Layanan Guild berakhir.",
|
||||
"faqQuestion37": "Mengapa Peralatan saya tidak ditampilkan di Avatar saya?",
|
||||
"webFaqAnswer37": "Periksa apakah opsi Kostum diaktifkan. Jika Avatar Anda mengenakan Kostum, set Peralatan itu akan ditampilkan sebagai ganti Peralatan Pertempuran Anda.\n\nUntuk mengaktifkan Kostum pada aplikasi seluler:\n\n* Dari menu, pilih \"Peralatan\" untuk menemukan tombol Kostum\n\nUntuk mengaktifkan Kostum pada situs web:\n\n* Dari Inventaris Anda, pilih \"Peralatan\" dan temukan tombol Kostum di tab Kostum pada laci Peralatan",
|
||||
"faqQuestion38": "Mengapa saya tidak dapat membeli barang tertentu?",
|
||||
"webFaqAnswer38": "Pemain Habitica baru hanya dapat membeli Peralatan kelas Prajurit dasar. Pemain harus membeli Peralatan secara berurutan untuk membuka bagian berikutnya.\n\nBanyak bagian Peralatan yang khusus untuk kelas tertentu, yang berarti bahwa pemain hanya dapat membeli Peralatan yang termasuk dalam kelas mereka saat ini.",
|
||||
"faqQuestion39": "Di mana saya bisa mendapatkan lebih banyak Peralatan?",
|
||||
"webFaqAnswer39": "Jika Anda ingin mendapatkan lebih banyak Peralatan, Anda dapat menjadi Pelanggan Habitica, mencoba Enchanted Armoire, atau berfoya-foya selama salah satu Gala Besar Habitica.\n\nPelanggan Habitica menerima set perlengkapan eksklusif khusus setiap bulan dan Mystic Hourglasses untuk membeli set Peralatan sebelumnya dari Toko Time Traveler.\n\nPeti harta karun Enchanted Armoire di Hadiah Anda memiliki lebih dari 350 buah Peralatan! Dengan 100 Emas, Anda akan berkesempatan menerima Peralatan khusus, Makanan untuk menaikkan Hewan Peliharaan Anda ke Tunggangan, atau Pengalaman untuk naik level!\n\nSelama empat Gala Besar musiman, Peralatan kelas baru tersedia untuk dibeli dengan Emas dan set Gala sebelumnya dapat dibeli dengan Permata.",
|
||||
"faqQuestion40": "Apa itu Gems, dan bagaimana cara mendapatkannya?",
|
||||
"webFaqAnswer40": "Permata adalah mata uang berbayar dalam aplikasi Habitica yang digunakan untuk membeli Peralatan, Kustomisasi Avatar, Latar Belakang, dan banyak lagi! Permata dapat dibeli dalam bentuk bundel atau dengan Emas jika Anda adalah pelanggan Habitica. Anda juga dapat memenangkan Permata dengan dipilih sebagai pemenang Tantangan.",
|
||||
"faqQuestion41": "Apa itu Mystic Hourglasses, dan bagaimana cara mendapatkannya?",
|
||||
"webFaqAnswer45": "Salah satu anggota Party Anda menggunakan item transformasi Seasonal Shop pada Anda! Avatar Anda akan berubah kembali normal keesokan harinya. Jika Anda ingin menghapus transformasi lebih cepat, Anda dapat membeli penawar racun (Ramuan Garam, Pasir, Bebas Kelopak, atau Opaque) dari Rewards.",
|
||||
"faqQuestion46": "Bagaimana cara melaporkan bug?",
|
||||
"webFaqAnswer46": "Jika Anda merasa menemukan bug, mohon beri tahu kami!\n\nUntuk melaporkan bug pada aplikasi seluler:\n\n* Dari menu, pilih Dukungan lalu ketuk “Dapatkan Bantuan” dan gulir ke bawah ke “Laporkan Bug”\n\nUntuk melaporkan bug pada situs web:\n\n* Dari menu Bantuan, pilih “Laporkan Bug”",
|
||||
"faqQuestion47": "Dapatkah saya melihat data tentang seberapa baik saya mengerjakan tugas dan kebiasaan saya?",
|
||||
"webFaqAnswer47": "Saat ini, Habitica tidak memiliki representasi visual data tugas Anda dari waktu ke waktu. Namun, di situs web Habitica, Anda dapat mengekspor data tugas dari tab Data Situs di Setelan.",
|
||||
"faqQuestion48": "Bisakah saya memainkan Habitica dengan orang lain?",
|
||||
"webFaqAnswer48": "Ya, dengan Pesta! Anda dapat memulai Pesta Anda sendiri atau bergabung dengan pesta yang sudah ada. Berpesta dengan pemain Habitica lainnya adalah cara yang bagus untuk menjalankan Misi, menerima buff dari keterampilan anggota Pesta, dan meningkatkan motivasi Anda dengan tanggung jawab tambahan.",
|
||||
"faqQuestion49": "Bagaimana cara menemukan Pesta bila saya tidak ada di dalamnya?",
|
||||
"webFaqAnswer49": "Jika Anda ingin mencoba Habitica bersama orang lain tetapi tidak mengenal pemain lain, mencari Party adalah pilihan terbaik! Jika Anda sudah mengenal pemain lain yang mengadakan Party, Anda dapat membagikan @username Anda kepada mereka untuk diundang. Atau, Anda dapat membuat Party baru dan mengundang mereka dengan @username atau alamat email mereka.\n\nUntuk membuat atau mencari Party, pilih \"Party\" di menu navigasi, lalu pilih opsi yang sesuai untuk Anda.",
|
||||
"faqQuestion50": "Bagaimana cara kerja pencarian Partai?",
|
||||
"webFaqAnswer50": "Setelah memilih \"Cari Grup\", Anda akan ditambahkan ke daftar pemain yang ingin bergabung dengan Grup. Pemimpin grup dapat melihat daftar ini dan mengirim undangan. Setelah menerima undangan, Anda dapat menerimanya dari notifikasi untuk bergabung dengan Grup pilihan Anda!\n\nAnda mungkin mendapatkan beberapa undangan ke Grup yang berbeda. Namun, Anda hanya dapat menjadi anggota satu Grup dalam satu waktu.",
|
||||
"faqQuestion51": "Berapa lama saya dapat mencari Partai setelah bergabung dalam daftar?",
|
||||
"webFaqAnswer51": "Anda akan tetap berada dalam daftar hingga Anda menerima undangan ke Pesta atau tidak masuk selama 7 hari, mana saja yang lebih dulu. Jika Anda masuk setelah tidak aktif selama 7 hari, kami akan secara otomatis menambahkan Anda kembali ke daftar selama Anda tidak memiliki undangan yang tertunda.",
|
||||
"faqQuestion52": "Bisakah saya berhenti mencari Partai?",
|
||||
"webFaqAnswer52": "Jika Anda tidak ingin lagi mencari Party, Anda dapat berhenti mencari kapan saja.\n\nUntuk berhenti mencari Party di aplikasi seluler:\n* Dari menu, pilih \"Party\" dan ketuk \"Leave\" di bagian bawah layar.\n\nUntuk berhenti mencari Party di situs web Habitica:\n* Pilih \"Party\" dari navigasi dan klik \"Leave\" di pop-up.",
|
||||
"faqQuestion53": "Saya punya Pesta, bagaimana cara mencari anggota lainnya?",
|
||||
"webFaqAnswer53": "Jika Anda menggunakan situs web Habitica, pilih \"Temukan Anggota\" dari menu tarik-turun Grup. Jika Anda menggunakan aplikasi Android, ketuk \"Temukan Anggota\" di atas daftar anggota Grup Anda. Ini akan menampilkan daftar pemain yang secara aktif mencari Grup dan dapat diundang untuk bergabung.\n\nUntuk membantu menemukan yang cocok untuk Grup Anda, Anda akan melihat beberapa informasi, seperti bahasa, kelas, level, dan berapa hari mereka telah menggunakan Habitica. Jika Anda ingin mengobrol dengan seseorang sebelum mengirim undangan, Anda dapat melihat Profil mereka dan mengirim pesan.",
|
||||
"faqQuestion54": "Berapa banyak anggota yang dapat saya undang ke Pesta saya?",
|
||||
"webFaqAnswer54": "Setiap grup memiliki batas maksimum 30 anggota dan minimum 1 anggota. Undangan yang tertunda dihitung dalam hitungan anggota. Misalnya, 29 anggota dan 1 undangan yang tertunda akan dihitung sebagai 30 anggota. Untuk menghapus undangan yang tertunda, pemain yang diundang harus menerima atau menolak, atau pemimpin grup harus membatalkan undangan.",
|
||||
"faqQuestion55": "Bisakah saya mengundang seseorang yang sudah saya kenal?",
|
||||
"webFaqAnswer55": "Ya! Jika Anda sudah memiliki nama pengguna atau alamat email pemain Habitica, Anda dapat mengundang mereka untuk bergabung dengan Pesta Anda. Berikut cara mengirim undangan di berbagai platform:\n\nUntuk mengundang seseorang di aplikasi seluler:\n\n1. Dari menu, pilih \"Pesta\" dan gulir ke bawah ke bagian Anggota\n\n2. Ketuk \"Temukan Anggota\" lalu alihkan ke tab \"Dengan Undangan\"\n\n3. Masukkan nama pengguna atau alamat email pemain yang ingin Anda undang dan klik \"Kirim Undangan\"\n\nUntuk mengundang seseorang di situs web:\n\n1. Navigasi ke Pesta Anda dan klik \"Undang ke Pesta\"\n\n2. Masukkan nama pengguna atau alamat email pemain yang ingin Anda undang dan klik \"Kirim Undangan\"",
|
||||
"faqQuestion56": "Bagaimana cara membatalkan undangan yang tertunda ke Pesta saya?",
|
||||
"webFaqAnswer56": "Untuk membatalkan undangan yang tertunda di aplikasi seluler:\n1. Saat melihat Grup Anda, gulir ke bawah hingga ke bagian bawah daftar Anggota Anda\n2. Temukan pemain yang undangannya ingin Anda batalkan dan ketuk tombol “Batalkan undangan”.\n\nUntuk membatalkan undangan yang tertunda di situs web:\n1. Navigasi ke daftar anggota Grup Anda dan alihkan ke tab “Undangan”\n2. Arahkan kursor ke pemain yang undangannya ingin Anda batalkan\n3. Klik tiga titik dan pilih “Batalkan Undangan”",
|
||||
"faqQuestion57": "Bagaimana cara menghentikan undangan yang tidak diinginkan?",
|
||||
"webFaqAnswer57": "Setelah bergabung dengan Party, Anda tidak akan lagi menerima undangan. Jika Anda ingin mencegah undangan dan komunikasi di masa mendatang dari pemain tertentu, lihat profil mereka dan klik tombol Blokir. Pada profil seluler, ketuk tiga titik di sudut atas lalu pilih \"Blokir\".\n\nJika Anda menghadapi situasi di mana Anda yakin pemain lain telah melanggar Pedoman Komunitas kami dalam nama, profil, atau pesan yang mereka kirim, harap laporkan pesan apa pun atau hubungi kami di admin@habitica.com.",
|
||||
"faqQuestion58": "Bagaimana cara menyaring daftar anggota yang mencari Partai?",
|
||||
"webFaqAnswer58": "Saat ini belum ada cara untuk memfilter daftar anggota yang mencari Partai. Namun, kami berencana untuk memperkenalkan filter di masa mendatang, seperti kelas, level, dan bahasa.",
|
||||
"groupPlan": "Rencana Grup",
|
||||
"faqQuestion59": "Apa itu Paket Grup?",
|
||||
"webFaqAnswer59": "Paket Grup Habitica memberikan pengalaman bersama dengan memungkinkan para anggota untuk menambahkan, menetapkan, dan menyelesaikan tugas dengan mudah dari papan tugas bersama. Dengan fitur-fitur seperti peran anggota, tampilan status, dan penugasan tugas, Paket Grup sangat cocok untuk keluarga atau tim kolega yang memiliki tujuan bersama. Paket ini juga merupakan cara yang bagus untuk saling memotivasi dalam perjalanan Anda untuk melawan monster dan meningkatkan kehidupan Anda.",
|
||||
"faqQuestion60": "Bagaimana cara memulai Paket Grup saya?",
|
||||
"webFaqAnswer60": "Berikut beberapa kiat cepat untuk membantu Anda memulai Paket Grup Habitica baru Anda:\n\n* Promosikan anggota ke manajer untuk memberi mereka kemampuan membuat dan mengedit tugas\n\n* Biarkan tugas tidak ditetapkan jika ada yang dapat menyelesaikannya dan tugas hanya perlu diselesaikan satu kali\n\n* Tetapkan tugas kepada satu orang untuk memastikan tidak ada orang lain yang dapat menyelesaikan tugas mereka\n\n* Tetapkan tugas kepada beberapa orang jika mereka semua perlu menyelesaikannya * Aktifkan kemampuan untuk menampilkan tugas bersama di papan pribadi Anda agar tidak ada yang terlewat\n\n* Anda mendapatkan hadiah untuk tugas yang Anda selesaikan, bahkan tugas yang ditugaskan kepada banyak orang\n\n* Hadiah penyelesaian tugas tidak dibagi di antara anggota\n\n* Gunakan warna tugas di papan tim untuk menilai tingkat penyelesaian tugas rata-rata\n\n* Tinjau tugas secara berkala di papan tugas bersama untuk memastikan tugas tersebut masih relevan\n\n* Melewatkan Tugas Harian tidak akan merugikan Anda atau tim Anda, tetapi tugas tersebut akan berubah warna",
|
||||
"faqQuestion61": "Bisakah anggota Rencana Grup lainnya membuat tugas?",
|
||||
"webFaqAnswer61": "Hanya pemimpin dan manajer Rencana Grup yang dapat membuat tugas bersama. Jika Anda ingin anggota dapat membuat tugas, maka Anda harus mempromosikannya menjadi manajer.\n\nUntuk mempromosikan anggota Rencana Grup menjadi manajer di situs web:\n1. Navigasi ke Rencana Grup Anda lalu alihkan ke tab \"Informasi Grup\"\n2. Lihat Daftar Anggota Anda dan klik ikon titik di samping anggota yang ingin Anda promosikan\n3. Pilih \"Tetapkan Manajer\"",
|
||||
"faqQuestion62": "Bagaimana cara kerja tugas yang diberikan?",
|
||||
"webFaqAnswer62": "Paket Grup memberi Anda kemampuan unik untuk menetapkan tugas bersama kepada anggota lain Paket Grup Anda. Saat tugas bersama ditetapkan kepada satu anggota, anggota lain tidak dapat menyelesaikannya.\n\nAnda juga dapat menetapkan tugas kepada beberapa anggota. Misalnya, jika setiap orang harus menggosok gigi, buat tugas dan tetapkan kepada setiap anggota. Setiap anggota akan dapat menyelesaikan tugas dan mendapatkan hadiah masing-masing. Tugas utama akan ditampilkan sebagai selesai setelah semua orang menyelesaikannya.",
|
||||
"faqQuestion63": "Bagaimana cara kerja tugas yang tidak ditetapkan?",
|
||||
"webFaqAnswer63": "Tugas yang belum ditetapkan dapat diselesaikan oleh anggota mana pun. Misalnya, membuang sampah. Siapa pun yang membuang sampah dapat menyelesaikan tugas yang belum ditetapkan dan tugas tersebut akan ditampilkan sebagai selesai untuk semua orang.",
|
||||
"faqQuestion64": "Bagaimana cara kerja pengaturan ulang hari yang disinkronkan?"
|
||||
"webFaqAnswer36": "Ada banyak cara untuk menyesuaikan tampilan Avatar Habitica Anda! Anda dapat mengubah bentuk tubuh Avatar Anda, gaya dan warna rambut, warna kulit, atau menambahkan kacamata atau alat bantu mobilitas dengan memilih Sesuaikan (atau Edit) Avatar dari menu.\n\nUntuk menyesuaikan Avatar Anda di aplikasi seluler:\n* Dari menu, pilih “Sesuaikan Avatar”\n\nUntuk menyesuaikan Avatar Anda di situs web:\n* Dari menu pengguna di navigasi, pilih \"Edit Avatar\""
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"groupBy": "<%= type %>でグループ分け",
|
||||
"classBonus": "(このアイテムはあなたのクラス用なので、能力値のボーナスが1.5倍になります。)",
|
||||
"classArmor": "クラスのよろい",
|
||||
"featuredset": "目玉商品: <%= name %>",
|
||||
"featuredset": "目玉商品 <%= name %>",
|
||||
"mysterySets": "ミステリーセット",
|
||||
"gearNotOwned": "このアイテムを持っていません。",
|
||||
"noGearItemsOfType": "この中のどれも持っていません。",
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
"battleGear": "Equipamento de Batalha",
|
||||
"gear": "Equipamento",
|
||||
"autoEquipBattleGear": "Auto-equipar novos equipamentos",
|
||||
"costume": "Disfarce",
|
||||
"costume": "Traje",
|
||||
"useCostume": "Usar Traje",
|
||||
"costumePopoverText": "Selecciona \"Usar Traje\" para equipares o teu avatar com itens sem afectar as Características do teu Equipamento de Batalha! Isto significa que à esquerda podes equipar-te para teres as melhores características e à direita podes vestir o teu avatar como preferires com o equipamento que tens disponível.",
|
||||
"autoEquipPopoverText": "Selecione esta opção para automaticamente equipar qualquer equipamento assim que o compre.",
|
||||
|
||||
@@ -90,36 +90,5 @@
|
||||
"faqQuestion39": "Onde posso encontrar mais Equipamentos?",
|
||||
"webFaqAnswer39": "Se quiser mais Equipamentos, você pode se tornar um Assinante Habitica, arriscar no Baú Encantado, ou se esbaldar durante uma Magnífica Festa de Gala do Habitica.\n\nOs assinantes do Habitica recebem um conjunto de equipamentos exclusivo todo mês, e Ampulhetas Místicas para comprar conjuntos de Equipamentos antigos na Loja do Viajante do Tempo.\n\nO Baú Encantado em suas Recompensas contém mais de 350 peças de Equipamentos! Por 100 Moedas, você terá a chance de receber Equipamentos especiais, Comida para transformar seu Animal de estimação em Montaria, ou Experiência para subir de nível!\n\nDurante as quatro Festas de Gala sazonais, novos Equipamentos para todas as classes se tornam disponíveis para compra com Moedas, e antigos conjuntos de Gala podem ser comprados com Gemas.",
|
||||
"webFaqAnswer40": "Gemas são a moeda paga do Habitica, usadas para comprar Equipamentos, Customizações de Personagem, Planos de Fundo, e muito mais! Gemas podem ser compradas em pacotes ou com Ouro se você é um Assinante Habitica. Você também pode ganhar gemas sendo selecionado como vencedor de um Desafio.",
|
||||
"faqQuestion41": "O que são Ampulhetas Místicas, e como consigo elas?",
|
||||
"webFaqAnswer43": "Para começa uma Missão, vai precisar de ser membro de um Grupo. Grupos podem ser aventuras a solo onde parte em Missões sozinho, ou pode convidar outros jogadores em Habitica para enfrentar Missões mais rápido!\n\nEscolha um Rolo de Missão do seu inventário ao selecionar o botão \"Começar Missão\" do seu Grupo. Complete as suas tarefas como faria normalmente para progredir na Missão! Ou vai acumular dano contra um monstro se estiver a fazer uma Missão com Boss, ou terá a chance de encontrar itens se estiver a fazer uma Missão de Colecionador. Todo o progresso pendente é aplicado no dia seguinte.\n\nQuando gera dano suficiente ou coleciona todos os itens, a Missão está completa e vai receber as suas recompensas!",
|
||||
"webFaqAnswer41": "Ampulhetas Místicas são a moeda de Subscritor exclusiva da Habitica usada na Loja dos Viajantes do Tempo! Ampulhetas são entregues num certo período baseado no seu plano de subscrição.\n\nPeríodo de entrega das Ampulhetas:\n * Subscritores de 1 Mês recebem 1 Ampulheta no início do mês depois do 3° pagamento consecutivo.\n * Subscritores de 3 Meses recebem 1 Ampulheta imediatamente após a subscrição, de seguida mais 1 Ampulheta no início do mês depois de cada renovação.\n * Subscritores de 6 Meses recebem 2 Ampulhetas imediatamente após a subscrição, de seguida mais 2 Ampulhetas no início do mês depois de cada renovação.\n * Subscritores de 12 Meses recebem 4 Ampulhetas imediatamente após a subscrição, de seguida mais 4 Ampulhetas no início do mês depois de cada renovação.",
|
||||
"faqQuestion43": "Como é que começo Missões?",
|
||||
"faqQuestion44": "Como é que apago tarefas de Desafio?",
|
||||
"faqQuestion42": "O que posso fazer para aumentar a minha responsabilidade?",
|
||||
"webFaqAnswer42": "Uma das melhores maneiras de se auto motivar e manter a responsabilidade de concluir as suas tarefas é juntar-se a um Grupo! Agrupar com outros jogadores em Habitica é uma ótima forma de partir em Missões para receber Animais de Estimação e Equipamento, receber \"buffs\" das habilidades de outros membros do Grupo, e aumentar a sua motivação.\n\nOutra forma de aumentar a responsabilidade é juntar-se a um Desafio. Desafios adicionam automaticamente tarefas relacionadas com um objetivo específico às suas listas! Também geram um elemento de competição contra outros jogadores em Habitica que o pode motivar enquanto luta pelo prémio em Gemas. Há desafios oficiais criados pela Equipa Habitica assim como Desafios feitos por outros jogadores.",
|
||||
"faqQuestion45": "O meu Avatar transformou-se num boneco de neve, estrela-do-mar, flor ou fantasma. Como posso voltar ao normal?",
|
||||
"faqQuestion46": "Como posso reportar um bug?",
|
||||
"parties": "Grupos",
|
||||
"webFaqAnswer44": "Vai precisar de abandonar o Desafio ou esperar que este seja fechado para poder apagar as tarefas associadas. Um ícone de megafone vermelho implica que o Desafio foi fechado e um megafone cinzento implica que o Desafio ainda está ativo.\n\nPara apagar tarefas de Desafio na app **Android**:\n 1. Toque na tarefa pertencente ao Desafio.\n 2. Toque em \"Apagar\" no canto superior direito do ecrã.\n 3. Escolha remover as tarefas de Desafio da sua lista de tarefas.\n\nPara apagar tarefas de Desafio na app **iOS**:\n 1. Encontre a tarefa de Desafio que quer apagar e olhe para o ícone do megafone.\n 2. Se o ícone do megafone estiver vermelho, toque na tarefa e selecione \"Apagar\" em baixo.\n 3. Se o ícone do megafone estiver cinzento, vai precisar de encontrar o Desafio e abandoná-lo para remover a tarefa.\n\nPara apagar tarefas de Desafio no **website**:\n 1. Encontre a tarefa de Desafio que deseja apagar e olhe para o ícone do megafone.\n 2. Se o ícone do megafone estiver vermelho, carregue nele e escolha remover as tarefas da sua lista de tarefas.\n\n Se o ícone do megafone estiver cinzento, vai precisar de encontrar o Desafio e abandoná-lo para remover a tarefa.",
|
||||
"webFaqAnswer45": "Um dos membros do seu Grupo usou um item de transformação da Loja Sazonal em si! O seu Personagem vai voltar ao normal no dia seguinte. Se quiser remover a transformação mais cedo, pode comprar um antídoto (Poção de Sal, Areia, Livre de Pétalas ou Opaca) das Recompensas.",
|
||||
"webFaqAnswer46": "Se acha que encontrou um bug, por favor avise-nos!\n\nPara reportar um bug nas aplicações móveis:\n * Do menu, selecione Apoio, carregue em \"Obter Ajuda\" e deslize para baixo para \"Reportar um Bug\"\n\nPara reportar um bug no website:\n * Do menu de Ajuda, selecione \"Reportar um Bug\"",
|
||||
"faqQuestion47": "Posso ver dados do quão bem tenho estado com as minhas tarefas e hábitos?",
|
||||
"webFaqAnswer47": "No momento, Habitica não tem uma representação visual dos seus dados das tarefas ao longo do tempo. No entanto, no website de Habitica, pode exportar os seus dados de tarefas do separador de Dados do Site nas Definições.",
|
||||
"faqQuestion48": "Posso jogar Habitica com outras pessoas?",
|
||||
"webFaqAnswer48": "Sim, com Grupos! Pode começar o seu próprio Grupo ou juntar-se a um já existente. Agrupar com outros jogadores em Habitica é uma ótima forma de partir em missões, receber \"buffs\" das habilidades de outros membros do Grupo, e aumentar a sua motivação com responsabilidade acrescida.",
|
||||
"faqQuestion49": "Como faço para encontrar um Grupo quando não estou em nenhum?",
|
||||
"webFaqAnswer49": "Se quiser experienciar Habitica com alguém mas não conhece outros jogadores, procurar um Grupo é a sua melhor opção! Se já conhece outros jogadores que tenham um Grupo, pode partilhar o seu @nome de usuário com eles para ser convidado. Alternativamente, pode criar um novo Grupo e convidá-los com os seus @nomes de usuário ou endereços de email.\n\nPara criar ou procurar um Grupo, selecione \"Grupo\" no menu de navegação, depois escolha a opção que funcionar para si.",
|
||||
"faqQuestion50": "Como funciona a procura por um Grupo?",
|
||||
"webFaqAnswer50": "Depois de selecionar \"Procurar um Grupo\", vai ser adicionado a uma lista de jogadores que se querem juntar a um Grupo. Líderes de Grupo pode ver esta lista e enviar convites. Quando receber um convite, pode aceitá-lo a partir das suas notificações para se juntar ao Grupo de sua escolha!\n\nPode receber vários convites para Grupos diferentes. Ainda assim, só pode ser membro de um Grupo de cada vez.",
|
||||
"faqQuestion51": "Por quanto tempo posso procurar um Grupo depois de me juntar à lista?",
|
||||
"webFaqAnswer51": "Vai ficar na lista até aceitar um convite para um Grupo ou não fazer log in por 7 dias, o que vier primeiro. Se fizer log in depois de estar inativo por 7 dias, vamos acicioná-lo automaticamente de volta à lista desde que não tenha um convite pendente.",
|
||||
"faqQuestion52": "Posso parar de procurar por um Grupo?",
|
||||
"webFaqAnswer52": "Se já não quiser encontrar um Grupo, pode parar de procurar a qualquer momento.\n\nPara parar de procurar um Grupo nas aplicações móveis:\n * Do menu, selecione \"Grupo\" e pressione \"Sair\" no fundo do ecrã.\n\nPara parar de procurar um Grupo no website de Habitica:\n * Selecione \"Grupo\" da navegação e clique em \"Sair\" na janela pop-up.",
|
||||
"faqQuestion53": "Tenho um Grupo, como encontro mais membros?",
|
||||
"webFaqAnswer53": "Se está a usar o website de Habitica, selecione \"Encontrar Membros\" do menu suspenso do Grupo. Se está a usar a app Android, toque em \"Encontrar Membros\" acima da lista de membros do Grupo. Isto vai mostrar uma lista de jogadores que estão ativamente à procura de um Grupo e que podem ser convidados para se juntarem.\n\nPara ajudá-lo a encontrar quem se ajuste ao seu Grupo, vai ver alguma informação, como idioma, classe, nível e quantos dias usaram Habitica. Caso queira conversar com alguém antes de enviar um convite, pode ver o seu Perfil e enviar uma mensagem.",
|
||||
"faqQuestion54": "Quantos membros posso convidar para o meu Grupo?",
|
||||
"webFaqAnswer54": "Grupos têm um limite máximo de 30 membros e um mínimo de 1 membro. Convites pendentes contam para o número de membros. Por exemplo, 29 membros e 1 convite pendente contaria como 30 membros. Para limpar um convite pendente, o jogador convidado tem de aceitar ou recusar, ou o líder do Grupo tem de cancelar o convite.",
|
||||
"faqQuestion55": "Posso convidar alguém que já conheço?",
|
||||
"webFaqAnswer55": "Sim! Se já tiver o nome de usuário ou endereço de email de um jogador de Habitica, pode convidá-lo a juntar-se ao seu Grupo. Aqui está como enviar um convite nas diferentes plataformas:\n\nPara convidar alguém nas aplicações móveis:\n 1. Do menu, selecione \"Grupo\" e deslize para baixo até à secção de Membros\n 2. Toque em \"Encontrar Membros\" e troque para o separador \"Por Convite\"\n 3. Insira os nomes de usuário ou endereços de email dos jogadores que quer convidar e clique em \"Enviar Convite\"\n\nPara convidar alguém no website:\n 1. Dirija-se ao seu Grupo e clique em \"Convidar para o Grupo\"\n 2. Insira os nomes de usuário ou endereços de email dos jogadores que quer convidar e clique em \"Enviar Convites\"",
|
||||
"faqQuestion56": "Como posso cancelar um convite pendente para o meu Grupo?"
|
||||
"faqQuestion41": "O que são Ampulhetas Místicas, e como consigo elas?"
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
"firstDrop": "Você liberou o Sistema de Drops! Agora quando completar tarefas, você terá uma pequena chance de encontrar um item, incluindo ovos, poções e comida! Você acabou de encontrar um <strong><%= eggText %>Ovo</strong>! <%= eggNotes %>",
|
||||
"hatchedPet": "Chocaste um(a) novo(a) <%= egg %> <%= potion %>!",
|
||||
"hatchedPetGeneric": "Chocaste uma nova mascote!",
|
||||
"hatchedPetHowToUse": "Visite o [Estábulo](<%= stableUrl %>) para alimentar e equipar o seu mais novo animal de estimação!",
|
||||
"hatchedPetHowToUse": "Visite o [Estábulo](<%= stableUrl %>) para alimentar e equipar a sua mais nova mascote!",
|
||||
"petNotOwned": "Não é o dono desta mascote.",
|
||||
"mountNotOwned": "Não tens esta montada.",
|
||||
"feedPet": "Alimentar o(a) <%= name %> com <%= text %>?",
|
||||
@@ -87,8 +87,8 @@
|
||||
"petsReleased": "Mascotes libertados.",
|
||||
"mountsAndPetsReleased": "Montadas e mascotes libertados",
|
||||
"mountsReleased": "Montarias libertadas",
|
||||
"welcomeStable": "Bem-Vindo às suas mascotes e montarias!",
|
||||
"welcomeStableText": "Bem-Vindo ao Estábulo! Eu sou o Matt, o Mestre das Bestas. Sempre que completar uma tarefa terá uma chance aleatória de receber um ovo ou poção de chocar para eclodir mascotes. Sempre que chocar um animal de estimação, ele irá aparecer aqui! Clique na imagem do Mascote para o adicionar ao seu avatar. Alimente-os com a comida e eles tornar-se-ão fortes montarias.",
|
||||
"welcomeStable": "Bem-Vindo ao Estábulo!",
|
||||
"welcomeStableText": "Bem-Vindo ao Estábulo! Eu sou o Matt, o Mestre de Bestas. Toda vez que você completar uma tarefa terá uma chance aleatória de receber um ovo ou poção de chocar para eclodir mascotes. Sempre que chocar um animal de estimação, ele irá aparecer aqui! Clique na imagem do Mascote para adicionar ao seu avatar. Alimente-os com a comida e eles se tornarão fortes montarias.",
|
||||
"petLikeToEat": "O que é que o meu animal de estimação gosta de comer?",
|
||||
"petLikeToEatText": "Mascotes crescerão não importa com o que você os alimentar, mas eles crescerão ainda mais rápido se você alimentá-los com a comida que eles preferem. Experimente até encontrar o padrão ou veja a resposta aqui: <br/><a href=\"https://habitica.fandom.com/pt-br/wiki/Food_Preferences\" target=\"_blank\">https://habitica.fandom.com/pt-br/wiki/Food_Preferences</a>",
|
||||
"filterByStandard": "Comum",
|
||||
@@ -115,6 +115,5 @@
|
||||
"invalidAmount": "Quantidade inválida de comida, deve ser um número inteiro positivo",
|
||||
"filterByWacky": "Maluco",
|
||||
"jubilantGryphatrice": "Gryphatrice Radiante",
|
||||
"veteranDragon": "Dragão Ancião",
|
||||
"veteranCactus": "Cato Ancião"
|
||||
"veteranDragon": "Dragão Ancião"
|
||||
}
|
||||
|
||||
@@ -246,7 +246,5 @@
|
||||
"contentAnswer53": "A Loja de Personalização estará ao lado das demais lojas do Menu.",
|
||||
"contentQuestion6": "O que acontecerá com outros eventos sazonais, como Habitoween, Dia da Mentira e Aniversário?",
|
||||
"contentAnswer02": "Novas <strong>Missões de Mascotes, Missões de Poções Mágicas de Eclosão e Poções Mágicas de Eclosão</strong> serão lançadas durante esta nova programação!",
|
||||
"contentAnswer01": "<strong>As Grandes Galas estão sendo estendidas</strong> para permanecerem ativas durante toda a temporada, junto com todos os equipamentos de Classe, personalizações de Avatar e outros itens exclusivos da estação.",
|
||||
"contentQuestion1": "Por que o Habitica está fazendo essas mudanças?",
|
||||
"contentAnswer12": "Os jogadores terão mais facilidade para completar suas coleções com os itens sendo lançados em um cronograma mais previsível."
|
||||
"contentAnswer01": "<strong>As Grandes Galas estão sendo estendidas</strong> para permanecerem ativas durante toda a temporada, junto com todos os equipamentos de Classe, personalizações de Avatar e outros itens exclusivos da estação."
|
||||
}
|
||||
|
||||
@@ -115,6 +115,5 @@
|
||||
"tooMuchFood": "Você está tentando dar muita comida para seu Mascote, ação cancelada",
|
||||
"notEnoughFood": "Você não tem comida suficiente",
|
||||
"jubilantGryphatrice": "Grifatriz Jubilante",
|
||||
"veteranDragon": "Dragão Veterano",
|
||||
"veteranCactus": "Cacto Veterano"
|
||||
"veteranDragon": "Dragão Veterano"
|
||||
}
|
||||
|
||||
@@ -351,7 +351,7 @@
|
||||
"questTurtleDropTurtleEgg": "Tartaruga (Ovo)",
|
||||
"questTurtleUnlockText": "Desbloqueia Ovos de Tartaruga para compra no Mercado",
|
||||
"questArmadilloText": "O Tatu Tolerante",
|
||||
"questArmadilloNotes": "É hora de sair de casa e começar o seu dia. Você tenta abrir sua porta, apenas para se dar conta de que ela ficou empacada no que parece ser uma camada de pedra. \"Eu só estou te dando o dia de folga!\", diz uma voz abafada através da porta bloqueada. \"Não seja tão estraga-prazeres, só relaxe hoje!\"<br><br>De repente, @Beffymaroo e @PainterPhophet batem na sua janela. \"Parece que o Tatu Tolerante gostou de você! Vamos, nós vamos te ajudar a tirá-lo do seu caminho!\"",
|
||||
"questArmadilloNotes": "É hora de ir lá fora e começar seu dia. Você abre a porta até ela bater em algo que parece uma parede de pedra. \"Eu só estou te dando um dia de folga!\" fala uma voz abafada através da porta bloqueada. \"Não fique reclamando, só relaxe hoje!\"<br><br>De repente, @Beffymaroo e @PainterPhophet batem na janela. \"Parece que que a Tatu Indulgente gostou de você! Vamos lá, nós vamos te ajudar a se livrar dela!\"",
|
||||
"questArmadilloCompletion": "Finalmente, após uma longa manhã tentando convencer o Tatu Tolerante que você quer, de fato, trabalhar, ele desiste. \"Me perdoe!\", ele se desculpa. \"Eu só queria ajudar. Eu achei que todo mundo gostasse de dias de preguiça!\"<br><br>Você sorri e explica pra ele que da próxima vez que você tiver um dia de folga, você vai convidá-lo. Ele sorri de volta. Os transeuntes @Tipsy e @krajzega te parabenizam pelo bom trabalho enquanto o tatu rola e vai embora, deixando alguns ovos como pedido de desculpas.",
|
||||
"questArmadilloBoss": "Tatu Tolerante",
|
||||
"questArmadilloDropArmadilloEgg": "Tatu (Ovo)",
|
||||
@@ -765,7 +765,7 @@
|
||||
"QuestPinkMarbleUnlockText": "Habilita a compra de Poções de Eclosão de Mármore Rosa pelo Mercado.",
|
||||
"questPinkMarbleUnlockText": "Desbloqueia Poções de Eclosão de Pérola Negra para compra no Mercado.",
|
||||
"questFungiRageEffect": "Uma névoa emana do Cogumelo Cabisbaixo e cerca seu grupo, deixando todos cabisbaixos e reprimindo sua magia. Os pontos de Mana do grupo são reduzidos!",
|
||||
"questFungiNotes": "Tem sido uma primavera chuvosa em Habitica e o solo ao redor dos estábulos está lamacento e cheio de poças. Você nota que alguns cogumelos começaram a crescer ao longo das paredes e cercas de madeira do estábulo. Há uma névoa pairando por todo lugar, impedindo o sol de aparecer, e isso é um pouco desanimador.<br><br>Dos limites da névoa você vê surgir o contorno do Piadista, nem um pouco saltitante como de costume.<br><br>\"Eu esperava trazer para todo mundo algumas adoráveis Poções Mágicas de Eclosão do Reino dos Fungos... Para que vocês pudessem manter seus amigos cogumelos do meu dia especial, o Primeiro de Abril, para sempre\", ele diz, sua expressão alarmantemente séria. \"Mas esta névoa fria está realmente enevoando minha mente, fazendo com que eu me sinta cansado e triste demais para trabalhar na minha mágica habitual.\"<br><br>\"Ah, não, sinto muito por ouvir isso\", você diz, percebendo seu próprio desânimo tornar-se cada vez mais intenso. \"Esta névoa está realmente deixando o dia sombrio. Eu me pergunto de onde veio…\"<br><br>Um estrondo baixo ecoa pelos campos e você nota um contorno emergindo da névoa. Você se espanta ao deparar-se com uma gigante e cabisbaixa criatura em forma de cogumelo... E a névoa parece estar emanando dela.<br><br>\"Ahá!\", diz o Piadista, \"Eu acredito que este champignon gigante pode ser a razão de toda a nossa tristeza. Vamos ver se conseguimos trazer um pouco de alegria para o nosso amigo aqui - e para nós mesmos!\"",
|
||||
"questFungiNotes": "Tem sido uma primavera chuvosa em Habitica e o solo ao redor dos estábulos está lamacento e cheio de poças. Você percebe que alguns cogumelos começaram a crescer ao longo das paredes e cercas de madeira do estábulo. Há uma névoa pairando por todo lugar que impede o sol de aparecer e isso é um pouco desanimador.<br><br>Dos limites da névoa você vê surgir o contorno do Piadista, nem um pouco saltitante como de costume.<br><br>\"Eu esperava trazer para todo mundo algumas encantadoras Poções Mágicas de Eclosão do Reino dos Fungos... Para que vocês pudessem manter seus amigos cogumelos do meu dia especial, o Primeiro de Abril, para sempre\", ele diz, sua expressão alarmantemente séria. \"Mas esta névoa fria está realmente entrando na minha mente, fazendo com que eu me sinta cansado e triste demais para trabalhar na minha mágica habitual.\"<br><br>\"Ah, não, sinto muito por ouvir isso\", você diz, percebendo seu próprio humor passando a tornar-se cada vez mais melancólico. \"Esta névoa está realmente deixando o dia sombrio. Eu me pergunto de onde veio…\"<br><br>Um estrondo baixo ecoa pelos campos e você nota um contorno emergindo da névoa. Você se espanta ao deparar-se com uma criatura gigante e cabisbaixa em forma de cogumelo... E a névoa parece estar emanando dela.<br><br>\"Ahá!\", diz o Piadista, \"Eu acho que este champignon gigante pode ser a razão de toda a nossa tristeza. Vamos ver se conseguimos trazer um pouco de alegria para o nosso amigo aqui - e para nós mesmos!\"",
|
||||
"questFungiText": "O Cogumelo Cabisbaixo",
|
||||
"questFungiBoss": "Cogumelo Cabisbaixo",
|
||||
"questFungiRageTitle": "Névoa do Cogumelo Cabisbaixo",
|
||||
|
||||
@@ -189,10 +189,5 @@
|
||||
"notEnoughGold": "Недостаточно золота.",
|
||||
"chatCastSpellPartyTimes": "<%= username %> бросает <%= spell %> для команды <%= times %> времени.",
|
||||
"chatCastSpellUserTimes": "<%= username %> применяет <%= spell %> на <%= target %> <%= times %> раз.",
|
||||
"nextReward": "Награда за следующий вход",
|
||||
"skins": "Внешний вид",
|
||||
"titleFacialHair": "Борода и усы",
|
||||
"titleHaircolor": "Цвет волос",
|
||||
"titleHairbase": "Прическа",
|
||||
"customizations": "Стили"
|
||||
"nextReward": "Награда за следующий вход"
|
||||
}
|
||||
|
||||
@@ -2994,7 +2994,7 @@
|
||||
"weaponArmoirePottersWheelNotes": "Бросьте немного глины на это колесо и сделайте миску, кружку, вазу или немного другую миску. Если вам повезет, во время творения вас может посетить призрак! Увеличивает восприятие на <%= за %>. Зачарованный шкаф: гончарный набор (предмет 4 из 4).",
|
||||
"weaponMystery202403Text": "Счастливый Изумрудный Меч",
|
||||
"weaponArmoireShadyBeachUmbrellaText": "Пляжный зонт",
|
||||
"weaponArmoireShadyBeachUmbrellaNotes": "Тень этого радужного зонтика ненадолго скроет вас от дневной звезды и нежелательных беспокойств. Увеличивает восприятие на <%= per %>. Зачарованный шкаф: пляжный набор (предмет 3 из 4).",
|
||||
"weaponArmoireShadyBeachUmbrellaNotes": "Тень этого радужного зонтика ненадолго скроет вас от дневной звезды и нежелательных беспокойств. Увеличивает восприятие на <%= за %>. Зачарованный шкаф: пляжный набор (предмет 3 из 4).",
|
||||
"weaponSpecialSpring2024RogueText": "Серебряный клинок",
|
||||
"weaponSpecialSpring2024RogueNotes": "Проблемы, твердые, как лед, можно разрезать на более мелкие кусочки. Увеличивает силу на <%= str %>. Ограниченное издание весеннего снаряжения 2024 г.",
|
||||
"weaponSpecialSpring2024WarriorText": "Флюоритовое копье",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"dataTool": "Анализ данных (англ.)",
|
||||
"resources": "Ресурсы",
|
||||
"communityGuidelines": "Правила сообщества",
|
||||
"bannedWordUsed": "Ой! Кажется, ваше сообщение содержит нецензурную лексику, упоминание запрещённых веществ или взрослую тематику (<%= swearWordsUsed %>). Habitica поддерживает чистоту общения. Пожалуйста, исправьте ваше сообщение и попробуйте отправить его снова! Вы должны удалить слово, а не просто цензурировать его.",
|
||||
"bannedWordUsed": "Упс, что-то пошло не так! Кажется, ваше сообщение содержит нецензурную лексик, упоминание запрещённых веществ или контент для взрослых (<%= swearWordsUsed %>). Хабитикой пользуется аудитория всех возрастов, поэтому мы стараемся быть приятными и безопасными для всех. Пожалуйста, исправьте ваше сообщение и после этого отправьте его снова! Вы должны удалить слово, а не просто отредактировать.",
|
||||
"bannedSlurUsed": "Ваша запись содержала несоответствующие выражения, поэтому ваши привилегии в чате были отменены.",
|
||||
"party": "Команда",
|
||||
"usernameCopied": "Имя пользователя скопировано в буфер обмена.",
|
||||
@@ -87,7 +87,7 @@
|
||||
"PMDisabledCaptionText": "Вы все еще можете отправлять личные сообщения, но никто не может сможет на них вам ответить.",
|
||||
"block": "Заблокировать игрока",
|
||||
"unblock": "Разблокировать",
|
||||
"blockWarning": "Не сработает, если игрок является администратором.",
|
||||
"blockWarning": "Блокировка - Если данный игрок сейчас является модератором или станет модератором в будущем, то блокировка перестанет действовать.",
|
||||
"inbox": "Почта",
|
||||
"messageRequired": "Требуется сообщение.",
|
||||
"toUserIDRequired": "Tребуется ID пользователя",
|
||||
@@ -98,10 +98,10 @@
|
||||
"badAmountOfGemsToSend": "Сумма должна быть в пределах 1 и текущего количества самоцветов.",
|
||||
"report": "Пожаловаться",
|
||||
"abuseFlagModalHeading": "Сообщить о нарушении",
|
||||
"abuseFlagModalBody": "Сообщайте о публикации только в том случае, если она нарушает <%= firstLinkStart %>Правила сообщества<%= linkEnd %> и/или <%= secondLinkStart %>Условия использования<%= linkEnd %>. Ложная жалоба на публикацию является нарушением Правил сообщества Habitica.",
|
||||
"abuseFlagModalBody": "Вы уверены, что хотите пожаловаться на это сообщение? Вы можете пожаловаться <strong>только</strong> на сообщения, нарушающие <%= firstLinkStart %>Правила сообщества<%= linkEnd %> и/или <%= secondLinkStart %>Условия предоставления сервиса<%= linkEnd %>. Некорректная жалоба является нарушением Правил сообщества и может стать поводом для вынесения предупреждения.",
|
||||
"abuseReported": "Спасибо, что сообщили об этом нарушении. Модераторы уведомлены.",
|
||||
"whyReportingPost": "Почему вы сообщаете об этом посте?",
|
||||
"whyReportingPostPlaceholder": "Причина жалобы",
|
||||
"whyReportingPostPlaceholder": "Пожалуйста, помогите нашим модераторам, уточнив причину жалобы на данный пост, например: спам, ругань, религиозные оскорбления, сектантство, брань, темы для взрослых, насилие.",
|
||||
"optional": "Дополнительное сообщение",
|
||||
"needsTextPlaceholder": "Напечатайте сообщение здесь.",
|
||||
"copyMessageAsToDo": "Скопировать сообщение как Задачу",
|
||||
@@ -222,7 +222,7 @@
|
||||
"groupPolicyCannotGetGems": "Правила группы, в которой вы состоите, не разрешают приобретать самоцветы членам группы.",
|
||||
"viewParty": "Посмотреть команду",
|
||||
"newGuildPlaceholder": "Введите название вашей Команды.",
|
||||
"guildBank": "Банк",
|
||||
"guildBank": "Банк гильдии",
|
||||
"chatPlaceholder": "Введите здесь сообщение для членов группы",
|
||||
"partyChatPlaceholder": "Введите здесь сообщение для членов команды",
|
||||
"fetchRecentMessages": "Обновить чат",
|
||||
@@ -235,14 +235,14 @@
|
||||
"emailOrUsernameInvite": "Адрес электронной почты или имя пользователя",
|
||||
"messageGuildLeader": "Написать главе группы",
|
||||
"donateGems": "Пожертвовать самоцветы",
|
||||
"updateGuild": "Обновить команду",
|
||||
"updateGuild": "Обновить гильдию",
|
||||
"viewMembers": "Посмотреть участников",
|
||||
"memberCount": "Количество участников",
|
||||
"recentActivity": "Недавние действия",
|
||||
"myGuilds": "Мои гильдии",
|
||||
"guildsDiscovery": "Найти гильдии",
|
||||
"role": "Класс",
|
||||
"guildLeader": "Глава команды",
|
||||
"guildLeader": "Глава гильдии",
|
||||
"member": "Участник",
|
||||
"guildSize": "Размер Команды",
|
||||
"goldTier": "Золотой ранг",
|
||||
@@ -250,8 +250,8 @@
|
||||
"bronzeTier": "Бронзовый ранг",
|
||||
"privacySettings": "Настройки конфиденциальности",
|
||||
"onlyLeaderCreatesChallenges": "Только предводитель может создавать испытания",
|
||||
"onlyLeaderCreatesChallengesDetail": "Если эта опция выбрана, обычные участники команды не смогу создавать испытания внутри команды.",
|
||||
"privateGuild": "Закрытая группа",
|
||||
"onlyLeaderCreatesChallengesDetail": "Выбрав эту опцию, участники команды не смогу создавать Испытания внутри команды.",
|
||||
"privateGuild": "Закрытая гильдия",
|
||||
"charactersRemaining": "<%= characters %> символов осталось",
|
||||
"guildSummary": "Сводка о гильдии",
|
||||
"guildSummaryPlaceholder": "Напишите краткое описание вашей гильдии для других жителей страны Habitica. В чём главный смысл вашей гильдии и почему люди должны вступать в неё? Старайтесь включать полезные ключевые слова в описании, чтобы другие жители страны Habitica могли легко найти эту гильдию, когда будут её искать!",
|
||||
@@ -439,8 +439,5 @@
|
||||
"tavernDiscontinued": "Таверна и гильдии были распущены",
|
||||
"tavernDiscontinuedLinks": "Прочитать более подробно о <a href='/static/faq/tavern-and-guilds'>прекращении действия услуг таверн и гильдий</a> или вернитесь на <a href='/'>homepage</a>.",
|
||||
"challengeBannedWords": "Ваше испытание содержит ругательство или ссылку на тему для взрослых. Пожалуйста, отредактируйте свое Испытание, чтобы сохранить его. Вы должны убрать запретные слова, а не просто цензурировать их.",
|
||||
"bannedUser": "<strong>Этот игрок был забанен.</strong>",
|
||||
"challengeBannedSlurs": "В вашем испытании содержится оскорбительное выражение, которое нарушает правила сообщества Habitica. Ваши права на общение в чате и создание испытаний были отозваны. Для получения дополнительной информации свяжитесь с администратором по адресу admin@habitica.com.",
|
||||
"challengeBannedSlursPrivate": "В вашем испытании содержится оскорбительное выражение, которое нарушает правила сообщества Habitica. Пожалуйста, удалите его, чтобы сохранить ваше испытание.",
|
||||
"blockedUser": "<strong>Вы заблокировали этого игрока.</strong> Они не могут отправлять вам личные сообщения, но вы всё равно будете видеть их публикации."
|
||||
"bannedUser": "<strong>Этот игрок был забанен.</strong>"
|
||||
}
|
||||
|
||||
@@ -497,7 +497,7 @@
|
||||
"questMayhemMistiflying3DropShield": "Шутливый радужный конверт (для защитной руки)",
|
||||
"questMayhemMistiflying3DropWeapon": "Шутливый радужный конверт (оружие)",
|
||||
"featheredFriendsText": "Набор квестов «Пернатые друзья»",
|
||||
"featheredFriendsNotes": "Содержит квесты «Помогите! Гарпия!», «Сова-полуночница» и «Птицы прокрастинации».",
|
||||
"featheredFriendsNotes": "Содержит квесты «Помогите! Гарпия!», «Сова-полуночница» и «Птицы прокрастинации». Доступен до <%= date %>.'",
|
||||
"questNudibranchText": "Заражение мотивирующими морскими слизнями",
|
||||
"questNudibranchNotes": "Вы, наконец, в один ленивый день в Habitica собрались проверить свой список дел. Броские пятна напротив ваших самых красных задач - это стая трепещущих синих морских слизней. Вы в восторге! Их сапфировые цвета делают ваши самые устрашающие задачи такими же легкими, как ваши лучшие привычки. В лихорадочном оцепенении вы начинаете работать, решая одну задачу за другой в непрерывном безумии ...<br><br>Последующее, что вы осознаете это то, как @LilithofAlfheim обливает вас холодной водой. «Мотивирующие морские слизни поразили вас повсюду! Вам необходимо передохнуть!»<br><br>Потрясенный, вы видите, что ваша кожа такая же ярко-красная, каким был ваш список дел. «Быть продуктивным - это одно, — говорит @beffymaroo, — но вы также должны заботиться и о себе. Поторопитесь скорее избавиться от них!»",
|
||||
"questNudibranchCompletion": "Вы видите как последние из морских слизней сползают с кучи завершенных задач, поскольку @amadshade смывает их проч. Один оставляет после себя тканевой мешок. Вы открываете его, чтобы обнаружить немного золота и несколько маленьких эллипсоидов, которые как вы предполагаете, яйца.",
|
||||
@@ -505,7 +505,7 @@
|
||||
"questNudibranchDropNudibranchEgg": "Морской слизень (яйцо)",
|
||||
"questNudibranchUnlockText": "Позволяет покупать на рынке морского слизня в яйце",
|
||||
"splashyPalsText": "Набор квестов «Плескающиеся друзья»",
|
||||
"splashyPalsNotes": "Содержит «Ежегодные скачки в Промедлении», «Помоги черепахе найти дорогу» и «Вой кита».",
|
||||
"splashyPalsNotes": "Содержит «Ежегодные скачки в Промедлении», «Помоги черепахе найти дорогу» и «Вой кита». Доступен до <%= date %>.",
|
||||
"questHippoText": "Что за Гиппо-Ханжа",
|
||||
"questHippoNotes": "Вы с @awesomekitty развалились в тени пальмы, изнуренные. Знойное Солнце, поднявшись над Слонопотамской Саванной, испепеляет земли внизу. До сих пор это был продуктивный день выполнения ваших ежедневных дел, и оазис ниже выглядит хорошим местом для перерыва и восстановления сил. Склоняясь рядом с водой, чтобы попить, вы спотыкаетесь в шоке от массивного, поднимающегося из воды гиппопотамуса. «Уже дрыхнете так скоро? Не будьте ленивыми, возвращайтесь к работе». Вы пытаетесь возразить, что вы тяжело работали и необходим перерыв, но бегемота не переубедить.<br><br>@hdarkwolf шепчет вам: «Заметь, как он бездельничает весь день, но имеет наглость назвать вас ленивым? Что за Ханжа!»<br><br>Ваш друг @jumorales кивает. «Давайте покажем ему, как выглядит тяжелая работа!»",
|
||||
"questHippoCompletion": "Бегемот кланяется, отступая. «Я вас недооценил. Кажется, вы не ленились. Мои извинения. По правде говоря, я, возможно, немного проецировал. Возможно, я должен сам проделать определенную работу. Вот, возьмите эти яйца в знак моей благодарности.» Схватив их, вы располагаетесь у воды, готовые наконец расслабиться.",
|
||||
@@ -513,9 +513,9 @@
|
||||
"questHippoDropHippoEgg": "Бегемот (яйцо)",
|
||||
"questHippoUnlockText": "Позволяет покупать на рынке бегемота в яйце",
|
||||
"farmFriendsText": "Набор квестов «Друзья фермера»",
|
||||
"farmFriendsNotes": "Содержит квесты «Корова-муутант», «Прокатись на Лошмаре!» и «Грозовой баран».",
|
||||
"farmFriendsNotes": "Содержит квесты «Корова-муутант», «Прокатись на Лошмаре!» и «Грозовой баран». Доступен до <%= date %>.",
|
||||
"witchyFamiliarsText": "Набор квестов «Фамильяры колдуньи»",
|
||||
"witchyFamiliarsNotes": "Содержит квесты «Крысиный король», Ледяной Арахнид» и «Болото Лягушки Беспорядка».",
|
||||
"witchyFamiliarsNotes": "Содержит квесты «Крысиный король», Ледяной Арахнид» и «Болото Лягушки Беспорядка». Доступен до <%= date %>.",
|
||||
"questGroupLostMasterclasser": "Тайна ордена Мастеров",
|
||||
"questUnlockLostMasterclasser": "Чтобы открыть этот квест, завершите финальные квесты в сериях «Бедствие Промедления», «Беспредел в Летящей дымке», «Стойкальмское бедствие» и «Ужас Трудобора».",
|
||||
"questLostMasterclasser1Text": "Тайна ордена Мастеров, часть 1: Чтение сквозь строки",
|
||||
@@ -559,7 +559,7 @@
|
||||
"questYarnDropYarnEgg": "Пряжа (яйцо)",
|
||||
"questYarnUnlockText": "Позволяет покупать на рынке пряжу в яйце",
|
||||
"winterQuestsText": "Зимний набор квестов",
|
||||
"winterQuestsNotes": "Содержит квесты «Санта-зверолов», «Найти детеныша» и «Птичий холод». Обратите внимание, что квесты «Санта-зверолов» и «Найти детеныша» имеют накопительные достижения, но в награду выдают редкого питомца и скакуна только один раз.",
|
||||
"winterQuestsNotes": "Содержит квесты «Санта-зверолов», «Найти детеныша» и «Птичий холод». Доступен до <%= date %>. Обратите внимание, что квесты «Санта-зверолов» и «Найти детеныша» имеют накопительные достижения, но в награду выдают редкого питомца и скакуна только один раз.",
|
||||
"questPterodactylText": "Птеррор-дактиль",
|
||||
"questPterodactylNotes": "Вы гуляете по мирным скалам Стойкальма, когда злой визг раздирает воздух. Поворачиваясь, вы находите летящее к вам отвратительное существо, наполненное веской угрозой. Когда вы поворачиваетесь, чтобы бежать, @Lilith из Альвхейма захватывает вас. «Не паникуйте, это просто Птеррор-дактиль».<br><br>@Procyon P кивает. «Они гнездятся рядом, но их привлекает запах негативных привычек и не сделанных ежедневных дел».<br><br>«Не волнуйся, - говорит Кэти133. «Нам просто нужно быть более продуктивным, чтобы победить его!» Вы наполнены новым чувством цели и поворачиваетесь лицом к своему врагу.",
|
||||
"questPterodactylCompletion": "С одним последним визгом Птеррор-дактиль падает на обочину скалы. Вы бежите вперед, чтобы посмотреть, как он парит в отдаленных степях. «Фу, я рад что все закончилось», - говорите вы. «Я тоже», - отвечает @GeraldThePixel. «Но смотри, у нас осталось несколько яиц». @Edge передает вам три яйца, и вы клянетесь, чтобы поднять их в тишине, в окружении положительных привычек и синих ежедневных дел.",
|
||||
@@ -594,7 +594,7 @@
|
||||
"questDysheartenerDropHippogriffMount": "Обнадеживающий гиппогриф (скакун)",
|
||||
"dysheartenerArtCredit": "Графика от @AnnDeLune",
|
||||
"hugabugText": "Набор квестов «Объятия бага»",
|
||||
"hugabugNotes": "Содержит «КРИТИЧЕСКИЙ БАГ», «Моллюск из подземелья Тяжелого труда» и «Пока, пока, бабочка».",
|
||||
"hugabugNotes": "Содержит «КРИТИЧЕСКИЙ БАГ», «Моллюск из подземелья Тяжелого труда» и «Пока, пока, бабочка». Доступен до <%= date %>.'",
|
||||
"questSquirrelText": "Подлая белка",
|
||||
"questSquirrelNotes": "Вы просыпаетесь и понимаете, что проспали! Почему не прозвенел будильник? ... Каким образом желудь оказался в нем?<br><br>Когда вы пытаетесь приготовить завтрак, тостер оказывается также забит желудями. Когда отправляетесь за ездовым животным, @Shtut в стойлах не может открыть замок от конюшни. Они посмотрели в замочную скважину: «Это что, желудь там?» @Randomdaisy выкрикивает: «Нет! Я знал, что мои белки убежали, но не думал, что они на такое способны! Помогите мне обхитрить их, прежде чем они сотворят еще один беспорядок?» Следуя по тропе из ореховой скорлупы, вы находите и ловите своенравных зверьков, вместе с @Cantras, чтобы безопасно перенести каждого домой. Но когда вы думаете, что ваша задача почти завершена, желудь звонко отскакивает от вашего шлема! Вы смотрите наверх, и видите свирепого зверя-белку, сидящего в защиту на огромной кучи припасов. «О, боже, — тихо сказала @randomdaisy. — Этот зверь что-то вроде хранителя ресурсов. Мы должны действовать очень осторожно!» Вы смыкаете строевой круг с командой, готовясь к неприятностям!",
|
||||
"questSquirrelCompletion": "С деликатным подходом, уговаривая на сделку и несколькими успокаивающими заклинаниями вы уговариваете белку отказаться от своего клада и вернуться в свой домик, который @Shtut только что доделал. Они оставили несколько желудей на верстаке. «Это яйца с белками! Может быть, вы сможете вырастить их и научить хорошим манерам без игры с едой.»",
|
||||
@@ -618,7 +618,7 @@
|
||||
"questKangarooDropKangarooEgg": "Кенгуру (яйцо)",
|
||||
"questKangarooUnlockText": "Позволяет покупать на рынке кенгуру в яйце",
|
||||
"forestFriendsText": "Набор квестов «Лесная братва»",
|
||||
"forestFriendsNotes": "Содержит квесты «Дух весны», «Еж-монстр» и «Запутанное дерево».",
|
||||
"forestFriendsNotes": "Содержит квесты «Дух весны», «Еж-монстр» и «Запутанное дерево». Акция доступна до <%= date %>.",
|
||||
"questAlligatorText": "Олег-атор",
|
||||
"questAlligatorNotes": "«Боже мой! — Восклицает @gully. — Олег-атор в своей естественной среде обитания! Осторожно, он отвлекает от важных задач, а питается он вашими не отмеченными Ежедневными заданиями, которые должны развивать вас». Вы замолкаете, чтобы не накликать беды, но безуспешно. Олег-атор видит вас и бросается с яростью! Отвлекающие голоса доносятся из Болота Застоя от Олега, заставляя обратить внимание: «Читайте посты в ВК! Смотрите фото котят! Обратите внимание на ОЛЕГА!» Вы запрыгиваете на своего скакуна, чтобы контратаковать, завершив свои Ежедневные задачи и выполняя хорошие привычки, чтобы дать отпор Олег-атору.",
|
||||
"questAlligatorCompletion": "С повышенным вниманием к действительно важными вещам, а не забавам Олег-атора, от проигранного боя он уплывает прочь. Победа! «Это что, его яйца? Они похожи на яйца аллигатора», — спрашивает @mfonda. «Если мы будем заботиться о них с любовью, то они будут верными питомцами или скакунами», — отвечает @UncommonCriminal, передавая вам три яйца. Будем надеяться, что Олег-атор не вернутся…",
|
||||
@@ -626,7 +626,7 @@
|
||||
"questAlligatorDropAlligatorEgg": "Аллигатор (яйцо)",
|
||||
"questAlligatorUnlockText": "Позволяет покупать на рынке аллигатора в яйце",
|
||||
"oddballsText": "Набор квестов «Чудные шары»",
|
||||
"oddballsNotes": "Содержит квесты «Желейный регент», «Побег от пещерного чудища» и «Спутанная пряжа».",
|
||||
"oddballsNotes": "Содержит квесты «Желейный регент», «Побег от пещерного чудища» и «Спутанная пряжа». Доступен до <%= date %>.",
|
||||
"birdBuddiesText": "Набор квестов «Пернатые друзья»",
|
||||
"birdBuddiesNotes": "Содержит квесты «Птичий холод», «Петушиное буйство» и «Павлин Тяни-Толкай».",
|
||||
"questVelociraptorText": "Велоци-рэпер",
|
||||
@@ -636,7 +636,7 @@
|
||||
"questVelociraptorDropVelociraptorEgg": "Велоцираптор (яйцо)",
|
||||
"questVelociraptorUnlockText": "Позволяет покупать на рынке велоцираптора в яйце",
|
||||
"mythicalMarvelsText": "Набор квестов «Фантастические твари»",
|
||||
"mythicalMarvelsNotes": "Включает квесты «Убедите Королеву Единорогов», «Огненный грифон» и «Беда в глубинах: Нападение морского змея!»",
|
||||
"mythicalMarvelsNotes": "Включает квесты «Убедите Королеву Единорогов», «Огненный грифон» и «Беда в глубинах: Нападение морского змея!» Доступен до <%= date %>.",
|
||||
"questBronzeText": "Битва с бронзовым жуком",
|
||||
"questBronzeNotes": "В качестве освежающего перерыва от выполнения задач вы с друзьями отправляетесь на прогулку по лесным тропам Трудобора и находите большое полое бревно с яркой искоркой внутри, которая привлекает ваше внимание.<br><br>Да ведь это тайник с волшебными инкубационными эликсирами! Переливающаяся бронзовая жидкость мягко кружится в бутылках, и @Hachiseiko достает одну из них, чтобы рассмотреть поближе.<br><br>«Стой!» - шипит голос позади вас. Это гигантский жук с блестящим бронзовым панцирем, поднимающий когтистые конечности в боевой стойке. «Это мои зелья, и если ты хочешь их заработать, ты должен проявить себя в дуэли!»",
|
||||
"questBronzeCompletion": "«Хорошая попытка, воин!» говорит жук, опускаясь на землю. Он улыбается? Трудно понять по этим мандибулам. «Ты действительно достоин этих эликсиров!»<br<br>«Ого, раньше мы никогда не получали такую награду за победу в битве!» говорит @UncommonCriminal, крутя сверкающую бутылку в руках. «Давайте выведем новых питомцев!»",
|
||||
@@ -657,7 +657,7 @@
|
||||
"questSilverUnlockText": "Позволяет покупать на рынке серебряные инкубационные эликсиры",
|
||||
"questSilverNotes": "В Habitica все только и говорят о недавнем открытии бронзовых инкубационных эликсиров. Возможны ли эликсиры ещё более ярких металлов? Вы отправляетесь в центральную публичную библиотеку города Habit вместе с @QuartzFox и @starsystemic, и начинаете штудировать всё, что связано с алхимией.<br><br>После нескольких часов тяжелого труда @QuartzFox издает не совсем подходящий для библиотеки триумфальный крик: «Ага! Я нашла!» Вы подбегаете к ней. «Серебряный инкубационный эликсир может быть приготовлен из зодиакальных рун рака, растворенных в чистом серебре, расплавленном над пламенем, наполненном силой лунных рун.»<br><br>«Нам потребуется побольше этих ингредиентов, — размышляет @starsystemic. —На случай, если что-то пойдет не так».<br><br>«Существует только одно место, где можно найти большое количество таких разных составляющих, — говорит @Edge, стоя в тени стеллажей со скрещенными руками. Он был там все это время? — Подземелье Тяжелого труда. Пойдемте.»",
|
||||
"questSilverCompletion": "Вы рыли. Вы копали. Вы расчищали. Наконец, вы выходите из подземелья, нагруженные рунами и серебряными слитками, покрытые грязью, но бодрые от успеха. Вы возвращаетесь в Habit City и продолжаете работу в алхимической лаборатории. Вы с @starsystemic следуете формулам, которые нашла @QuartzFox, под чутким руководством @Edge. И наконец, в большой струе блесток и дыма ваша смесь принимает хорошо знакомую вязкость инкубационного эликсира!<br><br>@Edge наливает смесь во флаконы и ухмыляется: «Давайте попробуем? У кого-нибудь есть яйца?»<br><br>Вы устремляетесь к стойлам, задаваясь вопросом, какие блестящие тайны еще остаются неразгаданными...",
|
||||
"rockingReptilesNotes": "Содержит квесты «Олег-атор», «Змей Безумия» и «Велоци-рэпер».",
|
||||
"rockingReptilesNotes": "Содержит квесты «Олег-атор», «Змей Безумия» и «Велоци-рэпер». Доступен до <%= date %>.",
|
||||
"rockingReptilesText": "Набор квестов «Скальные рептилии»",
|
||||
"questRobotUnlockText": "Позволяет покупать на рынке робота в яйце",
|
||||
"questRobotDropRobotEgg": "Робот (яйцо)",
|
||||
@@ -667,7 +667,7 @@
|
||||
"questRobotCompletion": "Когда @Rev и Ответственный приятель устанавливают последний болт на место, машина времени оживает. @FolleMente и @McCoyly запрыгивают на борт. «Спасибо за помощь! Увидимся в будущем! Кстати, это поможет вам в следующем изобретении!» — при этом путешественники во времени исчезают, но в обломках старого стабилизатора продуктивности остаются три заводных яйца. Возможно, это будут ключевые составляющие для новой версии Ответственных приятелей!",
|
||||
"questRobotNotes": "В Лабораториях Максимальных способностей, @Rev завершает работу над своим новейшим изобретением, роботизированным Ответственным приятелем, когда странное металлическое транспортное средство внезапно появляется в потоке дыма в нескольких сантиметрах от датчика флуктуаций робота! Из него выходят две чудные фигуры в серебре и снимают с себя космические шлемы. Оказывается, что это @FolleMente и @McCoyly.<br><br>«Я предполагаю, что мы неправильно реализовали нашу продуктивность», — смущенно говорит @FolleMente.<br><br>@McCoyly скрещивает руки: «Это значит, что они не выполняли свои ежедневные задания, что, как я полагаю, привело к распаду нашего стабилизатора продуктивности. Это важная составляющая путешествий во времени, для правильной работы которой необходима последовательность. Наши успехи стимулируют движение сквозь пространство и время! У меня больше нет времени объяснять, @Rev. Вы узнаете об этом через 37 лет, или, возможно, вам смогут помочь мистические путешественники во времени. А пока можете помочь починить нашу машину времени?»",
|
||||
"questRobotText": "Таинственные механические чудеса!",
|
||||
"delightfulDinosNotes": "Содержит квесты «Птеррор-дактиль», «Топот трицератопса» и «Динозавра раскопали!».",
|
||||
"delightfulDinosNotes": "Содержит квесты «Птеррор-дактиль», «Топот трицератопса» и «Динозавра раскопали!». Доступен до <%= date %>.",
|
||||
"delightfulDinosText": "Набор квестов «Восхитительные динозавры»",
|
||||
"questAmberUnlockText": "Позволяет покупать на рынке янтарные инкубационные эликсиры",
|
||||
"questAmberDropAmberPotion": "Янтарный инкубационный эликсир",
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"marketing3Lead2Title": "Integrácie",
|
||||
"marketing3Lead2": "Ďalšie**3. stranné nástroje** prispôsobujú Habiticu rôznym aspektom tvojho života. Naše API poskytuje jednoduchú integráciu napr. pre [Chrome Extension](https://chrome.google.com/webstore/detail/habitica/pidkmpibnnnhneohdgjclfdjpijggmjj?hl=en-US), pri ktorom strácaš body keď si prehliadaš neproduktívne webové stránky, a naopak body získavaš, pri prehliadaní tých produktívnych. [Zisti viac](https://habitica.fandom.com/wiki/Extensions,_Add-Ons,_and_Customizations).",
|
||||
"marketing4Header": "Použitie na organizovanie",
|
||||
"marketing4Lead1": "Vzdelávanie je jednou z najlepších oblastí pre gemifikáciu. Všetci dobre vieme ako sú študenti v týchto dňoch doslova prilepený k mobilom a počítačovým hrám; využite túto silu! Zapojte svojich študentov do priateľského súťaženia. Odmeňte ich dobré správanie cennými odmenami a pozorujte ako sa ich známky a správanie zlepšuje.",
|
||||
"marketing4Lead1": "Education is one of the best sectors for gamification. We all know how glued to phones and games students are these days; harness that power! Pit your students against each other in friendly competition. Reward good behavior with rare prizes. Watch their grades and behavior soar.",
|
||||
"marketing4Lead1Title": "Gamifikácia vo výučbe",
|
||||
"marketing4Lead2": "Zdravotná starostlivosť niečo stojí, no nie sme o nič zdravší. Vznikajú stovky programov na zníženie ceny a zlepšenie zdravia. Veríme, že Habitica môže vydláždiť cestu k zdravšiemu životnému štýlu.",
|
||||
"marketing4Lead2Title": "Gamifikácia životného štýlu a zdravia",
|
||||
@@ -55,32 +55,32 @@
|
||||
"marketing4Lead3Title": "Gamifikuj všetko",
|
||||
"mobileAndroid": "Android aplikácia",
|
||||
"mobileIOS": "iOS aplikácia",
|
||||
"oldNews": "Novinky",
|
||||
"oldNews": "News",
|
||||
"newsArchive": "News archive on Wikia (multilingual)",
|
||||
"setNewPass": "Nastaviť nové heslo",
|
||||
"setNewPass": "Set New Password",
|
||||
"password": "Heslo",
|
||||
"playButton": "Hrať",
|
||||
"playButtonFull": "Vstúp do Habitiky",
|
||||
"presskit": "Pre novinárov a média",
|
||||
"presskitText": "Ďakujeme za váš záujem o Habiticu! Nasledujúce obrázky môžu byť použité v článkoch alebo videách o Habitice. Pre viac informácií nás prosím kontaktujte na <%= pressEnquiryEmail %>.",
|
||||
"pkQuestion1": "Čo inšpirovalo Habiticu? Ako to všetko začalo?",
|
||||
"pkAnswer1": "Ak ste niekedy investovali čas do vylepšovania vašej postavičky v počítačovej hre, je ťažké nemyslieť na to aké úžasné by bolo, keby som všetku tú snahu vložil do zlepšovania môjho reálneho ja, namiesto môjho avatara. Habiticu sme začali vytvárať práve pre to aby sme odpovedali na túto otázku. <br /> Habitica bola oficiálne spustená cez Kickstarter v roku 2013 a nápad sa veľmi rýchlo ujal. Od vtedy, Habitica prerástla do obrovského projektu, podporovaného našimi úžasnými open-source dobrovoľníkmi a štedrými používateľmi.",
|
||||
"pkQuestion2": "Prečo Habitica funguje?",
|
||||
"presskit": "Press Kit",
|
||||
"presskitText": "Thanks for your interest in Habitica! The following images can be used for articles or videos about Habitica. For more information, please contact us at <%= pressEnquiryEmail %>.",
|
||||
"pkQuestion1": "What inspired Habitica? How did it start?",
|
||||
"pkAnswer1": "If you’ve ever invested time in leveling up a character in a game, it’s hard not to wonder how great your life would be if you put all of that effort into improving your real-life self instead of your avatar. We starting building Habitica to address that question. <br /> Habitica officially launched with a Kickstarter in 2013, and the idea really took off. Since then, it’s grown into a huge project, supported by our awesome open-source volunteers and our generous users.",
|
||||
"pkQuestion2": "Why does Habitica work?",
|
||||
"pkAnswer2": "Vytváranie nového návyku je náročné, pretože ľudia naozaj potrebujú očividnú a okamžitú odmenu. Na príklad, je náročné začať používať zubnú niť, pretože aj keď nám náš zubár povie, že z dlhodobého hľadiska je to prospešné, v tejto chvíli nás z toho budú akurát tak bolieť ďasná. <br /> Gemifikácia s Habiticou pridáva pocit okamžitého uspokojenia každodenným činnostiam práve odmeňovaním náročných úloh EXP bodmi, zlatom … a možno aj náhodnou odmenou, ako dračie vajce! To pomáha ľuďom zostať motivovanými aj keď úloha sama o sebe neprináša žiadnu okamžitú odmenu, a môžeme vidieť ako to ľuďom mení život.",
|
||||
"pkQuestion3": "Prečo ste pridali sociálne funkcie?",
|
||||
"pkQuestion3": "Why did you add social features?",
|
||||
"pkAnswer3": "Spoločenský tlak ja pre mnoho ľudí výrazným motivačným faktorom, takže sme vedeli, že chcem mať silnú komunitu, ktorá bude pomáhať ľuďom pri napĺňaní ich cieľov a oslavovať ich úspechy. Našťastie, jedna z vecí, ktorú hry pre viac hráčov robia najlepšie, je vytváranie pocitu spolupatričnosti medzi ich používateľmi! Štruktúra komunity v Habitice je práve preto požičaná z tohto typu hier. Aj keď niektorý používatelia preferujú hrať sólovo, väčšina sa rozhodne formovať podpornú sieť v malej Družine blízkych priateľov, ktorá ich povzbudzuje k spoločnej zodpovednosti cez funkcie Habitici ako sú Výzvy, pri ktorých členovia Družiny spájajú svoju produktívnu silu v spoločnom boji s príšerami.",
|
||||
"pkQuestion4": "Prečo nesplnenie úlohy znižuje život môjho avatara?",
|
||||
"pkAnswer4": "Ak vynecháš jednu zo svojich denných úloh, nasledujúci deň tvoj avatar stratí životy. To slúži ako významný motivačný faktor, ktorý povzbudzuje ľudí k napredovaniu vo svojich cieľoch. Nikto predsa nechce zraniť svojho malého avatara! Navyše, pre mnoho ľudí je nesmierne dôležitá aj sociálna zodpovednosť: ak bojuješ s priateľmi proti nejakej príšere, vynechanie úlohy zraní aj ich avatara.",
|
||||
"pkQuestion5": "Čo odlišuje Habiticu od iných gemifikačných programov?",
|
||||
"pkAnswer5": "Jednou z vecí, v ktorých je Habitica najúspešnejšia, čo sa týka použitia gemifikácie, je práve v dôkladnom premyslení herných aspektov a uistení sa, že sú skutočne zábavné. Taktiež sme do Habitici zahrnuli veľa sociálnych komponentov, lebo vnímame, že veľmi veľa hier je motivujúcich práve pre možnosť hrania s priateľmi. Výskumy taktiež potvrdzujú, že je jednoduchšie si budovať nové návyky pokiaľ sa zodpovedáme iným ľuďom.",
|
||||
"pkQuestion6": "Kto je typickým používateľom Habitici?",
|
||||
"pkAnswer6": "Habiticu používa veľa rôznych ľudí! Viac ako polovica našich používateľov je vo vekovom rozmedzí 18 až 34 rokov, ale taktiež sú to starý rodičia, ktorý používajú našu stránku s ich vnúčatami a všetky vekové kategórie medzi tým. Rodiny často vytvárajú družiny a spoločne bojujú s príšerami. <br /> Veľa našich používateľov má nejakú tú skúsenosť s počítačovými hrami, ale pri nedávnom prieskume nás prekvapilo, že až 40% našich používateľov sa nezaraďuje medzi tzv. gejmerov! Zdá sa teda, že naša metóda dokáže byť efektívna pre kohokoľvek, kto chce skombinovať produktivitu, wellness a zábavu.",
|
||||
"pkQuestion7": "Prečo Habitica používa pixel art?",
|
||||
"pkAnswer7": "Habitica používa pixel art z niekoľkých dôvodov. Popri tom, že je to zábavný nostalgický faktor, pixel art je veľmi dobre prístupný našim umelcom - dobrovoľníkom. Je veľmi jednoduché udržať naše pixel arty vzhľadovo konzistentné, aj napriek veľkému množstvu rôznych prispievajúcich umelcov, a umožňuje nám to tak rýchlo vytvárať dostatočné množstvo nového obsahu!",
|
||||
"pkQuestion8": "Ako Habitica ovplyvňuje skutočné životy ľudí?",
|
||||
"pkAnswer8": "Tu môžete nájsť veľa svedectiev o tom ako Habitica pomohla ľuďom: https://habitversary.tumblr.com",
|
||||
"pkMoreQuestions": "Máš otázku, ktorá nie je v zozname? Pošli nám email na admin@habitica.com!",
|
||||
"pkPromo": "Propagácie",
|
||||
"pkQuestion4": "Why does skipping tasks remove your avatar’s health?",
|
||||
"pkAnswer4": "If you skip one of your daily goals, your avatar will lose health the following day. This serves as an important motivating factor to encourage people to follow through with their goals because people really hate hurting their little avatar! Plus, the social accountability is critical for a lot of people: if you’re fighting a monster with your friends, skipping your tasks hurts their avatars, too.",
|
||||
"pkQuestion5": "What distinguishes Habitica from other gamification programs?",
|
||||
"pkAnswer5": "One of the ways that Habitica has been most successful at using gamification is that we've put a lot of effort into thinking about the game aspects to ensure that they are actually fun. We've also included many social components, because we feel that some of the most motivating games let you play with friends, and because research has shown that it's easier to form habits when you have accountability to other people.",
|
||||
"pkQuestion6": "Who is the typical user of Habitica?",
|
||||
"pkAnswer6": "Lots of different people use Habitica! More than half of our users are ages 18 to 34, but we have grandparents using the site with their young grandkids and every age in-between. Often families will join a party and battle monsters together. <br /> Many of our users have a background in games, but surprisingly, when we ran a survey a while back, 40% of our users identified as non-gamers! So it looks like our method can be effective for anyone who wants productivity and wellness to feel more fun.",
|
||||
"pkQuestion7": "Why does Habitica use pixel art?",
|
||||
"pkAnswer7": "Habitica uses pixel art for several reasons. In addition to the fun nostalgia factor, pixel art is very approachable to our volunteer artists who want to chip in. It's much easier to keep our pixel art consistent even when lots of different artists contribute, and it lets us quickly generate a ton of new content!",
|
||||
"pkQuestion8": "How has Habitica affected people's real lives?",
|
||||
"pkAnswer8": "You can find lots of testimonials for how Habitica has helped people here: https://habitversary.tumblr.com",
|
||||
"pkMoreQuestions": "Do you have a question that’s not on this list? Send an email to admin@habitica.com!",
|
||||
"pkPromo": "Promos",
|
||||
"pkLogo": "Logá",
|
||||
"pkBoss": "Bossovia",
|
||||
"pkSamples": "Vzorové screeny",
|
||||
|
||||
@@ -150,7 +150,5 @@
|
||||
"achievementDinosaurDynastyModalText": "Bütün kuş ve dinazor evcil hayvanlarını topladın!",
|
||||
"achievementReptacularRumble": "Sürünen Gümbürtü",
|
||||
"achievementBoneToPick": "Alacak bir Kemik",
|
||||
"achievementPlantParentModalText": "Bitki evcil hayvanlarının hepsini topladın!",
|
||||
"achievementCatsModalText": "Tüm evcil kedileri topladın!",
|
||||
"achievementBonelessBossModalText": "Tüm omurgasız evcil hayvanları topladın!"
|
||||
"achievementPlantParentModalText": "Bitki evcil hayvanlarının hepsini topladın!"
|
||||
}
|
||||
|
||||
@@ -52,33 +52,33 @@
|
||||
"questAlreadyUnderway": "Ваша команда вже приймає участь у квесті. Спробуйте пізніше, коли він закінчиться.",
|
||||
"questAlreadyAccepted": "Ви вже прийняли запрошення на квест.",
|
||||
"noActiveQuestToLeave": "No active quest to leave",
|
||||
"questLeaderCannotLeaveQuest": "Власник квесту не може покинути квест",
|
||||
"questLeaderCannotLeaveQuest": "Лідер квесту не може покинути його",
|
||||
"notPartOfQuest": "Ви не берете участь у цьому квесті",
|
||||
"youAreNotOnQuest": "Ви не берете участь в квесті",
|
||||
"noActiveQuestToAbort": "Немає активного квесту, який можна перервати.",
|
||||
"onlyLeaderAbortQuest": "Тільки керівник групи або власник квесту може перервати його.",
|
||||
"onlyLeaderAbortQuest": "Тільки лідер групи або квесту може перервати його.",
|
||||
"questAlreadyRejected": "Ви вже відхилили запрошення на квест.",
|
||||
"cantCancelActiveQuest": "Ви не можете скасувати активний квест, скористайтеся функцією переривання.",
|
||||
"onlyLeaderCancelQuest": "Тільки керівник групи або власник квесту може відмінити його.",
|
||||
"onlyLeaderCancelQuest": "Тільки лідер групи або квесту може відміняти його.",
|
||||
"questNotPending": "Немає квесту, котрий можна розпочати.",
|
||||
"questOrGroupLeaderOnlyStartQuest": "Тільки керівник групи або власник квесту може почати його",
|
||||
"questOrGroupLeaderOnlyStartQuest": "Тільки лідер групи або квесту може почати його",
|
||||
"loginIncentiveQuest": "Щоб розблокувати цей квест, заходьте в Habitica на протязі <%= count %> днів!",
|
||||
"loginReward": "<%= count %> відвідувань",
|
||||
"questBundles": "Набори квестів зі знижкою",
|
||||
"noQuestToStart": "Завітайте до <a href=\"<%= questShop %>\"> Магазину квестів</a>, щоб знайти нові сувої!",
|
||||
"noQuestToStart": "Завітайте до <a href=\"<%= questShop %>\"> магазину квестів</a>, щоб знайти нові сувої!",
|
||||
"pendingDamage": "<%= damage %> очікувана шкода",
|
||||
"pendingDamageLabel": "очікувана шкода",
|
||||
"bossHealth": "<%= currentHealth %> / <%= maxHealth %> Здоров'я",
|
||||
"bossHealth": "<%= currentHealth %> / <%= maxHealth %> ОЗ",
|
||||
"rageAttack": "Люта атака:",
|
||||
"bossRage": "<%= currentRage %> / <%= maxRage %> Лють",
|
||||
"rageStrikes": "Лютий урар",
|
||||
"questOwner": "Власник квесту",
|
||||
"rageStrikes": "Удари люті",
|
||||
"questOwner": "Лідер квесту",
|
||||
"cancelQuest": "Скасувати квест",
|
||||
"backToSelection": "Повернутися до вибору квесту",
|
||||
"yourQuests": "Ваші квести",
|
||||
"selectQuestModal": "Оберіть квест",
|
||||
"newItem": "Новий предмет",
|
||||
"ownerOnly": "Тільки для власника",
|
||||
"ownerOnly": "Тільки для лідера квесту",
|
||||
"tavernBossTired": "Бос <%= bossName %> намагається вивільнити <%= rageName %>, але втома не дозволяє це зробити.",
|
||||
"chatQuestCancelled": "<%= username %> скасував(-ла) квест <%= questName %>.",
|
||||
"chatQuestAborted": "<%= username %> перервав(-ла) квест <%= questName %>.",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"settings": "Налаштування",
|
||||
"language": "Мова",
|
||||
"americanEnglishGovern": "У разі розбіжностей в перекладі, версія американською англійською є головною.",
|
||||
"helpWithTranslation": "Ви зацікавлені в допомозі з перекладом Habitica? Чудово! Навідайтесь до проєкту <a href=\"https://translate.habitica.com\">Habitica's Weblate site</a>!",
|
||||
"americanEnglishGovern": "У разі невідповідності в перекладі, американська англійська версія є головною.",
|
||||
"helpWithTranslation": "Ви зацікавлені в допомозі з перекладом Habitica? Чудово! Перейдіть до <a href=\"https://translate.habitica.com\">Habitica's Weblate site</a>!",
|
||||
"stickyHeader": "Закріпити заголовок",
|
||||
"newTaskEdit": "Відкривати нові завдання у режимі редагування",
|
||||
"dailyDueDefaultView": "Налаштуйте Щоденні завдання у належній вкладці за замовчуванням",
|
||||
|
||||
@@ -40,30 +40,30 @@
|
||||
"streakCounter": "Лічильник серії",
|
||||
"repeat": "Повторення",
|
||||
"repeats": "Спосіб повторення",
|
||||
"repeatEvery": "Повторювати кожні",
|
||||
"repeatOn": "Повторювати в",
|
||||
"repeatEvery": "Повторювати кожен",
|
||||
"repeatOn": "Повторювати по",
|
||||
"day": "День",
|
||||
"days": "Дні(-в)",
|
||||
"restoreStreak": "Зкоректувати серію",
|
||||
"days": "Днів",
|
||||
"restoreStreak": "Відрегулюйте серію",
|
||||
"resetStreak": "Скинути серію",
|
||||
"todo": "Завдання",
|
||||
"todos": "Завдання",
|
||||
"todosDesc": "Завдання потрібно виконати лише раз. Додайте список підзавдань, щоб збільшити винагороду за його виконання.",
|
||||
"todosDesc": "Завдання потрібно виконати лише раз. Додавайте підзавдання, щоб підвищити винагороду за виконання.",
|
||||
"dueDate": "Виконати до",
|
||||
"remaining": "Активні",
|
||||
"complete": "Виконано",
|
||||
"complete": "Виконані",
|
||||
"complete2": "Завершені",
|
||||
"today": "Сьогодні",
|
||||
"dueIn": "Виконати до <%= dueIn %>",
|
||||
"dueIn": "Виконати <%= dueIn %>",
|
||||
"due": "Поточні",
|
||||
"notDue": "Не сьогодні",
|
||||
"notDue": "Інші",
|
||||
"grey": "Сірі",
|
||||
"score": "Рахунок",
|
||||
"reward": "Нагорода",
|
||||
"rewards": "Нагороди",
|
||||
"rewardsDesc": "Нагороди – чудовий спосіб використовувати Habitica й виконувати завдання. Спробуйте додати кілька прямо зараз!",
|
||||
"rewardsDesc": "Нагороди - це чудовий спосіб використовувати Habitica й виконувати задачі. Спробуй додати кілька прямо зараз!",
|
||||
"gold": "Золото",
|
||||
"silver": "Срібло (100 срібла = 1 золото)",
|
||||
"silver": "Срібло (100 монет срібла = 1 золото)",
|
||||
"price": "Ціна",
|
||||
"tags": "Ярлики",
|
||||
"editTags": "Редагувати",
|
||||
@@ -71,7 +71,7 @@
|
||||
"editTags2": "Редагувати теги",
|
||||
"toRequired": "Вам слід правильно вказати значення «to»",
|
||||
"startDate": "Дата початку",
|
||||
"streaks": "Досягнення Серії",
|
||||
"streaks": "Досягнення за серію",
|
||||
"streakName": "Досягнень за серію: <%= count %>",
|
||||
"streakText": "Виконано 21-денних серій щоденних завдань: <%= count %>",
|
||||
"streakSingular": "Серійник",
|
||||
@@ -136,7 +136,7 @@
|
||||
"tomorrow": "Завтра",
|
||||
"addNotes": "Додайте нотатки",
|
||||
"addATitle": "Додайте назву",
|
||||
"adjustCounter": "Зкоректувати лічильник",
|
||||
"adjustCounter": "Відрегулювати лічильник",
|
||||
"counter": "Лічильник",
|
||||
"resetCounter": "Скинути лічильник",
|
||||
"editTagsText": "Редагувати ярлики",
|
||||
|
||||
@@ -214,7 +214,7 @@
|
||||
"backgroundStormyRooftopsNotes": "从暴风屋顶上慢慢爬过。",
|
||||
"backgroundWindyAutumnText": "刮风的秋天",
|
||||
"backgroundWindyAutumnNotes": "在刮风的秋天中追赶落叶。",
|
||||
"incentiveBackgrounds": "基础背景套装",
|
||||
"incentiveBackgrounds": "简约背景套装",
|
||||
"backgroundVioletText": "紫罗兰境",
|
||||
"backgroundVioletNotes": "充满生气的紫罗兰境。",
|
||||
"backgroundBlueText": "蓝色",
|
||||
@@ -872,10 +872,5 @@
|
||||
"backgroundShellGateNotes": "穿过装饰着珊瑚的贝壳门。",
|
||||
"backgroundShellGateText": "贝壳门",
|
||||
"backgrounds072024": "第122组:2024年7月发布",
|
||||
"backgroundRiverBottomText": "河底",
|
||||
"backgroundRiverBottomNotes": "探索河床。",
|
||||
"monthlyBackgrounds": "每月背景",
|
||||
"backgrounds082024": "第123组:2024年8月发布",
|
||||
"backgroundSavannaText": "朦胧草原",
|
||||
"backgroundSavannaNotes": "徒步穿越朦胧的草原。"
|
||||
"backgroundRiverBottomText": "河底"
|
||||
}
|
||||
|
||||
@@ -189,10 +189,5 @@
|
||||
"notEnoughGold": "金币不足。",
|
||||
"chatCastSpellPartyTimes": "<%= username %>对队伍使用了<%= times %>次<%= spell %>。",
|
||||
"chatCastSpellUserTimes": "<%= username %>对<%= target %>使用了<%= times %>次<%= spell %>。",
|
||||
"nextReward": "下次登录奖励",
|
||||
"skins": "皮肤",
|
||||
"titleHaircolor": "发色",
|
||||
"titleFacialHair": "胡须",
|
||||
"customizations": "自定义",
|
||||
"titleHairbase": "发型"
|
||||
"nextReward": "下次登录奖励"
|
||||
}
|
||||
|
||||
@@ -376,15 +376,5 @@
|
||||
"hatchingPotionPinkMarble": "粉色大理石",
|
||||
"hatchingPotionTeaShop": "茶馆",
|
||||
"hatchingPotionRoseGold": "玫瑰金",
|
||||
"hatchingPotionFungi": "蘑菇",
|
||||
"questEggGiraffeText": "长颈鹿",
|
||||
"questEggGiraffeMountText": "长颈鹿",
|
||||
"questEggGiraffeAdjective": "一只卓越的",
|
||||
"questEggChameleonText": "变色龙",
|
||||
"questEggChameleonMountText": "变色龙",
|
||||
"questEggChameleonAdjective": "一只混乱的",
|
||||
"hatchingPotionKoi": "锦鲤",
|
||||
"questEggCrabText": "螃蟹",
|
||||
"questEggCrabMountText": "螃蟹",
|
||||
"questEggCrabAdjective": "一只微不足道的"
|
||||
"hatchingPotionFungi": "蘑菇"
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"groupBy": "按<%= type %>分组",
|
||||
"classBonus": "(这件物品与你的职业相匹配,因此可获得1.5倍的额外属性加成。)",
|
||||
"classArmor": "职业护甲",
|
||||
"featuredset": "精选套装:<%= name %>",
|
||||
"featuredset": "精选套装<%= name %>",
|
||||
"mysterySets": "神秘套装",
|
||||
"gearNotOwned": "您尚未拥有此物品。",
|
||||
"noGearItemsOfType": "你尚未获得过此类物品。",
|
||||
@@ -3124,22 +3124,5 @@
|
||||
"weaponArmoirePottersWheelNotes": "在这个转轮上拉制一些黏土,制作一个碗或一个杯子或一个花瓶或一个略有不同的碗。如果幸运的话,在你创作时可能会有幽灵造访!增加<%= per %>点感知。魔法宝箱:陶工套装(4/4)。",
|
||||
"armorArmoirePottersApronNotes": "你带着干活的工具有备而来。幸亏你穿了这条围裙。它有口袋!增加<%= str %>点力量。魔法宝箱:陶工套装(1/4)。",
|
||||
"backMystery202405Text": "镀金龙翼",
|
||||
"backMystery202405Notes": "这双华丽的翅膀闪耀着纯金的光芒,却又轻如羽毛。没有属性加成。2024年5月订阅者物品。",
|
||||
"eyewearMystery202406Notes": "尽量避免让一帮爱管闲事的孩子和他们会说话的狗把你的面具摘下来。没有属性加成。订阅者物品。2024年6月订阅者物品。",
|
||||
"shieldArmoireBuoyantBeachBallNotes": "已经有太多的球在空中飞舞了吗?这里有一个可以让你放心地放下、滚动、一遍又一遍地弹起...... 增加<%= str %>点力量。魔法宝箱:海滨套装(4/4)。",
|
||||
"weaponSpecialSummer2024RogueText": "海蛞蝓三叉戟",
|
||||
"weaponSpecialSummer2024WarriorNotes": "一些脱落的鲨鱼牙齿变成了武器,能够从任何方向造成伤害。增加<%= str %>点力量。2024 年夏季限量版装备。",
|
||||
"weaponSpecialSummer2024MageText": "海葵魔杖",
|
||||
"weaponSpecialSummer2024WarriorText": "鲸鲨齿切割机",
|
||||
"weaponSpecialSummer2024MageNotes": "这些可怕的触手可以同时分散、偏转和引导魔法。增加<%= int %>点智力和<%= per %>点感知。2024 年夏季限量版装备。",
|
||||
"weaponSpecialSummer2024HealerText": "海螺法杖",
|
||||
"weaponSpecialSummer2024HealerNotes": "你会惊奇地发现,这根法杖末端的外壳竟然如此坚硬。增加<%= int %>点智力。2024 年夏季限量版装备。",
|
||||
"armorMystery202407Text": "和蔼可亲的美西螈套装",
|
||||
"armorMystery202407Notes": "甩动粉红色的尾巴,在湖泊和运河中游动吧!没有属性加成。2024年7月订阅者物品。",
|
||||
"armorMystery202406Notes": "以时尚和炫目的方式纠缠你的敌人!没有属性加成。2024年6月订阅者物品。",
|
||||
"armorMystery202406Text": "幻影海盗套装",
|
||||
"armorArmoireYellowStripedSwimsuitText": "黄色条纹泳衣",
|
||||
"armorArmoireBlueStripedSwimsuitText": "蓝色条纹泳衣",
|
||||
"shieldArmoireBuoyantBeachBallText": "沙滩球",
|
||||
"eyewearMystery202406Text": "幻影海盗面具"
|
||||
"backMystery202405Notes": "这双华丽的翅膀闪耀着纯金的光芒,却又轻如羽毛。没有属性加成。2024年5月订阅者物品。"
|
||||
}
|
||||
|
||||
@@ -238,6 +238,5 @@
|
||||
"general": "一般",
|
||||
"mutePlayer": "屏蔽",
|
||||
"shadowMute": "隐形屏蔽",
|
||||
"playerReportModalBody": "您只能举报违反<%= firstLinkStart %>社区准则<%= linkEnd %>和/或<%= secondLinkStart %>服务条款<%= linkEnd %>的玩家。提交虚假举报是违反Habitica社区准则的行为。",
|
||||
"titleCustomizations": "自定义"
|
||||
"playerReportModalBody": "您只能举报违反<%= firstLinkStart %>社区准则<%= linkEnd %>和/或<%= secondLinkStart %>服务条款<%= linkEnd %>的玩家。提交虚假举报是违反Habitica社区准则的行为。"
|
||||
}
|
||||
|
||||
@@ -157,25 +157,25 @@
|
||||
"spring2019AmberMageSet": "琥珀(法师)",
|
||||
"spring2019OrchidWarriorSet": "兰花(战士)",
|
||||
"june2018": "2018年6月",
|
||||
"fall2019RavenSet": "渡鸦(战士)",
|
||||
"fall2019RavenSet": "渡鸦(战士)",
|
||||
"fall2019LichSet": "巫妖(医者)",
|
||||
"fall2019CyclopsSet": "独眼巨人(法师)",
|
||||
"fall2019OperaticSpecterSet": "歌剧幽灵(盗贼)",
|
||||
"september2018": "2018年9月",
|
||||
"september2017": "2017年9月",
|
||||
"winter2020LanternSet": "灯笼(盗贼)",
|
||||
"winter2020LanternSet": "灯笼(盗贼)",
|
||||
"winter2020WinterSpiceSet": "冬季香料(医者)",
|
||||
"winter2020CarolOfTheMageSet": "法师的颂歌(法师)",
|
||||
"winter2020EvergreenSet": "常青树(战士)",
|
||||
"spring2020LapisLazuliRogueSet": "青金石(盗贼)",
|
||||
"spring2020LapisLazuliRogueSet": "青金石(盗贼)",
|
||||
"spring2020IrisHealerSet": "鸢尾花(医者)",
|
||||
"spring2020PuddleMageSet": "水洼(法师)",
|
||||
"spring2020BeetleWarriorSet": "独角仙(战士)",
|
||||
"summer2020CrocodileRogueSet": "鳄鱼(盗贼)",
|
||||
"summer2020CrocodileRogueSet": "鳄鱼(盗贼)",
|
||||
"summer2020RainbowTroutWarriorSet": "虹鳟鱼(战士)",
|
||||
"summer2020OarfishMageSet": "桨鱼(法师)",
|
||||
"summer2020SeaGlassHealerSet": "海玻璃(医者)",
|
||||
"fall2020TwoHeadedRogueSet": "双头(盗贼)",
|
||||
"fall2020TwoHeadedRogueSet": "双头(盗贼)",
|
||||
"fall2020ThirdEyeMageSet": "第三只眼(法师)",
|
||||
"fall2020DeathsHeadMothHealerSet": "鬼脸天蛾(医者)",
|
||||
"fall2020WraithWarriorSet": "幽灵(战士)",
|
||||
@@ -210,15 +210,15 @@
|
||||
"winter2022StockingWarriorSet": "长袜(战士)",
|
||||
"winter2022PomegranateMageSet": "石榴(法师)",
|
||||
"winter2022IceCrystalHealerSet": "冰晶(医者)",
|
||||
"spring2022MagpieRogueSet": "喜鹊(盗贼)",
|
||||
"spring2022MagpieRogueSet": "喜鹊(盗贼)",
|
||||
"spring2022RainstormWarriorSet": "暴风雨(战士)",
|
||||
"spring2022ForsythiaMageSet": "连翘花(法师)",
|
||||
"spring2022PeridotHealerSet": "橄榄石(医者)",
|
||||
"summer2022CrabRogueSet": "螃蟹 (盗贼)",
|
||||
"summer2022CrabRogueSet": "螃蟹 (盗贼)",
|
||||
"summer2022WaterspoutWarriorSet": "水龙卷 (战士)",
|
||||
"summer2022MantaRayMageSet": "蝠鲼(法师)",
|
||||
"summer2022AngelfishHealerSet": "天使鱼(医者)",
|
||||
"gemSaleHow": "在<%= eventStartMonth %><%= eventStartOrdinal %>至<%= eventEndOrdinal %>期间,只需像往常一样购买任意宝石捆绑包,你的账户就会被存入促销赠送的宝石。这些多出来的宝石可用于消费、赠送或保存以供未来使用!",
|
||||
"gemSaleHow": "在<%= eventStartMonth %><%= eventStartOrdinal %>至<%= eventEndOrdinal %>期间,只需像往常一样购买任意宝石捆绑包,你的账户就会被存入促销赠送的宝石。这些多出来的宝石可用于消费、赠送或保存以供未来使用!",
|
||||
"gemSaleLimitations": "此促销仅适用于限时活动期间。此活动从<%= eventStartMonth %><%= eventStartOrdinal %>美国东部时间上午8:00(12:00 UTC)开始,到<%= eventEndMonth %><%= eventEndOrdinal %>美国东部时间晚上8:00(00:00 UTC)结束。此促销优惠仅适用于为自己购买宝石。",
|
||||
"fall2022KappaRogueSet": "河童(盗贼)",
|
||||
"fall2022OrcWarriorSet": "兽人(战士)",
|
||||
@@ -228,7 +228,7 @@
|
||||
"winter2023FairyLightsMageSet": "仙女灯(法师)",
|
||||
"winter2023CardinalHealerSet": "北美红雀(医者)",
|
||||
"winter2023RibbonRogueSet": "丝带(盗贼)",
|
||||
"anniversaryLimitations": "本活动为限时活动,从美国东部时间1月30日上午8:00(13:00 UTC)开始,到美国东部时间2月8日晚上11:59(04:59 UTC)结束。在此期间可购买限定版欢沁狮鹫蛇和十种魔法孵化药水。“免费四件套”部分中列出的其他礼物将自动发送至礼物发送日前30天内的所有活跃账号。礼物发送后创建的账号将无法领取礼品。",
|
||||
"anniversaryLimitations": "本活动为限时活动,从美国东部时间1月30日上午8:00(13:00 UTC)开始,到美国东部时间2月8日晚上11:59(04:59 UTC)结束。在此期间可购买限定版欢沁狮鹫蛇和十种魔法孵化药水。“免费四件套”部分中列出的其他礼物将自动发送至礼物发送日前30天内的所有活跃账号。礼物发送后创建的账号将无法领取礼品。",
|
||||
"anniversaryLimitedDates": "1月30日至2月8日",
|
||||
"limitedEvent": "限时活动",
|
||||
"celebrateAnniversary": "收下以下礼物和专属物品,庆祝Habitica的10岁生日!",
|
||||
@@ -275,9 +275,5 @@
|
||||
"spring2024FluoriteWarriorSet": "萤石套装(战士)",
|
||||
"spring2024HibiscusMageSet": "木槿套装(法师)",
|
||||
"spring2024BluebirdHealerSet": "蓝鸲套装(医者)",
|
||||
"spring2024MeltingSnowRogueSet": "融雪套装(盗贼)",
|
||||
"summer2024WhaleSharkWarriorSet": "鲸鲨(战士)",
|
||||
"summer2024SeaSnailHealerSet": "海螺(医者)",
|
||||
"summer2024SeaAnemoneMageSet": "海葵(法师)",
|
||||
"summer2024NudibranchRogueSet": "海蛞蝓(盗贼)"
|
||||
"spring2024MeltingSnowRogueSet": "融雪套装(盗贼)"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"checkinEarned": "你的总签到次数又提高了!",
|
||||
"unlockedCheckInReward": "你解锁了一个签到奖励!",
|
||||
"checkinProgressTitle": "距离下一次的进度",
|
||||
"incentiveBackgroundsUnlockedWithCheckins": "更多普通背景将通过每日签到解锁。",
|
||||
"incentiveBackgroundsUnlockedWithCheckins": "锁定的普通背景将通过每日签到解锁。",
|
||||
"oneOfAllPetEggs": "基础宠物蛋每种各一枚",
|
||||
"twoOfAllPetEggs": "基础宠物蛋每种各两枚",
|
||||
"threeOfAllPetEggs": "基础宠物蛋每种各三枚",
|
||||
|
||||
@@ -115,6 +115,5 @@
|
||||
"tooMuchFood": "你给宠物喂得太多了,操作已取消",
|
||||
"notEnoughFood": "你没有足够的食物",
|
||||
"jubilantGryphatrice": "欢沁狮鹫蛇",
|
||||
"veteranDragon": "退役军龙",
|
||||
"veteranCactus": "退役仙人掌"
|
||||
"veteranDragon": "退役军龙"
|
||||
}
|
||||
|
||||
@@ -497,7 +497,7 @@
|
||||
"questMayhemMistiflying3DropShield": "俏皮彩虹信使的信件(副手装备)",
|
||||
"questMayhemMistiflying3DropWeapon": "俏皮彩虹信使的信件(主手装备)",
|
||||
"featheredFriendsText": "羽毛朋友副本包",
|
||||
"featheredFriendsNotes": "包含副本 猫头鹰、鹦鹉、鹰宠物蛋:暗夜猫头鹰、救命!鹰身女妖!和 掠食明天之鸟 。",
|
||||
"featheredFriendsNotes": "包含“救命!鹰身女妖!”、“暗夜猫头鹰”和“掠食明天之鸟”。<%= date %>前可购买",
|
||||
"questNudibranchText": "NowDo海兔的侵袭",
|
||||
"questNudibranchNotes": "在Habitica又度过了懒散的一天,你总算说服自己检查一下待办事项。紧挨着那些深红的任务,有一群明亮鲜艳的蓝色海兔。你简直入了迷!那蔚蓝的颜色使你那些最吓人的任务看起来也像最习以为常一样简单。你在一种狂热恍惚的状态中开始了工作,不眠不休地解决掉一个又一个任务……<br><br>直到@LilithofAlfheim 朝你泼了一桶冷水,你才醒了过来。“NowDo海兔把你浑身上下都蜇伤了!你得休息一下!”<br><br>你惊讶地发现,自己的皮肤红得和待办列表一样。“高产是一方面,”@beffymaroo 说,“但是你也得照顾自己的身体,赶紧的,弄走这些海兔!”",
|
||||
"questNudibranchCompletion": "随着@amadshade 的搓洗,最后一只NowDo海兔从一桩已完成的任务上滑落。但它们留下了一个布袋,你打开之后发现里面有一些金币和一些似乎是蛋的小椭球。",
|
||||
@@ -594,7 +594,7 @@
|
||||
"questDysheartenerDropHippogriffMount": "希望天马(坐骑)",
|
||||
"dysheartenerArtCredit": "艺术作品由 @AnnDeLune 创作",
|
||||
"hugabugText": "拥抱昆虫副本包",
|
||||
"hugabugNotes": "包含“严重的BUG”、“苦差事淤泥蜗牛”和“再见啦,蝴蝶”。",
|
||||
"hugabugNotes": "包含“严重的BUG”、“苦差事淤泥蜗牛”和“再见啦,蝴蝶”。<%= date %>前可购买",
|
||||
"questSquirrelText": "狡猾的松鼠",
|
||||
"questSquirrelNotes": "你迷迷糊糊地起床,发现自己睡过头了!闹钟怎么没响?……闹钟的铃铛怎么被松果给卡住了?<br><br>你要做早饭,却发现烤面包机里塞满了松果。你去马厩准备把坐骑牵出来,却发现@Shtut 在那开不开锁了。他往锁孔里一瞄:“堵锁孔的那玩意儿是个松果吧?”<br><br>@randomdaisy 喊了起来:“哦,NO,我早知道我的宠物松鼠溜出来了,但是我没想到它们这么能惹祸!你能帮我赶在它们闯更多祸之前,把它们找回来吗?”<br><br>循着这些到处乱塞的橡果的踪迹,你抓住了这些任性的松鼠,由@Cantras 把它们安全送回家。但就在你觉得事情快搞定了时候,一个松果砸在了你的头盔上!你抬头看见一只巨大的松鼠怪兽,为了守卫一大堆被它认为是自己的种子而张牙舞爪。<br><br>“我的妈呀,”@randomdaisy 轻声说,“它一直都是保护财产的一把好手。咱们得小心行事!”你们全队集结完毕,准备对抗这场麻烦!",
|
||||
"questSquirrelCompletion": "你们用比较温柔的方式,和松鼠来了一把交易,念了些安抚性的咒术,成功把松鼠从囤积的东西上面哄走了,将它领回马厩,那边@Shtut 刚好把锁里的坚果搞出来。身旁的工作台上放了几个橡子。“这几个是松鼠蛋!或许你会出养几只不会老玩橡子的松鼠。”",
|
||||
@@ -635,7 +635,7 @@
|
||||
"questVelociraptorBoss": "光速rap迅猛龙",
|
||||
"questVelociraptorDropVelociraptorEgg": "迅猛龙(宠物蛋)",
|
||||
"questVelociraptorUnlockText": "已解锁迅猛龙蛋,可在市场购买",
|
||||
"mythicalMarvelsNotes": "包含副本 独角兽、狮鹫 和 海蛇宠物蛋:说服独角兽女王、火焰狮鹫 和 深度危险:海蛇冲撞!",
|
||||
"mythicalMarvelsNotes": "包含“说服独角兽女王”、“火焰狮鹫”和“深度危险:海蛇冲撞!”。<%= date %>前可购买。",
|
||||
"mythicalMarvelsText": "神话奇迹副本包",
|
||||
"rockingReptilesNotes": "包含“鳄鱼的煽动:此刻更要紧的事”、“分心蛇”和“光速rap迅猛龙”。<%= date %>前可购买。",
|
||||
"rockingReptilesText": "摇摆爬虫副本包",
|
||||
|
||||
@@ -796,24 +796,20 @@ export const TYPE_SCHEDULE = {
|
||||
customizations: GALA_SWITCHOVER_DAY,
|
||||
};
|
||||
|
||||
function adjustDateForUTCAndSwitch (date) {
|
||||
const checkDate = new Date(date.getTime() + date.getTimezoneOffset() * 60000);
|
||||
checkDate.setHours(checkDate.getHours() - SWITCHOVER_TIME);
|
||||
return checkDate;
|
||||
}
|
||||
|
||||
function getDay (date) {
|
||||
if (date === undefined) {
|
||||
return 0;
|
||||
}
|
||||
return adjustDateForUTCAndSwitch(date).getDate();
|
||||
const checkDate = new Date(date.getTime());
|
||||
checkDate.setHours(checkDate.getHours() - SWITCHOVER_TIME);
|
||||
return checkDate.getDate();
|
||||
}
|
||||
|
||||
function getMonth (date) {
|
||||
if (date === undefined) {
|
||||
return 0;
|
||||
}
|
||||
return adjustDateForUTCAndSwitch(date).getMonth();
|
||||
return date instanceof moment ? date.month() : date.getMonth();
|
||||
}
|
||||
|
||||
function getGalaIndex (date) {
|
||||
@@ -896,7 +892,7 @@ function makeEndDate (checkedDate, matcher) {
|
||||
end.year(checkedDate.getFullYear() + 1);
|
||||
}
|
||||
end.month(matcher.endMonth);
|
||||
} else if (end.valueOf() <= checkedDate.getTime()) {
|
||||
} else if (end.date() <= checkedDate.getDate()) {
|
||||
end = moment(end).add(1, 'months');
|
||||
}
|
||||
return end.toDate();
|
||||
@@ -908,7 +904,7 @@ export function clearCachedMatchers () {
|
||||
}
|
||||
|
||||
export function getAllScheduleMatchingGroups (date) {
|
||||
const checkedDate = date || moment.utc().toDate();
|
||||
const checkedDate = date || new Date();
|
||||
if (cacheDate !== null && (getDay(checkedDate) !== getDay(cacheDate)
|
||||
|| getMonth(checkedDate) !== getMonth(cacheDate))) {
|
||||
// Clear cached matchers, since they are old
|
||||
@@ -918,13 +914,9 @@ export function getAllScheduleMatchingGroups (date) {
|
||||
// No matchers exist, make new ones
|
||||
cacheDate = new Date();
|
||||
cachedScheduleMatchers = {};
|
||||
// subtract switchover time for the matcher classes, but
|
||||
// NOT to decide which matchers to assemble.
|
||||
// assembly uses getDate and getMonth which already adjust for switchover time
|
||||
const adjustedDate = adjustDateForUTCAndSwitch(checkedDate);
|
||||
assembleScheduledMatchers(checkedDate).forEach(matcher => {
|
||||
if (!cachedScheduleMatchers[matcher.type]) {
|
||||
cachedScheduleMatchers[matcher.type] = makeMatcherClass(adjustedDate);
|
||||
cachedScheduleMatchers[matcher.type] = makeMatcherClass(checkedDate);
|
||||
}
|
||||
cachedScheduleMatchers[matcher.type].end = makeEndDate(checkedDate, matcher);
|
||||
if (matcher.matcher instanceof Function) {
|
||||
|
||||
@@ -60,14 +60,6 @@ export class TooManyRequests extends CustomError {
|
||||
}
|
||||
}
|
||||
|
||||
export class RequestTimeout extends CustomError {
|
||||
constructor (customMessage) {
|
||||
super();
|
||||
this.name = this.constructor.name;
|
||||
this.httpCode = 408;
|
||||
this.message = customMessage || 'The request timed out.';
|
||||
}
|
||||
}
|
||||
export class NotImplementedError extends CustomError {
|
||||
constructor (str) {
|
||||
super();
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import isUUID from 'validator/lib/isUUID';
|
||||
import validator from 'validator';
|
||||
import i18n from '../i18n';
|
||||
import {
|
||||
BadRequest,
|
||||
} from '../libs/errors';
|
||||
|
||||
export default function blockUser (user, req = {}) {
|
||||
if (!isUUID(req.params.uuid)) throw new BadRequest(i18n.t('invalidUUID', req.language));
|
||||
if (!validator.isUUID(req.params.uuid)) throw new BadRequest(i18n.t('invalidUUID', req.language));
|
||||
if (req.params.uuid === user._id) throw new BadRequest(i18n.t('blockYourself', req.language));
|
||||
|
||||
const i = user.inbox.blocks.indexOf(req.params.uuid);
|
||||
|
||||
@@ -610,6 +610,7 @@ api.joinGroup = {
|
||||
|
||||
if (hasInvitation) {
|
||||
isUserInvited = true;
|
||||
inviter = hasInvitation.inviter;
|
||||
} else {
|
||||
isUserInvited = group.privacy !== 'private';
|
||||
}
|
||||
@@ -633,28 +634,42 @@ api.joinGroup = {
|
||||
group.leader = user._id; // If new user is only member -> set as leader
|
||||
}
|
||||
|
||||
let promises = [user.save()];
|
||||
|
||||
if (group.type === 'party') {
|
||||
// For parties we count the number of members from the database to get the correct value.
|
||||
// See #12275 on why this is necessary and only done for parties.
|
||||
const currentMembers = await group.getMemberCount();
|
||||
// Load the inviter
|
||||
if (inviter) inviter = await User.findById(inviter).exec();
|
||||
group.memberCount = currentMembers + 1;
|
||||
} else {
|
||||
group.memberCount += 1;
|
||||
}
|
||||
|
||||
// Check the inviter again, could be a deleted account
|
||||
if (inviter) {
|
||||
// Reward Inviter
|
||||
let promises = [group.save(), user.save()];
|
||||
|
||||
// Load the inviter
|
||||
if (inviter) inviter = await User.findById(inviter).exec();
|
||||
|
||||
// Check the inviter again, could be a deleted account
|
||||
if (inviter) {
|
||||
const data = {
|
||||
headerText: common.i18n.t('invitationAcceptedHeader', inviter.preferences.language),
|
||||
bodyText: common.i18n.t('invitationAcceptedBody', {
|
||||
groupName: group.name,
|
||||
username: user.profile.name,
|
||||
}, inviter.preferences.language),
|
||||
};
|
||||
inviter.addNotification('GROUP_INVITE_ACCEPTED', data);
|
||||
|
||||
// Reward Inviter
|
||||
if (group.type === 'party') {
|
||||
if (!inviter.items.quests.basilist) {
|
||||
inviter.items.quests.basilist = 0;
|
||||
}
|
||||
inviter.items.quests.basilist += 1;
|
||||
inviter.markModified('items.quests');
|
||||
promises.push(inviter.save());
|
||||
}
|
||||
group.memberCount = currentMembers + 1;
|
||||
}
|
||||
|
||||
// Handle awarding party-related achievements
|
||||
if (group.type === 'party' && inviter) {
|
||||
if (group.memberCount > 1) {
|
||||
const notification = new UserNotification({ type: 'ACHIEVEMENT_PARTY_UP' });
|
||||
|
||||
@@ -662,12 +677,20 @@ api.joinGroup = {
|
||||
{
|
||||
$or: [{ 'party._id': group._id }, { _id: user._id }],
|
||||
'achievements.partyUp': { $ne: true },
|
||||
_id: { $ne: inviter._id },
|
||||
},
|
||||
{
|
||||
$set: { 'achievements.partyUp': true },
|
||||
$push: { notifications: notification.toObject() },
|
||||
},
|
||||
).exec());
|
||||
|
||||
if (inviter) {
|
||||
if (inviter.achievements.partyUp !== true) {
|
||||
inviter.achievements.partyUp = true;
|
||||
inviter.addNotification('ACHIEVEMENT_PARTY_UP');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (group.memberCount > 3) {
|
||||
@@ -677,18 +700,22 @@ api.joinGroup = {
|
||||
{
|
||||
$or: [{ 'party._id': group._id }, { _id: user._id }],
|
||||
'achievements.partyOn': { $ne: true },
|
||||
_id: { $ne: inviter._id },
|
||||
},
|
||||
{
|
||||
$set: { 'achievements.partyOn': true },
|
||||
$push: { notifications: notification.toObject() },
|
||||
},
|
||||
).exec());
|
||||
}
|
||||
} else {
|
||||
group.memberCount += 1;
|
||||
}
|
||||
|
||||
promises.push(group.save());
|
||||
if (inviter) {
|
||||
if (inviter.achievements.partyOn !== true) {
|
||||
inviter.achievements.partyOn = true;
|
||||
inviter.addNotification('ACHIEVEMENT_PARTY_ON');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const analyticsObject = {
|
||||
uuid: user._id,
|
||||
@@ -700,9 +727,15 @@ api.joinGroup = {
|
||||
privacy: group.privacy,
|
||||
headers: req.headers,
|
||||
invited: isUserInvited,
|
||||
seekingParty: group.type === 'party' ? seekingParty : null,
|
||||
};
|
||||
if (group.type === 'party') {
|
||||
analyticsObject.seekingParty = seekingParty;
|
||||
}
|
||||
if (group.privacy === 'public') {
|
||||
analyticsObject.groupName = group.name;
|
||||
}
|
||||
|
||||
if (inviter) promises.push(inviter.save());
|
||||
promises = await Promise.all(promises);
|
||||
|
||||
if (group.hasNotCancelled()) {
|
||||
@@ -710,7 +743,7 @@ api.joinGroup = {
|
||||
await group.updateGroupPlan();
|
||||
}
|
||||
|
||||
const response = await Group.toJSONCleanChat(group, user);
|
||||
const response = await Group.toJSONCleanChat(promises[0], user);
|
||||
const leader = await User.findById(response.leader).select(nameFields).exec();
|
||||
if (leader) {
|
||||
response.leader = leader.toJSON({ minimize: true });
|
||||
|
||||
@@ -67,19 +67,6 @@ export const { Forbidden } = common.errors;
|
||||
*/
|
||||
export const { TooManyRequests } = common.errors;
|
||||
|
||||
/**
|
||||
* @apiDefine RequestTimeout
|
||||
* @apiError RequestTimeout The request took too long to complete.
|
||||
*
|
||||
* @apiErrorExample Error-Response:
|
||||
* HTTP/1.1 408 RequestTimeout
|
||||
* {
|
||||
* "error": "RequestTimeout",
|
||||
* "message": "Access forbidden."
|
||||
* }
|
||||
*/
|
||||
export const { RequestTimeout } = common.errors;
|
||||
|
||||
/**
|
||||
* @apiDefine NotificationNotFound
|
||||
* @apiError NotificationNotFound The notification was not found.
|
||||
|
||||
@@ -9,14 +9,12 @@ import {
|
||||
const IS_PROD = nconf.get('IS_PROD');
|
||||
const MAINTENANCE_MODE = nconf.get('MAINTENANCE_MODE');
|
||||
const POOL_SIZE = nconf.get('MONGODB_POOL_SIZE');
|
||||
const SOCKET_TIMEOUT = nconf.get('MONGODB_SOCKET_TIMEOUT');
|
||||
|
||||
// Do not connect to MongoDB when in maintenance mode
|
||||
if (MAINTENANCE_MODE !== 'true') {
|
||||
const mongooseOptions = getDefaultConnectionOptions();
|
||||
|
||||
if (POOL_SIZE) mongooseOptions.maxPoolSize = Number(POOL_SIZE);
|
||||
if (SOCKET_TIMEOUT) mongooseOptions.socketTimeoutMS = Number(SOCKET_TIMEOUT);
|
||||
|
||||
const DB_URI = nconf.get('IS_TEST') ? nconf.get('TEST_DB_URI') : nconf.get('NODE_DB_URI');
|
||||
const connectionUrl = IS_PROD ? DB_URI : getDevelopmentConnectionUrl(DB_URI);
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
CustomError,
|
||||
BadRequest,
|
||||
InternalServerError,
|
||||
RequestTimeout,
|
||||
} from '../libs/errors';
|
||||
|
||||
export default function errorHandler (err, req, res, next) { // eslint-disable-line no-unused-vars
|
||||
@@ -47,10 +46,6 @@ export default function errorHandler (err, req, res, next) { // eslint-disable-l
|
||||
}));
|
||||
}
|
||||
|
||||
if (err.name === 'MongoNetworkTimeoutError') {
|
||||
responseErr = new RequestTimeout();
|
||||
}
|
||||
|
||||
// Handle Stripe Card errors errors (can be safely shown to the users)
|
||||
// https://stripe.com/docs/api/node#errors
|
||||
if (err.type === 'StripeCardError') {
|
||||
|
||||
@@ -22,8 +22,6 @@ const REDIS_HOST = nconf.get('REDIS_HOST');
|
||||
const REDIS_PASSWORD = nconf.get('REDIS_PASSWORD');
|
||||
const REDIS_PORT = nconf.get('REDIS_PORT');
|
||||
const LIVELINESS_PROBE_KEY = nconf.get('LIVELINESS_PROBE_KEY');
|
||||
const REGISTRATION_COST = nconf.get('RATE_LIMITER_REGISTRATION_COST') || 5;
|
||||
const IP_RATE_LIMIT_COST = nconf.get('RATE_LIMITER_IP_COST') || 5;
|
||||
|
||||
let redisClient;
|
||||
let rateLimiter;
|
||||
@@ -78,14 +76,7 @@ export default function rateLimiterMiddleware (req, res, next) {
|
||||
|
||||
const userId = req.header('x-api-user');
|
||||
|
||||
let cost = 1;
|
||||
if (req.path === '/api/v4/user/auth/local/register' || req.path === '/api/v3/user/auth/local/register') {
|
||||
cost = REGISTRATION_COST;
|
||||
} else if (!userId) {
|
||||
cost = IP_RATE_LIMIT_COST;
|
||||
}
|
||||
|
||||
return rateLimiter.consume(userId || req.ip, cost)
|
||||
return rateLimiter.consume(userId || req.ip)
|
||||
.then(rateLimiterRes => {
|
||||
setResponseHeaders(res, rateLimiterRes);
|
||||
return next();
|
||||
|
||||
Reference in New Issue
Block a user