1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-09-05 20:56:22 +02:00

Compare commits

..

37 Commits

Author SHA1 Message Date
Laurent Cozic
f4a562bc3c Electron release v1.0.195 2020-03-22 19:43:12 +00:00
Laurent Cozic
de8bf33ad9 Tools: Disabling tool checks for now as it is printing many unecessary messages to log 2020-03-22 19:41:23 +00:00
妙呀
159eaf7899 Translation: Update zh_CN.po (#2825)
Adjusted and added some Chinese simplified translation text
I like Joplin very much and hope to do my best
------------
调整和新增了部分中文简体翻译文本
非常喜欢Joplin,希望能尽绵薄之力
2020-03-21 14:34:31 -04:00
lighthousebulb
1bc045eb18 Translation: Update de_DE.po (#2806)
updated some translation strings
2020-03-21 14:33:40 -04:00
Laurent Cozic
0f934e48bc Revert "Desktop: Fixes #2467: Menu items were not disabled in viewer-only mode (#2576)"
Some items still need to be enabled so implementation needs to be
reviewed. Reverting for now.

This reverts commit 0be982c798.
2020-03-21 13:18:37 +00:00
Naveen M V
3ecd29d0b5 All: Fixes #2803: Remember last selected note (#2809)
* Fix : Remember last selected note

Fixes #2803

* Add unit test
2020-03-21 11:29:22 +00:00
Helmut K. C. Tessarek
42498842b5 translation fixes 2020-03-19 00:02:36 -04:00
Helmut K. C. Tessarek
ed4fbf093d Update translations 2020-03-18 23:49:06 -04:00
StarFang208
96b19027ec Translation: Update it_IT.po (#2791)
* Update it_IT.po

New translated lines and translator's name fixed.

* fix it_IT.po

Added the removed lines.
2020-03-18 23:47:48 -04:00
nullpointer666
cdb8a1e98c Desktop: fix menu bar shortcut (Alt+E) while editing a note (Win) (#2776) 2020-03-17 12:49:36 -04:00
mic704b
8cd26c9380 All: Fix integration test harness issues. (#2723) 2020-03-16 13:30:54 +11:00
Helmut K. C. Tessarek
0863f0d564 Desktop: Add global shortcut to show/hide Joplin (#2653)
Previously it was possible to open Joplin by clicking on the tray icon.
This functionality is no longer available due to changes in Electron.

The following key combination will show or hide Joplin in the current workspace:

- macOS: `Cmd+Opt+J`
- Linux, Windows: `Ctrl+Alt+J`
2020-03-16 00:36:18 +00:00
mic704b
63a2f7b7a5 All: Fix calls to non-existent function (#2675)
* Fix calls to non-existent function

* Add tests.

* Fix travis lint problems.
2020-03-16 08:53:49 +11:00
PackElend
9b562276f3 updated ## Recommended steps
- replaced Development by Features in `4. Come up with project that you're interested in and discuss it in [Features category](https://discourse.joplinapp.org/c/features)`
-
2020-03-15 21:52:24 +01:00
mic704b
a17e01793e All: Fix format of note timestamps (#2672)
* Correct format of timestamps during unserialization.

* Add tests.
2020-03-15 12:07:01 +00:00
mic704b
7fb061ea76 Desktop: Fix show-all-notes update bugs. (#2642) 2020-03-15 12:05:17 +00:00
gasolin
91d864bded Mobile: Resolves #2286: Always show scrollbar in editor mode (#2594)
* Mobile: show scrollbar in editor mode

* always show the scrollbar
2020-03-15 11:55:41 +00:00
Laurent Cozic
339d7d16c7 Desktop: Fix issue with tag not being displayed below note when it is created 2020-03-15 11:45:33 +00:00
Laurent Cozic
8e5762c3a3 Merge branch 'master' of github.com:laurent22/joplin 2020-03-15 10:19:46 +00:00
Rahul Mohata
50a811720f Mobile: Fixes #2695: Fixed colour of background in OLED dark theme (#2757) 2020-03-15 10:13:44 +00:00
Anjula Karunarathne
c2e1c4c1e1 Desktop: Fixes #2700: Fix button label wrapping in toolbar (#2708) 2020-03-15 09:49:24 +00:00
Laurent Cozic
e7b11a2d82 Desktop: Fixes #2618: Fixed renaming tag issue 2020-03-15 09:47:47 +00:00
Laurent Cozic
61d3582357 Restored note history feature by Naveen M V <naveenmv7@gmail.com> 2020-03-15 09:40:57 +00:00
Laurent Cozic
9e66219690 Revert "Desktop: Reolves #2409: Added arrows to go front and back through note history (#2563)"
Fixing merge issue...

This reverts commit d049b8846c.
2020-03-15 09:40:12 +00:00
Naveen M V
d049b8846c Desktop: Reolves #2409: Added arrows to go front and back through note history (#2563) 2020-03-15 09:38:19 +00:00
RedDocMD
bdd760f343 Desktop: Resolves #2703: Fast notebook deletion (#2730)
* Batch delete for Notebooks added

* Extended the Folder.delete() unit test

* Unit tests added for Note.batchDelete()
2020-03-14 21:01:45 +11:00
Helmut K. C. Tessarek
1ee88618e8 reencrypt -> re-encrypt 2020-03-13 20:52:28 -04:00
Laurent Cozic
e399474b4e Tools: Apply "curly" eslint rule 2020-03-13 23:57:34 +00:00
Laurent Cozic
e2e55b6e08 Tools: Apply eslint space-infix-ops rule 2020-03-13 23:52:40 +00:00
Laurent Cozic
d0d2bad7f4 Tools: Enforce and apply eslint rules prefer-const and no-var 2020-03-13 23:46:14 +00:00
Laurent Cozic
92bee549a1 Electron release v1.0.194 2020-03-13 23:24:56 +00:00
Ishant Gupta
02121f66de Mobile: Resolves #2721: Added button to select all notes (#2744)
* added feature of select all and closes #2721

* added functionality of toggle select all button to deselect all notes
2020-03-13 22:41:56 +00:00
Ishant Gupta
115eb6f511 Mobile: Resolves #2715: Close sidebar when displaying error dialog (#2720)
* added a new close function to close sidebar for an error and fixed #2715

* changed function to inline call of dispatch fixes #2715
2020-03-13 19:58:17 +00:00
Rahul Mohata
d208da577f iOS: Resolves #2701: Removed "Export debug report" button (#2704) 2020-03-13 19:55:26 +00:00
Runo Saduwa
62665899c6 Tools: Added build tools detection script (#2661)
* finished writing first script version

* added preinstall script

* removed white space and platform if statements

* remove error log

* removed install function

* corrected commands

* changed ls to list
2020-03-13 18:48:17 +00:00
Laurent Cozic
7640839f92 Let's leave that undocumented for now
Not the recommended way to create tags - there's the /tags and /notes/:id/tags for this
2020-03-13 18:46:38 +00:00
Yuvaraj J
cda837247a API: Resolves #941: Add support for "tags" property for note PUT request (#2649)
* API: Fix updation of tags when updating a note

* Add test for fix updation of tags

* Rewrite unit test and change variable name

* Use consistent variables and function calls

* Use default function call and change variable

* Handle case when tags is empty string

* Restructure test cases and improve tags check

* Update documentation
2020-03-13 18:44:47 +00:00
356 changed files with 27297 additions and 23062 deletions

View File

@@ -54,16 +54,21 @@ module.exports = {
// This error is always a false positive so far since it detects
// possible race conditions in contexts where we know it cannot happen.
"require-atomic-updates": 0,
"prefer-const": ["error"],
"no-var": ["error"],
// Checks rules of Hooks
"react-hooks/rules-of-hooks": "error",
// Checks effect dependencies
"react-hooks/exhaustive-deps": "warn",
// Disable because of this: https://github.com/facebook/react/issues/16265
// "react-hooks/exhaustive-deps": "warn",
// -------------------------------
// Formatting
// -------------------------------
"space-in-parens": ["error", "never"],
"space-infix-ops": ["error"],
"curly": ["error", "multi-line", "consistent"],
"semi": ["error", "always"],
"eol-last": ["error", "always"],
"quotes": ["error", "single"],
@@ -92,7 +97,7 @@ module.exports = {
"multiline-comment-style": ["error", "separate-lines"],
"space-before-blocks": "error",
"spaced-comment": ["error", "always"],
"keyword-spacing": ["error", { "before": true, "after": true }]
"keyword-spacing": ["error", { "before": true, "after": true }],
},
"plugins": [
"react",

View File

@@ -134,7 +134,7 @@ class AppGui {
const item = folderList.currentItem;
if (item === '-') {
let newIndex = event.currentIndex + (event.previousIndex < event.currentIndex ? +1 : -1);
const newIndex = event.currentIndex + (event.previousIndex < event.currentIndex ? +1 : -1);
let nextItem = folderList.itemAt(newIndex);
if (!nextItem) nextItem = folderList.itemAt(event.previousIndex);
@@ -186,7 +186,7 @@ class AppGui {
borderRightWidth: 1,
};
noteList.on('currentItemChange', async () => {
let note = noteList.currentItem;
const note = noteList.currentItem;
this.store_.dispatch({
type: 'NOTE_SELECT',
id: note ? note.id : null,
@@ -338,7 +338,7 @@ class AppGui {
if (consoleWidget.isMaximized__ === doMaximize) return;
let constraints = {
const constraints = {
type: 'stretch',
factor: !doMaximize ? 1 : 4,
};
@@ -415,10 +415,10 @@ class AppGui {
async handleModelAction(action) {
this.logger().info('Action:', action);
let state = Object.assign({}, defaultState);
const state = Object.assign({}, defaultState);
state.notes = this.widget('noteList').items;
let newState = reducer(state, action);
const newState = reducer(state, action);
if (newState !== state) {
this.widget('noteList').items = newState.notes;
@@ -485,9 +485,9 @@ class AppGui {
// this.logger().debug('Got command: ' + cmd);
try {
let note = this.widget('noteList').currentItem;
let folder = this.widget('folderList').currentItem;
let args = splitCommandString(cmd);
const note = this.widget('noteList').currentItem;
const folder = this.widget('folderList').currentItem;
const args = splitCommandString(cmd);
for (let i = 0; i < args.length; i++) {
if (args[i] == '$n') {
@@ -548,7 +548,7 @@ class AppGui {
stdout(text) {
if (text === null || text === undefined) return;
let lines = text.split('\n');
const lines = text.split('\n');
for (let i = 0; i < lines.length; i++) {
const v = typeof lines[i] === 'object' ? JSON.stringify(lines[i]) : lines[i];
this.widget('console').addLine(v);
@@ -626,7 +626,7 @@ class AppGui {
if (link.type === 'item') {
const itemId = link.id;
let item = await BaseItem.loadItemById(itemId);
const item = await BaseItem.loadItemById(itemId);
if (!item) throw new Error(`No item with ID ${itemId}`); // Should be nearly impossible
if (item.type_ === BaseModel.TYPE_RESOURCE) {
@@ -750,7 +750,7 @@ class AppGui {
// -------------------------------------------------------------------------
const shortcutKey = this.currentShortcutKeys_.join('');
let keymapItem = this.keymapItemByKey(shortcutKey);
const keymapItem = this.keymapItemByKey(shortcutKey);
// If this command is an alias to another command, resolve to the actual command
@@ -766,7 +766,7 @@ class AppGui {
if (keymapItem.type === 'function') {
this.processFunctionCommand(keymapItem.command);
} else if (keymapItem.type === 'prompt') {
let promptOptions = {};
const promptOptions = {};
if ('cursorPosition' in keymapItem) promptOptions.cursorPosition = keymapItem.cursorPosition;
const commandString = await statusBar.prompt(keymapItem.command ? keymapItem.command : '', null, promptOptions);
this.addCommandToConsole(commandString);

View File

@@ -47,7 +47,7 @@ class Application extends BaseApplication {
}
async loadItem(type, pattern, options = null) {
let output = await this.loadItems(type, pattern, options);
const output = await this.loadItems(type, pattern, options);
if (output.length > 1) {
// output.sort((a, b) => { return a.user_updated_time < b.user_updated_time ? +1 : -1; });
@@ -144,7 +144,7 @@ class Application extends BaseApplication {
if (options.type === 'boolean') {
if (answer === null) return false; // Pressed ESCAPE
if (!answer) answer = options.answers[0];
let positiveIndex = options.booleanAnswerDefault == 'y' ? 0 : 1;
const positiveIndex = options.booleanAnswerDefault == 'y' ? 0 : 1;
return answer.toLowerCase() === options.answers[positiveIndex].toLowerCase();
} else {
return answer;
@@ -181,7 +181,7 @@ class Application extends BaseApplication {
const ext = fileExtension(path);
if (ext != 'js') return;
let CommandClass = require(`./${path}`);
const CommandClass = require(`./${path}`);
let cmd = new CommandClass();
if (!cmd.enabled()) return;
cmd = this.setupCommand(cmd);
@@ -192,8 +192,8 @@ class Application extends BaseApplication {
}
if (uiType !== null) {
let temp = [];
for (let n in this.commands_) {
const temp = [];
for (const n in this.commands_) {
if (!this.commands_.hasOwnProperty(n)) continue;
const c = this.commands_[n];
if (!c.supportsUi(uiType)) continue;
@@ -207,8 +207,8 @@ class Application extends BaseApplication {
async commandNames() {
const metadata = await this.commandMetadata();
let output = [];
for (let n in metadata) {
const output = [];
for (const n in metadata) {
if (!metadata.hasOwnProperty(n)) continue;
output.push(n);
}
@@ -227,7 +227,7 @@ class Application extends BaseApplication {
const commands = this.commands();
output = {};
for (let n in commands) {
for (const n in commands) {
if (!commands.hasOwnProperty(n)) continue;
const cmd = commands[n];
output[n] = cmd.metadata();
@@ -251,7 +251,7 @@ class Application extends BaseApplication {
CommandClass = require(`${__dirname}/command-${name}.js`);
} catch (error) {
if (error.message && error.message.indexOf('Cannot find module') >= 0) {
let e = new Error(_('No such command: %s', name));
const e = new Error(_('No such command: %s', name));
e.type = 'notFound';
throw e;
} else {
@@ -362,7 +362,7 @@ class Application extends BaseApplication {
}
const output = [];
for (let n in itemsByCommand) {
for (const n in itemsByCommand) {
if (!itemsByCommand.hasOwnProperty(n)) continue;
output.push(itemsByCommand[n]);
}

View File

@@ -1,20 +1,20 @@
var { app } = require('./app.js');
var Note = require('lib/models/Note.js');
var Folder = require('lib/models/Folder.js');
var Tag = require('lib/models/Tag.js');
var { cliUtils } = require('./cli-utils.js');
var yargParser = require('yargs-parser');
var fs = require('fs-extra');
const { app } = require('./app.js');
const Note = require('lib/models/Note.js');
const Folder = require('lib/models/Folder.js');
const Tag = require('lib/models/Tag.js');
const { cliUtils } = require('./cli-utils.js');
const yargParser = require('yargs-parser');
const fs = require('fs-extra');
async function handleAutocompletionPromise(line) {
// Auto-complete the command name
const names = await app().commandNames();
let words = getArguments(line);
const words = getArguments(line);
// If there is only one word and it is not already a command name then you
// should look for commands it could be
if (words.length == 1) {
if (names.indexOf(words[0]) === -1) {
let x = names.filter(n => n.indexOf(words[0]) === 0);
const x = names.filter(n => n.indexOf(words[0]) === 0);
if (x.length === 1) {
return `${x[0]} `;
}
@@ -36,8 +36,8 @@ async function handleAutocompletionPromise(line) {
}
// complete an option
let next = words.length > 1 ? words[words.length - 1] : '';
let l = [];
const next = words.length > 1 ? words[words.length - 1] : '';
const l = [];
if (next[0] === '-') {
for (let i = 0; i < metadata.options.length; i++) {
const options = metadata.options[i][0].split(' ');
@@ -60,7 +60,7 @@ async function handleAutocompletionPromise(line) {
if (l.length === 0) {
return line;
}
let ret = l.map(a => toCommandLine(a));
const ret = l.map(a => toCommandLine(a));
ret.prefix = `${toCommandLine(words.slice(0, -1))} `;
return ret;
}
@@ -69,7 +69,7 @@ async function handleAutocompletionPromise(line) {
// words that don't start with a - less one for the command name
const positionalArgs = words.filter(a => a.indexOf('-') !== 0).length - 1;
let cmdUsage = yargParser(metadata.usage)['_'];
const cmdUsage = yargParser(metadata.usage)['_'];
cmdUsage.splice(0, 1);
if (cmdUsage.length >= positionalArgs) {
@@ -95,29 +95,29 @@ async function handleAutocompletionPromise(line) {
}
if (argName == 'tag') {
let tags = await Tag.search({ titlePattern: `${next}*` });
const tags = await Tag.search({ titlePattern: `${next}*` });
l.push(...tags.map(n => n.title));
}
if (argName == 'file') {
let files = await fs.readdir('.');
const files = await fs.readdir('.');
l.push(...files);
}
if (argName == 'tag-command') {
let c = filterList(['add', 'remove', 'list', 'notetags'], next);
const c = filterList(['add', 'remove', 'list', 'notetags'], next);
l.push(...c);
}
if (argName == 'todo-command') {
let c = filterList(['toggle', 'clear'], next);
const c = filterList(['toggle', 'clear'], next);
l.push(...c);
}
}
if (l.length === 1) {
return toCommandLine([...words.slice(0, -1), l[0]]);
} else if (l.length > 1) {
let ret = l.map(a => toCommandLine(a));
const ret = l.map(a => toCommandLine(a));
ret.prefix = `${toCommandLine(words.slice(0, -1))} `;
return ret;
}
@@ -155,7 +155,7 @@ function getArguments(line) {
let inSingleQuotes = false;
let inDoubleQuotes = false;
let currentWord = '';
let parsed = [];
const parsed = [];
for (let i = 0; i < line.length; i++) {
if (line[i] === '"') {
if (inDoubleQuotes) {
@@ -192,7 +192,7 @@ function getArguments(line) {
return parsed;
}
function filterList(list, next) {
let output = [];
const output = [];
for (let i = 0; i < list.length; i++) {
if (list[i].indexOf(next) !== 0) continue;
output.push(list[i]);

View File

@@ -50,7 +50,7 @@ class BaseCommand {
async cancel() {}
name() {
let r = this.usage().split(' ');
const r = this.usage().split(' ');
return r[0];
}

View File

@@ -15,11 +15,11 @@ function wrap(text, indent) {
}
function renderOptions(options) {
let output = [];
const output = [];
const optionColWidth = getOptionColWidth(options);
for (let i = 0; i < options.length; i++) {
let option = options[i];
const option = options[i];
const flag = option[0];
const indent = INDENT + INDENT + ' '.repeat(optionColWidth + 2);
@@ -33,7 +33,7 @@ function renderOptions(options) {
}
function renderCommand(cmd) {
let output = [];
const output = [];
output.push(INDENT + cmd.usage());
output.push('');
output.push(wrap(cmd.description(), INDENT + INDENT));
@@ -48,14 +48,14 @@ function renderCommand(cmd) {
}
function getCommands() {
let output = [];
const output = [];
fs.readdirSync(__dirname).forEach(path => {
if (path.indexOf('command-') !== 0) return;
const ext = fileExtension(path);
if (ext != 'js') return;
let CommandClass = require(`./${path}`);
let cmd = new CommandClass();
const CommandClass = require(`./${path}`);
const cmd = new CommandClass();
if (!cmd.enabled()) return;
if (cmd.hidden()) return;
output.push(cmd);
@@ -73,7 +73,7 @@ function getOptionColWidth(options) {
}
function getHeader() {
let output = [];
const output = [];
output.push('NAME');
output.push('');
@@ -84,7 +84,7 @@ function getHeader() {
output.push('DESCRIPTION');
output.push('');
let description = [];
const description = [];
description.push('Joplin is a note taking and to-do application, which can handle a large number of notes organised into notebooks.');
description.push('The notes are searchable, can be copied, tagged and modified with your own text editor.');
description.push('\n\n');
@@ -98,7 +98,7 @@ function getHeader() {
}
function getFooter() {
let output = [];
const output = [];
output.push('WEBSITE');
output.push('');
@@ -120,10 +120,10 @@ async function main() {
// setLocale('fr_FR');
const commands = getCommands();
let commandBlocks = [];
const commandBlocks = [];
for (let i = 0; i < commands.length; i++) {
let cmd = commands[i];
const cmd = commands[i];
commandBlocks.push(renderCommand(cmd));
}

View File

@@ -40,8 +40,8 @@ function createClient(id) {
const client = createClient(1);
function execCommand(client, command) {
let exePath = `node ${joplinAppPath}`;
let cmd = `${exePath} --update-geolocation-disabled --env dev --profile ${client.profileDir} ${command}`;
const exePath = `node ${joplinAppPath}`;
const cmd = `${exePath} --update-geolocation-disabled --env dev --profile ${client.profileDir} ${command}`;
logger.info(`${client.id}: ${command}`);
return new Promise((resolve, reject) => {
@@ -129,8 +129,8 @@ testUnits.testCat = async () => {
await execCommand(client, 'mkbook nb1');
await execCommand(client, 'mknote mynote');
let folder = await Folder.loadByTitle('nb1');
let note = await Note.loadFolderNoteByField(folder.id, 'title', 'mynote');
const folder = await Folder.loadByTitle('nb1');
const note = await Note.loadFolderNoteByField(folder.id, 'title', 'mynote');
let r = await execCommand(client, 'cat mynote');
assertTrue(r.indexOf('mynote') >= 0);
@@ -149,7 +149,7 @@ testUnits.testConfig = async () => {
await Setting.load();
assertEquals('subl', Setting.value('editor'));
let r = await execCommand(client, 'config');
const r = await execCommand(client, 'config');
assertTrue(r.indexOf('editor') >= 0);
assertTrue(r.indexOf('subl') >= 0);
};
@@ -161,14 +161,14 @@ testUnits.testCp = async () => {
await execCommand(client, 'cp n1');
let f1 = await Folder.loadByTitle('nb1');
let f2 = await Folder.loadByTitle('nb2');
const f1 = await Folder.loadByTitle('nb1');
const f2 = await Folder.loadByTitle('nb2');
let notes = await Note.previews(f1.id);
assertEquals(2, notes.length);
await execCommand(client, 'cp n1 nb2');
let notesF1 = await Note.previews(f1.id);
const notesF1 = await Note.previews(f1.id);
assertEquals(2, notesF1.length);
notes = await Note.previews(f2.id);
assertEquals(1, notes.length);
@@ -179,7 +179,7 @@ testUnits.testLs = async () => {
await execCommand(client, 'mkbook nb1');
await execCommand(client, 'mknote note1');
await execCommand(client, 'mknote note2');
let r = await execCommand(client, 'ls');
const r = await execCommand(client, 'ls');
assertTrue(r.indexOf('note1') >= 0);
assertTrue(r.indexOf('note2') >= 0);
@@ -191,8 +191,8 @@ testUnits.testMv = async () => {
await execCommand(client, 'mknote n1');
await execCommand(client, 'mv n1 nb2');
let f1 = await Folder.loadByTitle('nb1');
let f2 = await Folder.loadByTitle('nb2');
const f1 = await Folder.loadByTitle('nb1');
const f2 = await Folder.loadByTitle('nb2');
let notes1 = await Note.previews(f1.id);
let notes2 = await Note.previews(f2.id);
@@ -218,18 +218,18 @@ async function main() {
logger.info(await execCommand(client, 'version'));
await db.open({ name: `${client.profileDir}/database.sqlite` });
BaseModel.db_ = db;
BaseModel.setDb(db);
await Setting.load();
let onlyThisTest = 'testMv';
onlyThisTest = '';
for (let n in testUnits) {
for (const n in testUnits) {
if (!testUnits.hasOwnProperty(n)) continue;
if (onlyThisTest && n != onlyThisTest) continue;
await clearDatabase();
let testName = n.substr(4).toLowerCase();
const testName = n.substr(4).toLowerCase();
process.stdout.write(`${testName}: `);
await testUnits[n]();
console.info('');

View File

@@ -11,27 +11,27 @@ cliUtils.printArray = function(logFunction, rows) {
const ALIGN_LEFT = 0;
const ALIGN_RIGHT = 1;
let colWidths = [];
let colAligns = [];
const colWidths = [];
const colAligns = [];
for (let i = 0; i < rows.length; i++) {
let row = rows[i];
const row = rows[i];
for (let j = 0; j < row.length; j++) {
let item = row[j];
let width = item ? item.toString().length : 0;
let align = typeof item == 'number' ? ALIGN_RIGHT : ALIGN_LEFT;
const item = row[j];
const width = item ? item.toString().length : 0;
const align = typeof item == 'number' ? ALIGN_RIGHT : ALIGN_LEFT;
if (!colWidths[j] || colWidths[j] < width) colWidths[j] = width;
if (colAligns.length <= j) colAligns[j] = align;
}
}
for (let row = 0; row < rows.length; row++) {
let line = [];
const line = [];
for (let col = 0; col < colWidths.length; col++) {
let item = rows[row][col];
let width = colWidths[col];
let dir = colAligns[col] == ALIGN_LEFT ? stringPadding.RIGHT : stringPadding.LEFT;
const item = rows[row][col];
const width = colWidths[col];
const dir = colAligns[col] == ALIGN_LEFT ? stringPadding.RIGHT : stringPadding.LEFT;
line.push(stringPadding(item, width, ' ', dir));
}
logFunction(line.join(' '));
@@ -39,7 +39,7 @@ cliUtils.printArray = function(logFunction, rows) {
};
cliUtils.parseFlags = function(flags) {
let output = {};
const output = {};
flags = flags.split(',');
for (let i = 0; i < flags.length; i++) {
let f = flags[i].trim();
@@ -76,11 +76,11 @@ cliUtils.parseCommandArg = function(arg) {
cliUtils.makeCommandArgs = function(cmd, argv) {
let cmdUsage = cmd.usage();
cmdUsage = yargParser(cmdUsage);
let output = {};
const output = {};
let options = cmd.options();
let booleanFlags = [];
let aliases = {};
const options = cmd.options();
const booleanFlags = [];
const aliases = {};
for (let i = 0; i < options.length; i++) {
if (options[i].length != 2) throw new Error(`Invalid options: ${options[i]}`);
let flags = options[i][0];
@@ -97,7 +97,7 @@ cliUtils.makeCommandArgs = function(cmd, argv) {
}
}
let args = yargParser(argv, {
const args = yargParser(argv, {
boolean: booleanFlags,
alias: aliases,
string: ['_'],
@@ -113,8 +113,8 @@ cliUtils.makeCommandArgs = function(cmd, argv) {
}
}
let argOptions = {};
for (let key in args) {
const argOptions = {};
for (const key in args) {
if (!args.hasOwnProperty(key)) continue;
if (key == '_') continue;
argOptions[key] = args[key];
@@ -134,7 +134,7 @@ cliUtils.promptMcq = function(message, answers) {
});
message += '\n\n';
for (let n in answers) {
for (const n in answers) {
if (!answers.hasOwnProperty(n)) continue;
message += `${_('%s: %s', n, answers[n])}\n`;
}

View File

@@ -56,7 +56,6 @@ class Command extends BaseCommand {
lines.push('# Joplin API');
lines.push('');
lines.push('When the Web Clipper service is enabled, Joplin exposes a [REST API](https://en.wikipedia.org/wiki/Representational_state_transfer) which allows third-party applications to access Joplin\'s data and to create, modify or delete notes, notebooks, resources or tags.');
lines.push('');
lines.push('In order to use it, you\'ll first need to find on which port the service is running. To do so, open the Web Clipper Options in Joplin and if the service is running it should tell you on which port. Normally it runs on port **41184**. If you want to find it programmatically, you may follow this kind of algorithm:');
lines.push('');

View File

@@ -14,9 +14,9 @@ class Command extends BaseCommand {
}
async action(args) {
let title = args['note'];
const title = args['note'];
let note = await app().loadItem(BaseModel.TYPE_NOTE, title, { parent: app().currentFolder() });
const note = await app().loadItem(BaseModel.TYPE_NOTE, title, { parent: app().currentFolder() });
this.encryptionCheck(note);
if (!note) throw new Error(_('Cannot find "%s".', title));

View File

@@ -18,9 +18,9 @@ class Command extends BaseCommand {
}
async action(args) {
let title = args['note'];
const title = args['note'];
let item = await app().loadItem(BaseModel.TYPE_NOTE, title, { parent: app().currentFolder() });
const item = await app().loadItem(BaseModel.TYPE_NOTE, title, { parent: app().currentFolder() });
if (!item) throw new Error(_('Cannot find "%s".', title));
const content = args.options.verbose ? await Note.serialize(item) : await Note.serializeForEdit(item);

View File

@@ -35,7 +35,7 @@ class Command extends BaseCommand {
});
inputStream.on('end', () => {
let json = chunks.join('');
const json = chunks.join('');
let settingsObj;
try {
settingsObj = JSON.parse(json);
@@ -83,7 +83,7 @@ class Command extends BaseCommand {
};
if (isExport || (!isImport && !args.value)) {
let keys = Setting.keys(!verbose, 'cli');
const keys = Setting.keys(!verbose, 'cli');
keys.sort();
if (isExport) {

View File

@@ -18,15 +18,15 @@ class Command extends BaseCommand {
async action() {
let items = [];
let folders = await Folder.all();
const folders = await Folder.all();
for (let i = 0; i < folders.length; i++) {
let folder = folders[i];
let notes = await Note.previews(folder.id);
const folder = folders[i];
const notes = await Note.previews(folder.id);
items.push(folder);
items = items.concat(notes);
}
let tags = await Tag.all();
const tags = await Tag.all();
for (let i = 0; i < tags.length; i++) {
tags[i].notes_ = await Tag.noteIds(tags[i].id);
}

View File

@@ -138,7 +138,7 @@ class Command extends BaseCommand {
if (!targetPath) throw new Error('Please specify the sync target path.');
const dirPaths = function(targetPath) {
let paths = [];
const paths = [];
fs.readdirSync(targetPath).forEach(path => {
paths.push(path);
});
@@ -151,10 +151,10 @@ class Command extends BaseCommand {
let encryptedResourceCount = 0;
let otherItemCount = 0;
let encryptedPaths = [];
let decryptedPaths = [];
const encryptedPaths = [];
const decryptedPaths = [];
let paths = dirPaths(targetPath);
const paths = dirPaths(targetPath);
for (let i = 0; i < paths.length; i++) {
const path = paths[i];
@@ -164,7 +164,7 @@ class Command extends BaseCommand {
// this.stdout(fullPath);
if (path === '.resource') {
let resourcePaths = dirPaths(fullPath);
const resourcePaths = dirPaths(fullPath);
for (let j = 0; j < resourcePaths.length; j++) {
const resourcePath = resourcePaths[j];
resourceCount++;

View File

@@ -35,7 +35,7 @@ class Command extends BaseCommand {
// Load note or create it if it doesn't exist
// -------------------------------------------------------------------------
let title = args['note'];
const title = args['note'];
if (!app().currentFolder()) throw new Error(_('No active notebook.'));
let note = await app().loadItem(BaseModel.TYPE_NOTE, title);
@@ -91,7 +91,7 @@ class Command extends BaseCommand {
const updatedContent = await fs.readFile(tempFilePath, 'utf8');
if (updatedContent !== originalContent) {
let updatedNote = await Note.unserializeForEdit(updatedContent);
const updatedNote = await Note.unserializeForEdit(updatedContent);
updatedNote.id = note.id;
await Note.save(updatedNote);
this.stdout(_('Note has been saved.'));

View File

@@ -24,7 +24,7 @@ class Command extends BaseCommand {
}
async action(args) {
let exportOptions = {};
const exportOptions = {};
exportOptions.path = args.path;
exportOptions.format = args.options.format ? args.options.format : 'jex';

View File

@@ -14,9 +14,9 @@ class Command extends BaseCommand {
}
async action(args) {
let title = args['note'];
const title = args['note'];
let item = await app().loadItem(BaseModel.TYPE_NOTE, title, { parent: app().currentFolder() });
const item = await app().loadItem(BaseModel.TYPE_NOTE, title, { parent: app().currentFolder() });
if (!item) throw new Error(_('Cannot find "%s".', title));
const url = Note.geolocationUrl(item);
this.stdout(url);

View File

@@ -15,8 +15,8 @@ class Command extends BaseCommand {
allCommands() {
const commands = app().commands(app().uiType());
let output = [];
for (let n in commands) {
const output = [];
for (const n in commands) {
if (!commands.hasOwnProperty(n)) continue;
const command = commands[n];
if (command.hidden()) continue;
@@ -48,7 +48,7 @@ class Command extends BaseCommand {
.gui()
.keymap();
let rows = [];
const rows = [];
for (let i = 0; i < keymap.length; i++) {
const item = keymap[i];

View File

@@ -25,7 +25,7 @@ class Command extends BaseCommand {
}
async action(args) {
let folder = await app().loadItem(BaseModel.TYPE_FOLDER, args.notebook);
const folder = await app().loadItem(BaseModel.TYPE_FOLDER, args.notebook);
if (args.notebook && !folder) throw new Error(_('Cannot find "%s".', args.notebook));
@@ -39,7 +39,7 @@ class Command extends BaseCommand {
// onProgress/onError supported by Enex import only
importOptions.onProgress = progressState => {
let line = [];
const line = [];
line.push(_('Found: %d.', progressState.loaded));
line.push(_('Created: %d.', progressState.created));
if (progressState.updated) line.push(_('Updated: %d.', progressState.updated));
@@ -51,7 +51,7 @@ class Command extends BaseCommand {
};
importOptions.onError = error => {
let s = error.trace ? error.trace : error.toString();
const s = error.trace ? error.trace : error.toString();
this.stdout(s);
};

View File

@@ -34,11 +34,11 @@ class Command extends BaseCommand {
}
async action(args) {
let pattern = args['note-pattern'];
const pattern = args['note-pattern'];
let items = [];
let options = args.options;
const options = args.options;
let queryOptions = {};
const queryOptions = {};
if (options.limit) queryOptions.limit = options.limit;
if (options.sort) {
queryOptions.orderBy = options.sort;
@@ -70,19 +70,19 @@ class Command extends BaseCommand {
} else {
let hasTodos = false;
for (let i = 0; i < items.length; i++) {
let item = items[i];
const item = items[i];
if (item.is_todo) {
hasTodos = true;
break;
}
}
let seenTitles = [];
let rows = [];
const seenTitles = [];
const rows = [];
let shortIdShown = false;
for (let i = 0; i < items.length; i++) {
let item = items[i];
let row = [];
const item = items[i];
const row = [];
if (options.long) {
row.push(BaseModel.shortId(item.id));

View File

@@ -13,7 +13,7 @@ class Command extends BaseCommand {
}
async action(args) {
let folder = await Folder.save({ title: args['new-notebook'] }, { userSideValidation: true });
const folder = await Folder.save({ title: args['new-notebook'] }, { userSideValidation: true });
app().switchCurrentFolder(folder);
}
}

View File

@@ -26,7 +26,7 @@ class Command extends BaseCommand {
const ok = force ? true : await this.prompt(notes.length > 1 ? _('%d notes match this pattern. Delete them?', notes.length) : _('Delete note?'), { booleanAnswerDefault: 'n' });
if (!ok) return;
let ids = notes.map(n => n.id);
const ids = notes.map(n => n.id);
await Note.batchDelete(ids);
}
}

View File

@@ -18,8 +18,8 @@ class Command extends BaseCommand {
}
async action(args) {
let pattern = args['pattern'];
let folderTitle = args['notebook'];
const pattern = args['pattern'];
const folderTitle = args['notebook'];
let folder = null;
if (folderTitle) {

View File

@@ -23,18 +23,18 @@ class Command extends BaseCommand {
}
async action(args) {
let title = args['note'];
let propName = args['name'];
const title = args['note'];
const propName = args['name'];
let propValue = args['value'];
if (!propValue) propValue = '';
let notes = await app().loadItems(BaseModel.TYPE_NOTE, title);
const notes = await app().loadItems(BaseModel.TYPE_NOTE, title);
if (!notes.length) throw new Error(_('Cannot find "%s".', title));
for (let i = 0; i < notes.length; i++) {
this.encryptionCheck(notes[i]);
let newNote = {
const newNote = {
id: notes[i].id,
type_: notes[i].type_,
};

View File

@@ -14,20 +14,20 @@ class Command extends BaseCommand {
}
async action() {
let service = new ReportService();
let report = await service.status(Setting.value('sync.target'));
const service = new ReportService();
const report = await service.status(Setting.value('sync.target'));
for (let i = 0; i < report.length; i++) {
let section = report[i];
const section = report[i];
if (i > 0) this.stdout('');
this.stdout(`# ${section.title}`);
this.stdout('');
for (let n in section.body) {
for (const n in section.body) {
if (!section.body.hasOwnProperty(n)) continue;
let line = section.body[n];
const line = section.body[n];
this.stdout(line);
}
}

View File

@@ -161,9 +161,9 @@ class Command extends BaseCommand {
const sync = await syncTarget.synchronizer();
let options = {
const options = {
onProgress: report => {
let lines = Synchronizer.reportToLines(report);
const lines = Synchronizer.reportToLines(report);
if (lines.length) cliUtils.redraw(lines.join(' '));
},
onMessage: msg => {
@@ -185,7 +185,7 @@ class Command extends BaseCommand {
options.context = context;
try {
let newContext = await sync.start(options);
const newContext = await sync.start(options);
Setting.setValue(contextKey, JSON.stringify(newContext));
} catch (error) {
if (error.code == 'alreadyStarted') {

View File

@@ -20,7 +20,7 @@ class Command extends BaseCommand {
async action(args) {
let tag = null;
let options = args.options;
const options = args.options;
if (args.tag) tag = await app().loadItem(BaseModel.TYPE_TAG, args.tag);
let notes = [];
@@ -46,7 +46,7 @@ class Command extends BaseCommand {
}
} else if (command == 'list') {
if (tag) {
let notes = await Tag.notes(tag.id);
const notes = await Tag.notes(tag.id);
notes.map(note => {
let line = '';
if (options.long) {
@@ -70,7 +70,7 @@ class Command extends BaseCommand {
this.stdout(line);
});
} else {
let tags = await Tag.all();
const tags = await Tag.all();
tags.map(tag => {
this.stdout(tag.title);
});

View File

@@ -17,7 +17,7 @@ class Command extends BaseCommand {
}
async action(args) {
let folder = await app().loadItem(BaseModel.TYPE_FOLDER, args['notebook']);
const folder = await app().loadItem(BaseModel.TYPE_FOLDER, args['notebook']);
if (!folder) throw new Error(_('Cannot find "%s".', args['notebook']));
app().switchCurrentFolder(folder);
}

View File

@@ -12,7 +12,7 @@ const fs = require('fs-extra');
const baseDir = `${dirname(__dirname)}/tests/fuzzing`;
const syncDir = `${baseDir}/sync`;
const joplinAppPath = `${__dirname}/main.js`;
let syncDurations = [];
const syncDurations = [];
const fsDriver = new FsDriverNode();
Logger.fsDriver_ = fsDriver;
@@ -34,10 +34,10 @@ function createClient(id) {
}
async function createClients() {
let output = [];
let promises = [];
const output = [];
const promises = [];
for (let clientId = 0; clientId < 2; clientId++) {
let client = createClient(clientId);
const client = createClient(clientId);
promises.push(fs.remove(client.profileDir));
promises.push(
execCommand(client, 'config sync.target 2').then(() => {
@@ -2064,8 +2064,8 @@ function randomWord() {
}
function execCommand(client, command, options = {}) {
let exePath = `node ${joplinAppPath}`;
let cmd = `${exePath} --update-geolocation-disabled --env dev --log-level debug --profile ${client.profileDir} ${command}`;
const exePath = `node ${joplinAppPath}`;
const cmd = `${exePath} --update-geolocation-disabled --env dev --log-level debug --profile ${client.profileDir} ${command}`;
logger.info(`${client.id}: ${command}`);
if (options.killAfter) {
@@ -2073,7 +2073,7 @@ function execCommand(client, command, options = {}) {
}
return new Promise((resolve, reject) => {
let childProcess = exec(cmd, (error, stdout, stderr) => {
const childProcess = exec(cmd, (error, stdout, stderr) => {
if (error) {
if (error.signal == 'SIGTERM') {
resolve('Process was killed');
@@ -2096,7 +2096,7 @@ function execCommand(client, command, options = {}) {
}
async function clientItems(client) {
let itemsJson = await execCommand(client, 'dump');
const itemsJson = await execCommand(client, 'dump');
try {
return JSON.parse(itemsJson);
} catch (error) {
@@ -2105,7 +2105,7 @@ async function clientItems(client) {
}
function randomTag(items) {
let tags = [];
const tags = [];
for (let i = 0; i < items.length; i++) {
if (items[i].type_ != 5) continue;
tags.push(items[i]);
@@ -2115,7 +2115,7 @@ function randomTag(items) {
}
function randomNote(items) {
let notes = [];
const notes = [];
for (let i = 0; i < items.length; i++) {
if (items[i].type_ != 1) continue;
notes.push(items[i]);
@@ -2125,14 +2125,14 @@ function randomNote(items) {
}
async function execRandomCommand(client) {
let possibleCommands = [
const possibleCommands = [
['mkbook {word}', 40], // CREATE FOLDER
['mknote {word}', 70], // CREATE NOTE
[
async () => {
// DELETE RANDOM ITEM
let items = await clientItems(client);
let item = randomElement(items);
const items = await clientItems(client);
const item = randomElement(items);
if (!item) return;
if (item.type_ == 1) {
@@ -2150,8 +2150,8 @@ async function execRandomCommand(client) {
[
async () => {
// SYNC
let avgSyncDuration = averageSyncDuration();
let options = {};
const avgSyncDuration = averageSyncDuration();
const options = {};
if (!isNaN(avgSyncDuration)) {
if (Math.random() >= 0.5) {
options.killAfter = avgSyncDuration * Math.random();
@@ -2164,8 +2164,8 @@ async function execRandomCommand(client) {
[
async () => {
// UPDATE RANDOM ITEM
let items = await clientItems(client);
let item = randomNote(items);
const items = await clientItems(client);
const item = randomNote(items);
if (!item) return;
return execCommand(client, `set ${item.id} title "${randomWord()}"`);
@@ -2175,12 +2175,12 @@ async function execRandomCommand(client) {
[
async () => {
// ADD TAG
let items = await clientItems(client);
let note = randomNote(items);
const items = await clientItems(client);
const note = randomNote(items);
if (!note) return;
let tag = randomTag(items);
let tagTitle = !tag || Math.random() >= 0.9 ? `tag-${randomWord()}` : tag.title;
const tag = randomTag(items);
const tagTitle = !tag || Math.random() >= 0.9 ? `tag-${randomWord()}` : tag.title;
return execCommand(client, `tag add ${tagTitle} ${note.id}`);
},
@@ -2191,7 +2191,7 @@ async function execRandomCommand(client) {
let cmd = null;
while (true) {
cmd = randomElement(possibleCommands);
let r = 1 + Math.floor(Math.random() * 100);
const r = 1 + Math.floor(Math.random() * 100);
if (r <= cmd[1]) break;
}
@@ -2210,7 +2210,7 @@ function averageSyncDuration() {
}
function randomNextCheckTime() {
let output = time.unixMs() + 1000 + Math.random() * 1000 * 120;
const output = time.unixMs() + 1000 + Math.random() * 1000 * 120;
logger.info(`Next sync check: ${time.unixMsToIso(output)} (${Math.round((output - time.unixMs()) / 1000)} sec.)`);
return output;
}
@@ -2223,11 +2223,11 @@ function findItem(items, itemId) {
}
function compareItems(item1, item2) {
let output = [];
for (let n in item1) {
const output = [];
for (const n in item1) {
if (!item1.hasOwnProperty(n)) continue;
let p1 = item1[n];
let p2 = item2[n];
const p1 = item1[n];
const p2 = item2[n];
if (n == 'notes_') {
p1.sort();
@@ -2243,13 +2243,13 @@ function compareItems(item1, item2) {
}
function findMissingItems_(items1, items2) {
let output = [];
const output = [];
for (let i = 0; i < items1.length; i++) {
let item1 = items1[i];
const item1 = items1[i];
let found = false;
for (let j = 0; j < items2.length; j++) {
let item2 = items2[j];
const item2 = items2[j];
if (item1.id == item2.id) {
found = true;
break;
@@ -2269,33 +2269,33 @@ function findMissingItems(items1, items2) {
}
async function compareClientItems(clientItems) {
let itemCounts = [];
const itemCounts = [];
for (let i = 0; i < clientItems.length; i++) {
let items = clientItems[i];
const items = clientItems[i];
itemCounts.push(items.length);
}
logger.info(`Item count: ${itemCounts.join(', ')}`);
let missingItems = findMissingItems(clientItems[0], clientItems[1]);
const missingItems = findMissingItems(clientItems[0], clientItems[1]);
if (missingItems[0].length || missingItems[1].length) {
logger.error('Items are different');
logger.error(missingItems);
process.exit(1);
}
let differences = [];
let items = clientItems[0];
const differences = [];
const items = clientItems[0];
for (let i = 0; i < items.length; i++) {
let item1 = items[i];
const item1 = items[i];
for (let clientId = 1; clientId < clientItems.length; clientId++) {
let item2 = findItem(clientItems[clientId], item1.id);
const item2 = findItem(clientItems[clientId], item1.id);
if (!item2) {
logger.error(`Item not found on client ${clientId}:`);
logger.error(item1);
process.exit(1);
}
let diff = compareItems(item1, item2);
const diff = compareItems(item1, item2);
if (diff.length) {
differences.push({
item1: JSON.stringify(item1),
@@ -2315,7 +2315,7 @@ async function compareClientItems(clientItems) {
async function main() {
await fs.remove(syncDir);
let clients = await createClients();
const clients = await createClients();
let clientId = 0;
for (let i = 0; i < clients.length; i++) {
@@ -2348,7 +2348,7 @@ async function main() {
if (state == 'syncCheck') {
state = 'waitForSyncCheck';
let clientItems = [];
const clientItems = [];
// Up to 3 sync operations must be performed by each clients in order for them
// to be perfectly in sync - in order for each items to send their changes
// and get those from the other clients, and to also get changes that are
@@ -2356,12 +2356,12 @@ async function main() {
// with another one).
for (let loopCount = 0; loopCount < 3; loopCount++) {
for (let i = 0; i < clients.length; i++) {
let beforeTime = time.unixMs();
const beforeTime = time.unixMs();
await execCommand(clients[i], 'sync');
syncDurations.push(time.unixMs() - beforeTime);
if (syncDurations.length > 20) syncDurations.splice(0, 1);
if (loopCount === 2) {
let dump = await execCommand(clients[i], 'dump');
const dump = await execCommand(clients[i], 'dump');
clientItems[i] = JSON.parse(dump);
}
}

View File

@@ -20,7 +20,7 @@ class FolderListWidget extends ListWidget {
this.trimItemTitle = false;
this.itemRenderer = item => {
let output = [];
const output = [];
if (item === '-') {
output.push('-'.repeat(this.innerWidth));
} else if (item.type_ === Folder.modelType()) {
@@ -121,7 +121,7 @@ class FolderListWidget extends ListWidget {
folderHasChildren_(folders, folderId) {
for (let i = 0; i < folders.length; i++) {
let folder = folders[i];
const folder = folders[i];
if (folder.parent_id === folderId) return true;
}
return false;

View File

@@ -106,7 +106,7 @@ class StatusBarWidget extends BaseWidget {
const isSecurePrompt = !!this.promptState_.secure;
let options = {
const options = {
cancelable: true,
history: this.history,
default: this.promptState_.initialText,

View File

@@ -6,11 +6,11 @@ const MAX_WIDTH = 78;
const INDENT = ' ';
function renderTwoColumnData(options, baseIndent, width) {
let output = [];
const output = [];
const optionColWidth = getOptionColWidth(options);
for (let i = 0; i < options.length; i++) {
let option = options[i];
const option = options[i];
const flag = option[0];
const indent = baseIndent + INDENT + ' '.repeat(optionColWidth + 2);
@@ -28,7 +28,7 @@ function renderCommandHelp(cmd, width = null) {
const baseIndent = '';
let output = [];
const output = [];
output.push(baseIndent + cmd.usage());
output.push('');
output.push(wrap(cmd.description(), baseIndent + INDENT, width));
@@ -42,7 +42,7 @@ function renderCommandHelp(cmd, width = null) {
if (cmd.name() === 'config') {
const renderMetadata = md => {
let desc = [];
const desc = [];
if (md.label) {
let label = md.label();
@@ -77,7 +77,7 @@ function renderCommandHelp(cmd, width = null) {
output.push(_('Possible keys/values:'));
output.push('');
let keysValues = [];
const keysValues = [];
const keys = Setting.keys(true, 'cli');
for (let i = 0; i < keys.length; i++) {
if (keysValues.length) keysValues.push(['', '']);

View File

@@ -54,7 +54,7 @@ shimInit();
const application = app();
if (process.platform === 'win32') {
var rl = require('readline').createInterface({
const rl = require('readline').createInterface({
input: process.stdin,
output: process.stdout,
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -36,40 +36,40 @@ locales['th_TH'] = require('./th_TH.json');
locales['tr_TR'] = require('./tr_TR.json');
locales['zh_CN'] = require('./zh_CN.json');
locales['zh_TW'] = require('./zh_TW.json');
stats['ar'] = {"percentDone":92};
stats['eu'] = {"percentDone":39};
stats['bs_BA'] = {"percentDone":85};
stats['bg_BG'] = {"percentDone":77};
stats['ca'] = {"percentDone":61};
stats['hr_HR'] = {"percentDone":32};
stats['cs_CZ'] = {"percentDone":94};
stats['da_DK'] = {"percentDone":85};
stats['de_DE'] = {"percentDone":100};
stats['et_EE'] = {"percentDone":76};
stats['ar'] = {"percentDone":89};
stats['eu'] = {"percentDone":38};
stats['bs_BA'] = {"percentDone":83};
stats['bg_BG'] = {"percentDone":74};
stats['ca'] = {"percentDone":59};
stats['hr_HR'] = {"percentDone":31};
stats['cs_CZ'] = {"percentDone":92};
stats['da_DK'] = {"percentDone":83};
stats['de_DE'] = {"percentDone":97};
stats['et_EE'] = {"percentDone":74};
stats['en_GB'] = {"percentDone":100};
stats['en_US'] = {"percentDone":100};
stats['es_ES'] = {"percentDone":95};
stats['eo'] = {"percentDone":44};
stats['fr_FR'] = {"percentDone":95};
stats['gl_ES'] = {"percentDone":50};
stats['it_IT'] = {"percentDone":97};
stats['nl_BE'] = {"percentDone":39};
stats['nl_NL'] = {"percentDone":97};
stats['nb_NO'] = {"percentDone":89};
stats['fa'] = {"percentDone":38};
stats['pl_PL'] = {"percentDone":75};
stats['pt_PT'] = {"percentDone":91};
stats['pt_BR'] = {"percentDone":88};
stats['ro'] = {"percentDone":39};
stats['sl_SI'] = {"percentDone":49};
stats['sv'] = {"percentDone":68};
stats['th_TH'] = {"percentDone":61};
stats['tr_TR'] = {"percentDone":92};
stats['el_GR'] = {"percentDone":93};
stats['ru_RU'] = {"percentDone":95};
stats['sr_RS'] = {"percentDone":75};
stats['zh_CN'] = {"percentDone":97};
stats['zh_TW'] = {"percentDone":91};
stats['ja_JP'] = {"percentDone":100};
stats['ko'] = {"percentDone":97};
stats['es_ES'] = {"percentDone":92};
stats['eo'] = {"percentDone":42};
stats['fr_FR'] = {"percentDone":93};
stats['gl_ES'] = {"percentDone":48};
stats['it_IT'] = {"percentDone":96};
stats['nl_BE'] = {"percentDone":38};
stats['nl_NL'] = {"percentDone":95};
stats['nb_NO'] = {"percentDone":87};
stats['fa'] = {"percentDone":37};
stats['pl_PL'] = {"percentDone":73};
stats['pt_PT'] = {"percentDone":88};
stats['pt_BR'] = {"percentDone":85};
stats['ro'] = {"percentDone":38};
stats['sl_SI'] = {"percentDone":48};
stats['sv'] = {"percentDone":66};
stats['th_TH'] = {"percentDone":59};
stats['tr_TR'] = {"percentDone":89};
stats['el_GR'] = {"percentDone":91};
stats['ru_RU'] = {"percentDone":93};
stats['sr_RS'] = {"percentDone":80};
stats['zh_CN'] = {"percentDone":95};
stats['zh_TW'] = {"percentDone":89};
stats['ja_JP'] = {"percentDone":97};
stats['ko'] = {"percentDone":95};
module.exports = { locales: locales, stats: stats };

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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