Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Todorant Mobile upload and download scripts to
const dotenv = require('dotenv')
dotenv.config({ path: `${__dirname}/../.env` })
const axios = require('axios')
const fs = require('fs')
;(async function getTranslations() {
console.log('==== Getting localizations')
const translations = (
await axios.get('')
).data.filter((l) => {
return l.tags.indexOf('mobile') > -1
console.log('==== Got localizations:')
console.log(JSON.stringify(translations, undefined, 2))
// Get flattened map
const flattenedMap = {} // { key: {en: '', ru: ''}}
translations.forEach((t) => {
const key = t.key
const variants = t.variants.filter((v) => !!v.selected)
flattenedMap[key] = variants.reduce((p, c) => {
p[c.language] = c.text
return p
}, {})
console.log('==== Decoded response:')
// Reverse the map
const reversedMap = {}
Object.keys(flattenedMap).forEach((k) => {
const internals = flattenedMap[k]
for (const language in internals) {
const text = internals[language]
if (!reversedMap[language]) {
reversedMap[language] = {}
reversedMap[language][k] = text
console.log('==== Reversed map')
for (let language in reversedMap) {
const obj = reversedMap[language]
const json = JSON.stringify(obj, undefined, 2)
if (language === 'ua') {
language = 'uk'
console.log('==== Saved object to the file')
"search": "Search",
"support": "Something isn't clear? Contact me at <a target=\"_blank\" href=\"\"></a>",
"cancel": "Cancel",
"save": "Save",
"delete": "Delete",
"current": "Current",
"planning": "Planning",
"skipped": "Skipped",
"name": "English",
"language": "Please, select the language.",
"login": "Please, login to using the button below.",
"settings": "Settings",
"addTodo": "Add todo",
"breakdownTodo": "Breakdown",
"pleaseLogin": "Please, login",
"subscription": "Subscription",
"allDoneTitle": "Congratulations!",
"allDoneText": "🥳 You did it! All the tasks for today are done, go get rest or maybe dance a little 💃",
"noTodosTitle": "To infinity!",
"noTodosText": "You don't have any todos for today. If you want to work — add a new todo for today or take the todos from future days.",
"todo": "Todo",
"text": "Text",
"addTodoDay": "Select exact day",
"addTodoMonth": "Or month",
"addTodoTime": "Exact time",
"addTodoFrog": "It's a frog!",
"completed": "Completed",
"addTodoOnTop": "Add on the top",
"addTodoMore": "More...",
"addTodoSingular": "Add todo!",
"addTodoPlural": "Add todos!",
"saveTodo": "Save todo!",
"planningText": "Looks like you have some planning to do! Please, redistribute the outstanding tasks below to unlock the \"Current\" tab and to keep being productive. Cheers!",
"editTodo": "Edit todo",
"anonymousText": "All your data is stored on your device at the moment. To start syncronizing with Todorant servers you need to login.",
"nameLabel": "Name",
"email": "Email",
"facebook": "Facebook",
"telegram": "Telegram",
"apple": "Apple",
"count": "Count",
"todosLastSync": "Todos",
"tags": "Hashtags",
"tagsCount": "Hashtags",
"todoCount": "Todos",
"notSyncedYet": "Not synced yet",
"settingsLastSync": "Settings",
"accountLastSync": "Account",
"syncData": "Sync data",
"googleTokenError": "No access token returned from Google",
"facebookPermissionsError": "Facebook permissions not granted",
"facebookTokenError": "Facebook access token cannot be obtained",
"loginWall": "Looks like you used Todorant for over a month and still haven't logged in! Keep your todos safe from getting lost — log in now and enjoy Todorant safely!",
"loginGoogle": "Login with Google",
"loginFacebook": "Login with Facebook",
"loginApple": "Login with Apple",
"loginTelegram": "Login with Telegram",
"logoutText": "Would you like to logout?",
"logout": "Logout",
"loginButton": "Login",
"alreadyRegistered": "(You are already registered)",
"purchaseError": "Error purchasing",
"purchaseThankYou": "Thank you",
"purchaseThankYouText": "Thank you for purchasing the subscription!",
"activeText": "🎉 Thank you a lot for supporting Todorant! I personally hope that Todorant has improved your life already and will keep making it better in future! You support allows me to work on Todorant daily and to add new features simplifying the work and freeing your time and your cognitive resources. Thank you a lot, again!",
"endTrialText": "🐝 It looks like your Todorant trial has come to the end. This is the awkward moment when you have to decide — whether Todorant has improved your life enough to spend money on it — and I have to navigate you towards the right decision. I am at the peak of my happines when I am able to bring value to the people; and if Todorant was able to make your life better, I will be more than thankful if you buy the subscription. It is just $5/month for the unlimited productivity and free mind. Every cent I earn on Todorant will be spent on improving the service. By supporting Todorant — you allow me, independent developer, to keep improving the product that benefits us all from day to day. Thank you a lot in advance!",
"earlyAdopterText": "👏👏 — this is me applauding you; you — the crazy ones who agreed to try out the instrument of ever increasing productivity, Todorant, among the first. One can say that you are the golden thousand, feedback of whom was shaping the Todorant from the very beginning. You have all the rights to use Todorant as much as you wish — you will never experience any limits, you have earned it. However, if you noticed that Todorant has drastically improved your life — you can still buy the subscription thus saying the best kind of \"Thank you\". You will never loose the \"Early adopter 🦄\" status — but will always be able to cancel the subscription. Thank you a lot for still using Todorant — and I will keep adding new features improving the product that positively affects all of us. Good luck!",
"earlyAdopterTextBonus": "🤗 Holy +*%$! Looks like either Todorant or I personally helped you enough that you purchased subscription even though you could use Todorant for free forever. I am deeply touched and happy to have a cup of coffee with you or just to chat a little. Feel free to reach me on Telegram (@borodutch) or by email — just click my name below. Thank you a lot! It is hard to imagine how important your contribution is!",
"trialText": "💪 Welcome to Todorant! You have 30 days after the registration to figure out whether Todorant works well for you. After 30 days will pass, you will still have access to the old tasks but will not be able to add new ones. It is perfectly fine to purchase subscription before 30 days end. I believe that using Todorant will bring you new heights in the personal productivity!",
"signature": "— Nikita, Todorant creator",
"rules1": "As soon as you get an actionable task (receive an email, phonecall, text, or if you see anything of interest that has to be put on your todo list) — create a todo for it right away. Do not wait, you will forget about it if you do not take it down.",
"rules2": "Todos should always be actionable and as explicit as possible. If a task takes less than 2 minutes, then do it right away and record it as completed.",
"rules3": "You either add a specific date or select a month while creating a todo. You cannot pick current month without selecting a specific date. This is done to relax your mind. If you trust the system and put everything that needs to be done on the correct date — you will encounter it at the right time. Huge amount of willpower is wasted on being constantly stressed about \"that other thing that I need to deal with but I am not quite sure what it was\". Learn to trust and relax.",
"rules4": "First thing you do each month is planning ahead. You take all the tasks assigned to the current month and you sort them in the correct dates. It allows you to filter out outdated tasks and keep your mind in peace with, knowing exactly what you need to do this month.",
"rules5": "First thing you do in the morning is planning your day. Have a glance at your Planning section. Can you handle everything? Distribute tasks that cannot be dealt with today. Redistribute any tasks left undone from the previous days.",
"rules6": "Unless it is an emergency, do not look at the planning section after you have finished planning. It will be way better psychologically if you only focus on one task, so keep your eyes on the Current section. Trust the system, it remembers everything. Do your job and relax your mind.",
"rules7": "Current section contains only one task that you need to focus on — nothing else. You can have more than one task a day, the amount of tasks as well as progress bar is displayed for your convenience. You are not allowed to jump between tasks — you should deal with every task linearly, one by one.",
"rules8": "Frogs are special types of tasks you generally do not want to deal with. Usually they are the tasks left behind for months and even years. Todorant ensures that you handle frogs first thing every day. In the morning your willpower reserve is large enough to handle even the most outrageous tasks. And after you finally deal with a frog — you receive just enough happiness to be smiling throughout the whole day. You feel proud of yourself when you deal with frogs.",
"rules9": "You are allowed to skip current task — but try to do so as rarely as possible. You cannot skip a frog. If you failed to complete a task and had to redistribute it twice, it becomes a frog.",
"rules10": "If the current task is too high level, then break it down to a list of subtasks. As soon as you break it down, the task is marked as completed.",
"rules11": "Add as much relevant information about the todo as possible. Add links to specific emails (gmail on web allows you to do this), websites, notes (like evernote), documents (like dropbox), leave phone numbers or add any information you might need to complete the task. Todorant is not meant to be a point of reference for you — instead it should act as a catalogue of links to the reference information relevant to specific todos.",
"rules12": "Feel free to join our multi-language group on Telegram to share experience and tricks on how to be more productive — @todorant_feedback! Your feedback about the service — suggestions, wishes and complaints — are highly welcome.",
"rules13": "Use the edit mode (the list order icon on top) on the Planning page to change the task order. If you want to assign a task to a specific week, just assign it to Monday and reassign it during the planning phase on Monday morning.",
"rules14": "Todorant does not have and will never have repeating tasks — the only thing they do well causing anxiety by hanging over you as unfinished tasks. If you need to complete repeating tasks — add all of them manually, your brain will thank you for conscious tasks.",
"rules15": "Todorant does not have the concept of \"Projects\" as it has proven itself to be demotivating, some of the \"folder\" never get open. Projects \"Fitness\" and \"Self-improvement\" send their regards. Instead, use #hashtags.",
"rules16": "Frogs will always appear on the top of the list.",
"rules17": "Todorant does not have notifications about the upcoming tasks with the exact time set. However, feel free to use Google Calendar integration so that Google can annoy you with notifications, not Todorant.",
"termsOfUse": "Terms of use",
"privacyPolicy": "Privacy policy",
"socketsInfo": "Sockets info",
"dataInfo": "Data info",
"howTo": "How to",
"howToUse": "How to use Todorant",
"account": "Account",
"todos": "Todos",
"general": "General",
"info": "Info",
"supportLabel": "Support",
"supportText": "Got questions or feedback? Send me an email or contact me on Telegram!",
"socketError": "Connection error: ",
"connected": "Connected",
"authorized": "Authorized",
"daysLeft": "Days left: ",
"buySubscription": "Buy subscription",
"defaultToToday": "Default to today",
"newTodosGoOnTop": "New todos go on top",
"deleteTodo": "Would you really like to delete",
"earlyAdopter": "Early adopter 🦄",
"active": "Active",
"inactive": "Inactive",
"trial": "Trial",
"error": "Error",
"ok": "OK",
"pleaseConfirm": "Please confirm",
"purchaseReceiptError": "No purchase receipt found",
"noTodosExistTitle": "No todos yet",
"noTodosExistText": "Go on — create a few todos by clicking the plus button below!",
"restorePurchases": "Restore purchases",
"noPurchasesError": "Sorry, you don't have any purchases yet",
"appleSigninError": "Could not sign in with Apple",
"syncDataHard": "Hard sync",
"firstDayOfWeek": "First day of a week",
"weekday1": "Monday",
"weekday2": "Tuesday",
"weekday3": "Wednesday",
"weekday4": "Thursday",
"weekday5": "Friday",
"weekday6": "Saturday",
"weekday0": "Sunday",
"appleUnauthorizedText": "I am obliged to ask you to start the trial by selecting an option below because this is required by the rules. If you already have an active subscription, please, login to you account in Settings.",
"appleUnauthorizedTextGoodNews": "Good news though: you will not be charged until the 30 days trial is finished.",
"appleUnauthorizedButtonExtra": "30 days free trial, then",
"introTitle": "Welcome!",
"introButton": "Intro message",
"intro1": "Let's keep it short: you want to improve your productivity. Todorant can help you. But Todorant is not another task list — it is a system that needs to be followed, it is a lifestyle, it is a habit.",
"intro2": "Reading through the \"How to use Todorant\" section in the settings will help you to get the most out of Todorant, but it is not necessary. Todorant will help you by limiting your actions — it will train your brain to get satisfaction from completing the tasks.",
"intro3": "If you have questions about something on a screen, first tap the \"i\" button on the top right of the screen. Not sure what a button does? Tap \"i\"!",
"intro4": "Todorant is free for the first 30 days and then $5/month. The reason it may appear a bit pricy is that you are not paying for a yet another todo app, you are purchasing productivity — the whole system that doesn't make you sink in settings and functions, but makes you complete the tasks! After all, try Todorant for 30 days for free and upgrade if you get more than $5 of value from it.",
"intro5": "I welcome you to the productivity journey, let the new era of your life begin!",
"introBack": "Let's go!",
"infoTitle": "Info",
"infoIntro": "Good job tapping the \"i\" button! This is the welcome message explaining what Todorant is. No more, no less.",
"infoCurrent": "This is the current task page. It only shows you one task that you should be working on right now. Stay focused, this is the only page you need after you planned your day.\n\nYou can skip the task if it's not a frog and if it is not the last task of the day.\n\nIf task is too broad — use the breakdown feature. After breaking down the task, it will be automatically marked as completed.",
"infoBreakdown": "This is the task breakdown screen. Feel free to add multiple tasks that are going to appear in the tasks list instead of the original task. After you add the new smaller tasks, the original task will be marked completed.",
"infoAdd": "This is the add task screen. Tasks should always be actionable (\"Find best flights to Mexico\" vs \"Go to Mexico\") and as small and exact as possible (\"Dust the displays\" vs \"Clean the house\"). You can add muptiple tasks here.\n\nTasks should have either a date or a month assigned to them. You cannot select the current month.\n\nFrogs are tasks that you don't want to deal with — they will appear first on your list. The earlier you start on a frog, the more chances are that you will complete it.",
"infoEdit": "This is the edit task screen. Here you can edit the task. Yep, this is it.",
"infoPlanning": "This is your planning section. Feel free to rearrange tasks and date titles (by long pressing and dragging them) — it's fun!\n\nAlso, don't forget to use #hashtags.",
"infoSettings": "This is your settings screen. Here you can configure various options. Please, make sure you read the \"How to use Todorant\" section.",
"infoSockets": "Todorant uses sockets to sync it's data with server. It works like magic as soon as both checkmarks are in place.",
"infoData": "Here you can see the most recent info about you local data storage and sync stats.",
"infoRules": "Please, read the rules thoroughly to get the most out of Todorant.",
"preserveOrderByTime": "Preserve exact time order",
"subscriptionMonth": "month",
"subscriptionYeariOS": "year (~15% discount)",
"subscriptionYearAndroid": "year (~16.6% discount)",
"languageSelect": "Language",
"languageAuto": "Auto",
"syncExactDates": "Recalculate exact dates",
"askBeforeDelete": "Verify deleting todos",
"copied": "copied",
"sync": "Synchronization",
"infoTags": "This is the list of all the hashtags you have used. If you don't see anything — go on, create a task with a #hastag in its text, it is the only way to add hashtags to this list.\n\nIf you want to change a hashtags color or to delete it, tap on it. Don't worry, hashtags are separate from todos — doing anything on this screen won't affect your todos. Well, changing colors can make your todos look cooler.",
"changeColor": "Change color",
"changeColorToDefault": "Reset color",
"colorMode": "Color mode",
"dark": "Dark",
"light": "Light",
"loadingData": "Loading your data...",
"breakdownRequest": "Looks like you move this task way too much. Please break it down, you can no longer move it to another date. Believe me, it will help to compele the task!",
"breakdownButton": "Breakdown",
"back": "Back",
"important": "Important",
"rateTitle": "You completed more than 100 tasks! 🎉🎉🎉 How much did Todorant improve your life?",
"rate": "Rate",
"send": "Send",
"rateCommentPlaceholder": "Please write a few words about what you did not like about Todorant",
"rateCommentEmptyError": "Please don't leave the comment field blank",
"starTerrible": "Not at all",
"starBad": "A bit",
"starOkay": "Somewhat",
"starGood": "Fairly",
"starGreat": "A lot",
"rateSolicitationApple": "Would you mind leaving Todorant a 5 star rating on the App Store, please? It helps a lot!",
"rateSolicitationGoogle": "Would you mind leaving Todorant a 5 star rating on the Play Store, please? It helps a lot!",
"rateButton": "Leave rating!",
"integrations": "Integrations",
"notConnected": "Not connected",
"disconnect": "Disconnect",
"infoIntegrations": "You can setup third party app integrations here by tapping the options.",
"googleCalendar": "Google Calendar",
"loginQR": "Login with QR",
"qrDescription": "Please open the QR code popup on the Todorant website and scan the code here",
"cameraAuthorization": "Camera not authorized",
"needCameraPermission": "Todorant uses camera to scan QR codes",
"security": "Security",
"encryptTodo": "Encrypt todos",
"infoSecurity": "Use this section with the utmost caution! Encryption will not work unless you add a password. There will be two types of tasks: encrypted and unencrypted. All new tasks will be encrypted. Old todos can be converted to be encrypted with the button below. If you loose the password there will be no way to recover tasks.",
"encryptedTodos": "Encrypted tasks",
"unencryptedTodos": "Unencrypted tasks",
"encryptAllButton": "Encrypt all",
"decryptAllButton": "Decrypt all",
"password": "Password",
"encryptionConfirm": "Are you sure you want to encrypt the todos with this password? You will be able to decrypt todos later with the same password. If you loose the password, you will not be able to decrypt todos!",
"encryptionDisableConfirm": "Are you sure you want to remove the key and disable the encryption? This will not decrypt the tasks that are encrypted.",
"disable": "Disable",
"confirmEncryptAll": "Are you sure you want to encrypt all tasks with the password? If you loose the password, you will not be able to decrypt the tasks!",
"confirmDecryptAll": "Are you sure you want to decrypt all tasks?",
"passwordError": "Wrong password. Looks like some of the encrypted tasks you have cannot be decrypted by this password.",
"soundEffects": "Sound effects",
"missionPassed": "Mission passed",
"respect": "Respect +"
"search": "Поиск",
"support": "Что-то непонятно? Пишите мне на <a target=\"_blank\" href=\"\"></a>",
"cancel": "Отменить",
"save": "Сохранить",
"delete": "Удалить",
"current": "Текущее",
"planning": "Планирование",
"skipped": "Пропущено",
"name": "Русский",
"language": "Пожалуйста, выберите язык.",
"login": "Пожалуйста, зайдите на, используя кнопку ниже.",
"settings": "Настройки",
"addTodo": "Новая задача",
"breakdownTodo": "Разбивка",
"pleaseLogin": "Пожалуйста, войдите",
"subscription": "Подписка",
"allDoneTitle": "Поздравляем!",
"allDoneText": "🥳 Вы это сделали! Все задачи на сегодня выполнены, идите отдохните — ну или потанцуйте немного 💃",
"noTodosTitle": "Вперед!",
"noTodosText": "На сегодня у вас нет задач. Хотите поработать — добавьте новые задачи на сегодня или заберите задачи с других дней.",
"todo": "Задача",
"text": "Текст задачи",
"addTodoDay": "Точный день",
"addTodoMonth": "Или месяц",
"addTodoTime": "Точное время",
"addTodoFrog": "Это лягушка!",
"completed": "Завершено",
"addTodoOnTop": "Добавить в начало списка",
"addTodoMore": "Больше настроек...",
"addTodoSingular": "Добавить задачу!",
"addTodoPlural": "Добавить задачи!",
"saveTodo": "Сохранить задачу!",
"planningText": "Похоже, вам нужно заняться планированием! Пожалуйста, перераспределите оставшиеся задачи ниже для того, чтобы разблокировать секцию \"Текущее\", и для того, чтобы оставаться продуктивными. Удачи!",
"editTodo": "Редактирование",
"anonymousText": "Все ваши данные сейчас хранятся у вас на девайсе. Чтобы начать синхронизировать данные с серверами Тудуранта, вам нужно залогиниться.",
"nameLabel": "Имя",
"email": "Имеил",
"facebook": "Фейсбук",
"telegram": "Телеграм",
"apple": "Эппл",
"count": "Количество",
"todosLastSync": "Задачи",
"tags": "Хештеги",
"tagsCount": "Хештеги",
"todoCount": "Задачи",
"notSyncedYet": "Не синхронизированно",
"settingsLastSync": "Настройки",
"accountLastSync": "Аккаунт",
"syncData": "Синхронизировать данные",
"googleTokenError": "Гугл не поделился с нами токеном доступа",
"facebookPermissionsError": "Фейсбук не выдал нам достаточные разрешения",
"facebookTokenError": "Фейсбук не дал нам токен доступа",
"loginWall": "Похоже, вы пользуетесь Тудурантом уже больше месяца и еще не залогинились! Сохраните ваши задачи — залогиньтесь в Тудурант и храните задачи в безопасном хранилище!",
"loginGoogle": "Зайти через Гугл",
"loginFacebook": "Зайти через Фейсбук",
"loginApple": "Зайти через Эппл",
"loginTelegram": "Зайти через Телеграм",
"logoutText": "Хотите выйти?",
"logout": "Выйти",
"loginButton": "Войти",
"alreadyRegistered": "(вы уже зарегистрированы)",
"purchaseError": "Ошибка покупки",
"purchaseThankYou": "Спасибо",
"purchaseThankYouText": "Спасибо за покупку подписки!",
"activeText": "🎉 Огромное спасибо за поддержку Тудуранта! Я лично надеюсь, что Тудурант достаточно изменил вашу жизнь и будет помогать ее улучшать изо дня в день в будущем! Ваша поддержка помогает мне заниматься Тудурантом на постоянной основе и добавлять новые функции, упрощающие работу и освобождающие вам время и когнитивные ресурсы. Спасибо вам еще раз!",
"endTrialText": "🐝 Похоже, ваш триал Тудуранта подошел к концу. Это тот самый неловкий момент, когда вам нужно сделать решение — настолько ли вам помог Тудурант, чтобы начать использовать его на постоянной основе; а мне нужно подтолкнуть вас в сторону правильного решения. Вершина моего счастья — это приносить пользу людям; а если Тудурант и вправду стал неотъемлемой частью вашей жизни, то я буду невероятно благодарен вам, если вы приобретете подписку. Всего $5/месяц — это цена бесконечной продуктивности и свободной головы. Каждый цент, который я получу с Тудуранта, я буду направлять на развитие этого сервиса. Поддержав Тудурант, вы лично поможете независимому разработчику ежедневно улучшать продукт, которым вы пользуетесь на постоянной основе. Заранее благодарю вас!",
"earlyAdopterText": "👏👏 — это я хлопаю вам стоя; вы — безумцы, которые согласились попробовать инструмент повышения персональной продуктивности Тудурант одними из первых. Можно сказать, вы — золотая тысяча пользователей, на отзывах которых и создавался Тудурант. Вы имеете полное право пользоваться Тудурантом столько, сколько вам угодно — для этого аккаунта никогда не будет введено никаких ограничений, вы заслужили это. Однако если вы заметили, что Тудурант резко изменил вашу жизнь к лучшему — вы все еще можете приобрести подписку, тем самым сказав простое, но очень важное для меня лично: \"Спасибо\". Вы никогда не потеряете статус \"Ранний адоптер 🦄\" — а подписку сможете отменить в любой момент. Спасибо большое, что вы продолжаете пользоваться Тудурантом — а я продолжу добавлять приятные функции в этот инструмент, который делает каждого из нас лучше. Удачи!",
"earlyAdopterTextBonus": "🤗 Вот это да! Должно быть, либо Тудурант, либо я лично вам настолько помог, что, даже имея возможность пользоваться Тудурантом бесплатно, вы решили меня поддержать. Я поражен прямо в сердце и с удовольствием попью с вами кофе или просто поболтаю по душам. Пишите либо мне в телеграме (@borodutch), либо на почту — просто нажмите на мое имя ниже. Спасибо вам огромное! Сложно представить, насколько для меня важен ваш вклад!",
"trialText": "💪 Добро пожаловать в Тудурант! С момента регистрации у вас есть ровно 30 дней для того, чтобы опробовать систему и понять, подходит ли она вам. По истечении 30 дней вы все еще будете иметь доступ к существующим задачам, но не сможете добавлять новые. Если что, то никто не мешает вам оформить подписку до окончания триального периода в 30 дней. Я уверен, что вместе с Тудурантом вы сможете достичь новых высот в собственной продуктивности!",
"signature": "— Никита, создатель Тудуранта",
"rules1": "Как только у вас появляется задача (получаете имеил, звонок, сообщение или просто видите что-то интересное что нужно добавить в ваш список задач) — сразу же создавайте задачу. Не ждите, вы забудете про эту задачу, если ее не запишете.",
"rules2": "Задачи всегда должны быть призывом к действию и как можно более понятными. Если задача займет меньше двух минут — сделайте ее сразу и создайте в списке задач, как выполненную.",
"rules3": "Во время создания задачи вы либо указываете точную дату, либо месяц. Вы не можете выбрать текущий месяц без определенной даты. Это сделано для того, чтобы расслабить вам мозг. Если вы доверяете системе и добавляете в нее все, что нужно, на правильные даты — то вы будете встречаться с задачами в правильное время. Огромное количество силы воли тратится зря на постоянный стресс вроде \"той вещи, которую мне нужно сделать, но я точно не помню, что это за вещь\". Научитесь доверять и расслабляться.",
"rules4": "Первая вещь, которую вам нужно будет сделать в начале каждого месяца — это планирование. Вы берете все задачи на текущий месяц и расфасовываете их в нужные даты. Это позволяет вам отфильтровать задачи, которые более не актуальны и помогает вам оставаться в полном спокойствии, четко осознавая, что вам нужно будет делать в этом месяце.",
"rules5": "Первым делом каждым утром вы будете планировать. Посмотрите на секцию \"Планирование\". Вы сможете все это сделать? Раскидайте задачи, с которыми сегодня не справитесь, на другие дни. Раскидайте так же и задачи, которые остались незаконченными с предыдущих дней.",
"rules6": "Кроме чрезвычайных случаев, никогда не смотрите на секцию планирования после окончания процесса планирования. Вам психологически будет гораздо проще, если вы будете сфокусированны только на одной задаче за раз, так что смотрите только на секцию \"Текущее\". Доверяйте системе, она помнит все. Работайте и расслабляйте свой мозг.",
"rules7": "В секции \"Текущее\" всегда есть максимум одна задача, на которой вы должны фокусироваться — больше ничего. У вас может быть больше одной задачи в день, количество задач и прогресс показан для вашего удобства. Вам нельзя прыгать между задачами — вы должны работать линейно, выполняя одну задачу за раз.",
"rules8": "Лягушки — это особый тип задач, которые вы не хотите делать. Обычно, это задачи, которые вы не делаете месяцами и даже годами. Тудурант заставляет вас разбираться с лягушками первым делом каждый день. Утром ваши резервы силы воли достаточно большие, чтобы справиться даже с самыми неприятными задачами. А после победы над лягушкой вы получите достаточный заряд счастья, чтобы сиять улыбкой весь день. Вы будете собой гордиться, что наконец-то справляетесь с лягушками.",
"rules9": "Вам разрешено пропускать текущую задачу — но делайте это как можно реже. Если вы не смогли выполнить задачу и вам пришлось ее перераспределить дважды — она становится лягушкой.",
"rules10": "Если текущая задача слишком высокоуровневая, то разбейте ее на список подзадач. Как только вы разбили задачу на подзадачи, она отмечается, как завершенная.",
"rules11": "Добавляйте настолько много важной информации в задачи, насколько сможете. Добавляйте ссылки на имейлы (gmail позволяет это делать), вебсайты, заметки (как evernote), документы (например, dropbox), оставляйте телефонные номера или добавляйте любую информацию, которая может быть важной для решения задачи. Тудурант не должен быть главным хранилищем и каталогом ваших данных, но местом, где ссылки на необходимые для задач данные, хранятся сразу с определенными задачами.",
"rules12": "Не стесняйтесь присоединяться к нашей группе в Телеграме для обмена опытом о том, как становиться продуктивнее — @todorant_feedback! Ваши отзывы о работе сервиса — предложения, пожелания и жалобы — крайне приветствуются.",
"rules13": "Переносите задачи на странице \"Планирования\" для изменения порядка. Если вы хотите создать задачу на определенную неделю — просто добавьте ее на понедельник и перераспределите во время планирования утром понедельника.",
"rules14": "В Тудуранте нет и никогда не будет автоматически повторяющихся задач — единственное, в чем они помогают — это создание атмосферы страха, накапливаясь невыполненным грузом. Если нужно внести повторяющуюся задачу — внесите ее вручную, ваш мозг скажет вам спасибо за осмысленную задачу.",
"rules15": "В Тудуранте нет концепта \"Проектов\", так как он показал себя демотивирующим, некоторые папки просто никогда не открываются. Проекты \"Фитнес\" и \"Саморазвитие\" передают привет. Вместо этого, используйте #хештеги.",
"rules16": "Лягушки всегда находятся сверху в списке.",
"rules17": "В Тудуранте нет напоминаний о задачах с точным временем. Однако вы можете включить интеграцию с Гугл Календарем, чтобы вам надоедал нотификации Гугл, а не Тудурант.",
"termsOfUse": "Условия использования",
"privacyPolicy": "Политика конфиденциальности",
"socketsInfo": "Соккеты",
"dataInfo": "Данные",
"howTo": "Как пользоваться?",
"howToUse": "Как использовать Тудурант?",
"account": "Аккаунт",
"todos": "Задачи",
"general": "Общее",
"info": "Информация",
"supportLabel": "Поддержка",
"supportText": "Есть вопросы или обратная связь? Пошлите мне имеил или напишите мне в Телеграме!",
"socketError": "Ошибка подключения: ",
"connected": "Подключено",
"authorized": "Авторизировано",
"daysLeft": "Осталось дней: ",
"buySubscription": "Купить подписку",
"defaultToToday": "Новые задачи — сегодня",
"newTodosGoOnTop": "Новые задачи добавляются в начало списка",
"deleteTodo": "Хотите удалить ",
"earlyAdopter": "Ранний адоптер 🦄",
"active": "Активная",
"inactive": "Неактивная",
"trial": "Триал",
"error": "Ошибка",
"ok": "ОК",
"pleaseConfirm": "Пожалуйста, подтвердите",
"purchaseReceiptError": "Не найден чек покупки",
"noTodosExistTitle": "Еще нет задач",
"noTodosExistText": "Давайте — добавьте задачи, нажав на кнопку с плюсом ниже!",
"restorePurchases": "Восстановить покупки",
"noPurchasesError": "Простите, но у вас пока нет покупок",
"appleSigninError": "Не получилось зайти через Эппл",
"syncDataHard": "Принудительная синхронизация",
"firstDayOfWeek": "Первый день недели",
"weekday1": "Понедельник",
"weekday2": "Вторник",
"weekday3": "Среда",
"weekday4": "Четверг",
"weekday5": "Пятница",
"weekday6": "Суббота",
"weekday0": "Воскресенье",
"appleUnauthorizedText": "Я вынужден попросить вас начать пробный период, выбрав опцию ниже, потому что Эппл требует, чтобы все пробные периоды проходили через их внутренние покупки, когда аккаунт был создан на девайсе от Эппл. Если у вас уже есть подписка, пожалуйста, зайдите в свой аккаунт в Настройках. Прошу прощения за неудобство, но иначе Эппл не разрешали добавить Тудурант в АппСтор.",
"appleUnauthorizedTextGoodNews": "Однако есть хорошие новости: с вас не снимут деньги, пока бесплатный пробный период в 30 дней не закончится.",
"appleUnauthorizedButtonExtra": "30 дней бесплатно, потом",
"introTitle": "Добро пожаловать!",
"introButton": "Вступительное сообщение",
"intro1": "Буду краток: вы хотите улучшить вашу продуктивность. Тудурант поможет вам с этим. Но учтите, что Тудурант — это не очередной список задач — это система, которой нужно следовать, это стиль жизни, это привычка.",
"intro2": "Прочтение пункта \"Как использовать Тудурант\" в настройках может помочь, но это совсем необязательно. Тудурант поможет вам, ограничив ваши действия — он заставит ваш мозг получать удовольствие от завершения задач.",
"intro3": "Если у вас появятся какие-либо вопросы о функциях на каком-либо экране, сначала нажмите на кнопку \"i\" справа вверху. Не знаете, что делает какая-либо кнопка? Жмите \"i\"!",
"intro4": "Тудурант бесплатен первый месяц, а потом стоит примерно $5/месяц. Причина, по которой Тудурант может выглядеть дорогим — это то, что вы не покупаете очередной менеджер задач, а подписываетесь на систему, которая заставляет вас наконец-то эти задачи выполнять. Другие приложения закидывают вас функциями и настройками — Тудурант же заставляет вас наконец-то начать выполнять задачи и добиваться целей! В конце концов, попробуйте Тудурант первые 30 дней и оплатите подписку, если вы получите больше $5 пользы.",
"intro5": "Я приветствую вас на вашем пути продуктивности, да начнется же новая эра вашей жизни!",
"introBack": "Поехали!",
"infoTitle": "Информация",
"infoIntro": "Отлично! Вы нажали на \"i\"! Это просто приветственное сообщение, которое немного разъясняет, что такое Тудурант. Не более и не менее.",
"infoCurrent": "Это страница текущей задачи. Она показывает только одну задачу, над которой вам сейчас нужно работать. Оставайтесь сосредоточенными, это единственная страница, которая вам нужна после планирования дня.\n\nВы можете пропускать задачи, если это не лягушки и не последние задачи дня.\n\nЕсли задача слишком большая и необъятная — используйте кнопку разбивки. После разбивки задачи, она автоматически будет помечена как выполненная.",
"infoBreakdown": "Это экран разбивки задачи. Добавьте несколько мелких задач, которые заменят собой более крупную задачу. После того, как вы добавите новые задачи, оригинальная большая задача будет помечена, как выполненная.",
"infoAdd": "Это экран добавления задач. Задачи должны быть указывающими на следующее действие (\"Найти лучшие билеты в Мексику на агрегаторе билетов\", а не \"Полететь в Мексику\") и наиболее маленькими и понятными (\"Протереть дисплей\", а не \"Прибраться дома\"). Вы можете добавлять несколько задач за раз.\n\nЗадачи должны быть привязаны либо к определенной дате, либо к определенному месяцу. На текущий месяц поставить задачу нельзя.\n\nЛягушки — это задачи, которые вы не хотите делать; они всегда будут наверху списка задач. Чем раньше днем вы расправитесь с лягушкой, тем больше удовольствия получите.",
"infoEdit": "Это экран редактирования задачи. Тут можно редактировать задачу. Именно так.",
"infoPlanning": "Это ваша секция планирования. Перетаскивайте задачи и даты (зажав их ненадолго) — это весело!\n\nИ не забывайте, что можно использовать #хештеги.",
"infoSettings": "Это ваш экран настроек. Здесь вы можете менять разные опции. Пожалуйста, прочитайте секцию \"Как пользоваться Тудурантом\".",
"infoSockets": "Тудурант использует соккеты, чтобы синхронизировать информацию с сервером. Все работает, как магия, когда оба пункта горят зеленой галочкой.",
"infoData": "Здесь расположена информация о ваших локальных данных и о статистике синхронизации.",
"infoRules": "Пожалуйста, прочитайте секцию \"Как пользоваться Тудурантом\", чтобы выжать максимум из Тудуранта.",
"preserveOrderByTime": "Следить за порядком задач с точным временем",
"subscriptionMonth": "месяц",
"subscriptionYeariOS": "год (~15% скидка)",
"subscriptionYearAndroid": "год (~16.6% скидка)",
"languageSelect": "Язык",
"languageAuto": "Авто",
"syncExactDates": "Пересчитать точные даты",
"askBeforeDelete": "Спрашивать перед удалением задач",
"copied": "скопировано",
"sync": "Синхронизация",
"infoTags": "Это список всех хештегов, которые вы использовали. Если вы здесь ничего не видите — вперед, создайте задачу с #хештегом в тексте задачи, это единственный способ добавить хештеги в этот список.\n\nЕсли вы хотите изменить цвет хештега или удалить хештег — просто коснитесь его пальцем. Не волнуйтесь, хештеги хранятся отдельно от задач — что бы вы ни сделали на этом экране, никак не повлияет на ваши задачи. Ну, разве что изменение цвета может сделать задачи клевее.",
"changeColor": "Поменять цвет",
"changeColorToDefault": "Сбросить цвет",
"colorMode": "Тема",
"dark": "Темная",
"light": "Светлая",
"loadingData": "Загружаем ваши данные...",
"breakdownRequest": "Похоже, вы переносите эту задачу слишком часто. Пожалуйста, разбейте ее на более мелкие задачи, вы больше не можете ее переносить. Поверьте, это поможет вам завершить задачу!",
"breakdownButton": "Разбить",
"back": "Назад",
"important": "Важное",
"rateTitle": "Вы заверишили больше 100 задач! 🎉🎉🎉 Насколько сильно Тудурант улучшил вашу жизнь?",
"rate": "Оценить",
"send": "Отправить",
"rateCommentPlaceholder": "Пожалуйста, напишите пару слов о том, что вам не понравилось в Тудуранте",
"rateCommentEmptyError": "Пожалуйста, не оставляйте это поле пустым",
"starTerrible": "Не улучшил",
"starBad": "Чуть-чуть",
"starOkay": "Немного",
"starGood": "Улучшил",
"starGreat": "Сильно улучшил",
"rateSolicitationApple": "Можете поставить 5 звезд Тудуранту в Апп Сторе, пожалуйста? Это сильно помогает приложению развиваться!",
"rateSolicitationGoogle": "Можете поставить 5 звезд Тудуранту в Плей Сторе, пожалуйста? Это сильно помогает приложению развиваться!",
"rateButton": "Поставить 5 звезд!",
"integrations": "Интеграции",
"notConnected": "Не подключено",
"disconnect": "Отключить",
"infoIntegrations": "Здесь можно настроить интеграции со сторонними сервисами, нажав на опции на экране.",
"googleCalendar": "Google Calendar",
"loginQR": "Зайти через QR",
"qrDescription": "Пожалуйста, откройте окно с QR кодом в веб-версии Тудуранта и просканируйте код тут",
"cameraAuthorization": "Камера не авторизована",
"needCameraPermission": "Тудурант использует камеру для сканирования QR кодов",
"security": "Безопасность",
"encryptTodo": "Шифровать задачи",
"infoSecurity": "Используйте эту секцию с максимальной осторожностью! Шифрование не будет работать, если вы не введете пароль. Дальше будет два типа задач: зашифрованные и незашифрованные. Все новые задачи будут зашифрованными. Старые задачи можно будет зашифровать, нажав на кнопку ниже. Если вы потеряете пароль, восстановить задачи будет невозможно.",
"encryptedTodos": "Зашифрованные задачи",
"unencryptedTodos": "Незашифрованные задачи",
"encryptAllButton": "Зашифровать все",
"decryptAllButton": "Расшифровать все",
"password": "Пароль",
"encryptionConfirm": "Уверены, что хотите шифровать все задачи паролем? Вы сможете расшифровать задачи этим же паролем. Если вы потеряете пароль, у вас не получится расшифровать задачи!",
"encryptionDisableConfirm": "Уверены, что хотите убрать пароль и выключить шифрование? Это действие не расшифрует зашифрованные задачи.",
"disable": "Выключить",
"confirmEncryptAll": "Уверены, что хотите зашифровать все задачи паролем? Если вы потеряете пароль, у вас не получится расшифровать задачи!",
"confirmDecryptAll": "Уверены, что хотите расшифровать все задачи?",
"passwordError": "Неправильный пароль. Похоже, какие-то ваши задачи нельзя расшифровать этим паролем.",
"soundEffects": "Звуковые эффекты",
"missionPassed": "Миссия завершена",
"respect": "Уважение +"
const dotenv = require('dotenv')
dotenv.config({ path: `${__dirname}/../.env` })
const axios = require('axios')
const fs = require('fs')
const files = fs.readdirSync(`${__dirname}/../src/@assets/translations`)
const localizations = {}
for (const fileName of files) {
let fileNameLeft = fileName.split('.')[0]
if (fileNameLeft === 'uk') {
fileNameLeft = 'ua'
localizations[fileNameLeft] = JSON.parse(
const result = {}
const keys = Array.from(
.map((key) => {
const names = Object.keys(localizations[key])
return names
.reduce((p, c) => {
c.forEach((e) => p.add(e))
return p
}, new Set())
keys.forEach((key) => {
const keyObject = {}
for (const language in localizations) {
if (localizations[language][key]) {
keyObject[language] = localizations[language][key]
result[key] = keyObject
;(async function postLocalizations() {
console.log('==== Posting body:')
console.log(JSON.stringify(result, undefined, 2))
try {
// await`http://localhost:1337/localizations`, {
await``, {
localizations: result,
password: process.env.PASSWORD,
username: 'borodutch',
tags: ['mobile'],
console.error(`==== Body posted!`)
} catch (err) {
console.error(`==== Error posting: ${err.message}`)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment