You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2026-01-02 00:08:04 +02:00
Compare commits
71 Commits
testing_up
...
server_str
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
275ea53523 | ||
|
|
c88e4f6628 | ||
|
|
395cb8bf34 | ||
|
|
8952c91712 | ||
|
|
32b0806b0e | ||
|
|
5a5d8a3325 | ||
|
|
c2dfb4593c | ||
|
|
2f79492192 | ||
|
|
b3ca7f228a | ||
|
|
ba726f643c | ||
|
|
cb78ea832c | ||
|
|
69aa749205 | ||
|
|
87a5f18c7b | ||
|
|
1d2a3a97d2 | ||
|
|
42891e37a1 | ||
|
|
fe802b8ebc | ||
|
|
3cb6d4568c | ||
|
|
5c8e4f24d6 | ||
|
|
a9f0a75d9d | ||
|
|
07d30eb5d2 | ||
|
|
8f6a47536c | ||
|
|
d8d83b236e | ||
|
|
a355600e76 | ||
|
|
2a58664735 | ||
|
|
89bc181072 | ||
|
|
ab7380a09f | ||
|
|
e1bbdbcf9b | ||
|
|
f8a26cf8f9 | ||
|
|
3505a2a973 | ||
|
|
5f94de0f24 | ||
|
|
6811ea1eb9 | ||
|
|
7be59a7435 | ||
|
|
c0683ca4c3 | ||
|
|
2b286410f6 | ||
|
|
907ac7c1f8 | ||
|
|
8bc27021db | ||
|
|
41ed66d323 | ||
|
|
0ef7e98479 | ||
|
|
161c77cb48 | ||
|
|
50d17bfb36 | ||
|
|
ee0f23718b | ||
|
|
cfe4546a0b | ||
|
|
f45e0d106f | ||
|
|
12a66342db | ||
|
|
f2b17560e6 | ||
|
|
ba30dce6c8 | ||
|
|
f5984313be | ||
|
|
df058352a5 | ||
|
|
cde25fad92 | ||
|
|
d89bbc5571 | ||
|
|
71a7fc015a | ||
|
|
83cef7a824 | ||
|
|
f65de0c9eb | ||
|
|
3edf74e6d2 | ||
|
|
b01aa7eb45 | ||
|
|
e59e3aa7d1 | ||
|
|
51051e0ee0 | ||
|
|
b20ab19f13 | ||
|
|
68e79f1573 | ||
|
|
ed8ee67048 | ||
|
|
68b516998d | ||
|
|
0fa7a66fb6 | ||
|
|
13f39b9bd5 | ||
|
|
013d37bd09 | ||
|
|
4760e5e8ba | ||
|
|
8930dac40e | ||
|
|
3f0586ef63 | ||
|
|
e94503abbe | ||
|
|
f8253cc2f0 | ||
|
|
2806aa1b19 | ||
|
|
8f57e07279 |
204
.eslintignore
204
.eslintignore
@@ -74,75 +74,21 @@ packages/app-cli/app/command-settingschema.js.map
|
||||
packages/app-cli/app/services/plugins/PluginRunner.d.ts
|
||||
packages/app-cli/app/services/plugins/PluginRunner.js
|
||||
packages/app-cli/app/services/plugins/PluginRunner.js.map
|
||||
packages/app-cli/tests/EnexToMd.d.ts
|
||||
packages/app-cli/tests/EnexToMd.js
|
||||
packages/app-cli/tests/EnexToMd.js.map
|
||||
packages/app-cli/tests/HtmlToMd.d.ts
|
||||
packages/app-cli/tests/HtmlToMd.js
|
||||
packages/app-cli/tests/HtmlToMd.js.map
|
||||
packages/app-cli/tests/InMemoryCache.d.ts
|
||||
packages/app-cli/tests/InMemoryCache.js
|
||||
packages/app-cli/tests/InMemoryCache.js.map
|
||||
packages/app-cli/tests/MdToHtml.d.ts
|
||||
packages/app-cli/tests/MdToHtml.js
|
||||
packages/app-cli/tests/MdToHtml.js.map
|
||||
packages/app-cli/tests/MdToMd.d.ts
|
||||
packages/app-cli/tests/MdToMd.js
|
||||
packages/app-cli/tests/MdToMd.js.map
|
||||
packages/app-cli/tests/Synchronizer.basics.d.ts
|
||||
packages/app-cli/tests/Synchronizer.basics.js
|
||||
packages/app-cli/tests/Synchronizer.basics.js.map
|
||||
packages/app-cli/tests/Synchronizer.conflicts.d.ts
|
||||
packages/app-cli/tests/Synchronizer.conflicts.js
|
||||
packages/app-cli/tests/Synchronizer.conflicts.js.map
|
||||
packages/app-cli/tests/Synchronizer.e2ee.d.ts
|
||||
packages/app-cli/tests/Synchronizer.e2ee.js
|
||||
packages/app-cli/tests/Synchronizer.e2ee.js.map
|
||||
packages/app-cli/tests/Synchronizer.resources.d.ts
|
||||
packages/app-cli/tests/Synchronizer.resources.js
|
||||
packages/app-cli/tests/Synchronizer.resources.js.map
|
||||
packages/app-cli/tests/Synchronizer.revisions.d.ts
|
||||
packages/app-cli/tests/Synchronizer.revisions.js
|
||||
packages/app-cli/tests/Synchronizer.revisions.js.map
|
||||
packages/app-cli/tests/Synchronizer.sharing.d.ts
|
||||
packages/app-cli/tests/Synchronizer.sharing.js
|
||||
packages/app-cli/tests/Synchronizer.sharing.js.map
|
||||
packages/app-cli/tests/Synchronizer.tags.d.ts
|
||||
packages/app-cli/tests/Synchronizer.tags.js
|
||||
packages/app-cli/tests/Synchronizer.tags.js.map
|
||||
packages/app-cli/tests/Synchronizer.tools.d.ts
|
||||
packages/app-cli/tests/Synchronizer.tools.js
|
||||
packages/app-cli/tests/Synchronizer.tools.js.map
|
||||
packages/app-cli/tests/dateTimeFormats.d.ts
|
||||
packages/app-cli/tests/dateTimeFormats.js
|
||||
packages/app-cli/tests/dateTimeFormats.js.map
|
||||
packages/app-cli/tests/file-api-driver.d.ts
|
||||
packages/app-cli/tests/file-api-driver.js
|
||||
packages/app-cli/tests/file-api-driver.js.map
|
||||
packages/app-cli/tests/fsDriver.d.ts
|
||||
packages/app-cli/tests/fsDriver.js
|
||||
packages/app-cli/tests/fsDriver.js.map
|
||||
packages/app-cli/tests/htmlUtils.d.ts
|
||||
packages/app-cli/tests/htmlUtils.js
|
||||
packages/app-cli/tests/htmlUtils.js.map
|
||||
packages/app-cli/tests/markdownUtils.d.ts
|
||||
packages/app-cli/tests/markdownUtils.js
|
||||
packages/app-cli/tests/markdownUtils.js.map
|
||||
packages/app-cli/tests/models_Folder.d.ts
|
||||
packages/app-cli/tests/models_Folder.js
|
||||
packages/app-cli/tests/models_Folder.js.map
|
||||
packages/app-cli/tests/models_Folder.sharing.d.ts
|
||||
packages/app-cli/tests/models_Folder.sharing.js
|
||||
packages/app-cli/tests/models_Folder.sharing.js.map
|
||||
packages/app-cli/tests/models_Note.d.ts
|
||||
packages/app-cli/tests/models_Note.js
|
||||
packages/app-cli/tests/models_Note.js.map
|
||||
packages/app-cli/tests/models_Setting.d.ts
|
||||
packages/app-cli/tests/models_Setting.js
|
||||
packages/app-cli/tests/models_Setting.js.map
|
||||
packages/app-cli/tests/registry.d.ts
|
||||
packages/app-cli/tests/registry.js
|
||||
packages/app-cli/tests/registry.js.map
|
||||
packages/app-cli/tests/services/keychain/KeychainService.d.ts
|
||||
packages/app-cli/tests/services/keychain/KeychainService.js
|
||||
packages/app-cli/tests/services/keychain/KeychainService.js.map
|
||||
packages/app-cli/tests/services/plugins/PluginService.d.ts
|
||||
packages/app-cli/tests/services/plugins/PluginService.js
|
||||
packages/app-cli/tests/services/plugins/PluginService.js.map
|
||||
packages/app-cli/tests/services/plugins/RepositoryApi.d.ts
|
||||
packages/app-cli/tests/services/plugins/RepositoryApi.js
|
||||
packages/app-cli/tests/services/plugins/RepositoryApi.js.map
|
||||
@@ -158,42 +104,9 @@ packages/app-cli/tests/services/plugins/api/JoplinWorkspace.js.map
|
||||
packages/app-cli/tests/services/plugins/sandboxProxy.d.ts
|
||||
packages/app-cli/tests/services/plugins/sandboxProxy.js
|
||||
packages/app-cli/tests/services/plugins/sandboxProxy.js.map
|
||||
packages/app-cli/tests/services_CommandService.d.ts
|
||||
packages/app-cli/tests/services_CommandService.js
|
||||
packages/app-cli/tests/services_CommandService.js.map
|
||||
packages/app-cli/tests/services_InteropService.d.ts
|
||||
packages/app-cli/tests/services_InteropService.js
|
||||
packages/app-cli/tests/services_InteropService.js.map
|
||||
packages/app-cli/tests/services_InteropService_Exporter_Html.d.ts
|
||||
packages/app-cli/tests/services_InteropService_Exporter_Html.js
|
||||
packages/app-cli/tests/services_InteropService_Exporter_Html.js.map
|
||||
packages/app-cli/tests/services_PluginService.d.ts
|
||||
packages/app-cli/tests/services_PluginService.js
|
||||
packages/app-cli/tests/services_PluginService.js.map
|
||||
packages/app-cli/tests/services_ResourceService.d.ts
|
||||
packages/app-cli/tests/services_ResourceService.js
|
||||
packages/app-cli/tests/services_ResourceService.js.map
|
||||
packages/app-cli/tests/services_SearchEngineUtils.d.ts
|
||||
packages/app-cli/tests/services_SearchEngineUtils.js
|
||||
packages/app-cli/tests/services_SearchEngineUtils.js.map
|
||||
packages/app-cli/tests/services_keychainService.d.ts
|
||||
packages/app-cli/tests/services_keychainService.js
|
||||
packages/app-cli/tests/services_keychainService.js.map
|
||||
packages/app-cli/tests/services_rest_Api.d.ts
|
||||
packages/app-cli/tests/services_rest_Api.js
|
||||
packages/app-cli/tests/services_rest_Api.js.map
|
||||
packages/app-cli/tests/synchronizer_LockHandler.d.ts
|
||||
packages/app-cli/tests/synchronizer_LockHandler.js
|
||||
packages/app-cli/tests/synchronizer_LockHandler.js.map
|
||||
packages/app-cli/tests/synchronizer_MigrationHandler.d.ts
|
||||
packages/app-cli/tests/synchronizer_MigrationHandler.js
|
||||
packages/app-cli/tests/synchronizer_MigrationHandler.js.map
|
||||
packages/app-cli/tests/test-utils-synchronizer.d.ts
|
||||
packages/app-cli/tests/test-utils-synchronizer.js
|
||||
packages/app-cli/tests/test-utils-synchronizer.js.map
|
||||
packages/app-cli/tests/test-utils.d.ts
|
||||
packages/app-cli/tests/test-utils.js
|
||||
packages/app-cli/tests/test-utils.js.map
|
||||
packages/app-cli/tests/testUtils.d.ts
|
||||
packages/app-cli/tests/testUtils.js
|
||||
packages/app-cli/tests/testUtils.js.map
|
||||
packages/app-desktop/ElectronAppWrapper.d.ts
|
||||
packages/app-desktop/ElectronAppWrapper.js
|
||||
packages/app-desktop/ElectronAppWrapper.js.map
|
||||
@@ -890,6 +803,9 @@ packages/lib/HtmlToMd.js.map
|
||||
packages/lib/InMemoryCache.d.ts
|
||||
packages/lib/InMemoryCache.js
|
||||
packages/lib/InMemoryCache.js.map
|
||||
packages/lib/InMemoryCache.test.d.ts
|
||||
packages/lib/InMemoryCache.test.js
|
||||
packages/lib/InMemoryCache.test.js.map
|
||||
packages/lib/JoplinDatabase.d.ts
|
||||
packages/lib/JoplinDatabase.js
|
||||
packages/lib/JoplinDatabase.js.map
|
||||
@@ -941,6 +857,9 @@ packages/lib/eventManager.js.map
|
||||
packages/lib/file-api-driver-joplinServer.d.ts
|
||||
packages/lib/file-api-driver-joplinServer.js
|
||||
packages/lib/file-api-driver-joplinServer.js.map
|
||||
packages/lib/file-api-driver.test.d.ts
|
||||
packages/lib/file-api-driver.test.js
|
||||
packages/lib/file-api-driver.test.js.map
|
||||
packages/lib/file-api.d.ts
|
||||
packages/lib/file-api.js
|
||||
packages/lib/file-api.js.map
|
||||
@@ -950,15 +869,24 @@ packages/lib/fs-driver-base.js.map
|
||||
packages/lib/fs-driver-node.d.ts
|
||||
packages/lib/fs-driver-node.js
|
||||
packages/lib/fs-driver-node.js.map
|
||||
packages/lib/fsDriver.test.d.ts
|
||||
packages/lib/fsDriver.test.js
|
||||
packages/lib/fsDriver.test.js.map
|
||||
packages/lib/htmlUtils.d.ts
|
||||
packages/lib/htmlUtils.js
|
||||
packages/lib/htmlUtils.js.map
|
||||
packages/lib/htmlUtils.test.d.ts
|
||||
packages/lib/htmlUtils.test.js
|
||||
packages/lib/htmlUtils.test.js.map
|
||||
packages/lib/htmlUtils2.test.d.ts
|
||||
packages/lib/htmlUtils2.test.js
|
||||
packages/lib/htmlUtils2.test.js.map
|
||||
packages/lib/import-enex-md-gen.d.ts
|
||||
packages/lib/import-enex-md-gen.js
|
||||
packages/lib/import-enex-md-gen.js.map
|
||||
packages/lib/import-enex-md-gen.test.d.ts
|
||||
packages/lib/import-enex-md-gen.test.js
|
||||
packages/lib/import-enex-md-gen.test.js.map
|
||||
packages/lib/locale.d.ts
|
||||
packages/lib/locale.js
|
||||
packages/lib/locale.js.map
|
||||
@@ -968,6 +896,9 @@ packages/lib/markdownUtils.js.map
|
||||
packages/lib/markdownUtils.test.d.ts
|
||||
packages/lib/markdownUtils.test.js
|
||||
packages/lib/markdownUtils.test.js.map
|
||||
packages/lib/markdownUtils2.test.d.ts
|
||||
packages/lib/markdownUtils2.test.js
|
||||
packages/lib/markdownUtils2.test.js.map
|
||||
packages/lib/markupLanguageUtils.d.ts
|
||||
packages/lib/markupLanguageUtils.js
|
||||
packages/lib/markupLanguageUtils.js.map
|
||||
@@ -980,6 +911,12 @@ packages/lib/models/BaseItem.js.map
|
||||
packages/lib/models/Folder.d.ts
|
||||
packages/lib/models/Folder.js
|
||||
packages/lib/models/Folder.js.map
|
||||
packages/lib/models/Folder.sharing.test.d.ts
|
||||
packages/lib/models/Folder.sharing.test.js
|
||||
packages/lib/models/Folder.sharing.test.js.map
|
||||
packages/lib/models/Folder.test.d.ts
|
||||
packages/lib/models/Folder.test.js
|
||||
packages/lib/models/Folder.test.js.map
|
||||
packages/lib/models/ItemChange.d.ts
|
||||
packages/lib/models/ItemChange.js
|
||||
packages/lib/models/ItemChange.js.map
|
||||
@@ -992,6 +929,9 @@ packages/lib/models/Migration.js.map
|
||||
packages/lib/models/Note.d.ts
|
||||
packages/lib/models/Note.js
|
||||
packages/lib/models/Note.js.map
|
||||
packages/lib/models/Note.test.d.ts
|
||||
packages/lib/models/Note.test.js
|
||||
packages/lib/models/Note.test.js.map
|
||||
packages/lib/models/NoteResource.d.ts
|
||||
packages/lib/models/NoteResource.js
|
||||
packages/lib/models/NoteResource.js.map
|
||||
@@ -1013,12 +953,18 @@ packages/lib/models/Search.js.map
|
||||
packages/lib/models/Setting.d.ts
|
||||
packages/lib/models/Setting.js
|
||||
packages/lib/models/Setting.js.map
|
||||
packages/lib/models/Setting.test.d.ts
|
||||
packages/lib/models/Setting.test.js
|
||||
packages/lib/models/Setting.test.js.map
|
||||
packages/lib/models/SmartFilter.d.ts
|
||||
packages/lib/models/SmartFilter.js
|
||||
packages/lib/models/SmartFilter.js.map
|
||||
packages/lib/models/Tag.d.ts
|
||||
packages/lib/models/Tag.js
|
||||
packages/lib/models/Tag.js.map
|
||||
packages/lib/models/dateTimeFormats.test.d.ts
|
||||
packages/lib/models/dateTimeFormats.test.js
|
||||
packages/lib/models/dateTimeFormats.test.js.map
|
||||
packages/lib/models/settings/FileHandler.d.ts
|
||||
packages/lib/models/settings/FileHandler.js
|
||||
packages/lib/models/settings/FileHandler.js.map
|
||||
@@ -1046,6 +992,9 @@ packages/lib/reducer.js.map
|
||||
packages/lib/registry.d.ts
|
||||
packages/lib/registry.js
|
||||
packages/lib/registry.js.map
|
||||
packages/lib/registry.test.d.ts
|
||||
packages/lib/registry.test.js
|
||||
packages/lib/registry.test.js.map
|
||||
packages/lib/services/AlarmService.d.ts
|
||||
packages/lib/services/AlarmService.js
|
||||
packages/lib/services/AlarmService.js.map
|
||||
@@ -1058,6 +1007,9 @@ packages/lib/services/BaseService.js.map
|
||||
packages/lib/services/CommandService.d.ts
|
||||
packages/lib/services/CommandService.js
|
||||
packages/lib/services/CommandService.js.map
|
||||
packages/lib/services/CommandService.test.d.ts
|
||||
packages/lib/services/CommandService.test.js
|
||||
packages/lib/services/CommandService.test.js.map
|
||||
packages/lib/services/DecryptionWorker.d.ts
|
||||
packages/lib/services/DecryptionWorker.js
|
||||
packages/lib/services/DecryptionWorker.js.map
|
||||
@@ -1106,6 +1058,9 @@ packages/lib/services/ResourceFetcher.js.map
|
||||
packages/lib/services/ResourceService.d.ts
|
||||
packages/lib/services/ResourceService.js
|
||||
packages/lib/services/ResourceService.js.map
|
||||
packages/lib/services/ResourceService.test.d.ts
|
||||
packages/lib/services/ResourceService.test.js
|
||||
packages/lib/services/ResourceService.test.js.map
|
||||
packages/lib/services/RevisionService.d.ts
|
||||
packages/lib/services/RevisionService.js
|
||||
packages/lib/services/RevisionService.js.map
|
||||
@@ -1154,6 +1109,9 @@ packages/lib/services/debug/populateDatabase.js.map
|
||||
packages/lib/services/interop/InteropService.d.ts
|
||||
packages/lib/services/interop/InteropService.js
|
||||
packages/lib/services/interop/InteropService.js.map
|
||||
packages/lib/services/interop/InteropService.test.d.ts
|
||||
packages/lib/services/interop/InteropService.test.js
|
||||
packages/lib/services/interop/InteropService.test.js.map
|
||||
packages/lib/services/interop/InteropService_Exporter_Base.d.ts
|
||||
packages/lib/services/interop/InteropService_Exporter_Base.js
|
||||
packages/lib/services/interop/InteropService_Exporter_Base.js.map
|
||||
@@ -1163,6 +1121,9 @@ packages/lib/services/interop/InteropService_Exporter_Custom.js.map
|
||||
packages/lib/services/interop/InteropService_Exporter_Html.d.ts
|
||||
packages/lib/services/interop/InteropService_Exporter_Html.js
|
||||
packages/lib/services/interop/InteropService_Exporter_Html.js.map
|
||||
packages/lib/services/interop/InteropService_Exporter_Html.test.d.ts
|
||||
packages/lib/services/interop/InteropService_Exporter_Html.test.js
|
||||
packages/lib/services/interop/InteropService_Exporter_Html.test.js.map
|
||||
packages/lib/services/interop/InteropService_Exporter_Jex.d.ts
|
||||
packages/lib/services/interop/InteropService_Exporter_Jex.js
|
||||
packages/lib/services/interop/InteropService_Exporter_Jex.js.map
|
||||
@@ -1325,6 +1286,9 @@ packages/lib/services/plugins/utils/validatePluginId.test.js.map
|
||||
packages/lib/services/rest/Api.d.ts
|
||||
packages/lib/services/rest/Api.js
|
||||
packages/lib/services/rest/Api.js.map
|
||||
packages/lib/services/rest/Api.test.d.ts
|
||||
packages/lib/services/rest/Api.test.js
|
||||
packages/lib/services/rest/Api.test.js.map
|
||||
packages/lib/services/rest/ApiResponse.d.ts
|
||||
packages/lib/services/rest/ApiResponse.js
|
||||
packages/lib/services/rest/ApiResponse.js.map
|
||||
@@ -1385,6 +1349,9 @@ packages/lib/services/searchengine/SearchEngine.js.map
|
||||
packages/lib/services/searchengine/SearchEngineUtils.d.ts
|
||||
packages/lib/services/searchengine/SearchEngineUtils.js
|
||||
packages/lib/services/searchengine/SearchEngineUtils.js.map
|
||||
packages/lib/services/searchengine/SearchEngineUtils.test.d.ts
|
||||
packages/lib/services/searchengine/SearchEngineUtils.test.js
|
||||
packages/lib/services/searchengine/SearchEngineUtils.test.js.map
|
||||
packages/lib/services/searchengine/filterParser.d.ts
|
||||
packages/lib/services/searchengine/filterParser.js
|
||||
packages/lib/services/searchengine/filterParser.js.map
|
||||
@@ -1409,6 +1376,30 @@ packages/lib/services/synchronizer/LockHandler.js.map
|
||||
packages/lib/services/synchronizer/MigrationHandler.d.ts
|
||||
packages/lib/services/synchronizer/MigrationHandler.js
|
||||
packages/lib/services/synchronizer/MigrationHandler.js.map
|
||||
packages/lib/services/synchronizer/Synchronizer.basics.test.d.ts
|
||||
packages/lib/services/synchronizer/Synchronizer.basics.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.basics.test.js.map
|
||||
packages/lib/services/synchronizer/Synchronizer.conflicts.test.d.ts
|
||||
packages/lib/services/synchronizer/Synchronizer.conflicts.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.conflicts.test.js.map
|
||||
packages/lib/services/synchronizer/Synchronizer.e2ee.test.d.ts
|
||||
packages/lib/services/synchronizer/Synchronizer.e2ee.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.e2ee.test.js.map
|
||||
packages/lib/services/synchronizer/Synchronizer.resources.test.d.ts
|
||||
packages/lib/services/synchronizer/Synchronizer.resources.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.resources.test.js.map
|
||||
packages/lib/services/synchronizer/Synchronizer.revisions.test.d.ts
|
||||
packages/lib/services/synchronizer/Synchronizer.revisions.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.revisions.test.js.map
|
||||
packages/lib/services/synchronizer/Synchronizer.sharing.test.d.ts
|
||||
packages/lib/services/synchronizer/Synchronizer.sharing.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.sharing.test.js.map
|
||||
packages/lib/services/synchronizer/Synchronizer.tags.test.d.ts
|
||||
packages/lib/services/synchronizer/Synchronizer.tags.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.tags.test.js.map
|
||||
packages/lib/services/synchronizer/Synchronizer.tools.test.d.ts
|
||||
packages/lib/services/synchronizer/Synchronizer.tools.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.tools.test.js.map
|
||||
packages/lib/services/synchronizer/gui/useSyncTargetUpgrade.d.ts
|
||||
packages/lib/services/synchronizer/gui/useSyncTargetUpgrade.js
|
||||
packages/lib/services/synchronizer/gui/useSyncTargetUpgrade.js.map
|
||||
@@ -1418,6 +1409,12 @@ packages/lib/services/synchronizer/migrations/1.js.map
|
||||
packages/lib/services/synchronizer/migrations/2.d.ts
|
||||
packages/lib/services/synchronizer/migrations/2.js
|
||||
packages/lib/services/synchronizer/migrations/2.js.map
|
||||
packages/lib/services/synchronizer/synchronizer_LockHandler.test.d.ts
|
||||
packages/lib/services/synchronizer/synchronizer_LockHandler.test.js
|
||||
packages/lib/services/synchronizer/synchronizer_LockHandler.test.js.map
|
||||
packages/lib/services/synchronizer/synchronizer_MigrationHandler.test.d.ts
|
||||
packages/lib/services/synchronizer/synchronizer_MigrationHandler.test.js
|
||||
packages/lib/services/synchronizer/synchronizer_MigrationHandler.test.js.map
|
||||
packages/lib/services/synchronizer/tools.d.ts
|
||||
packages/lib/services/synchronizer/tools.js
|
||||
packages/lib/services/synchronizer/tools.js.map
|
||||
@@ -1430,6 +1427,12 @@ packages/lib/services/synchronizer/utils/types.js.map
|
||||
packages/lib/shim.d.ts
|
||||
packages/lib/shim.js
|
||||
packages/lib/shim.js.map
|
||||
packages/lib/testing/test-utils-synchronizer.d.ts
|
||||
packages/lib/testing/test-utils-synchronizer.js
|
||||
packages/lib/testing/test-utils-synchronizer.js.map
|
||||
packages/lib/testing/test-utils.d.ts
|
||||
packages/lib/testing/test-utils.js
|
||||
packages/lib/testing/test-utils.js.map
|
||||
packages/lib/theme.d.ts
|
||||
packages/lib/theme.js
|
||||
packages/lib/theme.js.map
|
||||
@@ -1463,12 +1466,18 @@ packages/lib/themes/type.js.map
|
||||
packages/lib/time.d.ts
|
||||
packages/lib/time.js
|
||||
packages/lib/time.js.map
|
||||
packages/lib/utils/credentialFiles.d.ts
|
||||
packages/lib/utils/credentialFiles.js
|
||||
packages/lib/utils/credentialFiles.js.map
|
||||
packages/lib/uuid.d.ts
|
||||
packages/lib/uuid.js
|
||||
packages/lib/uuid.js.map
|
||||
packages/lib/versionInfo.d.ts
|
||||
packages/lib/versionInfo.js
|
||||
packages/lib/versionInfo.js.map
|
||||
packages/plugin-repo-cli/commands/updateRelease.d.ts
|
||||
packages/plugin-repo-cli/commands/updateRelease.js
|
||||
packages/plugin-repo-cli/commands/updateRelease.js.map
|
||||
packages/plugin-repo-cli/index.d.ts
|
||||
packages/plugin-repo-cli/index.js
|
||||
packages/plugin-repo-cli/index.js.map
|
||||
@@ -1607,4 +1616,7 @@ packages/tools/release-server.js.map
|
||||
packages/tools/tool-utils.d.ts
|
||||
packages/tools/tool-utils.js
|
||||
packages/tools/tool-utils.js.map
|
||||
packages/tools/update-readme-sponsors.d.ts
|
||||
packages/tools/update-readme-sponsors.js
|
||||
packages/tools/update-readme-sponsors.js.map
|
||||
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
|
||||
|
||||
204
.gitignore
vendored
204
.gitignore
vendored
@@ -60,75 +60,21 @@ packages/app-cli/app/command-settingschema.js.map
|
||||
packages/app-cli/app/services/plugins/PluginRunner.d.ts
|
||||
packages/app-cli/app/services/plugins/PluginRunner.js
|
||||
packages/app-cli/app/services/plugins/PluginRunner.js.map
|
||||
packages/app-cli/tests/EnexToMd.d.ts
|
||||
packages/app-cli/tests/EnexToMd.js
|
||||
packages/app-cli/tests/EnexToMd.js.map
|
||||
packages/app-cli/tests/HtmlToMd.d.ts
|
||||
packages/app-cli/tests/HtmlToMd.js
|
||||
packages/app-cli/tests/HtmlToMd.js.map
|
||||
packages/app-cli/tests/InMemoryCache.d.ts
|
||||
packages/app-cli/tests/InMemoryCache.js
|
||||
packages/app-cli/tests/InMemoryCache.js.map
|
||||
packages/app-cli/tests/MdToHtml.d.ts
|
||||
packages/app-cli/tests/MdToHtml.js
|
||||
packages/app-cli/tests/MdToHtml.js.map
|
||||
packages/app-cli/tests/MdToMd.d.ts
|
||||
packages/app-cli/tests/MdToMd.js
|
||||
packages/app-cli/tests/MdToMd.js.map
|
||||
packages/app-cli/tests/Synchronizer.basics.d.ts
|
||||
packages/app-cli/tests/Synchronizer.basics.js
|
||||
packages/app-cli/tests/Synchronizer.basics.js.map
|
||||
packages/app-cli/tests/Synchronizer.conflicts.d.ts
|
||||
packages/app-cli/tests/Synchronizer.conflicts.js
|
||||
packages/app-cli/tests/Synchronizer.conflicts.js.map
|
||||
packages/app-cli/tests/Synchronizer.e2ee.d.ts
|
||||
packages/app-cli/tests/Synchronizer.e2ee.js
|
||||
packages/app-cli/tests/Synchronizer.e2ee.js.map
|
||||
packages/app-cli/tests/Synchronizer.resources.d.ts
|
||||
packages/app-cli/tests/Synchronizer.resources.js
|
||||
packages/app-cli/tests/Synchronizer.resources.js.map
|
||||
packages/app-cli/tests/Synchronizer.revisions.d.ts
|
||||
packages/app-cli/tests/Synchronizer.revisions.js
|
||||
packages/app-cli/tests/Synchronizer.revisions.js.map
|
||||
packages/app-cli/tests/Synchronizer.sharing.d.ts
|
||||
packages/app-cli/tests/Synchronizer.sharing.js
|
||||
packages/app-cli/tests/Synchronizer.sharing.js.map
|
||||
packages/app-cli/tests/Synchronizer.tags.d.ts
|
||||
packages/app-cli/tests/Synchronizer.tags.js
|
||||
packages/app-cli/tests/Synchronizer.tags.js.map
|
||||
packages/app-cli/tests/Synchronizer.tools.d.ts
|
||||
packages/app-cli/tests/Synchronizer.tools.js
|
||||
packages/app-cli/tests/Synchronizer.tools.js.map
|
||||
packages/app-cli/tests/dateTimeFormats.d.ts
|
||||
packages/app-cli/tests/dateTimeFormats.js
|
||||
packages/app-cli/tests/dateTimeFormats.js.map
|
||||
packages/app-cli/tests/file-api-driver.d.ts
|
||||
packages/app-cli/tests/file-api-driver.js
|
||||
packages/app-cli/tests/file-api-driver.js.map
|
||||
packages/app-cli/tests/fsDriver.d.ts
|
||||
packages/app-cli/tests/fsDriver.js
|
||||
packages/app-cli/tests/fsDriver.js.map
|
||||
packages/app-cli/tests/htmlUtils.d.ts
|
||||
packages/app-cli/tests/htmlUtils.js
|
||||
packages/app-cli/tests/htmlUtils.js.map
|
||||
packages/app-cli/tests/markdownUtils.d.ts
|
||||
packages/app-cli/tests/markdownUtils.js
|
||||
packages/app-cli/tests/markdownUtils.js.map
|
||||
packages/app-cli/tests/models_Folder.d.ts
|
||||
packages/app-cli/tests/models_Folder.js
|
||||
packages/app-cli/tests/models_Folder.js.map
|
||||
packages/app-cli/tests/models_Folder.sharing.d.ts
|
||||
packages/app-cli/tests/models_Folder.sharing.js
|
||||
packages/app-cli/tests/models_Folder.sharing.js.map
|
||||
packages/app-cli/tests/models_Note.d.ts
|
||||
packages/app-cli/tests/models_Note.js
|
||||
packages/app-cli/tests/models_Note.js.map
|
||||
packages/app-cli/tests/models_Setting.d.ts
|
||||
packages/app-cli/tests/models_Setting.js
|
||||
packages/app-cli/tests/models_Setting.js.map
|
||||
packages/app-cli/tests/registry.d.ts
|
||||
packages/app-cli/tests/registry.js
|
||||
packages/app-cli/tests/registry.js.map
|
||||
packages/app-cli/tests/services/keychain/KeychainService.d.ts
|
||||
packages/app-cli/tests/services/keychain/KeychainService.js
|
||||
packages/app-cli/tests/services/keychain/KeychainService.js.map
|
||||
packages/app-cli/tests/services/plugins/PluginService.d.ts
|
||||
packages/app-cli/tests/services/plugins/PluginService.js
|
||||
packages/app-cli/tests/services/plugins/PluginService.js.map
|
||||
packages/app-cli/tests/services/plugins/RepositoryApi.d.ts
|
||||
packages/app-cli/tests/services/plugins/RepositoryApi.js
|
||||
packages/app-cli/tests/services/plugins/RepositoryApi.js.map
|
||||
@@ -144,42 +90,9 @@ packages/app-cli/tests/services/plugins/api/JoplinWorkspace.js.map
|
||||
packages/app-cli/tests/services/plugins/sandboxProxy.d.ts
|
||||
packages/app-cli/tests/services/plugins/sandboxProxy.js
|
||||
packages/app-cli/tests/services/plugins/sandboxProxy.js.map
|
||||
packages/app-cli/tests/services_CommandService.d.ts
|
||||
packages/app-cli/tests/services_CommandService.js
|
||||
packages/app-cli/tests/services_CommandService.js.map
|
||||
packages/app-cli/tests/services_InteropService.d.ts
|
||||
packages/app-cli/tests/services_InteropService.js
|
||||
packages/app-cli/tests/services_InteropService.js.map
|
||||
packages/app-cli/tests/services_InteropService_Exporter_Html.d.ts
|
||||
packages/app-cli/tests/services_InteropService_Exporter_Html.js
|
||||
packages/app-cli/tests/services_InteropService_Exporter_Html.js.map
|
||||
packages/app-cli/tests/services_PluginService.d.ts
|
||||
packages/app-cli/tests/services_PluginService.js
|
||||
packages/app-cli/tests/services_PluginService.js.map
|
||||
packages/app-cli/tests/services_ResourceService.d.ts
|
||||
packages/app-cli/tests/services_ResourceService.js
|
||||
packages/app-cli/tests/services_ResourceService.js.map
|
||||
packages/app-cli/tests/services_SearchEngineUtils.d.ts
|
||||
packages/app-cli/tests/services_SearchEngineUtils.js
|
||||
packages/app-cli/tests/services_SearchEngineUtils.js.map
|
||||
packages/app-cli/tests/services_keychainService.d.ts
|
||||
packages/app-cli/tests/services_keychainService.js
|
||||
packages/app-cli/tests/services_keychainService.js.map
|
||||
packages/app-cli/tests/services_rest_Api.d.ts
|
||||
packages/app-cli/tests/services_rest_Api.js
|
||||
packages/app-cli/tests/services_rest_Api.js.map
|
||||
packages/app-cli/tests/synchronizer_LockHandler.d.ts
|
||||
packages/app-cli/tests/synchronizer_LockHandler.js
|
||||
packages/app-cli/tests/synchronizer_LockHandler.js.map
|
||||
packages/app-cli/tests/synchronizer_MigrationHandler.d.ts
|
||||
packages/app-cli/tests/synchronizer_MigrationHandler.js
|
||||
packages/app-cli/tests/synchronizer_MigrationHandler.js.map
|
||||
packages/app-cli/tests/test-utils-synchronizer.d.ts
|
||||
packages/app-cli/tests/test-utils-synchronizer.js
|
||||
packages/app-cli/tests/test-utils-synchronizer.js.map
|
||||
packages/app-cli/tests/test-utils.d.ts
|
||||
packages/app-cli/tests/test-utils.js
|
||||
packages/app-cli/tests/test-utils.js.map
|
||||
packages/app-cli/tests/testUtils.d.ts
|
||||
packages/app-cli/tests/testUtils.js
|
||||
packages/app-cli/tests/testUtils.js.map
|
||||
packages/app-desktop/ElectronAppWrapper.d.ts
|
||||
packages/app-desktop/ElectronAppWrapper.js
|
||||
packages/app-desktop/ElectronAppWrapper.js.map
|
||||
@@ -876,6 +789,9 @@ packages/lib/HtmlToMd.js.map
|
||||
packages/lib/InMemoryCache.d.ts
|
||||
packages/lib/InMemoryCache.js
|
||||
packages/lib/InMemoryCache.js.map
|
||||
packages/lib/InMemoryCache.test.d.ts
|
||||
packages/lib/InMemoryCache.test.js
|
||||
packages/lib/InMemoryCache.test.js.map
|
||||
packages/lib/JoplinDatabase.d.ts
|
||||
packages/lib/JoplinDatabase.js
|
||||
packages/lib/JoplinDatabase.js.map
|
||||
@@ -927,6 +843,9 @@ packages/lib/eventManager.js.map
|
||||
packages/lib/file-api-driver-joplinServer.d.ts
|
||||
packages/lib/file-api-driver-joplinServer.js
|
||||
packages/lib/file-api-driver-joplinServer.js.map
|
||||
packages/lib/file-api-driver.test.d.ts
|
||||
packages/lib/file-api-driver.test.js
|
||||
packages/lib/file-api-driver.test.js.map
|
||||
packages/lib/file-api.d.ts
|
||||
packages/lib/file-api.js
|
||||
packages/lib/file-api.js.map
|
||||
@@ -936,15 +855,24 @@ packages/lib/fs-driver-base.js.map
|
||||
packages/lib/fs-driver-node.d.ts
|
||||
packages/lib/fs-driver-node.js
|
||||
packages/lib/fs-driver-node.js.map
|
||||
packages/lib/fsDriver.test.d.ts
|
||||
packages/lib/fsDriver.test.js
|
||||
packages/lib/fsDriver.test.js.map
|
||||
packages/lib/htmlUtils.d.ts
|
||||
packages/lib/htmlUtils.js
|
||||
packages/lib/htmlUtils.js.map
|
||||
packages/lib/htmlUtils.test.d.ts
|
||||
packages/lib/htmlUtils.test.js
|
||||
packages/lib/htmlUtils.test.js.map
|
||||
packages/lib/htmlUtils2.test.d.ts
|
||||
packages/lib/htmlUtils2.test.js
|
||||
packages/lib/htmlUtils2.test.js.map
|
||||
packages/lib/import-enex-md-gen.d.ts
|
||||
packages/lib/import-enex-md-gen.js
|
||||
packages/lib/import-enex-md-gen.js.map
|
||||
packages/lib/import-enex-md-gen.test.d.ts
|
||||
packages/lib/import-enex-md-gen.test.js
|
||||
packages/lib/import-enex-md-gen.test.js.map
|
||||
packages/lib/locale.d.ts
|
||||
packages/lib/locale.js
|
||||
packages/lib/locale.js.map
|
||||
@@ -954,6 +882,9 @@ packages/lib/markdownUtils.js.map
|
||||
packages/lib/markdownUtils.test.d.ts
|
||||
packages/lib/markdownUtils.test.js
|
||||
packages/lib/markdownUtils.test.js.map
|
||||
packages/lib/markdownUtils2.test.d.ts
|
||||
packages/lib/markdownUtils2.test.js
|
||||
packages/lib/markdownUtils2.test.js.map
|
||||
packages/lib/markupLanguageUtils.d.ts
|
||||
packages/lib/markupLanguageUtils.js
|
||||
packages/lib/markupLanguageUtils.js.map
|
||||
@@ -966,6 +897,12 @@ packages/lib/models/BaseItem.js.map
|
||||
packages/lib/models/Folder.d.ts
|
||||
packages/lib/models/Folder.js
|
||||
packages/lib/models/Folder.js.map
|
||||
packages/lib/models/Folder.sharing.test.d.ts
|
||||
packages/lib/models/Folder.sharing.test.js
|
||||
packages/lib/models/Folder.sharing.test.js.map
|
||||
packages/lib/models/Folder.test.d.ts
|
||||
packages/lib/models/Folder.test.js
|
||||
packages/lib/models/Folder.test.js.map
|
||||
packages/lib/models/ItemChange.d.ts
|
||||
packages/lib/models/ItemChange.js
|
||||
packages/lib/models/ItemChange.js.map
|
||||
@@ -978,6 +915,9 @@ packages/lib/models/Migration.js.map
|
||||
packages/lib/models/Note.d.ts
|
||||
packages/lib/models/Note.js
|
||||
packages/lib/models/Note.js.map
|
||||
packages/lib/models/Note.test.d.ts
|
||||
packages/lib/models/Note.test.js
|
||||
packages/lib/models/Note.test.js.map
|
||||
packages/lib/models/NoteResource.d.ts
|
||||
packages/lib/models/NoteResource.js
|
||||
packages/lib/models/NoteResource.js.map
|
||||
@@ -999,12 +939,18 @@ packages/lib/models/Search.js.map
|
||||
packages/lib/models/Setting.d.ts
|
||||
packages/lib/models/Setting.js
|
||||
packages/lib/models/Setting.js.map
|
||||
packages/lib/models/Setting.test.d.ts
|
||||
packages/lib/models/Setting.test.js
|
||||
packages/lib/models/Setting.test.js.map
|
||||
packages/lib/models/SmartFilter.d.ts
|
||||
packages/lib/models/SmartFilter.js
|
||||
packages/lib/models/SmartFilter.js.map
|
||||
packages/lib/models/Tag.d.ts
|
||||
packages/lib/models/Tag.js
|
||||
packages/lib/models/Tag.js.map
|
||||
packages/lib/models/dateTimeFormats.test.d.ts
|
||||
packages/lib/models/dateTimeFormats.test.js
|
||||
packages/lib/models/dateTimeFormats.test.js.map
|
||||
packages/lib/models/settings/FileHandler.d.ts
|
||||
packages/lib/models/settings/FileHandler.js
|
||||
packages/lib/models/settings/FileHandler.js.map
|
||||
@@ -1032,6 +978,9 @@ packages/lib/reducer.js.map
|
||||
packages/lib/registry.d.ts
|
||||
packages/lib/registry.js
|
||||
packages/lib/registry.js.map
|
||||
packages/lib/registry.test.d.ts
|
||||
packages/lib/registry.test.js
|
||||
packages/lib/registry.test.js.map
|
||||
packages/lib/services/AlarmService.d.ts
|
||||
packages/lib/services/AlarmService.js
|
||||
packages/lib/services/AlarmService.js.map
|
||||
@@ -1044,6 +993,9 @@ packages/lib/services/BaseService.js.map
|
||||
packages/lib/services/CommandService.d.ts
|
||||
packages/lib/services/CommandService.js
|
||||
packages/lib/services/CommandService.js.map
|
||||
packages/lib/services/CommandService.test.d.ts
|
||||
packages/lib/services/CommandService.test.js
|
||||
packages/lib/services/CommandService.test.js.map
|
||||
packages/lib/services/DecryptionWorker.d.ts
|
||||
packages/lib/services/DecryptionWorker.js
|
||||
packages/lib/services/DecryptionWorker.js.map
|
||||
@@ -1092,6 +1044,9 @@ packages/lib/services/ResourceFetcher.js.map
|
||||
packages/lib/services/ResourceService.d.ts
|
||||
packages/lib/services/ResourceService.js
|
||||
packages/lib/services/ResourceService.js.map
|
||||
packages/lib/services/ResourceService.test.d.ts
|
||||
packages/lib/services/ResourceService.test.js
|
||||
packages/lib/services/ResourceService.test.js.map
|
||||
packages/lib/services/RevisionService.d.ts
|
||||
packages/lib/services/RevisionService.js
|
||||
packages/lib/services/RevisionService.js.map
|
||||
@@ -1140,6 +1095,9 @@ packages/lib/services/debug/populateDatabase.js.map
|
||||
packages/lib/services/interop/InteropService.d.ts
|
||||
packages/lib/services/interop/InteropService.js
|
||||
packages/lib/services/interop/InteropService.js.map
|
||||
packages/lib/services/interop/InteropService.test.d.ts
|
||||
packages/lib/services/interop/InteropService.test.js
|
||||
packages/lib/services/interop/InteropService.test.js.map
|
||||
packages/lib/services/interop/InteropService_Exporter_Base.d.ts
|
||||
packages/lib/services/interop/InteropService_Exporter_Base.js
|
||||
packages/lib/services/interop/InteropService_Exporter_Base.js.map
|
||||
@@ -1149,6 +1107,9 @@ packages/lib/services/interop/InteropService_Exporter_Custom.js.map
|
||||
packages/lib/services/interop/InteropService_Exporter_Html.d.ts
|
||||
packages/lib/services/interop/InteropService_Exporter_Html.js
|
||||
packages/lib/services/interop/InteropService_Exporter_Html.js.map
|
||||
packages/lib/services/interop/InteropService_Exporter_Html.test.d.ts
|
||||
packages/lib/services/interop/InteropService_Exporter_Html.test.js
|
||||
packages/lib/services/interop/InteropService_Exporter_Html.test.js.map
|
||||
packages/lib/services/interop/InteropService_Exporter_Jex.d.ts
|
||||
packages/lib/services/interop/InteropService_Exporter_Jex.js
|
||||
packages/lib/services/interop/InteropService_Exporter_Jex.js.map
|
||||
@@ -1311,6 +1272,9 @@ packages/lib/services/plugins/utils/validatePluginId.test.js.map
|
||||
packages/lib/services/rest/Api.d.ts
|
||||
packages/lib/services/rest/Api.js
|
||||
packages/lib/services/rest/Api.js.map
|
||||
packages/lib/services/rest/Api.test.d.ts
|
||||
packages/lib/services/rest/Api.test.js
|
||||
packages/lib/services/rest/Api.test.js.map
|
||||
packages/lib/services/rest/ApiResponse.d.ts
|
||||
packages/lib/services/rest/ApiResponse.js
|
||||
packages/lib/services/rest/ApiResponse.js.map
|
||||
@@ -1371,6 +1335,9 @@ packages/lib/services/searchengine/SearchEngine.js.map
|
||||
packages/lib/services/searchengine/SearchEngineUtils.d.ts
|
||||
packages/lib/services/searchengine/SearchEngineUtils.js
|
||||
packages/lib/services/searchengine/SearchEngineUtils.js.map
|
||||
packages/lib/services/searchengine/SearchEngineUtils.test.d.ts
|
||||
packages/lib/services/searchengine/SearchEngineUtils.test.js
|
||||
packages/lib/services/searchengine/SearchEngineUtils.test.js.map
|
||||
packages/lib/services/searchengine/filterParser.d.ts
|
||||
packages/lib/services/searchengine/filterParser.js
|
||||
packages/lib/services/searchengine/filterParser.js.map
|
||||
@@ -1395,6 +1362,30 @@ packages/lib/services/synchronizer/LockHandler.js.map
|
||||
packages/lib/services/synchronizer/MigrationHandler.d.ts
|
||||
packages/lib/services/synchronizer/MigrationHandler.js
|
||||
packages/lib/services/synchronizer/MigrationHandler.js.map
|
||||
packages/lib/services/synchronizer/Synchronizer.basics.test.d.ts
|
||||
packages/lib/services/synchronizer/Synchronizer.basics.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.basics.test.js.map
|
||||
packages/lib/services/synchronizer/Synchronizer.conflicts.test.d.ts
|
||||
packages/lib/services/synchronizer/Synchronizer.conflicts.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.conflicts.test.js.map
|
||||
packages/lib/services/synchronizer/Synchronizer.e2ee.test.d.ts
|
||||
packages/lib/services/synchronizer/Synchronizer.e2ee.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.e2ee.test.js.map
|
||||
packages/lib/services/synchronizer/Synchronizer.resources.test.d.ts
|
||||
packages/lib/services/synchronizer/Synchronizer.resources.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.resources.test.js.map
|
||||
packages/lib/services/synchronizer/Synchronizer.revisions.test.d.ts
|
||||
packages/lib/services/synchronizer/Synchronizer.revisions.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.revisions.test.js.map
|
||||
packages/lib/services/synchronizer/Synchronizer.sharing.test.d.ts
|
||||
packages/lib/services/synchronizer/Synchronizer.sharing.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.sharing.test.js.map
|
||||
packages/lib/services/synchronizer/Synchronizer.tags.test.d.ts
|
||||
packages/lib/services/synchronizer/Synchronizer.tags.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.tags.test.js.map
|
||||
packages/lib/services/synchronizer/Synchronizer.tools.test.d.ts
|
||||
packages/lib/services/synchronizer/Synchronizer.tools.test.js
|
||||
packages/lib/services/synchronizer/Synchronizer.tools.test.js.map
|
||||
packages/lib/services/synchronizer/gui/useSyncTargetUpgrade.d.ts
|
||||
packages/lib/services/synchronizer/gui/useSyncTargetUpgrade.js
|
||||
packages/lib/services/synchronizer/gui/useSyncTargetUpgrade.js.map
|
||||
@@ -1404,6 +1395,12 @@ packages/lib/services/synchronizer/migrations/1.js.map
|
||||
packages/lib/services/synchronizer/migrations/2.d.ts
|
||||
packages/lib/services/synchronizer/migrations/2.js
|
||||
packages/lib/services/synchronizer/migrations/2.js.map
|
||||
packages/lib/services/synchronizer/synchronizer_LockHandler.test.d.ts
|
||||
packages/lib/services/synchronizer/synchronizer_LockHandler.test.js
|
||||
packages/lib/services/synchronizer/synchronizer_LockHandler.test.js.map
|
||||
packages/lib/services/synchronizer/synchronizer_MigrationHandler.test.d.ts
|
||||
packages/lib/services/synchronizer/synchronizer_MigrationHandler.test.js
|
||||
packages/lib/services/synchronizer/synchronizer_MigrationHandler.test.js.map
|
||||
packages/lib/services/synchronizer/tools.d.ts
|
||||
packages/lib/services/synchronizer/tools.js
|
||||
packages/lib/services/synchronizer/tools.js.map
|
||||
@@ -1416,6 +1413,12 @@ packages/lib/services/synchronizer/utils/types.js.map
|
||||
packages/lib/shim.d.ts
|
||||
packages/lib/shim.js
|
||||
packages/lib/shim.js.map
|
||||
packages/lib/testing/test-utils-synchronizer.d.ts
|
||||
packages/lib/testing/test-utils-synchronizer.js
|
||||
packages/lib/testing/test-utils-synchronizer.js.map
|
||||
packages/lib/testing/test-utils.d.ts
|
||||
packages/lib/testing/test-utils.js
|
||||
packages/lib/testing/test-utils.js.map
|
||||
packages/lib/theme.d.ts
|
||||
packages/lib/theme.js
|
||||
packages/lib/theme.js.map
|
||||
@@ -1449,12 +1452,18 @@ packages/lib/themes/type.js.map
|
||||
packages/lib/time.d.ts
|
||||
packages/lib/time.js
|
||||
packages/lib/time.js.map
|
||||
packages/lib/utils/credentialFiles.d.ts
|
||||
packages/lib/utils/credentialFiles.js
|
||||
packages/lib/utils/credentialFiles.js.map
|
||||
packages/lib/uuid.d.ts
|
||||
packages/lib/uuid.js
|
||||
packages/lib/uuid.js.map
|
||||
packages/lib/versionInfo.d.ts
|
||||
packages/lib/versionInfo.js
|
||||
packages/lib/versionInfo.js.map
|
||||
packages/plugin-repo-cli/commands/updateRelease.d.ts
|
||||
packages/plugin-repo-cli/commands/updateRelease.js
|
||||
packages/plugin-repo-cli/commands/updateRelease.js.map
|
||||
packages/plugin-repo-cli/index.d.ts
|
||||
packages/plugin-repo-cli/index.js
|
||||
packages/plugin-repo-cli/index.js.map
|
||||
@@ -1593,4 +1602,7 @@ packages/tools/release-server.js.map
|
||||
packages/tools/tool-utils.d.ts
|
||||
packages/tools/tool-utils.js
|
||||
packages/tools/tool-utils.js.map
|
||||
packages/tools/update-readme-sponsors.d.ts
|
||||
packages/tools/update-readme-sponsors.js
|
||||
packages/tools/update-readme-sponsors.js.map
|
||||
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
|
||||
|
||||
4
BUILD.md
4
BUILD.md
@@ -1,4 +1,4 @@
|
||||
[](https://travis-ci.org/laurent22/joplin) [](https://ci.appveyor.com/project/laurent22/joplin)
|
||||
[](https://travis-ci.com/laurent22/joplin) [](https://ci.appveyor.com/project/laurent22/joplin)
|
||||
|
||||
# Building the applications
|
||||
|
||||
@@ -64,7 +64,7 @@ Normally the **bundler** should start automatically with the application. If it
|
||||
npm install
|
||||
npm run watch # To watch for changes
|
||||
|
||||
To test the extension please refer to the relevant pages for each browser: [Firefox](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension#Trying_it_out) / [Chrome](https://developer.chrome.com/extensions/faq#faq-dev-01). Please note that the extension in dev mode will only connect to a dev instance of the desktop app (and vice-versa).
|
||||
To test the extension please refer to the relevant pages for each browser: [Firefox](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension#Trying_it_out) / [Chrome](https://developer.chrome.com/docs/extensions/mv3/getstarted/). Please note that the extension in dev mode will only connect to a dev instance of the desktop app (and vice-versa).
|
||||
|
||||
## Watching files
|
||||
|
||||
|
||||
218
README.md
218
README.md
@@ -68,13 +68,15 @@ The Web Clipper is a browser extension that allows you to save web pages and scr
|
||||
|
||||
* * *
|
||||
|
||||
| | | |
|
||||
| :---: | :---: | :---: |
|
||||
| <img width="50" src="https://avatars0.githubusercontent.com/u/6979755?s=96&v=4"/></br>[Devon Zuegel](https://github.com/devonzuegel) | <img width="50" src="https://avatars2.githubusercontent.com/u/24908652?s=96&v=4"/></br>[小西 孝宗](https://github.com/konishi-t) | <img width="50" src="https://avatars2.githubusercontent.com/u/215668?s=96&v=4"/></br>[Alexander van der Berg](https://github.com/avanderberg)
|
||||
| <img width="50" src="https://avatars0.githubusercontent.com/u/1168659?s=96&v=4"/></br>[Nicholas Head](https://github.com/nicholashead) | <img width="50" src="https://avatars2.githubusercontent.com/u/1439535?s=96&v=4"/></br>[Frank Bloise](https://github.com/fbloise) | <img width="50" src="https://avatars2.githubusercontent.com/u/15859362?s=96&v=4"/></br>[Thomas Broussard](https://github.com/thomasbroussard)
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/1307332?s=96&v=4"/></br>[Brandon Johnson](https://github.com/dbrandonjohnson) | <img width="50" src="https://avatars1.githubusercontent.com/u/3061769?s=96&v=4"/></br>[@cnagy](https://github.com/c-nagy) | <img width="50" src="https://avatars3.githubusercontent.com/u/53228972?s=96&v=4"/></br>[clmntsl](https://github.com/clmntsl)
|
||||
| <img width="50" src="https://avatars1.githubusercontent.com/u/29300939?s=96&v=4"/></br>[mcejp](https://github.com/mcejp) | <img width="50" src="https://avatars.githubusercontent.com/u/1248504?s=96&v=4"/></br>[joesfer](https://github.com/joesfer) | <img width="50" src="https://avatars.githubusercontent.com/u/67130?s=96&v=4"/></br>[chr15m](https://github.com/chr15m)
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/5782817?s=96&v=4"/></br>[piccobit](https://github.com/piccobit) | <img width="50" src="https://avatars3.githubusercontent.com/u/37297218?s=96&v=4"/></br>[Jess Sullivan](https://github.com/jesssullivan)
|
||||
<!-- SPONSORS -->
|
||||
| | | | |
|
||||
| :---: | :---: | :---: | :---: |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/215668?s=96&v=4"/></br>[avanderberg](https://github.com/avanderberg) | <img width="50" src="https://avatars2.githubusercontent.com/u/3061769?s=96&v=4"/></br>[c-nagy](https://github.com/c-nagy) | <img width="50" src="https://avatars2.githubusercontent.com/u/70780798?s=96&v=4"/></br>[cabottech](https://github.com/cabottech) | <img width="50" src="https://avatars2.githubusercontent.com/u/67130?s=96&v=4"/></br>[chr15m](https://github.com/chr15m) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/4862947?s=96&v=4"/></br>[chrootlogin](https://github.com/chrootlogin) | <img width="50" src="https://avatars2.githubusercontent.com/u/1307332?s=96&v=4"/></br>[dbrandonjohnson](https://github.com/dbrandonjohnson) | <img width="50" src="https://avatars2.githubusercontent.com/u/1439535?s=96&v=4"/></br>[fbloise](https://github.com/fbloise) | <img width="50" src="https://avatars2.githubusercontent.com/u/38898566?s=96&v=4"/></br>[h4sh5](https://github.com/h4sh5) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/37297218?s=96&v=4"/></br>[Jesssullivan](https://github.com/Jesssullivan) | <img width="50" src="https://avatars2.githubusercontent.com/u/1248504?s=96&v=4"/></br>[joesfer](https://github.com/joesfer) | <img width="50" src="https://avatars2.githubusercontent.com/u/24908652?s=96&v=4"/></br>[konishi-t](https://github.com/konishi-t) | <img width="50" src="https://avatars2.githubusercontent.com/u/1788010?s=96&v=4"/></br>[maxtruxa](https://github.com/maxtruxa) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/29300939?s=96&v=4"/></br>[mcejp](https://github.com/mcejp) | <img width="50" src="https://avatars2.githubusercontent.com/u/1168659?s=96&v=4"/></br>[nicholashead](https://github.com/nicholashead) | <img width="50" src="https://avatars2.githubusercontent.com/u/5782817?s=96&v=4"/></br>[piccobit](https://github.com/piccobit) | <img width="50" src="https://avatars2.githubusercontent.com/u/47742?s=96&v=4"/></br>[ravenscroftj](https://github.com/ravenscroftj) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/73081837?s=96&v=4"/></br>[thismarty](https://github.com/thismarty) | <img width="50" src="https://avatars2.githubusercontent.com/u/15859362?s=96&v=4"/></br>[thomasbroussard](https://github.com/thomasbroussard) | <img width="50" src="https://avatars2.githubusercontent.com/u/53228972?s=96&v=4"/></br>[wasteisobscene](https://github.com/wasteisobscene) | |
|
||||
<!-- SPONSORS -->
|
||||
|
||||
<!-- TOC -->
|
||||
# Table of contents
|
||||
@@ -511,47 +513,47 @@ Current translations:
|
||||
<!-- LOCALE-TABLE-AUTO-GENERATED -->
|
||||
| Language | Po File | Last translator | Percent done
|
||||
---|---|---|---|---
|
||||
 | Arabic | [ar](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ar.po) | [Whaell O](mailto:Whaell@protonmail.com) | 96%
|
||||
 | Basque | [eu](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eu.po) | juan.abasolo@ehu.eus | 30%
|
||||
 | Bosnian (Bosna i Hercegovina) | [bs_BA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bs_BA.po) | [Derviš T.](mailto:dervis.t@pm.me) | 75%
|
||||
 | Bulgarian (България) | [bg_BG](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bg_BG.po) | | 58%
|
||||
 | Catalan | [ca](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ca.po) | jmontane, 2019 | 83%
|
||||
 | Croatian (Hrvatska) | [hr_HR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hr_HR.po) | [Milo Ivir](mailto:mail@milotype.de) | 96%
|
||||
 | Czech (Česká republika) | [cs_CZ](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/cs_CZ.po) | [Lukas Helebrandt](mailto:lukas@aiya.cz) | 86%
|
||||
 | Dansk (Danmark) | [da_DK](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/da_DK.po) | Mustafa Al-Dailemi (dailemi@hotmail.com)Language-Team: | 96%
|
||||
 | Deutsch (Deutschland) | [de_DE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/de_DE.po) | [Atalanttore](mailto:atalanttore@googlemail.com) | 95%
|
||||
 | Eesti Keel (Eesti) | [et_EE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/et_EE.po) | | 57%
|
||||
 | English (United Kingdom) | [en_GB](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_GB.po) | | 100%
|
||||
 | English (United States of America) | [en_US](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_US.po) | | 100%
|
||||
 | Español (España) | [es_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/es_ES.po) | [Mario Campo](mailto:mario.campo@gmail.com) | 94%
|
||||
 | Esperanto | [eo](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eo.po) | Marton Paulo | 33%
|
||||
 | Finnish (Suomi) | [fi_FI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fi_FI.po) | mrkaato | 94%
|
||||
 | Français (France) | [fr_FR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fr_FR.po) | Laurent Cozic | 99%
|
||||
 | Galician (España) | [gl_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/gl_ES.po) | [Marcos Lans](mailto:marcoslansgarza@gmail.com) | 38%
|
||||
 | Indonesian (Indonesia) | [id_ID](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/id_ID.po) | [eresytter](mailto:42007357+eresytter@users.noreply.github.com) | 93%
|
||||
 | Italiano (Italia) | [it_IT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/it_IT.po) | [Alessandro Bernardello](mailto:mailfilledwithspam@gmail.com) | 94%
|
||||
 | Magyar (Magyarország) | [hu_HU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hu_HU.po) | [Szőke Sándor](mailto:mail@szokesandor.hu) | 88%
|
||||
 | Nederlands (België, Belgique, Belgien) | [nl_BE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_BE.po) | | 92%
|
||||
 | Nederlands (Nederland) | [nl_NL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_NL.po) | [MetBril](mailto:metbril@users.noreply.github.com) | 95%
|
||||
 | Norwegian (Norge, Noreg) | [nb_NO](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nb_NO.po) | [Mats Estensen](mailto:code@mxe.no) | 76%
|
||||
 | Persian | [fa](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fa.po) | [Kourosh Firoozbakht](mailto:kourox@protonmail.com) | 71%
|
||||
 | Polski (Polska) | [pl_PL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pl_PL.po) | [konhi](mailto:hello.konhi@gmail.com) | 94%
|
||||
 | Português (Brasil) | [pt_BR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_BR.po) | [Nicolas Suzuki](mailto:nicolas.suzuki@pm.me) | 94%
|
||||
 | Português (Portugal) | [pt_PT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_PT.po) | [Diogo Caveiro](mailto:dcaveiro@yahoo.com) | 94%
|
||||
 | Română | [ro](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ro.po) | [Cristi Duluta](mailto:cristi.duluta@gmail.com) | 66%
|
||||
 | Slovenian (Slovenija) | [sl_SI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sl_SI.po) | [Martin Korelič](mailto:martin.korelic@protonmail.com) | 96%
|
||||
 | Svenska | [sv](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sv.po) | [Jonatan Nyberg](mailto:jonatan@autistici.org) | 61%
|
||||
 | Thai (ประเทศไทย) | [th_TH](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/th_TH.po) | | 45%
|
||||
 | Tiếng Việt | [vi](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/vi.po) | | 73%
|
||||
 | Türkçe (Türkiye) | [tr_TR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/tr_TR.po) | [Arda Kılıçdağı](mailto:arda@kilicdagi.com) | 94%
|
||||
 | Ukrainian (Україна) | [uk_UA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/uk_UA.po) | [Vyacheslav Andreykiv](mailto:vandreykiv@gmail.com) | 94%
|
||||
 | Ελληνικά (Ελλάδα) | [el_GR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/el_GR.po) | [Harris Arvanitis](mailto:xaris@tuta.io) | 97%
|
||||
 | Русский (Россия) | [ru_RU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ru_RU.po) | [Sergey Segeda](mailto:thesermanarm@gmail.com) | 94%
|
||||
 | српски језик (Србија) | [sr_RS](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sr_RS.po) | | 71%
|
||||
 | 中文 (简体) | [zh_CN](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_CN.po) | [Yang Zhang](mailto:zyangmath@gmail.com) | 94%
|
||||
 | 中文 (繁體) | [zh_TW](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_TW.po) | [Yaoze Ye](mailto:yaozeye@yahoo.co.jp) | 92%
|
||||
 | 日本語 (日本) | [ja_JP](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ja_JP.po) | [genneko](mailto:genneko217@gmail.com) | 97%
|
||||
 | 한국어 | [ko](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ko.po) | [Ji-Hyeon Gim](mailto:potatogim@potatogim.net) | 96%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/arableague.png" width="16px"/> | Arabic | [ar](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ar.po) | [Whaell O](mailto:Whaell@protonmail.com) | 95%
|
||||
<img src="https://joplinapp.org/images/flags/es/basque_country.png" width="16px"/> | Basque | [eu](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eu.po) | juan.abasolo@ehu.eus | 30%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ba.png" width="16px"/> | Bosnian (Bosna i Hercegovina) | [bs_BA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bs_BA.po) | [Derviš T.](mailto:dervis.t@pm.me) | 74%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/bg.png" width="16px"/> | Bulgarian (България) | [bg_BG](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bg_BG.po) | | 58%
|
||||
<img src="https://joplinapp.org/images/flags/es/catalonia.png" width="16px"/> | Catalan | [ca](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ca.po) | jmontane, 2019 | 82%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/hr.png" width="16px"/> | Croatian (Hrvatska) | [hr_HR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hr_HR.po) | [Milo Ivir](mailto:mail@milotype.de) | 95%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/cz.png" width="16px"/> | Czech (Česká republika) | [cs_CZ](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/cs_CZ.po) | [Lukas Helebrandt](mailto:lukas@aiya.cz) | 86%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/dk.png" width="16px"/> | Dansk (Danmark) | [da_DK](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/da_DK.po) | Mustafa Al-Dailemi (dailemi@hotmail.com)Language-Team: | 95%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/de.png" width="16px"/> | Deutsch (Deutschland) | [de_DE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/de_DE.po) | [Atalanttore](mailto:atalanttore@googlemail.com) | 94%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ee.png" width="16px"/> | Eesti Keel (Eesti) | [et_EE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/et_EE.po) | | 56%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/gb.png" width="16px"/> | English (United Kingdom) | [en_GB](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_GB.po) | | 100%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/us.png" width="16px"/> | English (United States of America) | [en_US](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_US.po) | | 100%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/es.png" width="16px"/> | Español (España) | [es_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/es_ES.po) | [Mario Campo](mailto:mario.campo@gmail.com) | 93%
|
||||
<img src="https://joplinapp.org/images/flags/esperanto.png" width="16px"/> | Esperanto | [eo](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eo.po) | Marton Paulo | 32%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/fi.png" width="16px"/> | Finnish (Suomi) | [fi_FI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fi_FI.po) | mrkaato | 93%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/fr.png" width="16px"/> | Français (France) | [fr_FR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fr_FR.po) | Laurent Cozic | 98%
|
||||
<img src="https://joplinapp.org/images/flags/es/galicia.png" width="16px"/> | Galician (España) | [gl_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/gl_ES.po) | [Marcos Lans](mailto:marcoslansgarza@gmail.com) | 38%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/id.png" width="16px"/> | Indonesian (Indonesia) | [id_ID](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/id_ID.po) | [eresytter](mailto:42007357+eresytter@users.noreply.github.com) | 92%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/it.png" width="16px"/> | Italiano (Italia) | [it_IT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/it_IT.po) | [Alberto Pasqualetto](mailto:39854348+albertopasqualetto@users.) | 98%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/hu.png" width="16px"/> | Magyar (Magyarország) | [hu_HU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hu_HU.po) | [Szőke Sándor](mailto:mail@szokesandor.hu) | 87%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/be.png" width="16px"/> | Nederlands (België, Belgique, Belgien) | [nl_BE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_BE.po) | | 91%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/nl.png" width="16px"/> | Nederlands (Nederland) | [nl_NL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_NL.po) | [MetBril](mailto:metbril@users.noreply.github.com) | 94%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/no.png" width="16px"/> | Norwegian (Norge, Noreg) | [nb_NO](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nb_NO.po) | [Mats Estensen](mailto:code@mxe.no) | 76%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ir.png" width="16px"/> | Persian | [fa](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fa.po) | [Kourosh Firoozbakht](mailto:kourox@protonmail.com) | 71%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/pl.png" width="16px"/> | Polski (Polska) | [pl_PL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pl_PL.po) | [konhi](mailto:hello.konhi@gmail.com) | 93%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/br.png" width="16px"/> | Português (Brasil) | [pt_BR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_BR.po) | [Nicolas Suzuki](mailto:nicolas.suzuki@pm.me) | 93%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/pt.png" width="16px"/> | Português (Portugal) | [pt_PT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_PT.po) | [Diogo Caveiro](mailto:dcaveiro@yahoo.com) | 93%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ro.png" width="16px"/> | Română | [ro](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ro.po) | [Cristi Duluta](mailto:cristi.duluta@gmail.com) | 66%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/si.png" width="16px"/> | Slovenian (Slovenija) | [sl_SI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sl_SI.po) | [Martin Korelič](mailto:martin.korelic@protonmail.com) | 95%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/se.png" width="16px"/> | Svenska | [sv](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sv.po) | [Jonatan Nyberg](mailto:jonatan@autistici.org) | 61%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/th.png" width="16px"/> | Thai (ประเทศไทย) | [th_TH](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/th_TH.po) | | 45%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/vi.png" width="16px"/> | Tiếng Việt | [vi](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/vi.po) | | 73%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/tr.png" width="16px"/> | Türkçe (Türkiye) | [tr_TR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/tr_TR.po) | [Arda Kılıçdağı](mailto:arda@kilicdagi.com) | 93%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ua.png" width="16px"/> | Ukrainian (Україна) | [uk_UA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/uk_UA.po) | [Vyacheslav Andreykiv](mailto:vandreykiv@gmail.com) | 93%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/gr.png" width="16px"/> | Ελληνικά (Ελλάδα) | [el_GR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/el_GR.po) | [Harris Arvanitis](mailto:xaris@tuta.io) | 96%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ru.png" width="16px"/> | Русский (Россия) | [ru_RU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ru_RU.po) | [Sergey Segeda](mailto:thesermanarm@gmail.com) | 93%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/rs.png" width="16px"/> | српски језик (Србија) | [sr_RS](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sr_RS.po) | | 71%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/cn.png" width="16px"/> | 中文 (简体) | [zh_CN](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_CN.po) | [南宫小骏](mailto:jackytsu@vip.qq.com) | 98%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/tw.png" width="16px"/> | 中文 (繁體) | [zh_TW](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_TW.po) | [Yaoze Ye](mailto:yaozeye@yahoo.co.jp) | 92%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/jp.png" width="16px"/> | 日本語 (日本) | [ja_JP](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ja_JP.po) | [genneko](mailto:genneko217@gmail.com) | 96%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/kr.png" width="16px"/> | 한국어 | [ko](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ko.po) | [Ji-Hyeon Gim](mailto:potatogim@potatogim.net) | 98%
|
||||
<!-- LOCALE-TABLE-AUTO-GENERATED -->
|
||||
|
||||
# Contributors
|
||||
@@ -561,52 +563,80 @@ Thank you to everyone who've contributed to Joplin's source code!
|
||||
<!-- CONTRIBUTORS-TABLE-AUTO-GENERATED -->
|
||||
| | | | | |
|
||||
| :---: | :---: | :---: | :---: | :---: |
|
||||
| <img width="50" src="https://avatars0.githubusercontent.com/u/1285584?v=4"/></br>[laurent22](https://api.github.com/users/laurent22) | <img width="50" src="https://avatars3.githubusercontent.com/u/223439?v=4"/></br>[tessus](https://api.github.com/users/tessus) | <img width="50" src="https://avatars0.githubusercontent.com/u/1732810?v=4"/></br>[mic704b](https://api.github.com/users/mic704b) | <img width="50" src="https://avatars3.githubusercontent.com/u/2179547?v=4"/></br>[CalebJohn](https://api.github.com/users/CalebJohn) | <img width="50" src="https://avatars1.githubusercontent.com/u/3542031?v=4"/></br>[PackElend](https://api.github.com/users/PackElend) |
|
||||
| <img width="50" src="https://avatars3.githubusercontent.com/u/4553672?v=4"/></br>[tanrax](https://api.github.com/users/tanrax) | <img width="50" src="https://avatars0.githubusercontent.com/u/8701534?v=4"/></br>[rtmkrlv](https://api.github.com/users/rtmkrlv) | <img width="50" src="https://avatars3.githubusercontent.com/u/10997189?v=4"/></br>[fmrtn](https://api.github.com/users/fmrtn) | <img width="50" src="https://avatars1.githubusercontent.com/u/29672555?v=4"/></br>[genneko](https://api.github.com/users/genneko) | <img width="50" src="https://avatars1.githubusercontent.com/u/6979755?v=4"/></br>[devonzuegel](https://api.github.com/users/devonzuegel) |
|
||||
| <img width="50" src="https://avatars3.githubusercontent.com/u/16101778?v=4"/></br>[gabcoh](https://api.github.com/users/gabcoh) | <img width="50" src="https://avatars3.githubusercontent.com/u/10927304?v=4"/></br>[matsest](https://api.github.com/users/matsest) | <img width="50" src="https://avatars0.githubusercontent.com/u/6319051?v=4"/></br>[abonte](https://api.github.com/users/abonte) | <img width="50" src="https://avatars2.githubusercontent.com/u/1685517?v=4"/></br>[Abijeet](https://api.github.com/users/Abijeet) | <img width="50" src="https://avatars0.githubusercontent.com/u/27751740?v=4"/></br>[ishantgupta777](https://api.github.com/users/ishantgupta777) |
|
||||
| <img width="50" src="https://avatars3.githubusercontent.com/u/208212?v=4"/></br>[foxmask](https://api.github.com/users/foxmask) | <img width="50" src="https://avatars2.githubusercontent.com/u/6557454?v=4"/></br>[innocuo](https://api.github.com/users/innocuo) | <img width="50" src="https://avatars1.githubusercontent.com/u/26695184?v=4"/></br>[anjulalk](https://api.github.com/users/anjulalk) | <img width="50" src="https://avatars1.githubusercontent.com/u/44024553?v=4"/></br>[rabeehrz](https://api.github.com/users/rabeehrz) | <img width="50" src="https://avatars0.githubusercontent.com/u/35633575?v=4"/></br>[coderrsid](https://api.github.com/users/coderrsid) |
|
||||
| <img width="50" src="https://avatars1.githubusercontent.com/u/4237724?v=4"/></br>[alexdevero](https://api.github.com/users/alexdevero) | <img width="50" src="https://avatars3.githubusercontent.com/u/35904727?v=4"/></br>[Runo-saduwa](https://api.github.com/users/Runo-saduwa) | <img width="50" src="https://avatars2.githubusercontent.com/u/5365582?v=4"/></br>[marcosvega91](https://api.github.com/users/marcosvega91) | <img width="50" src="https://avatars3.githubusercontent.com/u/37639389?v=4"/></br>[petrz12](https://api.github.com/users/petrz12) | <img width="50" src="https://avatars0.githubusercontent.com/u/3194829?v=4"/></br>[moltenform](https://api.github.com/users/moltenform) |
|
||||
| <img width="50" src="https://avatars0.githubusercontent.com/u/5199995?v=4"/></br>[zuphilip](https://api.github.com/users/zuphilip) | <img width="50" src="https://avatars1.githubusercontent.com/u/1904967?v=4"/></br>[readingsnail](https://api.github.com/users/readingsnail) | <img width="50" src="https://avatars0.githubusercontent.com/u/3985557?v=4"/></br>[XarisA](https://api.github.com/users/XarisA) | <img width="50" src="https://avatars2.githubusercontent.com/u/4245227?v=4"/></br>[zblesk](https://api.github.com/users/zblesk) | <img width="50" src="https://avatars2.githubusercontent.com/u/31567272?v=4"/></br>[0ndrey](https://api.github.com/users/0ndrey) |
|
||||
| <img width="50" src="https://avatars3.githubusercontent.com/u/12906090?v=4"/></br>[amitsin6h](https://api.github.com/users/amitsin6h) | <img width="50" src="https://avatars3.githubusercontent.com/u/23281486?v=4"/></br>[martonpaulo](https://api.github.com/users/martonpaulo) | <img width="50" src="https://avatars3.githubusercontent.com/u/4497566?v=4"/></br>[rccavalcanti](https://api.github.com/users/rccavalcanti) | <img width="50" src="https://avatars0.githubusercontent.com/u/54268438?v=4"/></br>[Rahulm2310](https://api.github.com/users/Rahulm2310) | <img width="50" src="https://avatars0.githubusercontent.com/u/559346?v=4"/></br>[metbril](https://api.github.com/users/metbril) |
|
||||
| <img width="50" src="https://avatars0.githubusercontent.com/u/1540054?v=4"/></br>[ShaneKilkelly](https://api.github.com/users/ShaneKilkelly) | <img width="50" src="https://avatars1.githubusercontent.com/u/6734573?v=4"/></br>[stweil](https://api.github.com/users/stweil) | <img width="50" src="https://avatars3.githubusercontent.com/u/937861?v=4"/></br>[archont00](https://api.github.com/users/archont00) | <img width="50" src="https://avatars3.githubusercontent.com/u/32770029?v=4"/></br>[bradmcl](https://api.github.com/users/bradmcl) | <img width="50" src="https://avatars1.githubusercontent.com/u/22592201?v=4"/></br>[tfinnberg](https://api.github.com/users/tfinnberg) |
|
||||
| <img width="50" src="https://avatars1.githubusercontent.com/u/3870964?v=4"/></br>[marcushill](https://api.github.com/users/marcushill) | <img width="50" src="https://avatars3.githubusercontent.com/u/102242?v=4"/></br>[nathanleiby](https://api.github.com/users/nathanleiby) | <img width="50" src="https://avatars0.githubusercontent.com/u/226708?v=4"/></br>[RaphaelKimmig](https://api.github.com/users/RaphaelKimmig) | <img width="50" src="https://avatars0.githubusercontent.com/u/17768566?v=4"/></br>[RenatoXSR](https://api.github.com/users/RenatoXSR) | <img width="50" src="https://avatars1.githubusercontent.com/u/36303913?v=4"/></br>[sensor-freak](https://api.github.com/users/sensor-freak) |
|
||||
| <img width="50" src="https://avatars3.githubusercontent.com/u/2063957?v=4"/></br>[Ardakilic](https://api.github.com/users/Ardakilic) | <img width="50" src="https://avatars3.githubusercontent.com/u/21161146?v=4"/></br>[BartBucknill](https://api.github.com/users/BartBucknill) | <img width="50" src="https://avatars3.githubusercontent.com/u/2494769?v=4"/></br>[mrwulf](https://api.github.com/users/mrwulf) | <img width="50" src="https://avatars2.githubusercontent.com/u/560571?v=4"/></br>[chrisb86](https://api.github.com/users/chrisb86) | <img width="50" src="https://avatars3.githubusercontent.com/u/1686759?v=4"/></br>[chrmoritz](https://api.github.com/users/chrmoritz) |
|
||||
| <img width="50" src="https://avatars0.githubusercontent.com/u/5001259?v=4"/></br>[ethan42411](https://api.github.com/users/ethan42411) | <img width="50" src="https://avatars2.githubusercontent.com/u/2733783?v=4"/></br>[JOJ0](https://api.github.com/users/JOJ0) | <img width="50" src="https://avatars2.githubusercontent.com/u/3140223?v=4"/></br>[jdrobertso](https://api.github.com/users/jdrobertso) | <img width="50" src="https://avatars2.githubusercontent.com/u/339645?v=4"/></br>[jmontane](https://api.github.com/users/jmontane) | <img width="50" src="https://avatars2.githubusercontent.com/u/4168339?v=4"/></br>[solariz](https://api.github.com/users/solariz) |
|
||||
| <img width="50" src="https://avatars0.githubusercontent.com/u/390889?v=4"/></br>[mmahmoudian](https://api.github.com/users/mmahmoudian) | <img width="50" src="https://avatars1.githubusercontent.com/u/25288?v=4"/></br>[maicki](https://api.github.com/users/maicki) | <img width="50" src="https://avatars3.githubusercontent.com/u/2136373?v=4"/></br>[mjjzf](https://api.github.com/users/mjjzf) | <img width="50" src="https://avatars3.githubusercontent.com/u/30305957?v=4"/></br>[naviji](https://api.github.com/users/naviji) | <img width="50" src="https://avatars3.githubusercontent.com/u/27608187?v=4"/></br>[rt-oliveira](https://api.github.com/users/rt-oliveira) |
|
||||
| <img width="50" src="https://avatars0.githubusercontent.com/u/54576074?v=4"/></br>[Rishgod](https://api.github.com/users/Rishgod) | <img width="50" src="https://avatars0.githubusercontent.com/u/2486806?v=4"/></br>[sebastienjust](https://api.github.com/users/sebastienjust) | <img width="50" src="https://avatars2.githubusercontent.com/u/28362310?v=4"/></br>[sealch](https://api.github.com/users/sealch) | <img width="50" src="https://avatars1.githubusercontent.com/u/34258070?v=4"/></br>[StarFang208](https://api.github.com/users/StarFang208) | <img width="50" src="https://avatars2.githubusercontent.com/u/1782292?v=4"/></br>[SubodhDahal](https://api.github.com/users/SubodhDahal) |
|
||||
| <img width="50" src="https://avatars0.githubusercontent.com/u/5912371?v=4"/></br>[TobiasDev](https://api.github.com/users/TobiasDev) | <img width="50" src="https://avatars2.githubusercontent.com/u/692072?v=4"/></br>[conyx](https://api.github.com/users/conyx) | <img width="50" src="https://avatars2.githubusercontent.com/u/5730052?v=4"/></br>[vsimkus](https://api.github.com/users/vsimkus) | <img width="50" src="https://avatars1.githubusercontent.com/u/4079047?v=4"/></br>[Zorbeyd](https://api.github.com/users/Zorbeyd) | <img width="50" src="https://avatars3.githubusercontent.com/u/5077221?v=4"/></br>[axq](https://api.github.com/users/axq) |
|
||||
| <img width="50" src="https://avatars0.githubusercontent.com/u/8808502?v=4"/></br>[barbowza](https://api.github.com/users/barbowza) | <img width="50" src="https://avatars1.githubusercontent.com/u/4316805?v=4"/></br>[lightray22](https://api.github.com/users/lightray22) | <img width="50" src="https://avatars0.githubusercontent.com/u/17399340?v=4"/></br>[pf-siedler](https://api.github.com/users/pf-siedler) | <img width="50" src="https://avatars1.githubusercontent.com/u/17232523?v=4"/></br>[ruuti](https://api.github.com/users/ruuti) | <img width="50" src="https://avatars2.githubusercontent.com/u/23638148?v=4"/></br>[s1nceri7y](https://api.github.com/users/s1nceri7y) |
|
||||
| <img width="50" src="https://avatars3.githubusercontent.com/u/10117386?v=4"/></br>[kornava](https://api.github.com/users/kornava) | <img width="50" src="https://avatars1.githubusercontent.com/u/7471938?v=4"/></br>[ShuiHuo](https://api.github.com/users/ShuiHuo) | <img width="50" src="https://avatars2.githubusercontent.com/u/11596277?v=4"/></br>[ikunya](https://api.github.com/users/ikunya) | <img width="50" src="https://avatars3.githubusercontent.com/u/59133880?v=4"/></br>[bedwardly-down](https://api.github.com/users/bedwardly-down) | <img width="50" src="https://avatars2.githubusercontent.com/u/47456195?v=4"/></br>[hexclover](https://api.github.com/users/hexclover) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/45535789?v=4"/></br>[2jaeyeol](https://api.github.com/users/2jaeyeol) | <img width="50" src="https://avatars1.githubusercontent.com/u/15862474?v=4"/></br>[aaronxn](https://api.github.com/users/aaronxn) | <img width="50" src="https://avatars1.githubusercontent.com/u/3660978?v=4"/></br>[alanfortlink](https://api.github.com/users/alanfortlink) | <img width="50" src="https://avatars3.githubusercontent.com/u/14836659?v=4"/></br>[apankratov](https://api.github.com/users/apankratov) | <img width="50" src="https://avatars1.githubusercontent.com/u/7045739?v=4"/></br>[teterkin](https://api.github.com/users/teterkin) |
|
||||
| <img width="50" src="https://avatars0.githubusercontent.com/u/41290751?v=4"/></br>[serenitatis](https://api.github.com/users/serenitatis) | <img width="50" src="https://avatars2.githubusercontent.com/u/4408379?v=4"/></br>[lex111](https://api.github.com/users/lex111) | <img width="50" src="https://avatars2.githubusercontent.com/u/5417051?v=4"/></br>[tekdel](https://api.github.com/users/tekdel) | <img width="50" src="https://avatars1.githubusercontent.com/u/498326?v=4"/></br>[Shaxine](https://api.github.com/users/Shaxine) | <img width="50" src="https://avatars0.githubusercontent.com/u/201215?v=4"/></br>[assimd](https://api.github.com/users/assimd) |
|
||||
| <img width="50" src="https://avatars0.githubusercontent.com/u/42698687?v=4"/></br>[baymoe](https://api.github.com/users/baymoe) | <img width="50" src="https://avatars2.githubusercontent.com/u/7034200?v=4"/></br>[bimlas](https://api.github.com/users/bimlas) | <img width="50" src="https://avatars0.githubusercontent.com/u/16287077?v=4"/></br>[carlbordum](https://api.github.com/users/carlbordum) | <img width="50" src="https://avatars0.githubusercontent.com/u/105843?v=4"/></br>[chaifeng](https://api.github.com/users/chaifeng) | <img width="50" src="https://avatars2.githubusercontent.com/u/549349?v=4"/></br>[charles-e](https://api.github.com/users/charles-e) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/2348463?v=4"/></br>[Techwolf12](https://api.github.com/users/Techwolf12) | <img width="50" src="https://avatars0.githubusercontent.com/u/2282880?v=4"/></br>[cloudtrends](https://api.github.com/users/cloudtrends) | <img width="50" src="https://avatars2.githubusercontent.com/u/1044056?v=4"/></br>[daniellandau](https://api.github.com/users/daniellandau) | <img width="50" src="https://avatars2.githubusercontent.com/u/26189247?v=4"/></br>[daukadolt](https://api.github.com/users/daukadolt) | <img width="50" src="https://avatars2.githubusercontent.com/u/28535750?v=4"/></br>[NeverMendel](https://api.github.com/users/NeverMendel) |
|
||||
| <img width="50" src="https://avatars0.githubusercontent.com/u/11378282?v=4"/></br>[diego-betto](https://api.github.com/users/diego-betto) | <img width="50" src="https://avatars0.githubusercontent.com/u/215270?v=4"/></br>[erdody](https://api.github.com/users/erdody) | <img width="50" src="https://avatars0.githubusercontent.com/u/10371667?v=4"/></br>[domgoodwin](https://api.github.com/users/domgoodwin) | <img width="50" src="https://avatars3.githubusercontent.com/u/72066?v=4"/></br>[b4mboo](https://api.github.com/users/b4mboo) | <img width="50" src="https://avatars0.githubusercontent.com/u/5131923?v=4"/></br>[donbowman](https://api.github.com/users/donbowman) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/47756?v=4"/></br>[dflock](https://api.github.com/users/dflock) | <img width="50" src="https://avatars0.githubusercontent.com/u/7990534?v=4"/></br>[drobilica](https://api.github.com/users/drobilica) | <img width="50" src="https://avatars3.githubusercontent.com/u/1962738?v=4"/></br>[einverne](https://api.github.com/users/einverne) | <img width="50" src="https://avatars0.githubusercontent.com/u/628474?v=4"/></br>[Atalanttore](https://api.github.com/users/Atalanttore) | <img width="50" src="https://avatars1.githubusercontent.com/u/16492558?v=4"/></br>[eodeluga](https://api.github.com/users/eodeluga) |
|
||||
| <img width="50" src="https://avatars1.githubusercontent.com/u/3057302?v=4"/></br>[fer22f](https://api.github.com/users/fer22f) | <img width="50" src="https://avatars0.githubusercontent.com/u/43272148?v=4"/></br>[fpindado](https://api.github.com/users/fpindado) | <img width="50" src="https://avatars2.githubusercontent.com/u/1714374?v=4"/></br>[FleischKarussel](https://api.github.com/users/FleischKarussel) | <img width="50" src="https://avatars1.githubusercontent.com/u/18525376?v=4"/></br>[talkdirty](https://api.github.com/users/talkdirty) | <img width="50" src="https://avatars0.githubusercontent.com/u/6190183?v=4"/></br>[gmag11](https://api.github.com/users/gmag11) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/24235344?v=4"/></br>[guiemi](https://api.github.com/users/guiemi) | <img width="50" src="https://avatars2.githubusercontent.com/u/2257024?v=4"/></br>[gusbemacbe](https://api.github.com/users/gusbemacbe) | <img width="50" src="https://avatars0.githubusercontent.com/u/18524580?v=4"/></br>[Fvbor](https://api.github.com/users/Fvbor) | <img width="50" src="https://avatars0.githubusercontent.com/u/22606250?v=4"/></br>[bennetthanna](https://api.github.com/users/bennetthanna) | <img width="50" src="https://avatars3.githubusercontent.com/u/3379379?v=4"/></br>[sczhg](https://api.github.com/users/sczhg) |
|
||||
| <img width="50" src="https://avatars1.githubusercontent.com/u/1716229?v=4"/></br>[Vistaus](https://api.github.com/users/Vistaus) | <img width="50" src="https://avatars1.githubusercontent.com/u/19862172?v=4"/></br>[iahmedbacha](https://api.github.com/users/iahmedbacha) | <img width="50" src="https://avatars0.githubusercontent.com/u/1533624?v=4"/></br>[IrvinDominin](https://api.github.com/users/IrvinDominin) | <img width="50" src="https://avatars3.githubusercontent.com/u/33200024?v=4"/></br>[ishammahajan](https://api.github.com/users/ishammahajan) | <img width="50" src="https://avatars0.githubusercontent.com/u/19985741?v=4"/></br>[JRaiden16](https://api.github.com/users/JRaiden16) |
|
||||
| <img width="50" src="https://avatars3.githubusercontent.com/u/11466782?v=4"/></br>[jacobherrington](https://api.github.com/users/jacobherrington) | <img width="50" src="https://avatars2.githubusercontent.com/u/9365179?v=4"/></br>[jamesadjinwa](https://api.github.com/users/jamesadjinwa) | <img width="50" src="https://avatars1.githubusercontent.com/u/4995433?v=4"/></br>[jaredcrowe](https://api.github.com/users/jaredcrowe) | <img width="50" src="https://avatars3.githubusercontent.com/u/4374338?v=4"/></br>[potatogim](https://api.github.com/users/potatogim) | <img width="50" src="https://avatars0.githubusercontent.com/u/163555?v=4"/></br>[JoelRSimpson](https://api.github.com/users/JoelRSimpson) |
|
||||
| <img width="50" src="https://avatars1.githubusercontent.com/u/6965062?v=4"/></br>[joeltaylor](https://api.github.com/users/joeltaylor) | <img width="50" src="https://avatars3.githubusercontent.com/u/242107?v=4"/></br>[exic](https://api.github.com/users/exic) | <img width="50" src="https://avatars1.githubusercontent.com/u/23194385?v=4"/></br>[jony0008](https://api.github.com/users/jony0008) | <img width="50" src="https://avatars1.githubusercontent.com/u/6048003?v=4"/></br>[joybinchen](https://api.github.com/users/joybinchen) | <img width="50" src="https://avatars1.githubusercontent.com/u/1560189?v=4"/></br>[y-usuzumi](https://api.github.com/users/y-usuzumi) |
|
||||
| <img width="50" src="https://avatars0.githubusercontent.com/u/1660460?v=4"/></br>[xuhcc](https://api.github.com/users/xuhcc) | <img width="50" src="https://avatars0.githubusercontent.com/u/16933735?v=4"/></br>[kirtanprht](https://api.github.com/users/kirtanprht) | <img width="50" src="https://avatars3.githubusercontent.com/u/7824233?v=4"/></br>[kklas](https://api.github.com/users/kklas) | <img width="50" src="https://avatars1.githubusercontent.com/u/8622992?v=4"/></br>[xmlangel](https://api.github.com/users/xmlangel) | <img width="50" src="https://avatars0.githubusercontent.com/u/1055100?v=4"/></br>[troilus](https://api.github.com/users/troilus) |
|
||||
| <img width="50" src="https://avatars3.githubusercontent.com/u/50335724?v=4"/></br>[Lorinson](https://api.github.com/users/Lorinson) | <img width="50" src="https://avatars2.githubusercontent.com/u/2599210?v=4"/></br>[lboullo0](https://api.github.com/users/lboullo0) | <img width="50" src="https://avatars1.githubusercontent.com/u/1562062?v=4"/></br>[dbinary](https://api.github.com/users/dbinary) | <img width="50" src="https://avatars3.githubusercontent.com/u/5699725?v=4"/></br>[mvonmaltitz](https://api.github.com/users/mvonmaltitz) | <img width="50" src="https://avatars3.githubusercontent.com/u/11036464?v=4"/></br>[mlkood](https://api.github.com/users/mlkood) |
|
||||
| <img width="50" src="https://avatars3.githubusercontent.com/u/5788516?v=4"/></br>[Marmo](https://api.github.com/users/Marmo) | <img width="50" src="https://avatars0.githubusercontent.com/u/640949?v=4"/></br>[freaktechnik](https://api.github.com/users/freaktechnik) | <img width="50" src="https://avatars2.githubusercontent.com/u/12831489?v=4"/></br>[mgroth0](https://api.github.com/users/mgroth0) | <img width="50" src="https://avatars0.githubusercontent.com/u/21796?v=4"/></br>[silentmatt](https://api.github.com/users/silentmatt) | <img width="50" src="https://avatars0.githubusercontent.com/u/51273874?v=4"/></br>[MichipX](https://api.github.com/users/MichipX) |
|
||||
| <img width="50" src="https://avatars1.githubusercontent.com/u/53177864?v=4"/></br>[MrTraduttore](https://api.github.com/users/MrTraduttore) | <img width="50" src="https://avatars3.githubusercontent.com/u/9076687?v=4"/></br>[NJannasch](https://api.github.com/users/NJannasch) | <img width="50" src="https://avatars2.githubusercontent.com/u/12369770?v=4"/></br>[Ouvill](https://api.github.com/users/Ouvill) | <img width="50" src="https://avatars3.githubusercontent.com/u/43815417?v=4"/></br>[shorty2380](https://api.github.com/users/shorty2380) | <img width="50" src="https://avatars0.githubusercontent.com/u/19418601?v=4"/></br>[Rakleed](https://api.github.com/users/Rakleed) |
|
||||
| <img width="50" src="https://avatars3.githubusercontent.com/u/6306608?v=4"/></br>[Diadlo](https://api.github.com/users/Diadlo) | <img width="50" src="https://avatars1.githubusercontent.com/u/13197246?v=4"/></br>[R-L-T-Y](https://api.github.com/users/R-L-T-Y) | <img width="50" src="https://avatars2.githubusercontent.com/u/42652941?v=4"/></br>[rajprakash00](https://api.github.com/users/rajprakash00) | <img width="50" src="https://avatars0.githubusercontent.com/u/54888685?v=4"/></br>[RedDocMD](https://api.github.com/users/RedDocMD) | <img width="50" src="https://avatars2.githubusercontent.com/u/17312341?v=4"/></br>[reinhart1010](https://api.github.com/users/reinhart1010) |
|
||||
| <img width="50" src="https://avatars1.githubusercontent.com/u/744655?v=4"/></br>[ruzaq](https://api.github.com/users/ruzaq) | <img width="50" src="https://avatars0.githubusercontent.com/u/19328605?v=4"/></br>[SamuelBlickle](https://api.github.com/users/SamuelBlickle) | <img width="50" src="https://avatars1.githubusercontent.com/u/1776?v=4"/></br>[bronson](https://api.github.com/users/bronson) | <img width="50" src="https://avatars0.githubusercontent.com/u/24606935?v=4"/></br>[semperor](https://api.github.com/users/semperor) | <img width="50" src="https://avatars0.githubusercontent.com/u/7091080?v=4"/></br>[sinkuu](https://api.github.com/users/sinkuu) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/9937486?v=4"/></br>[SFoskitt](https://api.github.com/users/SFoskitt) | <img width="50" src="https://avatars2.githubusercontent.com/u/505011?v=4"/></br>[kcrt](https://api.github.com/users/kcrt) | <img width="50" src="https://avatars1.githubusercontent.com/u/538584?v=4"/></br>[xissy](https://api.github.com/users/xissy) | <img width="50" src="https://avatars3.githubusercontent.com/u/466122?v=4"/></br>[Tekki](https://api.github.com/users/Tekki) | <img width="50" src="https://avatars0.githubusercontent.com/u/21969426?v=4"/></br>[TheoDutch](https://api.github.com/users/TheoDutch) |
|
||||
| <img width="50" src="https://avatars0.githubusercontent.com/u/8731922?v=4"/></br>[tbroadley](https://api.github.com/users/tbroadley) | <img width="50" src="https://avatars1.githubusercontent.com/u/114300?v=4"/></br>[Kriechi](https://api.github.com/users/Kriechi) | <img width="50" src="https://avatars0.githubusercontent.com/u/3457339?v=4"/></br>[tkilaker](https://api.github.com/users/tkilaker) | <img width="50" src="https://avatars1.githubusercontent.com/u/4201229?v=4"/></br>[tcyrus](https://api.github.com/users/tcyrus) | <img width="50" src="https://avatars2.githubusercontent.com/u/834914?v=4"/></br>[tobias-grasse](https://api.github.com/users/tobias-grasse) |
|
||||
| <img width="50" src="https://avatars3.githubusercontent.com/u/6691273?v=4"/></br>[strobeltobias](https://api.github.com/users/strobeltobias) | <img width="50" src="https://avatars2.githubusercontent.com/u/70296?v=4"/></br>[tbergeron](https://api.github.com/users/tbergeron) | <img width="50" src="https://avatars1.githubusercontent.com/u/10265443?v=4"/></br>[Ullas-Aithal](https://api.github.com/users/Ullas-Aithal) | <img width="50" src="https://avatars2.githubusercontent.com/u/6104498?v=4"/></br>[MyTheValentinus](https://api.github.com/users/MyTheValentinus) | <img width="50" src="https://avatars3.githubusercontent.com/u/26511487?v=4"/></br>[WisdomCode](https://api.github.com/users/WisdomCode) |
|
||||
| <img width="50" src="https://avatars1.githubusercontent.com/u/1921957?v=4"/></br>[xsak](https://api.github.com/users/xsak) | <img width="50" src="https://avatars2.githubusercontent.com/u/11031696?v=4"/></br>[ymitsos](https://api.github.com/users/ymitsos) | <img width="50" src="https://avatars3.githubusercontent.com/u/29891001?v=4"/></br>[jyuvaraj03](https://api.github.com/users/jyuvaraj03) | <img width="50" src="https://avatars0.githubusercontent.com/u/15380913?v=4"/></br>[kowalskidev](https://api.github.com/users/kowalskidev) | <img width="50" src="https://avatars0.githubusercontent.com/u/63324960?v=4"/></br>[abolishallprivateproperty](https://api.github.com/users/abolishallprivateproperty) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/11336076?v=4"/></br>[aerotog](https://api.github.com/users/aerotog) | <img width="50" src="https://avatars2.githubusercontent.com/u/49116134?v=4"/></br>[anihm136](https://api.github.com/users/anihm136) | <img width="50" src="https://avatars2.githubusercontent.com/u/35600612?v=4"/></br>[boring10](https://api.github.com/users/boring10) | <img width="50" src="https://avatars0.githubusercontent.com/u/35413451?v=4"/></br>[chenlhlinux](https://api.github.com/users/chenlhlinux) | <img width="50" src="https://avatars3.githubusercontent.com/u/30935096?v=4"/></br>[cybertramp](https://api.github.com/users/cybertramp) |
|
||||
| <img width="50" src="https://avatars3.githubusercontent.com/u/9694906?v=4"/></br>[delta-emil](https://api.github.com/users/delta-emil) | <img width="50" src="https://avatars0.githubusercontent.com/u/926263?v=4"/></br>[doc75](https://api.github.com/users/doc75) | <img width="50" src="https://avatars2.githubusercontent.com/u/2903013?v=4"/></br>[ebayer](https://api.github.com/users/ebayer) | <img width="50" src="https://avatars3.githubusercontent.com/u/701050?v=4"/></br>[espinosa](https://api.github.com/users/espinosa) | <img width="50" src="https://avatars1.githubusercontent.com/u/18619090?v=4"/></br>[exponentactivity](https://api.github.com/users/exponentactivity) |
|
||||
| <img width="50" src="https://avatars1.githubusercontent.com/u/16708935?v=4"/></br>[exprez135](https://api.github.com/users/exprez135) | <img width="50" src="https://avatars1.githubusercontent.com/u/9768112?v=4"/></br>[fab4x](https://api.github.com/users/fab4x) | <img width="50" src="https://avatars0.githubusercontent.com/u/47755037?v=4"/></br>[fabianski7](https://api.github.com/users/fabianski7) | <img width="50" src="https://avatars0.githubusercontent.com/u/14201321?v=4"/></br>[rasperepodvipodvert](https://api.github.com/users/rasperepodvipodvert) | <img width="50" src="https://avatars1.githubusercontent.com/u/748808?v=4"/></br>[gasolin](https://api.github.com/users/gasolin) |
|
||||
| <img width="50" src="https://avatars0.githubusercontent.com/u/47191051?v=4"/></br>[githubaccount073](https://api.github.com/users/githubaccount073) | <img width="50" src="https://avatars1.githubusercontent.com/u/11388094?v=4"/></br>[hydrandt](https://api.github.com/users/hydrandt) | <img width="50" src="https://avatars0.githubusercontent.com/u/557540?v=4"/></br>[jabdoa2](https://api.github.com/users/jabdoa2) | <img width="50" src="https://avatars3.githubusercontent.com/u/53862536?v=4"/></br>[johanvanheusden](https://api.github.com/users/johanvanheusden) | <img width="50" src="https://avatars1.githubusercontent.com/u/54991735?v=4"/></br>[krzysiekwie](https://api.github.com/users/krzysiekwie) |
|
||||
| <img width="50" src="https://avatars0.githubusercontent.com/u/12849008?v=4"/></br>[lighthousebulb](https://api.github.com/users/lighthousebulb) | <img width="50" src="https://avatars0.githubusercontent.com/u/4140247?v=4"/></br>[luzpaz](https://api.github.com/users/luzpaz) | <img width="50" src="https://avatars2.githubusercontent.com/u/30428258?v=4"/></br>[nmiquan](https://api.github.com/users/nmiquan) | <img width="50" src="https://avatars0.githubusercontent.com/u/31123054?v=4"/></br>[nullpointer666](https://api.github.com/users/nullpointer666) | <img width="50" src="https://avatars2.githubusercontent.com/u/2979926?v=4"/></br>[oscaretu](https://api.github.com/users/oscaretu) |
|
||||
| <img width="50" src="https://avatars0.githubusercontent.com/u/36965591?v=4"/></br>[daehruoydeef](https://api.github.com/users/daehruoydeef) | <img width="50" src="https://avatars1.githubusercontent.com/u/42961947?v=4"/></br>[pensierocrea](https://api.github.com/users/pensierocrea) | <img width="50" src="https://avatars3.githubusercontent.com/u/10206967?v=4"/></br>[rhtenhove](https://api.github.com/users/rhtenhove) | <img width="50" src="https://avatars2.githubusercontent.com/u/16728217?v=4"/></br>[rikanotank1](https://api.github.com/users/rikanotank1) | <img width="50" src="https://avatars1.githubusercontent.com/u/51550769?v=4"/></br>[rnbastos](https://api.github.com/users/rnbastos) |
|
||||
| <img width="50" src="https://avatars3.githubusercontent.com/u/14062932?v=4"/></br>[simonsan](https://api.github.com/users/simonsan) | <img width="50" src="https://avatars2.githubusercontent.com/u/5004545?v=4"/></br>[stellarpower](https://api.github.com/users/stellarpower) | <img width="50" src="https://avatars1.githubusercontent.com/u/12995773?v=4"/></br>[sumomo-99](https://api.github.com/users/sumomo-99) | <img width="50" src="https://avatars0.githubusercontent.com/u/6908872?v=4"/></br>[taw00](https://api.github.com/users/taw00) | <img width="50" src="https://avatars0.githubusercontent.com/u/10956653?v=4"/></br>[tcassaert](https://api.github.com/users/tcassaert) |
|
||||
| <img width="50" src="https://avatars1.githubusercontent.com/u/46327531?v=4"/></br>[vicoutorama](https://api.github.com/users/vicoutorama) | <img width="50" src="https://avatars0.githubusercontent.com/u/2216902?v=4"/></br>[xcffl](https://api.github.com/users/xcffl) | <img width="50" src="https://avatars2.githubusercontent.com/u/37692927?v=4"/></br>[zaoyifan](https://api.github.com/users/zaoyifan) | <img width="50" src="https://avatars3.githubusercontent.com/u/55245068?v=4"/></br>[zen-quo](https://api.github.com/users/zen-quo) | <img width="50" src="https://avatars0.githubusercontent.com/u/25315?v=4"/></br>[xcession](https://api.github.com/users/xcession) |
|
||||
| <img width="50" src="https://avatars0.githubusercontent.com/u/34542665?v=4"/></br>[paventyang](https://api.github.com/users/paventyang) | <img width="50" src="https://avatars1.githubusercontent.com/u/1308646?v=4"/></br>[zhangmx](https://api.github.com/users/zhangmx) | | | |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/1285584?v=4"/></br>[laurent22](https://github.com/laurent22) | <img width="50" src="https://avatars.githubusercontent.com/u/223439?v=4"/></br>[tessus](https://github.com/tessus) | <img width="50" src="https://avatars.githubusercontent.com/u/2179547?v=4"/></br>[CalebJohn](https://github.com/CalebJohn) | <img width="50" src="https://avatars.githubusercontent.com/u/1732810?v=4"/></br>[mic704b](https://github.com/mic704b) | <img width="50" src="https://avatars.githubusercontent.com/u/995612?v=4"/></br>[roman-r-m](https://github.com/roman-r-m) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/29672555?v=4"/></br>[genneko](https://github.com/genneko) | <img width="50" src="https://avatars.githubusercontent.com/u/63491353?v=4"/></br>[j-krl](https://github.com/j-krl) | <img width="50" src="https://avatars.githubusercontent.com/u/4553672?v=4"/></br>[tanrax](https://github.com/tanrax) | <img width="50" src="https://avatars.githubusercontent.com/u/30305957?v=4"/></br>[naviji](https://github.com/naviji) | <img width="50" src="https://avatars.githubusercontent.com/u/3542031?v=4"/></br>[PackElend](https://github.com/PackElend) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/8701534?v=4"/></br>[rtmkrlv](https://github.com/rtmkrlv) | <img width="50" src="https://avatars.githubusercontent.com/u/10997189?v=4"/></br>[fmrtn](https://github.com/fmrtn) | <img width="50" src="https://avatars.githubusercontent.com/u/4374338?v=4"/></br>[potatogim](https://github.com/potatogim) | <img width="50" src="https://avatars.githubusercontent.com/u/6979755?v=4"/></br>[devonzuegel](https://github.com/devonzuegel) | <img width="50" src="https://avatars.githubusercontent.com/u/26695184?v=4"/></br>[anjulalk](https://github.com/anjulalk) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/16101778?v=4"/></br>[gabcoh](https://github.com/gabcoh) | <img width="50" src="https://avatars.githubusercontent.com/u/10927304?v=4"/></br>[matsest](https://github.com/matsest) | <img width="50" src="https://avatars.githubusercontent.com/u/6319051?v=4"/></br>[abonte](https://github.com/abonte) | <img width="50" src="https://avatars.githubusercontent.com/u/1685517?v=4"/></br>[Abijeet](https://github.com/Abijeet) | <img width="50" src="https://avatars.githubusercontent.com/u/27751740?v=4"/></br>[ishantgupta777](https://github.com/ishantgupta777) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/24863925?v=4"/></br>[JackGruber](https://github.com/JackGruber) | <img width="50" src="https://avatars.githubusercontent.com/u/2063957?v=4"/></br>[Ardakilic](https://github.com/Ardakilic) | <img width="50" src="https://avatars.githubusercontent.com/u/44024553?v=4"/></br>[rabeehrz](https://github.com/rabeehrz) | <img width="50" src="https://avatars.githubusercontent.com/u/35633575?v=4"/></br>[coderrsid](https://github.com/coderrsid) | <img width="50" src="https://avatars.githubusercontent.com/u/208212?v=4"/></br>[foxmask](https://github.com/foxmask) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/6557454?v=4"/></br>[innocuo](https://github.com/innocuo) | <img width="50" src="https://avatars.githubusercontent.com/u/54268438?v=4"/></br>[Rahulm2310](https://github.com/Rahulm2310) | <img width="50" src="https://avatars.githubusercontent.com/u/1904967?v=4"/></br>[readingsnail](https://github.com/readingsnail) | <img width="50" src="https://avatars.githubusercontent.com/u/7415668?v=4"/></br>[mablin7](https://github.com/mablin7) | <img width="50" src="https://avatars.githubusercontent.com/u/3985557?v=4"/></br>[XarisA](https://github.com/XarisA) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/49979415?v=4"/></br>[jonath92](https://github.com/jonath92) | <img width="50" src="https://avatars.githubusercontent.com/u/4237724?v=4"/></br>[alexdevero](https://github.com/alexdevero) | <img width="50" src="https://avatars.githubusercontent.com/u/35904727?v=4"/></br>[Runo-saduwa](https://github.com/Runo-saduwa) | <img width="50" src="https://avatars.githubusercontent.com/u/5365582?v=4"/></br>[marcosvega91](https://github.com/marcosvega91) | <img width="50" src="https://avatars.githubusercontent.com/u/37639389?v=4"/></br>[petrz12](https://github.com/petrz12) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/51550769?v=4"/></br>[rnbastos](https://github.com/rnbastos) | <img width="50" src="https://avatars.githubusercontent.com/u/32396?v=4"/></br>[ProgramFan](https://github.com/ProgramFan) | <img width="50" src="https://avatars.githubusercontent.com/u/4245227?v=4"/></br>[zblesk](https://github.com/zblesk) | <img width="50" src="https://avatars.githubusercontent.com/u/5730052?v=4"/></br>[vsimkus](https://github.com/vsimkus) | <img width="50" src="https://avatars.githubusercontent.com/u/3194829?v=4"/></br>[moltenform](https://github.com/moltenform) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/36989112?v=4"/></br>[nishantwrp](https://github.com/nishantwrp) | <img width="50" src="https://avatars.githubusercontent.com/u/5199995?v=4"/></br>[zuphilip](https://github.com/zuphilip) | <img width="50" src="https://avatars.githubusercontent.com/u/54576074?v=4"/></br>[Rishabh-malhotraa](https://github.com/Rishabh-malhotraa) | <img width="50" src="https://avatars.githubusercontent.com/u/559346?v=4"/></br>[metbril](https://github.com/metbril) | <img width="50" src="https://avatars.githubusercontent.com/u/47623588?v=4"/></br>[WhiredPlanck](https://github.com/WhiredPlanck) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/43657314?v=4"/></br>[milotype](https://github.com/milotype) | <img width="50" src="https://avatars.githubusercontent.com/u/32196447?v=4"/></br>[yaozeye](https://github.com/yaozeye) | <img width="50" src="https://avatars.githubusercontent.com/u/12264626?v=4"/></br>[ylc395](https://github.com/ylc395) | <img width="50" src="https://avatars.githubusercontent.com/u/17768566?v=4"/></br>[RenatoXSR](https://github.com/RenatoXSR) | <img width="50" src="https://avatars.githubusercontent.com/u/54888685?v=4"/></br>[RedDocMD](https://github.com/RedDocMD) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/31567272?v=4"/></br>[q1011](https://github.com/q1011) | <img width="50" src="https://avatars.githubusercontent.com/u/12906090?v=4"/></br>[amitsin6h](https://github.com/amitsin6h) | <img width="50" src="https://avatars.githubusercontent.com/u/628474?v=4"/></br>[Atalanttore](https://github.com/Atalanttore) | <img width="50" src="https://avatars.githubusercontent.com/u/42747216?v=4"/></br>[Mannivu](https://github.com/Mannivu) | <img width="50" src="https://avatars.githubusercontent.com/u/23281486?v=4"/></br>[martonpaulo](https://github.com/martonpaulo) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/390889?v=4"/></br>[mmahmoudian](https://github.com/mmahmoudian) | <img width="50" src="https://avatars.githubusercontent.com/u/4497566?v=4"/></br>[rccavalcanti](https://github.com/rccavalcanti) | <img width="50" src="https://avatars.githubusercontent.com/u/1540054?v=4"/></br>[ShaneKilkelly](https://github.com/ShaneKilkelly) | <img width="50" src="https://avatars.githubusercontent.com/u/7091080?v=4"/></br>[sinkuu](https://github.com/sinkuu) | <img width="50" src="https://avatars.githubusercontent.com/u/6734573?v=4"/></br>[stweil](https://github.com/stweil) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/692072?v=4"/></br>[conyx](https://github.com/conyx) | <img width="50" src="https://avatars.githubusercontent.com/u/49116134?v=4"/></br>[anihm136](https://github.com/anihm136) | <img width="50" src="https://avatars.githubusercontent.com/u/937861?v=4"/></br>[archont00](https://github.com/archont00) | <img width="50" src="https://avatars.githubusercontent.com/u/32770029?v=4"/></br>[bradmcl](https://github.com/bradmcl) | <img width="50" src="https://avatars.githubusercontent.com/u/22592201?v=4"/></br>[tfinnberg](https://github.com/tfinnberg) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/8716226?v=4"/></br>[amandamcg](https://github.com/amandamcg) | <img width="50" src="https://avatars.githubusercontent.com/u/3870964?v=4"/></br>[marcushill](https://github.com/marcushill) | <img width="50" src="https://avatars.githubusercontent.com/u/102242?v=4"/></br>[nathanleiby](https://github.com/nathanleiby) | <img width="50" src="https://avatars.githubusercontent.com/u/226708?v=4"/></br>[RaphaelKimmig](https://github.com/RaphaelKimmig) | <img width="50" src="https://avatars.githubusercontent.com/u/20461071?v=4"/></br>[Vaso3](https://github.com/Vaso3) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/36303913?v=4"/></br>[sensor-freak](https://github.com/sensor-freak) | <img width="50" src="https://avatars.githubusercontent.com/u/63918341?v=4"/></br>[lkiThakur](https://github.com/lkiThakur) | <img width="50" src="https://avatars.githubusercontent.com/u/28987176?v=4"/></br>[infinity052](https://github.com/infinity052) | <img width="50" src="https://avatars.githubusercontent.com/u/21161146?v=4"/></br>[BartBucknill](https://github.com/BartBucknill) | <img width="50" src="https://avatars.githubusercontent.com/u/2494769?v=4"/></br>[mrwulf](https://github.com/mrwulf) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/560571?v=4"/></br>[chrisb86](https://github.com/chrisb86) | <img width="50" src="https://avatars.githubusercontent.com/u/1686759?v=4"/></br>[chrmoritz](https://github.com/chrmoritz) | <img width="50" src="https://avatars.githubusercontent.com/u/58074586?v=4"/></br>[Daeraxa](https://github.com/Daeraxa) | <img width="50" src="https://avatars.githubusercontent.com/u/71190696?v=4"/></br>[Elaborendum](https://github.com/Elaborendum) | <img width="50" src="https://avatars.githubusercontent.com/u/5001259?v=4"/></br>[ethan42411](https://github.com/ethan42411) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/2733783?v=4"/></br>[JOJ0](https://github.com/JOJ0) | <img width="50" src="https://avatars.githubusercontent.com/u/17108695?v=4"/></br>[jalajcodes](https://github.com/jalajcodes) | <img width="50" src="https://avatars.githubusercontent.com/u/238088?v=4"/></br>[jblunck](https://github.com/jblunck) | <img width="50" src="https://avatars.githubusercontent.com/u/3140223?v=4"/></br>[jdrobertso](https://github.com/jdrobertso) | <img width="50" src="https://avatars.githubusercontent.com/u/37297218?v=4"/></br>[Jesssullivan](https://github.com/Jesssullivan) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/339645?v=4"/></br>[jmontane](https://github.com/jmontane) | <img width="50" src="https://avatars.githubusercontent.com/u/69011?v=4"/></br>[johanhammar](https://github.com/johanhammar) | <img width="50" src="https://avatars.githubusercontent.com/u/4168339?v=4"/></br>[solariz](https://github.com/solariz) | <img width="50" src="https://avatars.githubusercontent.com/u/25288?v=4"/></br>[maicki](https://github.com/maicki) | <img width="50" src="https://avatars.githubusercontent.com/u/2136373?v=4"/></br>[mjjzf](https://github.com/mjjzf) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/27608187?v=4"/></br>[rt-oliveira](https://github.com/rt-oliveira) | <img width="50" src="https://avatars.githubusercontent.com/u/2486806?v=4"/></br>[sebastienjust](https://github.com/sebastienjust) | <img width="50" src="https://avatars.githubusercontent.com/u/28362310?v=4"/></br>[sealch](https://github.com/sealch) | <img width="50" src="https://avatars.githubusercontent.com/u/34258070?v=4"/></br>[StarFang208](https://github.com/StarFang208) | <img width="50" src="https://avatars.githubusercontent.com/u/59690052?v=4"/></br>[Subhra264](https://github.com/Subhra264) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/1782292?v=4"/></br>[SubodhDahal](https://github.com/SubodhDahal) | <img width="50" src="https://avatars.githubusercontent.com/u/5912371?v=4"/></br>[TobiasDev](https://github.com/TobiasDev) | <img width="50" src="https://avatars.githubusercontent.com/u/13502069?v=4"/></br>[Whaell](https://github.com/Whaell) | <img width="50" src="https://avatars.githubusercontent.com/u/29891001?v=4"/></br>[jyuvaraj03](https://github.com/jyuvaraj03) | <img width="50" src="https://avatars.githubusercontent.com/u/15380913?v=4"/></br>[kowalskidev](https://github.com/kowalskidev) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/337455?v=4"/></br>[alexchee](https://github.com/alexchee) | <img width="50" src="https://avatars.githubusercontent.com/u/5077221?v=4"/></br>[axq](https://github.com/axq) | <img width="50" src="https://avatars.githubusercontent.com/u/8808502?v=4"/></br>[barbowza](https://github.com/barbowza) | <img width="50" src="https://avatars.githubusercontent.com/u/42007357?v=4"/></br>[eresytter](https://github.com/eresytter) | <img width="50" src="https://avatars.githubusercontent.com/u/4316805?v=4"/></br>[lightray22](https://github.com/lightray22) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/11711053?v=4"/></br>[lscolombo](https://github.com/lscolombo) | <img width="50" src="https://avatars.githubusercontent.com/u/36228623?v=4"/></br>[mrkaato](https://github.com/mrkaato) | <img width="50" src="https://avatars.githubusercontent.com/u/17399340?v=4"/></br>[pf-siedler](https://github.com/pf-siedler) | <img width="50" src="https://avatars.githubusercontent.com/u/17232523?v=4"/></br>[ruuti](https://github.com/ruuti) | <img width="50" src="https://avatars.githubusercontent.com/u/23638148?v=4"/></br>[s1nceri7y](https://github.com/s1nceri7y) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/10117386?v=4"/></br>[kornava](https://github.com/kornava) | <img width="50" src="https://avatars.githubusercontent.com/u/7471938?v=4"/></br>[ShuiHuo](https://github.com/ShuiHuo) | <img width="50" src="https://avatars.githubusercontent.com/u/11596277?v=4"/></br>[ikunya](https://github.com/ikunya) | <img width="50" src="https://avatars.githubusercontent.com/u/8184424?v=4"/></br>[Ahmad45123](https://github.com/Ahmad45123) | <img width="50" src="https://avatars.githubusercontent.com/u/59133880?v=4"/></br>[bedwardly-down](https://github.com/bedwardly-down) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/50335724?v=4"/></br>[dcaveiro](https://github.com/dcaveiro) | <img width="50" src="https://avatars.githubusercontent.com/u/47456195?v=4"/></br>[hexclover](https://github.com/hexclover) | <img width="50" src="https://avatars.githubusercontent.com/u/45535789?v=4"/></br>[2jaeyeol](https://github.com/2jaeyeol) | <img width="50" src="https://avatars.githubusercontent.com/u/25622825?v=4"/></br>[thackeraaron](https://github.com/thackeraaron) | <img width="50" src="https://avatars.githubusercontent.com/u/15862474?v=4"/></br>[aaronxn](https://github.com/aaronxn) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/40672207?v=4"/></br>[xUser5000](https://github.com/xUser5000) | <img width="50" src="https://avatars.githubusercontent.com/u/56785486?v=4"/></br>[iamabhi222](https://github.com/iamabhi222) | <img width="50" src="https://avatars.githubusercontent.com/u/63443657?v=4"/></br>[Aksh-Konda](https://github.com/Aksh-Konda) | <img width="50" src="https://avatars.githubusercontent.com/u/3660978?v=4"/></br>[alanfortlink](https://github.com/alanfortlink) | <img width="50" src="https://avatars.githubusercontent.com/u/53372753?v=4"/></br>[AverageUser2](https://github.com/AverageUser2) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/4056990?v=4"/></br>[afischer211](https://github.com/afischer211) | <img width="50" src="https://avatars.githubusercontent.com/u/26230870?v=4"/></br>[a13xk](https://github.com/a13xk) | <img width="50" src="https://avatars.githubusercontent.com/u/14836659?v=4"/></br>[apankratov](https://github.com/apankratov) | <img width="50" src="https://avatars.githubusercontent.com/u/7045739?v=4"/></br>[teterkin](https://github.com/teterkin) | <img width="50" src="https://avatars.githubusercontent.com/u/215668?v=4"/></br>[avanderberg](https://github.com/avanderberg) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/41290751?v=4"/></br>[serenitatis](https://github.com/serenitatis) | <img width="50" src="https://avatars.githubusercontent.com/u/4408379?v=4"/></br>[lex111](https://github.com/lex111) | <img width="50" src="https://avatars.githubusercontent.com/u/60134194?v=4"/></br>[Alkindi42](https://github.com/Alkindi42) | <img width="50" src="https://avatars.githubusercontent.com/u/7129815?v=4"/></br>[Jumanjii](https://github.com/Jumanjii) | <img width="50" src="https://avatars.githubusercontent.com/u/19962243?v=4"/></br>[AlphaJack](https://github.com/AlphaJack) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/65647302?v=4"/></br>[Lord-Aman](https://github.com/Lord-Aman) | <img width="50" src="https://avatars.githubusercontent.com/u/14096959?v=4"/></br>[richtwin567](https://github.com/richtwin567) | <img width="50" src="https://avatars.githubusercontent.com/u/487182?v=4"/></br>[ajilderda](https://github.com/ajilderda) | <img width="50" src="https://avatars.githubusercontent.com/u/922429?v=4"/></br>[adrynov](https://github.com/adrynov) | <img width="50" src="https://avatars.githubusercontent.com/u/94937?v=4"/></br>[andrewperry](https://github.com/andrewperry) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/5417051?v=4"/></br>[tekdel](https://github.com/tekdel) | <img width="50" src="https://avatars.githubusercontent.com/u/54475686?v=4"/></br>[anshuman9999](https://github.com/anshuman9999) | <img width="50" src="https://avatars.githubusercontent.com/u/25694659?v=4"/></br>[rasklaad](https://github.com/rasklaad) | <img width="50" src="https://avatars.githubusercontent.com/u/17809291?v=4"/></br>[Technik-J](https://github.com/Technik-J) | <img width="50" src="https://avatars.githubusercontent.com/u/498326?v=4"/></br>[Shaxine](https://github.com/Shaxine) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/9095073?v=4"/></br>[antonio-ramadas](https://github.com/antonio-ramadas) | <img width="50" src="https://avatars.githubusercontent.com/u/28067395?v=4"/></br>[heyapoorva](https://github.com/heyapoorva) | <img width="50" src="https://avatars.githubusercontent.com/u/201215?v=4"/></br>[assimd](https://github.com/assimd) | <img width="50" src="https://avatars.githubusercontent.com/u/26827848?v=4"/></br>[Atrate](https://github.com/Atrate) | <img width="50" src="https://avatars.githubusercontent.com/u/60288895?v=4"/></br>[Beowulf2](https://github.com/Beowulf2) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/7034200?v=4"/></br>[bimlas](https://github.com/bimlas) | <img width="50" src="https://avatars.githubusercontent.com/u/47641641?v=4"/></br>[brenobaptista](https://github.com/brenobaptista) | <img width="50" src="https://avatars.githubusercontent.com/u/60824?v=4"/></br>[brttbndr](https://github.com/brttbndr) | <img width="50" src="https://avatars.githubusercontent.com/u/16287077?v=4"/></br>[carlbordum](https://github.com/carlbordum) | <img width="50" src="https://avatars.githubusercontent.com/u/20382?v=4"/></br>[carlosedp](https://github.com/carlosedp) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/105843?v=4"/></br>[chaifeng](https://github.com/chaifeng) | <img width="50" src="https://avatars.githubusercontent.com/u/549349?v=4"/></br>[charles-e](https://github.com/charles-e) | <img width="50" src="https://avatars.githubusercontent.com/u/19870089?v=4"/></br>[cyy5358](https://github.com/cyy5358) | <img width="50" src="https://avatars.githubusercontent.com/u/32337926?v=4"/></br>[Chillu1](https://github.com/Chillu1) | <img width="50" src="https://avatars.githubusercontent.com/u/2348463?v=4"/></br>[Techwolf12](https://github.com/Techwolf12) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/2282880?v=4"/></br>[cloudtrends](https://github.com/cloudtrends) | <img width="50" src="https://avatars.githubusercontent.com/u/17257053?v=4"/></br>[idcristi](https://github.com/idcristi) | <img width="50" src="https://avatars.githubusercontent.com/u/15956322?v=4"/></br>[damienmascre](https://github.com/damienmascre) | <img width="50" src="https://avatars.githubusercontent.com/u/1044056?v=4"/></br>[daniellandau](https://github.com/daniellandau) | <img width="50" src="https://avatars.githubusercontent.com/u/12847693?v=4"/></br>[danil-tolkachev](https://github.com/danil-tolkachev) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/7279100?v=4"/></br>[darshani28](https://github.com/darshani28) | <img width="50" src="https://avatars.githubusercontent.com/u/26189247?v=4"/></br>[daukadolt](https://github.com/daukadolt) | <img width="50" src="https://avatars.githubusercontent.com/u/28535750?v=4"/></br>[NeverMendel](https://github.com/NeverMendel) | <img width="50" src="https://avatars.githubusercontent.com/u/26790323?v=4"/></br>[dervist](https://github.com/dervist) | <img width="50" src="https://avatars.githubusercontent.com/u/11378282?v=4"/></br>[diego-betto](https://github.com/diego-betto) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/215270?v=4"/></br>[erdody](https://github.com/erdody) | <img width="50" src="https://avatars.githubusercontent.com/u/10371667?v=4"/></br>[domgoodwin](https://github.com/domgoodwin) | <img width="50" src="https://avatars.githubusercontent.com/u/72066?v=4"/></br>[b4mboo](https://github.com/b4mboo) | <img width="50" src="https://avatars.githubusercontent.com/u/5131923?v=4"/></br>[donbowman](https://github.com/donbowman) | <img width="50" src="https://avatars.githubusercontent.com/u/579727?v=4"/></br>[sirnacnud](https://github.com/sirnacnud) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/47756?v=4"/></br>[dflock](https://github.com/dflock) | <img width="50" src="https://avatars.githubusercontent.com/u/7990534?v=4"/></br>[drobilica](https://github.com/drobilica) | <img width="50" src="https://avatars.githubusercontent.com/u/21699905?v=4"/></br>[educbraga](https://github.com/educbraga) | <img width="50" src="https://avatars.githubusercontent.com/u/67867099?v=4"/></br>[eduardokimmel](https://github.com/eduardokimmel) | <img width="50" src="https://avatars.githubusercontent.com/u/30393516?v=4"/></br>[VodeniZeko](https://github.com/VodeniZeko) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/17415256?v=4"/></br>[ei-ke](https://github.com/ei-ke) | <img width="50" src="https://avatars.githubusercontent.com/u/1962738?v=4"/></br>[einverne](https://github.com/einverne) | <img width="50" src="https://avatars.githubusercontent.com/u/16492558?v=4"/></br>[eodeluga](https://github.com/eodeluga) | <img width="50" src="https://avatars.githubusercontent.com/u/16875937?v=4"/></br>[fathyar](https://github.com/fathyar) | <img width="50" src="https://avatars.githubusercontent.com/u/3057302?v=4"/></br>[fer22f](https://github.com/fer22f) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/43272148?v=4"/></br>[fpindado](https://github.com/fpindado) | <img width="50" src="https://avatars.githubusercontent.com/u/1714374?v=4"/></br>[FleischKarussel](https://github.com/FleischKarussel) | <img width="50" src="https://avatars.githubusercontent.com/u/18525376?v=4"/></br>[talkdirty](https://github.com/talkdirty) | <img width="50" src="https://avatars.githubusercontent.com/u/19814827?v=4"/></br>[gmaubach](https://github.com/gmaubach) | <img width="50" src="https://avatars.githubusercontent.com/u/6190183?v=4"/></br>[gmag11](https://github.com/gmag11) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/6209647?v=4"/></br>[Jackymancs4](https://github.com/Jackymancs4) | <img width="50" src="https://avatars.githubusercontent.com/u/297578?v=4"/></br>[Glandos](https://github.com/Glandos) | <img width="50" src="https://avatars.githubusercontent.com/u/24235344?v=4"/></br>[vibraniumdev](https://github.com/vibraniumdev) | <img width="50" src="https://avatars.githubusercontent.com/u/2257024?v=4"/></br>[gusbemacbe](https://github.com/gusbemacbe) | <img width="50" src="https://avatars.githubusercontent.com/u/64917442?v=4"/></br>[HOLLYwyh](https://github.com/HOLLYwyh) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/18524580?v=4"/></br>[Fvbor](https://github.com/Fvbor) | <img width="50" src="https://avatars.githubusercontent.com/u/22606250?v=4"/></br>[bennetthanna](https://github.com/bennetthanna) | <img width="50" src="https://avatars.githubusercontent.com/u/67231570?v=4"/></br>[harshitkathuria](https://github.com/harshitkathuria) | <img width="50" src="https://avatars.githubusercontent.com/u/1716229?v=4"/></br>[Vistaus](https://github.com/Vistaus) | <img width="50" src="https://avatars.githubusercontent.com/u/6509881?v=4"/></br>[ianjs](https://github.com/ianjs) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/19862172?v=4"/></br>[iahmedbacha](https://github.com/iahmedbacha) | <img width="50" src="https://avatars.githubusercontent.com/u/1533624?v=4"/></br>[IrvinDominin](https://github.com/IrvinDominin) | <img width="50" src="https://avatars.githubusercontent.com/u/33200024?v=4"/></br>[ishammahajan](https://github.com/ishammahajan) | <img width="50" src="https://avatars.githubusercontent.com/u/6916297?v=4"/></br>[ffadilaputra](https://github.com/ffadilaputra) | <img width="50" src="https://avatars.githubusercontent.com/u/19985741?v=4"/></br>[JRaiden16](https://github.com/JRaiden16) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/11466782?v=4"/></br>[jacobherrington](https://github.com/jacobherrington) | <img width="50" src="https://avatars.githubusercontent.com/u/9365179?v=4"/></br>[jamesadjinwa](https://github.com/jamesadjinwa) | <img width="50" src="https://avatars.githubusercontent.com/u/20801821?v=4"/></br>[jrwrigh](https://github.com/jrwrigh) | <img width="50" src="https://avatars.githubusercontent.com/u/4995433?v=4"/></br>[jaredcrowe](https://github.com/jaredcrowe) | <img width="50" src="https://avatars.githubusercontent.com/u/4087105?v=4"/></br>[volatilevar](https://github.com/volatilevar) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/47724360?v=4"/></br>[innkuika](https://github.com/innkuika) | <img width="50" src="https://avatars.githubusercontent.com/u/163555?v=4"/></br>[JoelRSimpson](https://github.com/JoelRSimpson) | <img width="50" src="https://avatars.githubusercontent.com/u/6965062?v=4"/></br>[joeltaylor](https://github.com/joeltaylor) | <img width="50" src="https://avatars.githubusercontent.com/u/242107?v=4"/></br>[exic](https://github.com/exic) | <img width="50" src="https://avatars.githubusercontent.com/u/13716151?v=4"/></br>[JonathanPlasse](https://github.com/JonathanPlasse) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/1248504?v=4"/></br>[joesfer](https://github.com/joesfer) | <img width="50" src="https://avatars.githubusercontent.com/u/6048003?v=4"/></br>[joybinchen](https://github.com/joybinchen) | <img width="50" src="https://avatars.githubusercontent.com/u/37601331?v=4"/></br>[kaustubhsh](https://github.com/kaustubhsh) | <img width="50" src="https://avatars.githubusercontent.com/u/1560189?v=4"/></br>[y-usuzumi](https://github.com/y-usuzumi) | <img width="50" src="https://avatars.githubusercontent.com/u/1660460?v=4"/></br>[xuhcc](https://github.com/xuhcc) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/16933735?v=4"/></br>[kirtanprht](https://github.com/kirtanprht) | <img width="50" src="https://avatars.githubusercontent.com/u/37491732?v=4"/></br>[k0ur0x](https://github.com/k0ur0x) | <img width="50" src="https://avatars.githubusercontent.com/u/7824233?v=4"/></br>[kklas](https://github.com/kklas) | <img width="50" src="https://avatars.githubusercontent.com/u/8622992?v=4"/></br>[xmlangel](https://github.com/xmlangel) | <img width="50" src="https://avatars.githubusercontent.com/u/1055100?v=4"/></br>[troilus](https://github.com/troilus) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/2599210?v=4"/></br>[lboullo0](https://github.com/lboullo0) | <img width="50" src="https://avatars.githubusercontent.com/u/1562062?v=4"/></br>[dbinary](https://github.com/dbinary) | <img width="50" src="https://avatars.githubusercontent.com/u/15436007?v=4"/></br>[marc-bouvier](https://github.com/marc-bouvier) | <img width="50" src="https://avatars.githubusercontent.com/u/5699725?v=4"/></br>[mvonmaltitz](https://github.com/mvonmaltitz) | <img width="50" src="https://avatars.githubusercontent.com/u/11036464?v=4"/></br>[mlkood](https://github.com/mlkood) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/2480960?v=4"/></br>[plextoriano](https://github.com/plextoriano) | <img width="50" src="https://avatars.githubusercontent.com/u/5788516?v=4"/></br>[Marmo](https://github.com/Marmo) | <img width="50" src="https://avatars.githubusercontent.com/u/29300939?v=4"/></br>[mcejp](https://github.com/mcejp) | <img width="50" src="https://avatars.githubusercontent.com/u/640949?v=4"/></br>[freaktechnik](https://github.com/freaktechnik) | <img width="50" src="https://avatars.githubusercontent.com/u/79802125?v=4"/></br>[martinkorelic](https://github.com/martinkorelic) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/287105?v=4"/></br>[Petemir](https://github.com/Petemir) | <img width="50" src="https://avatars.githubusercontent.com/u/5218859?v=4"/></br>[matsair](https://github.com/matsair) | <img width="50" src="https://avatars.githubusercontent.com/u/12831489?v=4"/></br>[mgroth0](https://github.com/mgroth0) | <img width="50" src="https://avatars.githubusercontent.com/u/21796?v=4"/></br>[silentmatt](https://github.com/silentmatt) | <img width="50" src="https://avatars.githubusercontent.com/u/76700192?v=4"/></br>[maxs-test](https://github.com/maxs-test) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/59669349?v=4"/></br>[MichBoi](https://github.com/MichBoi) | <img width="50" src="https://avatars.githubusercontent.com/u/51273874?v=4"/></br>[MichipX](https://github.com/MichipX) | <img width="50" src="https://avatars.githubusercontent.com/u/53177864?v=4"/></br>[MrTraduttore](https://github.com/MrTraduttore) | <img width="50" src="https://avatars.githubusercontent.com/u/48156230?v=4"/></br>[sanjarcode](https://github.com/sanjarcode) | <img width="50" src="https://avatars.githubusercontent.com/u/43955099?v=4"/></br>[Mustafa-ALD](https://github.com/Mustafa-ALD) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/9076687?v=4"/></br>[NJannasch](https://github.com/NJannasch) | <img width="50" src="https://avatars.githubusercontent.com/u/8016073?v=4"/></br>[zomglings](https://github.com/zomglings) | <img width="50" src="https://avatars.githubusercontent.com/u/10386884?v=4"/></br>[Frichetten](https://github.com/Frichetten) | <img width="50" src="https://avatars.githubusercontent.com/u/5541611?v=4"/></br>[nicolas-suzuki](https://github.com/nicolas-suzuki) | <img width="50" src="https://avatars.githubusercontent.com/u/12369770?v=4"/></br>[Ouvill](https://github.com/Ouvill) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/43815417?v=4"/></br>[shorty2380](https://github.com/shorty2380) | <img width="50" src="https://avatars.githubusercontent.com/u/15014287?v=4"/></br>[dist3r](https://github.com/dist3r) | <img width="50" src="https://avatars.githubusercontent.com/u/19418601?v=4"/></br>[rakleed](https://github.com/rakleed) | <img width="50" src="https://avatars.githubusercontent.com/u/7881932?v=4"/></br>[idle-code](https://github.com/idle-code) | <img width="50" src="https://avatars.githubusercontent.com/u/168931?v=4"/></br>[bobchao](https://github.com/bobchao) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/6306608?v=4"/></br>[Diadlo](https://github.com/Diadlo) | <img width="50" src="https://avatars.githubusercontent.com/u/42793024?v=4"/></br>[pranavmodx](https://github.com/pranavmodx) | <img width="50" src="https://avatars.githubusercontent.com/u/50834839?v=4"/></br>[R3dError](https://github.com/R3dError) | <img width="50" src="https://avatars.githubusercontent.com/u/42652941?v=4"/></br>[rajprakash00](https://github.com/rajprakash00) | <img width="50" src="https://avatars.githubusercontent.com/u/32304956?v=4"/></br>[rahil1304](https://github.com/rahil1304) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/8257474?v=4"/></br>[rasulkireev](https://github.com/rasulkireev) | <img width="50" src="https://avatars.githubusercontent.com/u/17312341?v=4"/></br>[reinhart1010](https://github.com/reinhart1010) | <img width="50" src="https://avatars.githubusercontent.com/u/60484714?v=4"/></br>[Retew](https://github.com/Retew) | <img width="50" src="https://avatars.githubusercontent.com/u/10456131?v=4"/></br>[ambrt](https://github.com/ambrt) | <img width="50" src="https://avatars.githubusercontent.com/u/15892014?v=4"/></br>[Derkades](https://github.com/Derkades) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/49439044?v=4"/></br>[fourstepper](https://github.com/fourstepper) | <img width="50" src="https://avatars.githubusercontent.com/u/54365?v=4"/></br>[rodgco](https://github.com/rodgco) | <img width="50" src="https://avatars.githubusercontent.com/u/96014?v=4"/></br>[Ronnie76er](https://github.com/Ronnie76er) | <img width="50" src="https://avatars.githubusercontent.com/u/79168?v=4"/></br>[roryokane](https://github.com/roryokane) | <img width="50" src="https://avatars.githubusercontent.com/u/744655?v=4"/></br>[ruzaq](https://github.com/ruzaq) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/20490839?v=4"/></br>[szokesandor](https://github.com/szokesandor) | <img width="50" src="https://avatars.githubusercontent.com/u/19328605?v=4"/></br>[SamuelBlickle](https://github.com/SamuelBlickle) | <img width="50" src="https://avatars.githubusercontent.com/u/80849457?v=4"/></br>[livingc0l0ur](https://github.com/livingc0l0ur) | <img width="50" src="https://avatars.githubusercontent.com/u/1776?v=4"/></br>[bronson](https://github.com/bronson) | <img width="50" src="https://avatars.githubusercontent.com/u/24606935?v=4"/></br>[semperor](https://github.com/semperor) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/607938?v=4"/></br>[shawnaxsom](https://github.com/shawnaxsom) | <img width="50" src="https://avatars.githubusercontent.com/u/9937486?v=4"/></br>[SFoskitt](https://github.com/SFoskitt) | <img width="50" src="https://avatars.githubusercontent.com/u/505011?v=4"/></br>[kcrt](https://github.com/kcrt) | <img width="50" src="https://avatars.githubusercontent.com/u/538584?v=4"/></br>[xissy](https://github.com/xissy) | <img width="50" src="https://avatars.githubusercontent.com/u/164962?v=4"/></br>[tams](https://github.com/tams) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/466122?v=4"/></br>[Tekki](https://github.com/Tekki) | <img width="50" src="https://avatars.githubusercontent.com/u/2112477?v=4"/></br>[ThatcherC](https://github.com/ThatcherC) | <img width="50" src="https://avatars.githubusercontent.com/u/21969426?v=4"/></br>[TheoDutch](https://github.com/TheoDutch) | <img width="50" src="https://avatars.githubusercontent.com/u/8731922?v=4"/></br>[tbroadley](https://github.com/tbroadley) | <img width="50" src="https://avatars.githubusercontent.com/u/114300?v=4"/></br>[Kriechi](https://github.com/Kriechi) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/3457339?v=4"/></br>[tkilaker](https://github.com/tkilaker) | <img width="50" src="https://avatars.githubusercontent.com/u/802148?v=4"/></br>[Tim-Erwin](https://github.com/Tim-Erwin) | <img width="50" src="https://avatars.githubusercontent.com/u/4201229?v=4"/></br>[tcyrus](https://github.com/tcyrus) | <img width="50" src="https://avatars.githubusercontent.com/u/834914?v=4"/></br>[tobias-grasse](https://github.com/tobias-grasse) | <img width="50" src="https://avatars.githubusercontent.com/u/6691273?v=4"/></br>[strobeltobias](https://github.com/strobeltobias) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/1677578?v=4"/></br>[kostegit](https://github.com/kostegit) | <img width="50" src="https://avatars.githubusercontent.com/u/70296?v=4"/></br>[tbergeron](https://github.com/tbergeron) | <img width="50" src="https://avatars.githubusercontent.com/u/10265443?v=4"/></br>[Ullas-Aithal](https://github.com/Ullas-Aithal) | <img width="50" src="https://avatars.githubusercontent.com/u/6104498?v=4"/></br>[MyTheValentinus](https://github.com/MyTheValentinus) | <img width="50" src="https://avatars.githubusercontent.com/u/2830093?v=4"/></br>[vassudanagunta](https://github.com/vassudanagunta) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/54314949?v=4"/></br>[vijayjoshi16](https://github.com/vijayjoshi16) | <img width="50" src="https://avatars.githubusercontent.com/u/59287619?v=4"/></br>[max-keviv](https://github.com/max-keviv) | <img width="50" src="https://avatars.githubusercontent.com/u/598576?v=4"/></br>[vandreykiv](https://github.com/vandreykiv) | <img width="50" src="https://avatars.githubusercontent.com/u/26511487?v=4"/></br>[WisdomCode](https://github.com/WisdomCode) | <img width="50" src="https://avatars.githubusercontent.com/u/1921957?v=4"/></br>[xsak](https://github.com/xsak) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/11031696?v=4"/></br>[ymitsos](https://github.com/ymitsos) | <img width="50" src="https://avatars.githubusercontent.com/u/63324960?v=4"/></br>[abolishallprivateproperty](https://github.com/abolishallprivateproperty) | <img width="50" src="https://avatars.githubusercontent.com/u/11336076?v=4"/></br>[aerotog](https://github.com/aerotog) | <img width="50" src="https://avatars.githubusercontent.com/u/39854348?v=4"/></br>[albertopasqualetto](https://github.com/albertopasqualetto) | <img width="50" src="https://avatars.githubusercontent.com/u/44570278?v=4"/></br>[asrient](https://github.com/asrient) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/621360?v=4"/></br>[bestlibre](https://github.com/bestlibre) | <img width="50" src="https://avatars.githubusercontent.com/u/35600612?v=4"/></br>[boring10](https://github.com/boring10) | <img width="50" src="https://avatars.githubusercontent.com/u/13894820?v=4"/></br>[cadolphs](https://github.com/cadolphs) | <img width="50" src="https://avatars.githubusercontent.com/u/12461043?v=4"/></br>[colorchestra](https://github.com/colorchestra) | <img width="50" src="https://avatars.githubusercontent.com/u/30935096?v=4"/></br>[cybertramp](https://github.com/cybertramp) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/15824892?v=4"/></br>[dartero](https://github.com/dartero) | <img width="50" src="https://avatars.githubusercontent.com/u/9694906?v=4"/></br>[delta-emil](https://github.com/delta-emil) | <img width="50" src="https://avatars.githubusercontent.com/u/926263?v=4"/></br>[doc75](https://github.com/doc75) | <img width="50" src="https://avatars.githubusercontent.com/u/5589253?v=4"/></br>[dsp77](https://github.com/dsp77) | <img width="50" src="https://avatars.githubusercontent.com/u/2903013?v=4"/></br>[ebayer](https://github.com/ebayer) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/9206310?v=4"/></br>[elsiehupp](https://github.com/elsiehupp) | <img width="50" src="https://avatars.githubusercontent.com/u/701050?v=4"/></br>[espinosa](https://github.com/espinosa) | <img width="50" src="https://avatars.githubusercontent.com/u/18619090?v=4"/></br>[exponentactivity](https://github.com/exponentactivity) | <img width="50" src="https://avatars.githubusercontent.com/u/16708935?v=4"/></br>[exprez135](https://github.com/exprez135) | <img width="50" src="https://avatars.githubusercontent.com/u/9768112?v=4"/></br>[fab4x](https://github.com/fab4x) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/47755037?v=4"/></br>[fabianski7](https://github.com/fabianski7) | <img width="50" src="https://avatars.githubusercontent.com/u/14201321?v=4"/></br>[rasperepodvipodvert](https://github.com/rasperepodvipodvert) | <img width="50" src="https://avatars.githubusercontent.com/u/748808?v=4"/></br>[gasolin](https://github.com/gasolin) | <img width="50" src="https://avatars.githubusercontent.com/u/47191051?v=4"/></br>[githubaccount073](https://github.com/githubaccount073) | <img width="50" src="https://avatars.githubusercontent.com/u/43672033?v=4"/></br>[hms5232](https://github.com/hms5232) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/11388094?v=4"/></br>[hydrandt](https://github.com/hydrandt) | <img width="50" src="https://avatars.githubusercontent.com/u/61012185?v=4"/></br>[iamtalwinder](https://github.com/iamtalwinder) | <img width="50" src="https://avatars.githubusercontent.com/u/557540?v=4"/></br>[jabdoa2](https://github.com/jabdoa2) | <img width="50" src="https://avatars.githubusercontent.com/u/29166402?v=4"/></br>[jduar](https://github.com/jduar) | <img width="50" src="https://avatars.githubusercontent.com/u/2678545?v=4"/></br>[jibedoubleve](https://github.com/jibedoubleve) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/53862536?v=4"/></br>[johanvanheusden](https://github.com/johanvanheusden) | <img width="50" src="https://avatars.githubusercontent.com/u/38327267?v=4"/></br>[jtagcat](https://github.com/jtagcat) | <img width="50" src="https://avatars.githubusercontent.com/u/61631665?v=4"/></br>[konhi](https://github.com/konhi) | <img width="50" src="https://avatars.githubusercontent.com/u/54991735?v=4"/></br>[krzysiekwie](https://github.com/krzysiekwie) | <img width="50" src="https://avatars.githubusercontent.com/u/12849008?v=4"/></br>[lighthousebulb](https://github.com/lighthousebulb) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/4140247?v=4"/></br>[luzpaz](https://github.com/luzpaz) | <img width="50" src="https://avatars.githubusercontent.com/u/29355048?v=4"/></br>[majsterkovic](https://github.com/majsterkovic) | <img width="50" src="https://avatars.githubusercontent.com/u/77744862?v=4"/></br>[mak2002](https://github.com/mak2002) | <img width="50" src="https://avatars.githubusercontent.com/u/30428258?v=4"/></br>[nmiquan](https://github.com/nmiquan) | <img width="50" src="https://avatars.githubusercontent.com/u/31123054?v=4"/></br>[nullpointer666](https://github.com/nullpointer666) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/2979926?v=4"/></br>[oscaretu](https://github.com/oscaretu) | <img width="50" src="https://avatars.githubusercontent.com/u/36965591?v=4"/></br>[oskarsh](https://github.com/oskarsh) | <img width="50" src="https://avatars.githubusercontent.com/u/52031346?v=4"/></br>[osso73](https://github.com/osso73) | <img width="50" src="https://avatars.githubusercontent.com/u/29743024?v=4"/></br>[over-soul](https://github.com/over-soul) | <img width="50" src="https://avatars.githubusercontent.com/u/42961947?v=4"/></br>[pensierocrea](https://github.com/pensierocrea) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/45542782?v=4"/></br>[pomeloy](https://github.com/pomeloy) | <img width="50" src="https://avatars.githubusercontent.com/u/10206967?v=4"/></br>[rhtenhove](https://github.com/rhtenhove) | <img width="50" src="https://avatars.githubusercontent.com/u/16728217?v=4"/></br>[rikanotank1](https://github.com/rikanotank1) | <img width="50" src="https://avatars.githubusercontent.com/u/24560368?v=4"/></br>[rxliuli](https://github.com/rxliuli) | <img width="50" src="https://avatars.githubusercontent.com/u/14062932?v=4"/></br>[simonsan](https://github.com/simonsan) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/5004545?v=4"/></br>[stellarpower](https://github.com/stellarpower) | <img width="50" src="https://avatars.githubusercontent.com/u/20983267?v=4"/></br>[suixinio](https://github.com/suixinio) | <img width="50" src="https://avatars.githubusercontent.com/u/12995773?v=4"/></br>[sumomo-99](https://github.com/sumomo-99) | <img width="50" src="https://avatars.githubusercontent.com/u/367170?v=4"/></br>[xtatsux](https://github.com/xtatsux) | <img width="50" src="https://avatars.githubusercontent.com/u/6908872?v=4"/></br>[taw00](https://github.com/taw00) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/10956653?v=4"/></br>[tcassaert](https://github.com/tcassaert) | <img width="50" src="https://avatars.githubusercontent.com/u/46327531?v=4"/></br>[victante](https://github.com/victante) | <img width="50" src="https://avatars.githubusercontent.com/u/7252567?v=4"/></br>[Voltinus](https://github.com/Voltinus) | <img width="50" src="https://avatars.githubusercontent.com/u/2216902?v=4"/></br>[xcffl](https://github.com/xcffl) | <img width="50" src="https://avatars.githubusercontent.com/u/46404814?v=4"/></br>[yourcontact](https://github.com/yourcontact) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/37692927?v=4"/></br>[zaoyifan](https://github.com/zaoyifan) | <img width="50" src="https://avatars.githubusercontent.com/u/10813608?v=4"/></br>[zawnk](https://github.com/zawnk) | <img width="50" src="https://avatars.githubusercontent.com/u/55245068?v=4"/></br>[zen-quo](https://github.com/zen-quo) | <img width="50" src="https://avatars.githubusercontent.com/u/23507174?v=4"/></br>[zozolina123](https://github.com/zozolina123) | <img width="50" src="https://avatars.githubusercontent.com/u/25315?v=4"/></br>[xcession](https://github.com/xcession) |
|
||||
| <img width="50" src="https://avatars.githubusercontent.com/u/34542665?v=4"/></br>[paventyang](https://github.com/paventyang) | <img width="50" src="https://avatars.githubusercontent.com/u/608014?v=4"/></br>[jackytsu](https://github.com/jackytsu) | <img width="50" src="https://avatars.githubusercontent.com/u/1308646?v=4"/></br>[zhangmx](https://github.com/zhangmx) | | |
|
||||
<!-- CONTRIBUTORS-TABLE-AUTO-GENERATED -->
|
||||
|
||||
# Known bugs
|
||||
|
||||
@@ -9,6 +9,8 @@ version: '3'
|
||||
services:
|
||||
db:
|
||||
image: postgres:13.1
|
||||
volumes:
|
||||
- ./data/postgres:/var/lib/postgresql/data
|
||||
ports:
|
||||
- "5432:5432"
|
||||
restart: unless-stopped
|
||||
|
||||
@@ -108,11 +108,12 @@
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
<div class="lead">
|
||||
<p>Defines whether the command should be enabled or disabled, which in turns affects
|
||||
the enabled state of any associated button or menu item.</p>
|
||||
<p>Defines whether the command should be enabled or disabled, which in turns
|
||||
affects the enabled state of any associated button or menu item.</p>
|
||||
</div>
|
||||
<p>The condition should be expressed as a "when-clause" (as in Visual Studio Code). It's a simple boolean expression that evaluates to
|
||||
<code>true</code> or <code>false</code>. It supports the following operators:</p>
|
||||
<p>The condition should be expressed as a "when-clause" (as in Visual Studio
|
||||
Code). It's a simple boolean expression that evaluates to <code>true</code> or
|
||||
<code>false</code>. It supports the following operators:</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -142,7 +143,17 @@
|
||||
<td>"oneNoteSelected && !inConflictFolder"</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<p>Currently the supported context variables aren't documented, but you can <a href="https://github.com/laurent22/joplin/blob/dev/packages/lib/services/commands/stateToWhenClauseContext.ts">find the list here</a>.</p>
|
||||
<p>Joplin, unlike VSCode, also supports parenthesis, which allows creating
|
||||
more complex expressions such as <code>cond1 || (cond2 && cond3)</code>. Only one
|
||||
level of parenthesis is possible (nested ones aren't supported).</p>
|
||||
<p>Currently the supported context variables aren't documented, but you can
|
||||
find the list below:</p>
|
||||
<ul>
|
||||
<li>[Global When
|
||||
Clauses](<a href="https://github.com/laurent22/joplin/blob/dev/packages/lib/services/commands/stateToWhenClauseContext.ts">https://github.com/laurent22/joplin/blob/dev/packages/lib/services/commands/stateToWhenClauseContext.ts</a>).</li>
|
||||
<li>[Desktop app When
|
||||
Clauses](<a href="https://github.com/laurent22/joplin/blob/dev/packages/app-desktop/services/commands/stateToWhenClauseContext.ts">https://github.com/laurent22/joplin/blob/dev/packages/app-desktop/services/commands/stateToWhenClauseContext.ts</a>).</li>
|
||||
</ul>
|
||||
<p>Note: Commands are enabled by default unless you use this property.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -721,6 +721,11 @@ async function fetchAllNotes() {
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>share_id</td>
|
||||
<td>text</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>body_html</td>
|
||||
<td>text</td>
|
||||
<td>Note body, in HTML format</td>
|
||||
@@ -841,6 +846,11 @@ async function fetchAllNotes() {
|
||||
<td>int</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>share_id</td>
|
||||
<td>text</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h2>GET /folders<a name="get-folders" href="#get-folders" class="heading-anchor">🔗</a></h2>
|
||||
@@ -937,6 +947,11 @@ async function fetchAllNotes() {
|
||||
<td>int</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>share_id</td>
|
||||
<td>text</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h2>GET /resources<a name="get-resources" href="#get-resources" class="heading-anchor">🔗</a></h2>
|
||||
|
||||
@@ -405,6 +405,46 @@ https://github.com/laurent22/joplin/blob/dev/readme/changelog.md
|
||||
<p><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=E8JMYD2LQ8MMA&lc=GB&item_name=Joplin+Development&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"><img src="https://joplinapp.org/images/badges/Donate-PayPal-green.svg" alt="Donate using PayPal"></a> <a href="https://github.com/sponsors/laurent22/"><img src="https://joplinapp.org/images/badges/GitHub-Badge.svg" alt="Sponsor on GitHub"></a> <a href="https://www.patreon.com/joplin"><img src="https://joplinapp.org/images/badges/Patreon-Badge.svg" alt="Become a patron"></a> <a href="https://joplinapp.org/donate/#donations"><img src="https://joplinapp.org/images/badges/Donate-IBAN.svg" alt="Donate using IBAN"></a></p>
|
||||
<hr>
|
||||
<h1>Joplin changelog<a name="joplin-changelog" href="#joplin-changelog" class="heading-anchor">🔗</a></h1>
|
||||
<h2><a href="https://github.com/laurent22/joplin/releases/tag/v2.0.2">v2.0.2</a> (Pre-release) - 2021-05-21T18:07:48Z<a name="v2-0-2-https-github-com-laurent22-joplin-releases-tag-v2-0-2-pre-release-2021-05-21t18-07-48z" href="#v2-0-2-https-github-com-laurent22-joplin-releases-tag-v2-0-2-pre-release-2021-05-21t18-07-48z" class="heading-anchor">🔗</a></h2>
|
||||
<ul>
|
||||
<li>New: Add Share Notebook menu item (6f2f241)</li>
|
||||
<li>New: Add classnames to DOM elements for theming purposes (<a href="https://github.com/laurent22/joplin/issues/4933">#4933</a> by <a href="https://github.com/ajilderda">@ajilderda</a>)</li>
|
||||
<li>Improved: Allow unsharing a note (f7d164b)</li>
|
||||
<li>Improved: Displays error info when Joplin Server fails (3f0586e)</li>
|
||||
<li>Improved: Handle too large items for Joplin Server (d29624c)</li>
|
||||
<li>Improved: Import SVG as images when importing ENEX files (<a href="https://github.com/laurent22/joplin/issues/4968">#4968</a>)</li>
|
||||
<li>Improved: Import linked local files when importing Markdown files (<a href="https://github.com/laurent22/joplin/issues/4966">#4966</a>) (<a href="https://github.com/laurent22/joplin/issues/4433">#4433</a> by <a href="https://github.com/JackGruber">@JackGruber</a>)</li>
|
||||
<li>Improved: Improved usability when plugin repository cannot be connected to (<a href="https://github.com/laurent22/joplin/issues/4462">#4462</a>)</li>
|
||||
<li>Improved: Made sync more reliable by making it skip items that time out, and improved sync status screen (15fe119)</li>
|
||||
<li>Improved: Pass custom CSS property to all export handlers and renderers (bd08041)</li>
|
||||
<li>Improved: Regression: It was no longer possible to add list items in an empty note (6577f4f)</li>
|
||||
<li>Improved: Regression: Pasting plain text in Rich Text editor was broken (9e9bf63)</li>
|
||||
<li>Fixed: Fixed issue with empty panels being created by plugins (<a href="https://github.com/laurent22/joplin/issues/4926">#4926</a>)</li>
|
||||
<li>Fixed: Fixed pasting HTML in Rich Text editor, and improved pasting plain text (2226b79)</li>
|
||||
<li>Fixed: Improved importing Evernote notes that contain codeblocks (<a href="https://github.com/laurent22/joplin/issues/4965">#4965</a>)</li>
|
||||
<li>Fixed: Prevent cursor from jumping to top of page when pasting image (<a href="https://github.com/laurent22/joplin/issues/4591">#4591</a>)</li>
|
||||
</ul>
|
||||
<h2><a href="https://github.com/laurent22/joplin/releases/tag/v2.0.1">v2.0.1</a> (Pre-release) - 2021-05-15T13:22:58Z<a name="v2-0-1-https-github-com-laurent22-joplin-releases-tag-v2-0-1-pre-release-2021-05-15t13-22-58z" href="#v2-0-1-https-github-com-laurent22-joplin-releases-tag-v2-0-1-pre-release-2021-05-15t13-22-58z" class="heading-anchor">🔗</a></h2>
|
||||
<ul>
|
||||
<li>New: Add support for sharing notebooks with Joplin Server (<a href="https://github.com/laurent22/joplin/issues/4772">#4772</a>)</li>
|
||||
<li>New: Add new date format YYMMDD (<a href="https://github.com/laurent22/joplin/issues/4954">#4954</a> by Helmut K. C. Tessarek)</li>
|
||||
<li>New: Added button to skip an application update (a31b402)</li>
|
||||
<li>Fixed: Display proper error message when JEX file is corrupted (<a href="https://github.com/laurent22/joplin/issues/4958">#4958</a>)</li>
|
||||
<li>Fixed: Show or hide completed todos in search results based on user settings (<a href="https://github.com/laurent22/joplin/issues/4951">#4951</a>) (<a href="https://github.com/laurent22/joplin/issues/4581">#4581</a> by <a href="https://github.com/JackGruber">@JackGruber</a>)</li>
|
||||
<li>Fixed: Solve "Resource Id not provided" error (<a href="https://github.com/laurent22/joplin/issues/4943">#4943</a>) (<a href="https://github.com/laurent22/joplin/issues/4891">#4891</a> by <a href="https://github.com/Subhra264">@Subhra264</a>)</li>
|
||||
</ul>
|
||||
<h2><a href="https://github.com/laurent22/joplin/releases/tag/v1.8.5">v1.8.5</a> - 2021-05-10T11:58:14Z<a name="v1-8-5-https-github-com-laurent22-joplin-releases-tag-v1-8-5-2021-05-10t11-58-14z" href="#v1-8-5-https-github-com-laurent22-joplin-releases-tag-v1-8-5-2021-05-10t11-58-14z" class="heading-anchor">🔗</a></h2>
|
||||
<ul>
|
||||
<li>Fixed: Fixed pasting of text and images from Word on Windows (<a href="https://github.com/laurent22/joplin/issues/4916">#4916</a>)</li>
|
||||
<li>Security: Filter out NOSCRIPT tags that could be used to cause an XSS (found by <a href="https://twitter.com/jubairfolder">Jubair Rehman Yousafzai</a>) (9c20d59)</li>
|
||||
</ul>
|
||||
<h2><a href="https://github.com/laurent22/joplin/releases/tag/v1.8.4">v1.8.4</a> (Pre-release) - 2021-05-09T18:05:05Z<a name="v1-8-4-https-github-com-laurent22-joplin-releases-tag-v1-8-4-pre-release-2021-05-09t18-05-05z" href="#v1-8-4-https-github-com-laurent22-joplin-releases-tag-v1-8-4-pre-release-2021-05-09t18-05-05z" class="heading-anchor">🔗</a></h2>
|
||||
<ul>
|
||||
<li>Improved: Improve display of release notes for new versions (f76f99b)</li>
|
||||
<li>Fixed: Ensure that image paths that contain spaces are pasted correctly in the Rich Text editor (<a href="https://github.com/laurent22/joplin/issues/4916">#4916</a>)</li>
|
||||
<li>Fixed: Make sure sync startup operations are cleared after startup (<a href="https://github.com/laurent22/joplin/issues/4919">#4919</a>)</li>
|
||||
<li>Security: Apply npm audit security fixes (0b67446)</li>
|
||||
</ul>
|
||||
<h2><a href="https://github.com/laurent22/joplin/releases/tag/v1.8.3">v1.8.3</a> (Pre-release) - 2021-05-04T10:38:16Z<a name="v1-8-3-https-github-com-laurent22-joplin-releases-tag-v1-8-3-pre-release-2021-05-04t10-38-16z" href="#v1-8-3-https-github-com-laurent22-joplin-releases-tag-v1-8-3-pre-release-2021-05-04t10-38-16z" class="heading-anchor">🔗</a></h2>
|
||||
<ul>
|
||||
<li>New: Add "id" and "due" search filters (<a href="https://github.com/laurent22/joplin/issues/4898">#4898</a> by <a href="https://github.com/JackGruber">@JackGruber</a>)</li>
|
||||
|
||||
443
docs/changelog_android/index.html
Normal file
443
docs/changelog_android/index.html
Normal file
@@ -0,0 +1,443 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
|
||||
<!--
|
||||
|
||||
!!! WARNING !!!
|
||||
|
||||
This file was auto-generated from readme/changelog_android.md and any manual change
|
||||
made to it will be overwritten. To make a change to this file please modify
|
||||
the source Markdown file:
|
||||
|
||||
https://github.com/laurent22/joplin/blob/dev/readme/changelog_android.md
|
||||
|
||||
-->
|
||||
|
||||
<head>
|
||||
<title>Joplin Android app changelog | Joplin</title>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="https://joplinapp.org/css/bootstrap.min.css">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="https://joplinapp.org/favicon.ico">
|
||||
<!-- <link rel="stylesheet" href="https://joplinapp.org/css/fontawesome-all.min.css"> -->
|
||||
<link rel="stylesheet" href="https://joplinapp.org/css/fork-awesome.min.css">
|
||||
<script src="https://joplinapp.org/js/jquery-3.2.1.slim.min.js"></script>
|
||||
<style>
|
||||
body {
|
||||
background-color: #F1F1F1;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.root {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
a[href^="mailto:"] {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
table {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
td, th {
|
||||
padding: .8em;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.page-markdown table pre,
|
||||
.page-markdown table blockquote {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.page-markdown table pre,
|
||||
.page-markdown table blockquote {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.page-markdown table pre {
|
||||
background-color: rgba(0,0,0,0);
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h1, h2 {
|
||||
border-bottom: 1px solid #eaecef;
|
||||
padding-bottom: 0.3em;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
font-weight: 600;
|
||||
font-size: 2em;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.6em;
|
||||
}
|
||||
h3 {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
code {
|
||||
color: black;
|
||||
background-color: #eee;
|
||||
border: 1px solid #ccc;
|
||||
font-size: .85em;
|
||||
/* word-break: break-all; */
|
||||
}
|
||||
pre code {
|
||||
border: none;
|
||||
}
|
||||
pre {
|
||||
font-size: .85em;
|
||||
}
|
||||
blockquote {
|
||||
font-size: 1em;
|
||||
color: #555;
|
||||
};
|
||||
#toc ul {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
#toc > ul > li {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
#toc {
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.title-icon {
|
||||
display: flex;
|
||||
height: 1em;
|
||||
}
|
||||
.title-text {
|
||||
display: flex;
|
||||
font-weight: normal;
|
||||
margin-bottom: .2em;
|
||||
margin-left: .5em;
|
||||
}
|
||||
.sub-title {
|
||||
font-weight: normal;
|
||||
}
|
||||
.container {
|
||||
background-color: white;
|
||||
padding: 0;
|
||||
box-shadow: 0 10px 20px #888888;
|
||||
}
|
||||
table.screenshots {
|
||||
margin-top: 2em;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
table.screenshots th {
|
||||
height: 3em;
|
||||
text-align: center;
|
||||
}
|
||||
table.screenshots th,
|
||||
table.screenshots td {
|
||||
border: 1px solid #C2C2C2;
|
||||
}
|
||||
img[align="left"] {
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.mobile-screenshot {
|
||||
height: 40em;
|
||||
padding: 1em;
|
||||
}
|
||||
.cli-screenshot-wrapper {
|
||||
background-color: black;
|
||||
vertical-align: top;
|
||||
padding: 1em 2em 1em 1em;
|
||||
}
|
||||
.cli-screenshot {
|
||||
font-family: "Monaco", "Inconsolata", "CONSOLAS", "Deja Vu Sans Mono", "Droid Sans Mono", "Andale Mono", monospace;
|
||||
background-color: black;
|
||||
color: white;
|
||||
border: none;
|
||||
}
|
||||
.cli-screenshot .prompt {
|
||||
color: #48C2F0;
|
||||
}
|
||||
.top-screenshot {
|
||||
margin-top: 2em;
|
||||
text-align: center;
|
||||
}
|
||||
.header {
|
||||
position: relative;
|
||||
padding-left: 2em;
|
||||
padding-right: 2em;
|
||||
padding-top: 1em;
|
||||
padding-bottom: 1em;
|
||||
color: white;
|
||||
background-color: #2B2B3D;
|
||||
}
|
||||
.header a h1 {
|
||||
color: white;
|
||||
}
|
||||
.header a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
.content {
|
||||
padding-left: 2em;
|
||||
padding-right: 2em;
|
||||
padding-bottom: 2em;
|
||||
padding-top: 2em;
|
||||
}
|
||||
.forkme {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top:0;
|
||||
}
|
||||
.nav-wrapper {
|
||||
position: relative;
|
||||
width: inherit;
|
||||
}
|
||||
.nav {
|
||||
background-color: black;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
.nav.sticky {
|
||||
position:fixed;
|
||||
top: 0;
|
||||
width: inherit;
|
||||
box-shadow: 0 0 10px #000000;
|
||||
}
|
||||
.nav a {
|
||||
color: white;
|
||||
display: inline-block;
|
||||
padding: .6em .9em .6em .9em;
|
||||
}
|
||||
.nav ul {
|
||||
padding-left: 2em;
|
||||
margin-bottom: 0;
|
||||
display: table-cell;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
/* For GSoC: */
|
||||
min-width: 470px;
|
||||
}
|
||||
.nav ul li {
|
||||
display: inline-block;
|
||||
padding: 0;
|
||||
}
|
||||
.nav li.selected {
|
||||
background-color: #222;
|
||||
font-weight: bold;
|
||||
}
|
||||
.nav-right {
|
||||
display: flex;
|
||||
text-align: right;
|
||||
vertical-align: middle;
|
||||
line-height: 0;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.nav-right .share-btn {
|
||||
display: none;
|
||||
}
|
||||
.nav-right .small-share-btn {
|
||||
display: none;
|
||||
}
|
||||
.footer {
|
||||
padding: 2em;
|
||||
border-top: 1px solid #d4d4d4;
|
||||
margin-top: 2em;
|
||||
color: gray;
|
||||
font-size: .9em;
|
||||
}
|
||||
a.heading-anchor {
|
||||
display: inline-block;
|
||||
opacity: 0;
|
||||
width: 1.3em;
|
||||
font-size: 0.7em;
|
||||
margin-left: 0.4em;
|
||||
line-height: 1em;
|
||||
text-decoration: none;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
a.heading-anchor:hover,
|
||||
h1:hover a.heading-anchor,
|
||||
h2:hover a.heading-anchor,
|
||||
h3:hover a.heading-anchor,
|
||||
h4:hover a.heading-anchor,
|
||||
h5:hover a.heading-anchor,
|
||||
h6:hover a.heading-anchor {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
.content{
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#toc{
|
||||
display: block!important;
|
||||
align-self: flex-start;
|
||||
width: 300px;
|
||||
position: sticky; top: 20px; left: 0;
|
||||
}
|
||||
|
||||
.main{
|
||||
width: calc(100% - 300px);
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-links {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
border-top: 1px solid #d4d4d4;
|
||||
margin-top: 30px;
|
||||
padding-top: 25px;
|
||||
}
|
||||
|
||||
@media all and (min-width: 400px) {
|
||||
.nav-right .share-btn {
|
||||
display: inline-block;
|
||||
}
|
||||
.nav-right .small-share-btn {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="container root page-changelog_android">
|
||||
|
||||
<div class="header">
|
||||
<a class="forkme" href="https://github.com/laurent22/joplin"><img src="https://joplinapp.org/images/ForkMe.png"/></a>
|
||||
<a href="https://joplinapp.org"><h1 class="title"><img class="title-icon" src="https://joplinapp.org/images/Icon512.png"><span class="title-text">Joplin</span></h1></a>
|
||||
<p class="sub-title">An open source note taking and to-do application with synchronisation capabilities</p>
|
||||
</div>
|
||||
|
||||
<div class="nav-wrapper">
|
||||
<div class="nav">
|
||||
<ul>
|
||||
<li class=""><a href="https://joplinapp.org/" title="Home"><i class="fa fa-home"></i></a></li>
|
||||
<li><a href="https://discourse.joplinapp.org" title="Forum">Forum</a></li>
|
||||
<li><a class="gsoc" href="https://joplinapp.org/gsoc2021/index/" title="Google Summer of Code 2021">GSoC 2021</a></li>
|
||||
</ul>
|
||||
<div class="nav-right">
|
||||
<iframe class="share-btn share-btn-github" src="https://ghbtns.com/github-btn.html?user=laurent22&repo=joplin&type=star&count=true" frameborder="0" scrolling="0" width="115px" height="20px"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div id="toc"><ul>
|
||||
<li>
|
||||
<p>Applications</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/desktop/">Desktop application</a></li>
|
||||
<li><a href="https://joplinapp.org/mobile/">Mobile applications</a></li>
|
||||
<li><a href="https://joplinapp.org/terminal/">Terminal application</a></li>
|
||||
<li><a href="https://joplinapp.org/clipper/">Web Clipper</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p>Support</p>
|
||||
<ul>
|
||||
<li><a href="https://discourse.joplinapp.org">Joplin Forum</a></li>
|
||||
<li><a href="https://joplinapp.org/markdown/">Markdown Guide</a></li>
|
||||
<li><a href="https://joplinapp.org/e2ee/">How to enable end-to-end encryption</a></li>
|
||||
<li><a href="https://joplinapp.org/conflict/">What is a conflict?</a></li>
|
||||
<li><a href="https://joplinapp.org/debugging/">How to enable debug mode</a></li>
|
||||
<li><a href="https://joplinapp.org/rich_text_editor/">About the Rich Text editor limitations</a></li>
|
||||
<li><a href="https://joplinapp.org/faq/">FAQ</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p>Joplin API - Get Started</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/api/overview/">Joplin API Overview</a></li>
|
||||
<li><a href="https://joplinapp.org/api/get_started/plugins/">Plugin development</a></li>
|
||||
<li><a href="https://joplinapp.org/api/tutorials/toc_plugin/">Plugin tutorial</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p>Joplin API - References</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/api/references/plugin_api/classes/joplin.html">Plugin API</a></li>
|
||||
<li><a href="https://joplinapp.org/api/references/rest_api/">Data API</a></li>
|
||||
<li><a href="https://joplinapp.org/api/references/plugin_manifest/">Plugin manifest</a></li>
|
||||
<li><a href="https://joplinapp.org/api/references/plugin_loading_rules/">Plugin loading rules</a></li>
|
||||
<li><a href="https://joplinapp.org/api/references/plugin_theming/">Plugin theming</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p>Development</p>
|
||||
<ul>
|
||||
<li><a href="https://github.com/laurent22/joplin/blob/dev/BUILD.md">How to build the apps</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/e2ee/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/history/">Note History spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/sync_lock/">Sync Lock spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/plugins/">Plugin Architecture spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/search_sorting/">Search Sorting spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/server_file_url_format/">Server: File URL Format</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/server_delta_sync/">Server: Delta Sync</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/server_sharing/">Server: Sharing</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p>Google Summer of Code 2021</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/gsoc2021/index/">Google Summer of Code 2021</a></li>
|
||||
<li><a href="https://joplinapp.org/gsoc2021/pull_request_guidelines/">How to submit a GSoC pull request</a></li>
|
||||
<li><a href="https://joplinapp.org/gsoc2021/ideas/">Project Ideas</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p>About</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/changelog/">Changelog (Desktop App)</a></li>
|
||||
<li><a href="https://joplinapp.org/changelog_cli/">Changelog (CLI App)</a></li>
|
||||
<li><a href="https://joplinapp.org/changelog_server/">Changelog (Server)</a></li>
|
||||
<li><a href="https://joplinapp.org/stats/">Stats</a></li>
|
||||
<li><a href="https://joplinapp.org/donate/">Donate</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="main">
|
||||
<p><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=E8JMYD2LQ8MMA&lc=GB&item_name=Joplin+Development&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"><img src="https://joplinapp.org/images/badges/Donate-PayPal-green.svg" alt="Donate using PayPal"></a> <a href="https://github.com/sponsors/laurent22/"><img src="https://joplinapp.org/images/badges/GitHub-Badge.svg" alt="Sponsor on GitHub"></a> <a href="https://www.patreon.com/joplin"><img src="https://joplinapp.org/images/badges/Patreon-Badge.svg" alt="Become a patron"></a> <a href="https://joplinapp.org/donate/#donations"><img src="https://joplinapp.org/images/badges/Donate-IBAN.svg" alt="Donate using IBAN"></a></p>
|
||||
<hr>
|
||||
<h1>Joplin Android app changelog<a name="joplin-android-app-changelog" href="#joplin-android-app-changelog" class="heading-anchor">🔗</a></h1>
|
||||
|
||||
<div class="bottom-links">
|
||||
<a href="https://github.com/laurent22/joplin/blob/dev/readme/changelog_android.md">
|
||||
<i class="fa fa-github"></i> Improve this doc
|
||||
</a>
|
||||
</div>
|
||||
<script>
|
||||
function stickyHeader() {
|
||||
return; // Disabled
|
||||
|
||||
if ($(window).scrollTop() > 179) {
|
||||
$('.nav').addClass('sticky');
|
||||
} else {
|
||||
$('.nav').removeClass('sticky');
|
||||
}
|
||||
}
|
||||
|
||||
$(window).scroll(function() {
|
||||
stickyHeader();
|
||||
});
|
||||
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', 'UA-103586105-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
</script>
|
||||
|
||||
</div></div>
|
||||
|
||||
<div class="footer">
|
||||
Copyright (C) 2016-2021 Laurent Cozic
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -405,6 +405,16 @@ https://github.com/laurent22/joplin/blob/dev/readme/changelog_server.md
|
||||
<p><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=E8JMYD2LQ8MMA&lc=GB&item_name=Joplin+Development&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"><img src="https://joplinapp.org/images/badges/Donate-PayPal-green.svg" alt="Donate using PayPal"></a> <a href="https://github.com/sponsors/laurent22/"><img src="https://joplinapp.org/images/badges/GitHub-Badge.svg" alt="Sponsor on GitHub"></a> <a href="https://www.patreon.com/joplin"><img src="https://joplinapp.org/images/badges/Patreon-Badge.svg" alt="Become a patron"></a> <a href="https://joplinapp.org/donate/#donations"><img src="https://joplinapp.org/images/badges/Donate-IBAN.svg" alt="Donate using IBAN"></a></p>
|
||||
<hr>
|
||||
<h1>Joplin Server Changelog<a name="joplin-server-changelog" href="#joplin-server-changelog" class="heading-anchor">🔗</a></h1>
|
||||
<h2><a href="https://github.com/laurent22/joplin/releases/tag/server-v2.0.1">server-v2.0.1</a> (Pre-release) - 2021-05-14T13:55:45Z<a name="server-v2-0-1-https-github-com-laurent22-joplin-releases-tag-server-v2-0-1-pre-release-2021-05-14t13-55-45z" href="#server-v2-0-1-https-github-com-laurent22-joplin-releases-tag-server-v2-0-1-pre-release-2021-05-14t13-55-45z" class="heading-anchor">🔗</a></h2>
|
||||
<ul>
|
||||
<li>New: Add support for sharing notes via a link (ccbc329)</li>
|
||||
<li>New: Add support for sharing a folder (#4772)</li>
|
||||
<li>New: Added log page to view latest changes to files (874f301)</li>
|
||||
<li>Fixed: Prevent new user password from being hashed twice (76c143e)</li>
|
||||
<li>Fixed: Fixed crash when rendering note with links to non-existing resources or notes (07484de)</li>
|
||||
<li>Fixed: Fixed error handling when no session is provided (63a5bfa)</li>
|
||||
<li>Fixed: Fixed uploading empty file to the API (#4402)</li>
|
||||
</ul>
|
||||
<h2><a href="https://github.com/laurent22/joplin/releases/tag/server-v1.7.2">server-v1.7.2</a> - 2021-01-24T19:11:10Z<a name="server-v1-7-2-https-github-com-laurent22-joplin-releases-tag-server-v1-7-2-2021-01-24t19-11-10z" href="#server-v1-7-2-https-github-com-laurent22-joplin-releases-tag-server-v1-7-2-2021-01-24t19-11-10z" class="heading-anchor">🔗</a></h2>
|
||||
<ul>
|
||||
<li>Fixed: Fixed password hashing when changing password</li>
|
||||
|
||||
@@ -424,19 +424,19 @@ https://github.com/laurent22/joplin/blob/dev/README.md
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Windows (32 and 64-bit)</td>
|
||||
<td><a href='https://github.com/laurent22/joplin/releases/download/v1.7.11/Joplin-Setup-1.7.11.exe'><img alt='Get it on Windows' width="134px" src='https://joplinapp.org/images/BadgeWindows.png'/></a></td>
|
||||
<td><a href='https://github.com/laurent22/joplin/releases/download/v1.8.5/Joplin-Setup-1.8.5.exe'><img alt='Get it on Windows' width="134px" src='https://joplinapp.org/images/BadgeWindows.png'/></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>macOS</td>
|
||||
<td><a href='https://github.com/laurent22/joplin/releases/download/v1.7.11/Joplin-1.7.11.dmg'><img alt='Get it on macOS' width="134px" src='https://joplinapp.org/images/BadgeMacOS.png'/></a></td>
|
||||
<td><a href='https://github.com/laurent22/joplin/releases/download/v1.8.5/Joplin-1.8.5.dmg'><img alt='Get it on macOS' width="134px" src='https://joplinapp.org/images/BadgeMacOS.png'/></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Linux</td>
|
||||
<td><a href='https://github.com/laurent22/joplin/releases/download/v1.7.11/Joplin-1.7.11.AppImage'><img alt='Get it on Linux' width="134px" src='https://joplinapp.org/images/BadgeLinux.png'/></a></td>
|
||||
<td><a href='https://github.com/laurent22/joplin/releases/download/v1.8.5/Joplin-1.8.5.AppImage'><img alt='Get it on Linux' width="134px" src='https://joplinapp.org/images/BadgeLinux.png'/></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><strong>On Windows</strong>, you may also use the <a href='https://github.com/laurent22/joplin/releases/download/v1.7.11/JoplinPortable.exe'>Portable version</a>. The <a href="https://en.wikipedia.org/wiki/Portable_application">portable application</a> allows installing the software on a portable device such as a USB key. Simply copy the file JoplinPortable.exe in any directory on that USB key ; the application will then create a directory called "JoplinProfile" next to the executable file.</p>
|
||||
<p><strong>On Windows</strong>, you may also use the <a href='https://github.com/laurent22/joplin/releases/download/v1.8.5/JoplinPortable.exe'>Portable version</a>. The <a href="https://en.wikipedia.org/wiki/Portable_application">portable application</a> allows installing the software on a portable device such as a USB key. Simply copy the file JoplinPortable.exe in any directory on that USB key ; the application will then create a directory called "JoplinProfile" next to the executable file.</p>
|
||||
<p><strong>On Linux</strong>, the recommended way is to use the following installation script as it will handle the desktop icon too:</p>
|
||||
<pre><code style="word-break: break-all">wget -O - https://raw.githubusercontent.com/laurent22/joplin/dev/Joplin_install_and_update.sh | bash</code></pre>
|
||||
<h2>Mobile applications<a name="mobile-applications" href="#mobile-applications" class="heading-anchor">🔗</a></h2>
|
||||
@@ -662,7 +662,7 @@ Joplin is also capable of exporting to a number of other formats including HTML
|
||||
"s3:DeleteObject",
|
||||
"s3:DeleteObjectVersion",
|
||||
"s3:PutObject"
|
||||
]
|
||||
],
|
||||
"Resource": [
|
||||
"arn:aws:s3:::joplin-bucket",
|
||||
"arn:aws:s3:::joplin-bucket/*"
|
||||
@@ -692,7 +692,7 @@ Joplin is also capable of exporting to a number of other formats including HTML
|
||||
<ul>
|
||||
<li><strong>Windows</strong>: >= 8. Make sure the Action Center is enabled on Windows. Task bar balloon for Windows < 8. Growl as fallback. Growl takes precedence over Windows balloons.</li>
|
||||
<li><strong>macOS</strong>: >= 10.8 or Growl if earlier.</li>
|
||||
<li><strong>Linux</strong>: <code>notify-osd</code> or <code>libnotify-bin</code> installed (Ubuntu should have this by default). Growl otherwise</li>
|
||||
<li><strong>Linux</strong>: <code>notify-send</code> tool, delivered through packages <code>notify-osd</code>, <code>libnotify-bin</code> or <code>libnotify-tools</code>. GNOME should have this by default, but install <code>libnotify-tools</code> if using KDE Plasma.</li>
|
||||
</ul>
|
||||
<p>See <a href="https://github.com/mikaelbr/node-notifier/blob/master/DECISION_FLOW.md">documentation and flow chart for reporter choice</a></p>
|
||||
<p>On mobile, the alarms will be displayed using the built-in notification system.</p>
|
||||
@@ -989,49 +989,49 @@ Eg. <code>:search -- "-tag:tag1"</code>.</p>
|
||||
<td>Arabic</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ar.po">ar</a></td>
|
||||
<td><a href="mailto:Whaell@protonmail.com">Whaell O</a></td>
|
||||
<td>99%</td>
|
||||
<td>96%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/es/basque_country.png" alt=""></td>
|
||||
<td>Basque</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eu.po">eu</a></td>
|
||||
<td>juan.abasolo@ehu.eus</td>
|
||||
<td>31%</td>
|
||||
<td>30%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/ba.png" alt=""></td>
|
||||
<td>Bosnian (Bosna i Hercegovina)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bs_BA.po">bs_BA</a></td>
|
||||
<td><a href="mailto:dervis.t@pm.me">Derviš T.</a></td>
|
||||
<td>74%</td>
|
||||
<td>75%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/bg.png" alt=""></td>
|
||||
<td>Bulgarian (България)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bg_BG.po">bg_BG</a></td>
|
||||
<td></td>
|
||||
<td>60%</td>
|
||||
<td>58%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/es/catalonia.png" alt=""></td>
|
||||
<td>Catalan</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ca.po">ca</a></td>
|
||||
<td>jmontane, 2019</td>
|
||||
<td>85%</td>
|
||||
<td>83%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/hr.png" alt=""></td>
|
||||
<td>Croatian (Hrvatska)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hr_HR.po">hr_HR</a></td>
|
||||
<td><a href="mailto:mail@milotype.de">Milo Ivir</a></td>
|
||||
<td>99%</td>
|
||||
<td>96%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/cz.png" alt=""></td>
|
||||
<td>Czech (Česká republika)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/cs_CZ.po">cs_CZ</a></td>
|
||||
<td><a href="mailto:lukas@aiya.cz">Lukas Helebrandt</a></td>
|
||||
<td>89%</td>
|
||||
<td>86%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/dk.png" alt=""></td>
|
||||
@@ -1045,14 +1045,14 @@ Eg. <code>:search -- "-tag:tag1"</code>.</p>
|
||||
<td>Deutsch (Deutschland)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/de_DE.po">de_DE</a></td>
|
||||
<td><a href="mailto:atalanttore@googlemail.com">Atalanttore</a></td>
|
||||
<td>98%</td>
|
||||
<td>95%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/ee.png" alt=""></td>
|
||||
<td>Eesti Keel (Eesti)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/et_EE.po">et_EE</a></td>
|
||||
<td></td>
|
||||
<td>58%</td>
|
||||
<td>57%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/gb.png" alt=""></td>
|
||||
@@ -1073,203 +1073,203 @@ Eg. <code>:search -- "-tag:tag1"</code>.</p>
|
||||
<td>Español (España)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/es_ES.po">es_ES</a></td>
|
||||
<td><a href="mailto:mario.campo@gmail.com">Mario Campo</a></td>
|
||||
<td>97%</td>
|
||||
<td>94%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/esperanto.png" alt=""></td>
|
||||
<td>Esperanto</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eo.po">eo</a></td>
|
||||
<td>Marton Paulo</td>
|
||||
<td>34%</td>
|
||||
<td>33%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/fi.png" alt=""></td>
|
||||
<td>Finnish (Suomi)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fi_FI.po">fi_FI</a></td>
|
||||
<td>mrkaato</td>
|
||||
<td>97%</td>
|
||||
<td>94%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/fr.png" alt=""></td>
|
||||
<td>Français (France)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fr_FR.po">fr_FR</a></td>
|
||||
<td>Laurent Cozic</td>
|
||||
<td>95%</td>
|
||||
<td>99%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/es/galicia.png" alt=""></td>
|
||||
<td>Galician (España)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/gl_ES.po">gl_ES</a></td>
|
||||
<td><a href="mailto:marcoslansgarza@gmail.com">Marcos Lans</a></td>
|
||||
<td>39%</td>
|
||||
<td>38%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/id.png" alt=""></td>
|
||||
<td>Indonesian (Indonesia)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/id_ID.po">id_ID</a></td>
|
||||
<td><a href="mailto:42007357+eresytter@users.noreply.github.com">eresytter</a></td>
|
||||
<td>96%</td>
|
||||
<td>93%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/it.png" alt=""></td>
|
||||
<td>Italiano (Italia)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/it_IT.po">it_IT</a></td>
|
||||
<td><a href="mailto:mailfilledwithspam@gmail.com">Alessandro Bernardello</a></td>
|
||||
<td>97%</td>
|
||||
<td>94%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/hu.png" alt=""></td>
|
||||
<td>Magyar (Magyarország)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hu_HU.po">hu_HU</a></td>
|
||||
<td><a href="mailto:mail@szokesandor.hu">Szőke Sándor</a></td>
|
||||
<td>91%</td>
|
||||
<td>88%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/be.png" alt=""></td>
|
||||
<td>Nederlands (België, Belgique, Belgien)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_BE.po">nl_BE</a></td>
|
||||
<td></td>
|
||||
<td>95%</td>
|
||||
<td>92%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/nl.png" alt=""></td>
|
||||
<td>Nederlands (Nederland)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_NL.po">nl_NL</a></td>
|
||||
<td><a href="mailto:metbril@users.noreply.github.com">MetBril</a></td>
|
||||
<td>98%</td>
|
||||
<td>95%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/no.png" alt=""></td>
|
||||
<td>Norwegian (Norge, Noreg)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nb_NO.po">nb_NO</a></td>
|
||||
<td><a href="mailto:code@mxe.no">Mats Estensen</a></td>
|
||||
<td>78%</td>
|
||||
<td>76%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/ir.png" alt=""></td>
|
||||
<td>Persian</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fa.po">fa</a></td>
|
||||
<td><a href="mailto:kourox@protonmail.com">Kourosh Firoozbakht</a></td>
|
||||
<td>74%</td>
|
||||
<td>71%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/pl.png" alt=""></td>
|
||||
<td>Polski (Polska)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pl_PL.po">pl_PL</a></td>
|
||||
<td><a href="mailto:hello.konhi@gmail.com">konhi</a></td>
|
||||
<td>97%</td>
|
||||
<td>94%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/br.png" alt=""></td>
|
||||
<td>Português (Brasil)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_BR.po">pt_BR</a></td>
|
||||
<td><a href="mailto:nicolas.suzuki@pm.me">Nicolas Suzuki</a></td>
|
||||
<td>97%</td>
|
||||
<td>94%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/pt.png" alt=""></td>
|
||||
<td>Português (Portugal)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_PT.po">pt_PT</a></td>
|
||||
<td><a href="mailto:dcaveiro@yahoo.com">Diogo Caveiro</a></td>
|
||||
<td>97%</td>
|
||||
<td>94%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/ro.png" alt=""></td>
|
||||
<td>Română</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ro.po">ro</a></td>
|
||||
<td><a href="mailto:cristi.duluta@gmail.com">Cristi Duluta</a></td>
|
||||
<td>68%</td>
|
||||
<td>66%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/si.png" alt=""></td>
|
||||
<td>Slovenian (Slovenija)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sl_SI.po">sl_SI</a></td>
|
||||
<td><a href="mailto:martin.korelic@protonmail.com">Martin Korelič</a></td>
|
||||
<td>99%</td>
|
||||
<td>96%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/se.png" alt=""></td>
|
||||
<td>Svenska</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sv.po">sv</a></td>
|
||||
<td><a href="mailto:jonatan@autistici.org">Jonatan Nyberg</a></td>
|
||||
<td>63%</td>
|
||||
<td>61%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/th.png" alt=""></td>
|
||||
<td>Thai (ประเทศไทย)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/th_TH.po">th_TH</a></td>
|
||||
<td></td>
|
||||
<td>47%</td>
|
||||
<td>45%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/vi.png" alt=""></td>
|
||||
<td>Tiếng Việt</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/vi.po">vi</a></td>
|
||||
<td></td>
|
||||
<td>75%</td>
|
||||
<td>73%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/tr.png" alt=""></td>
|
||||
<td>Türkçe (Türkiye)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/tr_TR.po">tr_TR</a></td>
|
||||
<td><a href="mailto:arda@kilicdagi.com">Arda Kılıçdağı</a></td>
|
||||
<td>97%</td>
|
||||
<td>94%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/ua.png" alt=""></td>
|
||||
<td>Ukrainian (Україна)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/uk_UA.po">uk_UA</a></td>
|
||||
<td><a href="mailto:vandreykiv@gmail.com">Vyacheslav Andreykiv</a></td>
|
||||
<td>97%</td>
|
||||
<td>94%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/gr.png" alt=""></td>
|
||||
<td>Ελληνικά (Ελλάδα)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/el_GR.po">el_GR</a></td>
|
||||
<td><a href="mailto:xaris@tuta.io">Harris Arvanitis</a></td>
|
||||
<td>85%</td>
|
||||
<td>97%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/ru.png" alt=""></td>
|
||||
<td>Русский (Россия)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ru_RU.po">ru_RU</a></td>
|
||||
<td><a href="mailto:thesermanarm@gmail.com">Sergey Segeda</a></td>
|
||||
<td>97%</td>
|
||||
<td>94%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/rs.png" alt=""></td>
|
||||
<td>српски језик (Србија)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sr_RS.po">sr_RS</a></td>
|
||||
<td></td>
|
||||
<td>73%</td>
|
||||
<td>71%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/cn.png" alt=""></td>
|
||||
<td>中文 (简体)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_CN.po">zh_CN</a></td>
|
||||
<td><a href="mailto:zyangmath@gmail.com">Yang Zhang</a></td>
|
||||
<td>97%</td>
|
||||
<td>94%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/tw.png" alt=""></td>
|
||||
<td>中文 (繁體)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_TW.po">zh_TW</a></td>
|
||||
<td><a href="mailto:yaozeye@yahoo.co.jp">Yaoze Ye</a></td>
|
||||
<td>95%</td>
|
||||
<td>92%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/jp.png" alt=""></td>
|
||||
<td>日本語 (日本)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ja_JP.po">ja_JP</a></td>
|
||||
<td><a href="mailto:genneko217@gmail.com">genneko</a></td>
|
||||
<td>98%</td>
|
||||
<td>97%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/kr.png" alt=""></td>
|
||||
<td>한국어</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ko.po">ko</a></td>
|
||||
<td><a href="mailto:potatogim@potatogim.net">Ji-Hyeon Gim</a></td>
|
||||
<td>97%</td>
|
||||
<td>96%</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -101,15 +101,10 @@
|
||||
"default": "",
|
||||
"description": "Joplin Server URL. Attention: If you change this location, make sure you copy all your content to it before syncing, otherwise all files will be removed! See the FAQ for more details: https://joplinapp.org/faq/"
|
||||
},
|
||||
"sync.9.directory": {
|
||||
"type": "string",
|
||||
"default": "Apps/Joplin",
|
||||
"description": "Joplin Server Directory"
|
||||
},
|
||||
"sync.9.username": {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"description": "Joplin Server username"
|
||||
"description": "Joplin Server email"
|
||||
},
|
||||
"sync.9.password": {
|
||||
"type": "string",
|
||||
@@ -602,6 +597,11 @@
|
||||
"default": -1,
|
||||
"$comment": "private"
|
||||
},
|
||||
"sync.userId": {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"$comment": "private"
|
||||
},
|
||||
"style.zoom": {
|
||||
"type": "integer",
|
||||
"default": 100,
|
||||
@@ -633,7 +633,7 @@
|
||||
},
|
||||
"autoUpdateEnabled": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"default": true,
|
||||
"description": "Automatically update the application"
|
||||
},
|
||||
"autoUpdate.includePreReleases": {
|
||||
@@ -726,12 +726,6 @@
|
||||
"description": "Enable spell checking in Markdown editor? (WARNING BETA feature). Spell checker in the Markdown editor was previously unstable (cursor location was not stable, sometimes edits would not be saved or reflected in the viewer, etc.) however it appears to be more reliable now. If you notice any issue, please report it on GitHub or the Joplin Forum (Help -> Joplin Forum)",
|
||||
"$comment": "private"
|
||||
},
|
||||
"image.noresizing": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Do not resize images",
|
||||
"$comment": "private"
|
||||
},
|
||||
"net.customCertificates": {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -33,8 +33,7 @@ module.exports = {
|
||||
'<rootDir>/node_modules/',
|
||||
'<rootDir>/tests/support/',
|
||||
'<rootDir>/build/',
|
||||
'<rootDir>/tests/test-utils.js',
|
||||
'<rootDir>/tests/test-utils-synchronizer.js',
|
||||
'<rootDir>/tests/testUtils.js',
|
||||
'<rootDir>/tests/tmp/',
|
||||
'<rootDir>/tests/test data/',
|
||||
],
|
||||
|
||||
@@ -1,4 +1,17 @@
|
||||
const { afterEachCleanUp } = require('./tests/test-utils.js');
|
||||
const { afterEachCleanUp } = require('@joplin/lib/testing/test-utils.js');
|
||||
const { shimInit } = require('@joplin/lib/shim-init-node.js');
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
const sharp = require('sharp');
|
||||
|
||||
let keytar;
|
||||
try {
|
||||
keytar = shim.platformSupportsKeyChain() ? require('keytar') : null;
|
||||
} catch (error) {
|
||||
console.error('Cannot load keytar - keychain support will be disabled', error);
|
||||
keytar = null;
|
||||
}
|
||||
|
||||
shimInit(sharp, keytar);
|
||||
|
||||
global.afterEach(async () => {
|
||||
await afterEachCleanUp();
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
"@joplin/renderer": "1.8",
|
||||
"aws-sdk": "^2.588.0",
|
||||
"chalk": "^4.1.0",
|
||||
"clean-html": "^1.5.0",
|
||||
"compare-version": "^0.1.2",
|
||||
"fs-extra": "^5.0.0",
|
||||
"html-entities": "^1.2.1",
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
|
||||
const { setupDatabaseAndSynchronizer, switchClient } = require('./test-utils.js');
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
const { enexXmlToHtml } = require('@joplin/lib/import-enex-html-gen.js');
|
||||
const cleanHtml = require('clean-html');
|
||||
|
||||
const fileWithPath = (filename) =>
|
||||
`${__dirname}/enex_to_html/${filename}`;
|
||||
|
||||
const audioResource = {
|
||||
filename: 'audio test',
|
||||
id: '9168ee833d03c5ea7c730ac6673978c1',
|
||||
mime: 'audio/x-m4a',
|
||||
size: 82011,
|
||||
title: 'audio test',
|
||||
};
|
||||
|
||||
// All the test HTML files are beautified ones, so we need to run
|
||||
// this before the comparison. Before, beautifying was done by `enexXmlToHtml`
|
||||
// but that was removed due to problems with the clean-html package.
|
||||
const beautifyHtml = (html) => {
|
||||
return new Promise((resolve) => {
|
||||
try {
|
||||
cleanHtml.clean(html, { wrap: 0 }, (...cleanedHtml) => resolve(cleanedHtml.join('')));
|
||||
} catch (error) {
|
||||
console.warn(`Could not clean HTML - the "unclean" version will be used: ${error.message}: ${html.trim().substr(0, 512).replace(/[\n\r]/g, ' ')}...`);
|
||||
resolve([html].join(''));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Tests the importer for a single note, checking that the result of
|
||||
* processing the given `.enex` input file matches the contents of the given
|
||||
* `.html` file.
|
||||
*
|
||||
* Note that this does not test the importing of an entire exported `.enex`
|
||||
* archive, but rather a single node of such a file. Thus, the test data files
|
||||
* (e.g. `./enex_to_html/code1.enex`) correspond to the contents of a single
|
||||
* `<note>...</note>` node in an `.enex` file already extracted from
|
||||
* `<content><![CDATA[...]]</content>`.
|
||||
*/
|
||||
const compareOutputToExpected = (options) => {
|
||||
const inputFile = fileWithPath(`${options.testName}.enex`);
|
||||
const outputFile = fileWithPath(`${options.testName}.html`);
|
||||
const testTitle = `should convert from Enex to Html: ${options.testName}`;
|
||||
|
||||
it(testTitle, (async () => {
|
||||
const enexInput = await shim.fsDriver().readFile(inputFile);
|
||||
const expectedOutput = await shim.fsDriver().readFile(outputFile);
|
||||
const actualOutput = await beautifyHtml(await enexXmlToHtml(enexInput, options.resources));
|
||||
|
||||
expect(actualOutput).toEqual(expectedOutput);
|
||||
}));
|
||||
};
|
||||
|
||||
describe('EnexToHtml', function() {
|
||||
beforeEach(async (done) => {
|
||||
await setupDatabaseAndSynchronizer(1);
|
||||
await switchClient(1);
|
||||
done();
|
||||
});
|
||||
|
||||
compareOutputToExpected({
|
||||
testName: 'checklist-list',
|
||||
resources: [],
|
||||
});
|
||||
|
||||
compareOutputToExpected({
|
||||
testName: 'svg',
|
||||
resources: [],
|
||||
});
|
||||
|
||||
compareOutputToExpected({
|
||||
testName: 'en-media--image',
|
||||
resources: [{
|
||||
filename: '',
|
||||
id: '89ce7da62c6b2832929a6964237e98e9', // Mock id
|
||||
mime: 'image/jpeg',
|
||||
size: 50347,
|
||||
title: '',
|
||||
}],
|
||||
});
|
||||
|
||||
compareOutputToExpected({
|
||||
testName: 'en-media--audio',
|
||||
resources: [audioResource],
|
||||
});
|
||||
|
||||
compareOutputToExpected({
|
||||
testName: 'attachment',
|
||||
resources: [{
|
||||
filename: 'attachment-1',
|
||||
id: '21ca2b948f222a38802940ec7e2e5de3',
|
||||
mime: 'application/pdf', // Any non-image/non-audio mime type will do
|
||||
size: 1000,
|
||||
}],
|
||||
});
|
||||
|
||||
// it('fails when not given a matching resource', (async () => {
|
||||
// // To test the promise-unexpectedly-resolved case, add `audioResource` to the array.
|
||||
// const resources = [];
|
||||
// const inputFile = fileWithPath('en-media--image.enex');
|
||||
// const enexInput = await shim.fsDriver().readFile(inputFile);
|
||||
// const promisedOutput = enexXmlToHtml(enexInput, resources);
|
||||
|
||||
// promisedOutput.then(() => {
|
||||
// // Promise should not be resolved
|
||||
// expect(false).toEqual(true);
|
||||
// }, (reason) => {
|
||||
// expect(reason)
|
||||
// .toBe('Hash with no associated resource: 89ce7da62c6b2832929a6964237e98e9');
|
||||
// });
|
||||
// }));
|
||||
|
||||
});
|
||||
@@ -4,7 +4,7 @@
|
||||
const os = require('os');
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { filename } = require('@joplin/lib/path-utils');
|
||||
const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('./test-utils.js');
|
||||
const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('@joplin/lib/testing/test-utils.js');
|
||||
const Folder = require('@joplin/lib/models/Folder').default;
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import MdToHtml from '@joplin/renderer/MdToHtml';
|
||||
const os = require('os');
|
||||
const { filename } = require('@joplin/lib/path-utils');
|
||||
const { setupDatabaseAndSynchronizer, switchClient } = require('./test-utils.js');
|
||||
const { setupDatabaseAndSynchronizer, switchClient } = require('@joplin/lib/testing/test-utils.js');
|
||||
import shim from '@joplin/lib/shim';
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const mdImporterService = require('@joplin/lib/services/interop/InteropService_Importer_Md').default;
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
const { setupDatabaseAndSynchronizer, switchClient } = require('./test-utils.js');
|
||||
const { setupDatabaseAndSynchronizer, switchClient } = require('@joplin/lib/testing/test-utils.js');
|
||||
|
||||
const importer = new mdImporterService();
|
||||
|
||||
|
||||
@@ -1,290 +0,0 @@
|
||||
'use strict';
|
||||
const __awaiter = (this && this.__awaiter) || function(thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function(resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function(resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator['throw'](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
const Setting_1 = require('@joplin/lib/models/Setting');
|
||||
const test_utils_synchronizer_1 = require('./test-utils-synchronizer');
|
||||
const { syncTargetName, afterAllCleanUp, synchronizerStart, setupDatabaseAndSynchronizer, synchronizer, sleep, switchClient, syncTargetId, fileApi } = require('./test-utils.js');
|
||||
const Folder_1 = require('@joplin/lib/models/Folder');
|
||||
const Note_1 = require('@joplin/lib/models/Note');
|
||||
const BaseItem_1 = require('@joplin/lib/models/BaseItem');
|
||||
const WelcomeUtils = require('@joplin/lib/WelcomeUtils');
|
||||
describe('Synchronizer.basics', function() {
|
||||
beforeEach((done) => __awaiter(this, void 0, void 0, function* () {
|
||||
yield setupDatabaseAndSynchronizer(1);
|
||||
yield setupDatabaseAndSynchronizer(2);
|
||||
yield switchClient(1);
|
||||
done();
|
||||
}));
|
||||
afterAll(() => __awaiter(this, void 0, void 0, function* () {
|
||||
yield afterAllCleanUp();
|
||||
}));
|
||||
it('should create remote items', (() => __awaiter(this, void 0, void 0, function* () {
|
||||
const folder = yield Folder_1.default.save({ title: 'folder1' });
|
||||
yield Note_1.default.save({ title: 'un', parent_id: folder.id });
|
||||
const all = yield test_utils_synchronizer_1.allNotesFolders();
|
||||
yield synchronizerStart();
|
||||
yield test_utils_synchronizer_1.localNotesFoldersSameAsRemote(all, expect);
|
||||
})));
|
||||
it('should update remote items', (() => __awaiter(this, void 0, void 0, function* () {
|
||||
const folder = yield Folder_1.default.save({ title: 'folder1' });
|
||||
const note = yield Note_1.default.save({ title: 'un', parent_id: folder.id });
|
||||
yield synchronizerStart();
|
||||
yield Note_1.default.save({ title: 'un UPDATE', id: note.id });
|
||||
const all = yield test_utils_synchronizer_1.allNotesFolders();
|
||||
yield synchronizerStart();
|
||||
yield test_utils_synchronizer_1.localNotesFoldersSameAsRemote(all, expect);
|
||||
})));
|
||||
it('should create local items', (() => __awaiter(this, void 0, void 0, function* () {
|
||||
const folder = yield Folder_1.default.save({ title: 'folder1' });
|
||||
yield Note_1.default.save({ title: 'un', parent_id: folder.id });
|
||||
yield synchronizerStart();
|
||||
yield switchClient(2);
|
||||
yield synchronizerStart();
|
||||
const all = yield test_utils_synchronizer_1.allNotesFolders();
|
||||
yield test_utils_synchronizer_1.localNotesFoldersSameAsRemote(all, expect);
|
||||
})));
|
||||
it('should update local items', (() => __awaiter(this, void 0, void 0, function* () {
|
||||
const folder1 = yield Folder_1.default.save({ title: 'folder1' });
|
||||
const note1 = yield Note_1.default.save({ title: 'un', parent_id: folder1.id });
|
||||
yield synchronizerStart();
|
||||
yield switchClient(2);
|
||||
yield synchronizerStart();
|
||||
yield sleep(0.1);
|
||||
let note2 = yield Note_1.default.load(note1.id);
|
||||
note2.title = 'Updated on client 2';
|
||||
yield Note_1.default.save(note2);
|
||||
note2 = yield Note_1.default.load(note2.id);
|
||||
yield synchronizerStart();
|
||||
yield switchClient(1);
|
||||
yield synchronizerStart();
|
||||
const all = yield test_utils_synchronizer_1.allNotesFolders();
|
||||
yield test_utils_synchronizer_1.localNotesFoldersSameAsRemote(all, expect);
|
||||
})));
|
||||
it('should delete remote notes', (() => __awaiter(this, void 0, void 0, function* () {
|
||||
const folder1 = yield Folder_1.default.save({ title: 'folder1' });
|
||||
const note1 = yield Note_1.default.save({ title: 'un', parent_id: folder1.id });
|
||||
yield synchronizerStart();
|
||||
yield switchClient(2);
|
||||
yield synchronizerStart();
|
||||
yield sleep(0.1);
|
||||
yield Note_1.default.delete(note1.id);
|
||||
yield synchronizerStart();
|
||||
const remotes = yield test_utils_synchronizer_1.remoteNotesAndFolders();
|
||||
expect(remotes.length).toBe(1);
|
||||
expect(remotes[0].id).toBe(folder1.id);
|
||||
const deletedItems = yield BaseItem_1.default.deletedItems(syncTargetId());
|
||||
expect(deletedItems.length).toBe(0);
|
||||
})));
|
||||
it('should not created deleted_items entries for items deleted via sync', (() => __awaiter(this, void 0, void 0, function* () {
|
||||
const folder1 = yield Folder_1.default.save({ title: 'folder1' });
|
||||
yield Note_1.default.save({ title: 'un', parent_id: folder1.id });
|
||||
yield synchronizerStart();
|
||||
yield switchClient(2);
|
||||
yield synchronizerStart();
|
||||
yield Folder_1.default.delete(folder1.id);
|
||||
yield synchronizerStart();
|
||||
yield switchClient(1);
|
||||
yield synchronizerStart();
|
||||
const deletedItems = yield BaseItem_1.default.deletedItems(syncTargetId());
|
||||
expect(deletedItems.length).toBe(0);
|
||||
})));
|
||||
it('should delete local notes', (() => __awaiter(this, void 0, void 0, function* () {
|
||||
const folder1 = yield Folder_1.default.save({ title: 'folder1' });
|
||||
const note1 = yield Note_1.default.save({ title: 'un', parent_id: folder1.id });
|
||||
const note2 = yield Note_1.default.save({ title: 'deux', parent_id: folder1.id });
|
||||
yield synchronizerStart();
|
||||
yield switchClient(2);
|
||||
yield synchronizerStart();
|
||||
yield Note_1.default.delete(note1.id);
|
||||
yield synchronizerStart();
|
||||
yield switchClient(1);
|
||||
yield synchronizerStart();
|
||||
const items = yield test_utils_synchronizer_1.allNotesFolders();
|
||||
expect(items.length).toBe(2);
|
||||
const deletedItems = yield BaseItem_1.default.deletedItems(syncTargetId());
|
||||
expect(deletedItems.length).toBe(0);
|
||||
yield Note_1.default.delete(note2.id);
|
||||
yield synchronizerStart();
|
||||
})));
|
||||
it('should delete remote folder', (() => __awaiter(this, void 0, void 0, function* () {
|
||||
yield Folder_1.default.save({ title: 'folder1' });
|
||||
const folder2 = yield Folder_1.default.save({ title: 'folder2' });
|
||||
yield synchronizerStart();
|
||||
yield switchClient(2);
|
||||
yield synchronizerStart();
|
||||
yield sleep(0.1);
|
||||
yield Folder_1.default.delete(folder2.id);
|
||||
yield synchronizerStart();
|
||||
const all = yield test_utils_synchronizer_1.allNotesFolders();
|
||||
yield test_utils_synchronizer_1.localNotesFoldersSameAsRemote(all, expect);
|
||||
})));
|
||||
it('should delete local folder', (() => __awaiter(this, void 0, void 0, function* () {
|
||||
yield Folder_1.default.save({ title: 'folder1' });
|
||||
const folder2 = yield Folder_1.default.save({ title: 'folder2' });
|
||||
yield synchronizerStart();
|
||||
yield switchClient(2);
|
||||
yield synchronizerStart();
|
||||
yield Folder_1.default.delete(folder2.id);
|
||||
yield synchronizerStart();
|
||||
yield switchClient(1);
|
||||
yield synchronizerStart();
|
||||
const items = yield test_utils_synchronizer_1.allNotesFolders();
|
||||
yield test_utils_synchronizer_1.localNotesFoldersSameAsRemote(items, expect);
|
||||
})));
|
||||
it('should cross delete all folders', (() => __awaiter(this, void 0, void 0, function* () {
|
||||
// If client1 and 2 have two folders, client 1 deletes item 1 and client
|
||||
// 2 deletes item 2, they should both end up with no items after sync.
|
||||
const folder1 = yield Folder_1.default.save({ title: 'folder1' });
|
||||
const folder2 = yield Folder_1.default.save({ title: 'folder2' });
|
||||
yield synchronizerStart();
|
||||
yield switchClient(2);
|
||||
yield synchronizerStart();
|
||||
yield sleep(0.1);
|
||||
yield Folder_1.default.delete(folder1.id);
|
||||
yield switchClient(1);
|
||||
yield Folder_1.default.delete(folder2.id);
|
||||
yield synchronizerStart();
|
||||
yield switchClient(2);
|
||||
yield synchronizerStart();
|
||||
const items2 = yield test_utils_synchronizer_1.allNotesFolders();
|
||||
yield switchClient(1);
|
||||
yield synchronizerStart();
|
||||
const items1 = yield test_utils_synchronizer_1.allNotesFolders();
|
||||
expect(items1.length).toBe(0);
|
||||
expect(items1.length).toBe(items2.length);
|
||||
})));
|
||||
it('items should be downloaded again when user cancels in the middle of delta operation', (() => __awaiter(this, void 0, void 0, function* () {
|
||||
const folder1 = yield Folder_1.default.save({ title: 'folder1' });
|
||||
yield Note_1.default.save({ title: 'un', is_todo: 1, parent_id: folder1.id });
|
||||
yield synchronizerStart();
|
||||
yield switchClient(2);
|
||||
synchronizer().testingHooks_ = ['cancelDeltaLoop2'];
|
||||
yield synchronizerStart();
|
||||
let notes = yield Note_1.default.all();
|
||||
expect(notes.length).toBe(0);
|
||||
synchronizer().testingHooks_ = [];
|
||||
yield synchronizerStart();
|
||||
notes = yield Note_1.default.all();
|
||||
expect(notes.length).toBe(1);
|
||||
})));
|
||||
it('should skip items that cannot be synced', (() => __awaiter(this, void 0, void 0, function* () {
|
||||
const folder1 = yield Folder_1.default.save({ title: 'folder1' });
|
||||
const note1 = yield Note_1.default.save({ title: 'un', is_todo: 1, parent_id: folder1.id });
|
||||
const noteId = note1.id;
|
||||
yield synchronizerStart();
|
||||
let disabledItems = yield BaseItem_1.default.syncDisabledItems(syncTargetId());
|
||||
expect(disabledItems.length).toBe(0);
|
||||
yield Note_1.default.save({ id: noteId, title: 'un mod' });
|
||||
synchronizer().testingHooks_ = ['notesRejectedByTarget'];
|
||||
yield synchronizerStart();
|
||||
synchronizer().testingHooks_ = [];
|
||||
yield synchronizerStart(); // Another sync to check that this item is now excluded from sync
|
||||
yield switchClient(2);
|
||||
yield synchronizerStart();
|
||||
const notes = yield Note_1.default.all();
|
||||
expect(notes.length).toBe(1);
|
||||
expect(notes[0].title).toBe('un');
|
||||
yield switchClient(1);
|
||||
disabledItems = yield BaseItem_1.default.syncDisabledItems(syncTargetId());
|
||||
expect(disabledItems.length).toBe(1);
|
||||
})));
|
||||
it('should allow duplicate folder titles', (() => __awaiter(this, void 0, void 0, function* () {
|
||||
yield Folder_1.default.save({ title: 'folder' });
|
||||
yield switchClient(2);
|
||||
let remoteF2 = yield Folder_1.default.save({ title: 'folder' });
|
||||
yield synchronizerStart();
|
||||
yield switchClient(1);
|
||||
yield sleep(0.1);
|
||||
yield synchronizerStart();
|
||||
const localF2 = yield Folder_1.default.load(remoteF2.id);
|
||||
expect(localF2.title == remoteF2.title).toBe(true);
|
||||
// Then that folder that has been renamed locally should be set in such a way
|
||||
// that synchronizing it applies the title change remotely, and that new title
|
||||
// should be retrieved by client 2.
|
||||
yield synchronizerStart();
|
||||
yield switchClient(2);
|
||||
yield sleep(0.1);
|
||||
yield synchronizerStart();
|
||||
remoteF2 = yield Folder_1.default.load(remoteF2.id);
|
||||
expect(remoteF2.title == localF2.title).toBe(true);
|
||||
})));
|
||||
it('should create remote items with UTF-8 content', (() => __awaiter(this, void 0, void 0, function* () {
|
||||
const folder = yield Folder_1.default.save({ title: 'Fahrräder' });
|
||||
yield Note_1.default.save({ title: 'Fahrräder', body: 'Fahrräder', parent_id: folder.id });
|
||||
const all = yield test_utils_synchronizer_1.allNotesFolders();
|
||||
yield synchronizerStart();
|
||||
yield test_utils_synchronizer_1.localNotesFoldersSameAsRemote(all, expect);
|
||||
})));
|
||||
it('should update remote items but not pull remote changes', (() => __awaiter(this, void 0, void 0, function* () {
|
||||
const folder = yield Folder_1.default.save({ title: 'folder1' });
|
||||
const note = yield Note_1.default.save({ title: 'un', parent_id: folder.id });
|
||||
yield synchronizerStart();
|
||||
yield switchClient(2);
|
||||
yield synchronizerStart();
|
||||
yield Note_1.default.save({ title: 'deux', parent_id: folder.id });
|
||||
yield synchronizerStart();
|
||||
yield switchClient(1);
|
||||
yield Note_1.default.save({ title: 'un UPDATE', id: note.id });
|
||||
yield synchronizerStart(null, { syncSteps: ['update_remote'] });
|
||||
const all = yield test_utils_synchronizer_1.allNotesFolders();
|
||||
expect(all.length).toBe(2);
|
||||
yield switchClient(2);
|
||||
yield synchronizerStart();
|
||||
const note2 = yield Note_1.default.load(note.id);
|
||||
expect(note2.title).toBe('un UPDATE');
|
||||
})));
|
||||
it('should create a new Welcome notebook on each client', (() => __awaiter(this, void 0, void 0, function* () {
|
||||
// Create the Welcome items on two separate clients
|
||||
yield WelcomeUtils.createWelcomeItems();
|
||||
yield synchronizerStart();
|
||||
yield switchClient(2);
|
||||
yield WelcomeUtils.createWelcomeItems();
|
||||
const beforeFolderCount = (yield Folder_1.default.all()).length;
|
||||
const beforeNoteCount = (yield Note_1.default.all()).length;
|
||||
expect(beforeFolderCount === 1).toBe(true);
|
||||
expect(beforeNoteCount > 1).toBe(true);
|
||||
yield synchronizerStart();
|
||||
const afterFolderCount = (yield Folder_1.default.all()).length;
|
||||
const afterNoteCount = (yield Note_1.default.all()).length;
|
||||
expect(afterFolderCount).toBe(beforeFolderCount * 2);
|
||||
expect(afterNoteCount).toBe(beforeNoteCount * 2);
|
||||
// Changes to the Welcome items should be synced to all clients
|
||||
const f1 = (yield Folder_1.default.all())[0];
|
||||
yield Folder_1.default.save({ id: f1.id, title: 'Welcome MOD' });
|
||||
yield synchronizerStart();
|
||||
yield switchClient(1);
|
||||
yield synchronizerStart();
|
||||
const f1_1 = yield Folder_1.default.load(f1.id);
|
||||
expect(f1_1.title).toBe('Welcome MOD');
|
||||
})));
|
||||
it('should not wipe out user data when syncing with an empty target', (() => __awaiter(this, void 0, void 0, function* () {
|
||||
// Only these targets support the wipeOutFailSafe flag (in other words, the targets that use basicDelta)
|
||||
if (!['nextcloud', 'memory', 'filesystem', 'amazon_s3'].includes(syncTargetName())) { return; }
|
||||
for (let i = 0; i < 10; i++) { yield Note_1.default.save({ title: 'note' }); }
|
||||
Setting_1.default.setValue('sync.wipeOutFailSafe', true);
|
||||
yield synchronizerStart();
|
||||
yield fileApi().clearRoot(); // oops
|
||||
yield synchronizerStart();
|
||||
expect((yield Note_1.default.all()).length).toBe(10); // but since the fail-safe if on, the notes have not been deleted
|
||||
Setting_1.default.setValue('sync.wipeOutFailSafe', false); // Now switch it off
|
||||
yield synchronizerStart();
|
||||
expect((yield Note_1.default.all()).length).toBe(0); // Since the fail-safe was off, the data has been cleared
|
||||
// Handle case where the sync target has been wiped out, then the user creates one note and sync.
|
||||
for (let i = 0; i < 10; i++) { yield Note_1.default.save({ title: 'note' }); }
|
||||
Setting_1.default.setValue('sync.wipeOutFailSafe', true);
|
||||
yield synchronizerStart();
|
||||
yield fileApi().clearRoot();
|
||||
yield Note_1.default.save({ title: 'ma note encore' });
|
||||
yield synchronizerStart();
|
||||
expect((yield Note_1.default.all()).length).toBe(11);
|
||||
})));
|
||||
});
|
||||
// # sourceMappingURL=Synchronizer.share.js.map
|
||||
@@ -1,31 +0,0 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { sortedIds, createNTestNotes, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('./test-utils.js');
|
||||
const Folder = require('@joplin/lib/models/Folder').default;
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const ArrayUtils = require('@joplin/lib/ArrayUtils.js');
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
|
||||
describe('database', function() {
|
||||
beforeEach(async (done) => {
|
||||
await setupDatabaseAndSynchronizer(1);
|
||||
await switchClient(1);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should not modify cached field names', (async () => {
|
||||
const db = BaseModel.db();
|
||||
|
||||
const fieldNames = db.tableFieldNames('notes');
|
||||
const fieldCount = fieldNames.length;
|
||||
fieldNames.push('type_');
|
||||
|
||||
expect(fieldCount).toBeGreaterThan(0);
|
||||
expect(db.tableFieldNames('notes').length).toBe(fieldCount);
|
||||
}));
|
||||
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
const { id, ids, createNTestFolders, sortedIds, createNTestNotes, TestApp } = require('./test-utils.js');
|
||||
const { id, ids, createNTestFolders, sortedIds, createNTestNotes, TestApp } = require('@joplin/lib/testing/test-utils.js');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const uuid = require('@joplin/lib/uuid').default;
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
const { setupDatabaseAndSynchronizer, switchClient, createNTestFolders, createNTestNotes, createNTestTags, TestApp } = require('./test-utils.js');
|
||||
const { setupDatabaseAndSynchronizer, switchClient, createNTestFolders, createNTestNotes, createNTestTags, TestApp } = require('@joplin/lib/testing/test-utils.js');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const Folder = require('@joplin/lib/models/Folder').default;
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
const { setupDatabaseAndSynchronizer, switchClient, id, ids, sortedIds, at, createNTestFolders, createNTestNotes, createNTestTags, TestApp } = require('./test-utils.js');
|
||||
const { setupDatabaseAndSynchronizer, switchClient, id, ids, sortedIds, at, createNTestFolders, createNTestNotes, createNTestTags, TestApp } = require('@joplin/lib/testing/test-utils.js');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const Folder = require('@joplin/lib/models/Folder').default;
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
const { setupDatabaseAndSynchronizer, switchClient, createNTestFolders, createNTestNotes, createNTestTags, TestApp } = require('./test-utils.js');
|
||||
const { setupDatabaseAndSynchronizer, switchClient, createNTestFolders, createNTestNotes, createNTestTags, TestApp } = require('@joplin/lib/testing/test-utils.js');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const Folder = require('@joplin/lib/models/Folder').default;
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import KeychainService from '@joplin/lib/services/keychain/KeychainService';
|
||||
import shim from '@joplin/lib/shim';
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
|
||||
const { db, setupDatabaseAndSynchronizer, switchClient } = require('./test-utils.js');
|
||||
import { db, setupDatabaseAndSynchronizer, switchClient } from '@joplin/lib/testing/test-utils';
|
||||
|
||||
function describeIfCompatible(name: string, fn: any, elseFn: any) {
|
||||
if (['win32', 'darwin'].includes(shim.platformName())) {
|
||||
@@ -1,4 +1,4 @@
|
||||
import PluginRunner from '../app/services/plugins/PluginRunner';
|
||||
import PluginRunner from '../../../app/services/plugins/PluginRunner';
|
||||
import PluginService from '@joplin/lib/services/plugins/PluginService';
|
||||
import { ContentScriptType } from '@joplin/lib/services/plugins/api/types';
|
||||
import MdToHtml from '@joplin/renderer/MdToHtml';
|
||||
@@ -7,10 +7,10 @@ import Setting from '@joplin/lib/models/Setting';
|
||||
import * as fs from 'fs-extra';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
import { newPluginScript } from './test-utils';
|
||||
import { expectNotThrow, setupDatabaseAndSynchronizer, switchClient, expectThrow, createTempDir } from './test-utils.js';
|
||||
import { expectNotThrow, setupDatabaseAndSynchronizer, switchClient, expectThrow, createTempDir, supportDir } from '@joplin/lib/testing/test-utils';
|
||||
import { newPluginScript } from '../../testUtils';
|
||||
|
||||
const testPluginDir = `${__dirname}/../tests/support/plugins`;
|
||||
const testPluginDir = `${supportDir}/plugins`;
|
||||
|
||||
function newPluginService(appVersion: string = '1.4') {
|
||||
const runner = new PluginRunner();
|
||||
@@ -102,7 +102,7 @@ describe('services_PluginService', function() {
|
||||
"homepage_url": "https://joplinapp.org"
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
joplin.plugins.register({
|
||||
onStart: async function() {
|
||||
await joplin.data.post(['folders'], null, { title: "my plugin folder" });
|
||||
@@ -141,14 +141,14 @@ describe('services_PluginService', function() {
|
||||
"not_a_valid_manifest_at_all": 1
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
joplin.plugins.register({
|
||||
onStart: async function() {},
|
||||
});
|
||||
`, `
|
||||
/* joplin-manifest:
|
||||
*/
|
||||
|
||||
|
||||
joplin.plugins.register({
|
||||
onStart: async function() {},
|
||||
});
|
||||
@@ -189,7 +189,7 @@ describe('services_PluginService', function() {
|
||||
"homepage_url": "https://joplinapp.org"
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
joplin.plugins.register({
|
||||
onStart: async function() {
|
||||
await joplin.contentScripts.register('markdownItPlugin', 'justtesting', './markdownItTestPlugin.js');
|
||||
@@ -236,7 +236,7 @@ describe('services_PluginService', function() {
|
||||
"version": "1.0.0"
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
joplin.plugins.register({
|
||||
onStart: async function() { },
|
||||
});
|
||||
@@ -283,7 +283,7 @@ describe('services_PluginService', function() {
|
||||
}));
|
||||
|
||||
it('should create the data directory', (async () => {
|
||||
const pluginScript = newPluginScript(`
|
||||
const pluginScript = newPluginScript(`
|
||||
joplin.plugins.register({
|
||||
onStart: async function() {
|
||||
const dataDir = await joplin.plugins.dataDir();
|
||||
@@ -1,10 +1,10 @@
|
||||
import RepositoryApi from '@joplin/lib/services/plugins/RepositoryApi';
|
||||
import shim from '@joplin/lib/shim';
|
||||
import { setupDatabaseAndSynchronizer, switchClient, supportDir, createTempDir } from '../../test-utils';
|
||||
import { setupDatabaseAndSynchronizer, switchClient, supportDir, createTempDir } from '@joplin/lib/testing/test-utils';
|
||||
|
||||
async function newRepoApi(): Promise<RepositoryApi> {
|
||||
const repo = new RepositoryApi(`${supportDir}/pluginRepo`, await createTempDir());
|
||||
await repo.loadManifests();
|
||||
await repo.initialize();
|
||||
return repo;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import PluginService from '@joplin/lib/services/plugins/PluginService';
|
||||
const { waitForFolderCount, newPluginService, newPluginScript, setupDatabaseAndSynchronizer, switchClient, afterEachCleanUp } = require('../../../test-utils');
|
||||
import { waitForFolderCount, setupDatabaseAndSynchronizer, switchClient, afterEachCleanUp } from '@joplin/lib/testing/test-utils';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
import { newPluginScript, newPluginService } from '../../../testUtils';
|
||||
|
||||
describe('JoplinSettings', () => {
|
||||
|
||||
@@ -16,7 +16,7 @@ describe('JoplinSettings', () => {
|
||||
});
|
||||
|
||||
test('should listen to setting change event', async () => {
|
||||
const service = new newPluginService() as PluginService;
|
||||
const service = newPluginService();
|
||||
|
||||
const pluginScript = newPluginScript(`
|
||||
joplin.plugins.register({
|
||||
@@ -68,7 +68,7 @@ describe('JoplinSettings', () => {
|
||||
});
|
||||
|
||||
test('should allow registering multiple settings', async () => {
|
||||
const service = new newPluginService() as PluginService;
|
||||
const service = newPluginService();
|
||||
|
||||
const pluginScript = newPluginScript(`
|
||||
joplin.plugins.register({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import KeymapService from '@joplin/lib/services/KeymapService';
|
||||
import PluginService from '@joplin/lib/services/plugins/PluginService';
|
||||
const { newPluginService, newPluginScript, setupDatabaseAndSynchronizer, switchClient, afterEachCleanUp } = require('../../../test-utils');
|
||||
import { setupDatabaseAndSynchronizer, switchClient, afterEachCleanUp } from '@joplin/lib/testing/test-utils';
|
||||
import { newPluginScript, newPluginService } from '../../../testUtils';
|
||||
|
||||
describe('JoplinViewMenuItem', () => {
|
||||
|
||||
@@ -15,7 +15,7 @@ describe('JoplinViewMenuItem', () => {
|
||||
});
|
||||
|
||||
test('should register commands with the keymap service', async () => {
|
||||
const service = new newPluginService() as PluginService;
|
||||
const service = newPluginService();
|
||||
|
||||
KeymapService.instance().initialize();
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import { newPluginService, newPluginScript, setupDatabaseAndSynchronizer, switchClient, afterEachCleanUp } from '../../../test-utils';
|
||||
import { setupDatabaseAndSynchronizer, switchClient, afterEachCleanUp } from '@joplin/lib/testing/test-utils';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
import ItemChange from '@joplin/lib/models/ItemChange';
|
||||
import { newPluginScript, newPluginService } from '../../../testUtils';
|
||||
|
||||
describe('JoplinWorkspace', () => {
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import sandboxProxy, { Target } from '@joplin/lib/services/plugins/sandboxProxy';
|
||||
|
||||
const { setupDatabaseAndSynchronizer, switchClient } = require('../../test-utils.js');
|
||||
import { setupDatabaseAndSynchronizer, switchClient } from '@joplin/lib/testing/test-utils';
|
||||
|
||||
describe('services_plugins_sandboxProxy', function() {
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const {main} = require('./syncTargetUtils');
|
||||
const {main} = require('@joplin/lib/testing/syncTargetUtils');
|
||||
|
||||
const syncTargetType = process.argv.length <= 2 ? 'normal' : process.argv[2];
|
||||
|
||||
|
||||
41
packages/app-cli/tests/testUtils.ts
Normal file
41
packages/app-cli/tests/testUtils.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import PluginService from '@joplin/lib/services/plugins/PluginService';
|
||||
import PluginRunner from '../app/services/plugins/PluginRunner';
|
||||
|
||||
export interface PluginServiceOptions {
|
||||
getState?(): Record<string, any>;
|
||||
}
|
||||
|
||||
export function newPluginService(appVersion = '1.4', options: PluginServiceOptions = null): PluginService {
|
||||
options = options || {};
|
||||
|
||||
const runner = new PluginRunner();
|
||||
const service = new PluginService();
|
||||
service.initialize(
|
||||
appVersion,
|
||||
{
|
||||
joplin: {},
|
||||
},
|
||||
runner,
|
||||
{
|
||||
dispatch: () => {},
|
||||
getState: options.getState ? options.getState : () => {},
|
||||
}
|
||||
);
|
||||
return service;
|
||||
}
|
||||
|
||||
export function newPluginScript(script: string) {
|
||||
return `
|
||||
/* joplin-manifest:
|
||||
{
|
||||
"id": "org.joplinapp.plugins.PluginTest",
|
||||
"manifest_version": 1,
|
||||
"app_min_version": "1.4",
|
||||
"name": "JS Bundle test",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
*/
|
||||
|
||||
${script}
|
||||
`;
|
||||
}
|
||||
@@ -113,7 +113,7 @@ export default function(props: Props) {
|
||||
|
||||
let loadError: Error = null;
|
||||
try {
|
||||
await repoApi().loadManifests();
|
||||
await repoApi().initialize();
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
loadError = error;
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as React from 'react';
|
||||
import { useRef, useState, useEffect } from 'react';
|
||||
import useWindowResizeEvent from './utils/useWindowResizeEvent';
|
||||
import setLayoutItemProps from './utils/setLayoutItemProps';
|
||||
import useLayoutItemSizes, { LayoutItemSizes, itemSize } from './utils/useLayoutItemSizes';
|
||||
import useLayoutItemSizes, { LayoutItemSizes, itemSize, calculateMaxSizeAvailableForItem, itemMinWidth, itemMinHeight } from './utils/useLayoutItemSizes';
|
||||
import validateLayout from './utils/validateLayout';
|
||||
import { Size, LayoutItem } from './utils/types';
|
||||
import { canMove, MoveDirection } from './utils/movements';
|
||||
@@ -11,9 +11,6 @@ import { StyledWrapperRoot, StyledMoveOverlay, MoveModeRootWrapper, MoveModeRoot
|
||||
import { Resizable } from 're-resizable';
|
||||
const EventEmitter = require('events');
|
||||
|
||||
const itemMinWidth = 20;
|
||||
const itemMinHeight = 20;
|
||||
|
||||
interface onResizeEvent {
|
||||
layout: LayoutItem;
|
||||
}
|
||||
@@ -35,7 +32,7 @@ function itemVisible(item: LayoutItem, moveMode: boolean) {
|
||||
return item.visible !== false;
|
||||
}
|
||||
|
||||
function renderContainer(item: LayoutItem, parent: LayoutItem | null, sizes: LayoutItemSizes, onResizeStart: Function, onResize: Function, onResizeStop: Function, children: any[], isLastChild: boolean, moveMode: boolean): any {
|
||||
function renderContainer(item: LayoutItem, parent: LayoutItem | null, sizes: LayoutItemSizes, resizedItemMaxSize: Size | null, onResizeStart: Function, onResize: Function, onResizeStop: Function, children: any[], isLastChild: boolean, moveMode: boolean): any {
|
||||
const style: any = {
|
||||
display: itemVisible(item, moveMode) ? 'flex' : 'none',
|
||||
flexDirection: item.direction,
|
||||
@@ -68,6 +65,8 @@ function renderContainer(item: LayoutItem, parent: LayoutItem | null, sizes: Lay
|
||||
enable={enable}
|
||||
minWidth={'minWidth' in item ? item.minWidth : itemMinWidth}
|
||||
minHeight={'minHeight' in item ? item.minHeight : itemMinHeight}
|
||||
maxWidth={resizedItemMaxSize?.width}
|
||||
maxHeight={resizedItemMaxSize?.height}
|
||||
>
|
||||
{children}
|
||||
</Resizable>
|
||||
@@ -114,6 +113,7 @@ function ResizableLayout(props: Props) {
|
||||
key: item.key,
|
||||
initialWidth: sizes[item.key].width,
|
||||
initialHeight: sizes[item.key].height,
|
||||
maxSize: calculateMaxSizeAvailableForItem(item, parent, sizes),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -143,6 +143,7 @@ function ResizableLayout(props: Props) {
|
||||
setResizedItem(null);
|
||||
}
|
||||
|
||||
const resizedItemMaxSize = item.key === resizedItem?.key ? resizedItem.maxSize : null;
|
||||
if (!item.children) {
|
||||
const size = itemSize(item, parent, sizes, false);
|
||||
|
||||
@@ -155,7 +156,7 @@ function ResizableLayout(props: Props) {
|
||||
|
||||
const wrapper = renderItemWrapper(comp, item, parent, size, props.moveMode);
|
||||
|
||||
return renderContainer(item, parent, sizes, onResizeStart, onResize, onResizeStop, [wrapper], isLastChild, props.moveMode);
|
||||
return renderContainer(item, parent, sizes, resizedItemMaxSize, onResizeStart, onResize, onResizeStop, [wrapper], isLastChild, props.moveMode);
|
||||
} else {
|
||||
const childrenComponents = [];
|
||||
for (let i = 0; i < item.children.length; i++) {
|
||||
@@ -163,7 +164,7 @@ function ResizableLayout(props: Props) {
|
||||
childrenComponents.push(renderLayoutItem(child, item, sizes, isVisible && itemVisible(child, props.moveMode), i === item.children.length - 1));
|
||||
}
|
||||
|
||||
return renderContainer(item, parent, sizes, onResizeStart, onResize, onResizeStop, childrenComponents, isLastChild, props.moveMode);
|
||||
return renderContainer(item, parent, sizes, resizedItemMaxSize, onResizeStart, onResize, onResizeStop, childrenComponents, isLastChild, props.moveMode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import useLayoutItemSizes, { itemSize } from './useLayoutItemSizes';
|
||||
import useLayoutItemSizes, { itemSize, calculateMaxSizeAvailableForItem } from './useLayoutItemSizes';
|
||||
import { LayoutItem, LayoutItemDirection } from './types';
|
||||
import { renderHook } from '@testing-library/react-hooks';
|
||||
import validateLayout from './validateLayout';
|
||||
@@ -138,4 +138,219 @@ describe('useLayoutItemSizes', () => {
|
||||
expect(itemSize(parent.children[1], parent, sizes, false)).toEqual({ width: 95, height: 50 });
|
||||
});
|
||||
|
||||
test('should decrease size of the largest item if the total size would be larger than the container', () => {
|
||||
const layout: LayoutItem = validateLayout({
|
||||
key: 'root',
|
||||
width: 200,
|
||||
height: 100,
|
||||
direction: LayoutItemDirection.Row,
|
||||
children: [
|
||||
{
|
||||
key: 'col1',
|
||||
width: 110,
|
||||
},
|
||||
{
|
||||
key: 'col2',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
key: 'col3',
|
||||
minWidth: 50,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useLayoutItemSizes(layout));
|
||||
const sizes = result.current;
|
||||
|
||||
expect(sizes.col1.width).toBe(50);
|
||||
expect(sizes.col2.width).toBe(100);
|
||||
expect(sizes.col3.width).toBe(50);
|
||||
});
|
||||
|
||||
test('should not allow a minWidth of 0, should still make space for the item', () => {
|
||||
const layout: LayoutItem = validateLayout({
|
||||
key: 'root',
|
||||
width: 200,
|
||||
height: 100,
|
||||
direction: LayoutItemDirection.Row,
|
||||
children: [
|
||||
{
|
||||
key: 'col1',
|
||||
width: 210,
|
||||
},
|
||||
{
|
||||
key: 'col2',
|
||||
minWidth: 0,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useLayoutItemSizes(layout));
|
||||
const sizes = result.current;
|
||||
|
||||
expect(sizes.col1.width).toBe(160);
|
||||
expect(sizes.col2.width).toBe(40); // default minWidth is 40
|
||||
});
|
||||
|
||||
test('should ignore invisible items when counting remaining size', () => {
|
||||
const layout: LayoutItem = validateLayout({
|
||||
key: 'root',
|
||||
width: 200,
|
||||
height: 100,
|
||||
direction: LayoutItemDirection.Row,
|
||||
children: [
|
||||
{
|
||||
key: 'col1',
|
||||
width: 110,
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
key: 'col2',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
key: 'col3',
|
||||
minWidth: 50,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useLayoutItemSizes(layout));
|
||||
const sizes = result.current;
|
||||
|
||||
expect(sizes.col1.width).toBe(0);
|
||||
expect(sizes.col2.width).toBe(100);
|
||||
expect(sizes.col3.width).toBe(100);
|
||||
});
|
||||
|
||||
test('should ignore invisible items when selecting largest child', () => {
|
||||
const layout: LayoutItem = validateLayout({
|
||||
key: 'root',
|
||||
width: 200,
|
||||
height: 100,
|
||||
direction: LayoutItemDirection.Row,
|
||||
children: [
|
||||
{
|
||||
key: 'col1',
|
||||
width: 110,
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
key: 'col2',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
key: 'col3',
|
||||
width: 110,
|
||||
},
|
||||
{
|
||||
key: 'col4',
|
||||
minWidth: 50,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useLayoutItemSizes(layout));
|
||||
const sizes = result.current;
|
||||
|
||||
expect(sizes.col1.width).toBe(0);
|
||||
expect(sizes.col2.width).toBe(100);
|
||||
expect(sizes.col3.width).toBe(50);
|
||||
expect(sizes.col4.width).toBe(50);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('calculateMaxSizeAvailableForItem', () => {
|
||||
|
||||
test('should give maximum available space this item can take up during resizing', () => {
|
||||
const layout: LayoutItem = validateLayout({
|
||||
key: 'root',
|
||||
width: 200,
|
||||
height: 100,
|
||||
direction: LayoutItemDirection.Row,
|
||||
children: [
|
||||
{
|
||||
key: 'col1',
|
||||
width: 50,
|
||||
},
|
||||
{
|
||||
key: 'col2',
|
||||
width: 70,
|
||||
},
|
||||
{
|
||||
key: 'col3',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useLayoutItemSizes(layout));
|
||||
const sizes = result.current;
|
||||
const maxSize1 = calculateMaxSizeAvailableForItem(layout.children[0], layout, sizes);
|
||||
const maxSize2 = calculateMaxSizeAvailableForItem(layout.children[1], layout, sizes);
|
||||
|
||||
// maxSize = totalSize - ( [size of items with set size, except for the current item] + [minimum size of items with no set size] )
|
||||
expect(maxSize1.width).toBe(90); // 90 = layout.width - (col2.width + col3.minWidth(=40) )
|
||||
expect(maxSize2.width).toBe(110); // 110 = layout.width - (col1.width + col3.minWidth(=40) )
|
||||
});
|
||||
|
||||
test('should respect minimum sizes', () => {
|
||||
const layout: LayoutItem = validateLayout({
|
||||
key: 'root',
|
||||
width: 200,
|
||||
height: 100,
|
||||
direction: LayoutItemDirection.Row,
|
||||
children: [
|
||||
{
|
||||
key: 'col1',
|
||||
width: 50,
|
||||
},
|
||||
{
|
||||
key: 'col2',
|
||||
width: 70,
|
||||
},
|
||||
{
|
||||
key: 'col3',
|
||||
minWidth: 60,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useLayoutItemSizes(layout));
|
||||
const sizes = result.current;
|
||||
const maxSize1 = calculateMaxSizeAvailableForItem(layout.children[0], layout, sizes);
|
||||
const maxSize2 = calculateMaxSizeAvailableForItem(layout.children[1], layout, sizes);
|
||||
|
||||
// maxSize = totalSize - ( [size of items with set size, except for the current item] + [minimum size of items with no set size] )
|
||||
expect(maxSize1.width).toBe(70); // 70 = layout.width - (col2.width + col3.minWidth)
|
||||
expect(maxSize2.width).toBe(90); // 90 = layout.width - (col1.width + col3.minWidth)
|
||||
});
|
||||
|
||||
test('should not allow a minWidth of 0, should still leave space for the item', () => {
|
||||
const layout: LayoutItem = validateLayout({
|
||||
key: 'root',
|
||||
width: 200,
|
||||
height: 100,
|
||||
direction: LayoutItemDirection.Row,
|
||||
children: [
|
||||
{
|
||||
key: 'col1',
|
||||
width: 50,
|
||||
},
|
||||
{
|
||||
key: 'col2',
|
||||
minWidth: 0,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useLayoutItemSizes(layout));
|
||||
const sizes = result.current;
|
||||
const maxSize1 = calculateMaxSizeAvailableForItem(layout.children[0], layout, sizes);
|
||||
|
||||
// maxSize = totalSize - ( [size of items with set size, except for the current item] + [minimum size of items with no set size] )
|
||||
expect(maxSize1.width).toBe(160); // 160 = layout.width - col2.minWidth(=40)
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -3,6 +3,9 @@ import { LayoutItem, Size } from './types';
|
||||
|
||||
const dragBarThickness = 5;
|
||||
|
||||
export const itemMinWidth = 40;
|
||||
export const itemMinHeight = 40;
|
||||
|
||||
export interface LayoutItemSizes {
|
||||
[key: string]: Size;
|
||||
}
|
||||
@@ -17,8 +20,8 @@ export function itemSize(item: LayoutItem, parent: LayoutItem | null, sizes: Lay
|
||||
const bottomGap = !isContainer && (item.resizableBottom || parentResizableBottom) ? dragBarThickness : 0;
|
||||
|
||||
return {
|
||||
width: ('width' in item ? item.width : sizes[item.key].width) - rightGap,
|
||||
height: ('height' in item ? item.height : sizes[item.key].height) - bottomGap,
|
||||
width: sizes[item.key].width - rightGap,
|
||||
height: sizes[item.key].height - bottomGap,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -38,6 +41,10 @@ function calculateChildrenSizes(item: LayoutItem, parent: LayoutItem | null, siz
|
||||
const noWidthChildren: any[] = [];
|
||||
const noHeightChildren: any[] = [];
|
||||
|
||||
// The minimum space required for items with no defined size
|
||||
let noWidthChildrenMinWidth = 0;
|
||||
let noHeightChildrenMinHeight = 0;
|
||||
|
||||
for (const child of item.children) {
|
||||
let w = 'width' in child ? child.width : null;
|
||||
let h = 'height' in child ? child.height : null;
|
||||
@@ -47,10 +54,43 @@ function calculateChildrenSizes(item: LayoutItem, parent: LayoutItem | null, siz
|
||||
}
|
||||
|
||||
sizes[child.key] = { width: w, height: h };
|
||||
|
||||
if (w !== null) remainingSize.width -= w;
|
||||
if (h !== null) remainingSize.height -= h;
|
||||
if (w === null) noWidthChildren.push({ item: child, parent: item });
|
||||
if (h === null) noHeightChildren.push({ item: child, parent: item });
|
||||
if (w === null) {
|
||||
noWidthChildren.push({ item: child, parent: item });
|
||||
noWidthChildrenMinWidth += child.minWidth || itemMinWidth;
|
||||
}
|
||||
if (h === null) {
|
||||
noHeightChildren.push({ item: child, parent: item });
|
||||
noHeightChildrenMinHeight += child.minHeight || itemMinHeight;
|
||||
}
|
||||
}
|
||||
|
||||
while (remainingSize.width < noWidthChildrenMinWidth) {
|
||||
// There is not enough space, the widest item will be made smaller
|
||||
let widestChild = item.children[0].key;
|
||||
for (const child of item.children) {
|
||||
if (!child.visible) continue;
|
||||
if (sizes[child.key].width > sizes[widestChild].width) widestChild = child.key;
|
||||
}
|
||||
|
||||
const dw = Math.abs(remainingSize.width - noWidthChildrenMinWidth);
|
||||
sizes[widestChild].width -= dw;
|
||||
remainingSize.width += dw;
|
||||
}
|
||||
|
||||
while (remainingSize.height < noHeightChildrenMinHeight) {
|
||||
// There is not enough space, the tallest item will be made smaller
|
||||
let tallestChild = item.children[0].key;
|
||||
for (const child of item.children) {
|
||||
if (!child.visible) continue;
|
||||
if (sizes[child.key].height > sizes[tallestChild].height) tallestChild = child.key;
|
||||
}
|
||||
|
||||
const dh = Math.abs(remainingSize.height - noHeightChildrenMinHeight);
|
||||
sizes[tallestChild].height -= dh;
|
||||
remainingSize.height += dh;
|
||||
}
|
||||
|
||||
if (noWidthChildren.length) {
|
||||
@@ -77,6 +117,24 @@ function calculateChildrenSizes(item: LayoutItem, parent: LayoutItem | null, siz
|
||||
return sizes;
|
||||
}
|
||||
|
||||
// Gives the maximum available space for this item that it can take up during resizing
|
||||
// availableSize = totalSize - ( [size of items with set size, except for the current item] + [minimum size of items with no set size] )
|
||||
export function calculateMaxSizeAvailableForItem(item: LayoutItem, parent: LayoutItem, sizes: LayoutItemSizes): Size {
|
||||
const availableSize: Size = { ...sizes[parent.key] };
|
||||
|
||||
for (const sibling of parent.children) {
|
||||
if (!sibling.visible) continue;
|
||||
|
||||
availableSize.width -= 'width' in sibling ? sizes[sibling.key].width : (sibling.minWidth || itemMinWidth);
|
||||
availableSize.height -= 'height' in sibling ? sizes[sibling.key].height : (sibling.minHeight || itemMinHeight);
|
||||
}
|
||||
|
||||
availableSize.width += sizes[item.key].width;
|
||||
availableSize.height += sizes[item.key].height;
|
||||
|
||||
return availableSize;
|
||||
}
|
||||
|
||||
export default function useLayoutItemSizes(layout: LayoutItem, makeAllVisible: boolean = false) {
|
||||
return useMemo(() => {
|
||||
let sizes: LayoutItemSizes = {};
|
||||
|
||||
@@ -449,7 +449,11 @@ class SidebarComponent extends React.Component<Props, State> {
|
||||
|
||||
renderTag(tag: any, selected: boolean) {
|
||||
const anchorRef = this.anchorItemRef('tag', tag.id);
|
||||
const noteCount = Setting.value('showNoteCounts') ? this.renderNoteCount(tag.note_count) : '';
|
||||
let noteCount = null;
|
||||
if (Setting.value('showNoteCounts')) {
|
||||
if (Setting.value('showCompletedTodos')) noteCount = this.renderNoteCount(tag.note_count);
|
||||
else noteCount = this.renderNoteCount(tag.note_count - tag.todo_completed_count);
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledListItem selected={selected}
|
||||
|
||||
2
packages/app-desktop/package-lock.json
generated
2
packages/app-desktop/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/app-desktop",
|
||||
"version": "2.0.1",
|
||||
"version": "2.0.4",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/app-desktop",
|
||||
"version": "2.0.1",
|
||||
"version": "2.0.4",
|
||||
"description": "Joplin for Desktop",
|
||||
"main": "main.js",
|
||||
"private": true,
|
||||
|
||||
@@ -26,12 +26,12 @@ if [ "$RESET_ALL" == "1" ]; then
|
||||
|
||||
echo "config keychain.supported 0" >> "$CMD_FILE"
|
||||
echo "config sync.target 9" >> "$CMD_FILE"
|
||||
echo "config sync.9.path http://localhost:22300" >> "$CMD_FILE"
|
||||
echo "config sync.9.path http://api-joplincloud.local:22300" >> "$CMD_FILE"
|
||||
echo "config sync.9.username $USER_EMAIL" >> "$CMD_FILE"
|
||||
echo "config sync.9.password 123456" >> "$CMD_FILE"
|
||||
|
||||
if [ "$1" == "1" ]; then
|
||||
curl --data '{"action": "createTestUsers"}' http://localhost:22300/api/debug
|
||||
if [ "$USER_NUM" == "1" ]; then
|
||||
curl --data '{"action": "createTestUsers"}' -H 'Content-Type: application/json' http://api-joplincloud.local:22300/api/debug
|
||||
|
||||
echo 'mkbook "shared"' >> "$CMD_FILE"
|
||||
echo 'mkbook "other"' >> "$CMD_FILE"
|
||||
|
||||
@@ -240,7 +240,7 @@ PODS:
|
||||
- React-cxxreact (= 0.63.3)
|
||||
- React-jsi (= 0.63.3)
|
||||
- React-jsinspector (0.63.3)
|
||||
- react-native-alarm-notification (1.7.1):
|
||||
- react-native-alarm-notification (1.0.3):
|
||||
- React
|
||||
- react-native-camera (3.40.0):
|
||||
- React-Core
|
||||
@@ -391,7 +391,7 @@ DEPENDENCIES:
|
||||
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
|
||||
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
|
||||
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
|
||||
- react-native-alarm-notification (from `../node_modules/react-native-alarm-notification`)
|
||||
- react-native-alarm-notification (from `../node_modules/joplin-rn-alarm-notification`)
|
||||
- react-native-camera (from `../node_modules/react-native-camera`)
|
||||
- react-native-document-picker (from `../node_modules/react-native-document-picker`)
|
||||
- "react-native-geolocation (from `../node_modules/@react-native-community/geolocation`)"
|
||||
@@ -475,7 +475,7 @@ EXTERNAL SOURCES:
|
||||
React-jsinspector:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsinspector"
|
||||
react-native-alarm-notification:
|
||||
:path: "../node_modules/react-native-alarm-notification"
|
||||
:path: "../node_modules/joplin-rn-alarm-notification"
|
||||
react-native-camera:
|
||||
:path: "../node_modules/react-native-camera"
|
||||
react-native-document-picker:
|
||||
@@ -568,7 +568,7 @@ SPEC CHECKSUMS:
|
||||
React-jsi: df07aa95b39c5be3e41199921509bfa929ed2b9d
|
||||
React-jsiexecutor: b56c03e61c0dd5f5801255f2160a815f4a53d451
|
||||
React-jsinspector: 8e68ffbfe23880d3ee9bafa8be2777f60b25cbe2
|
||||
react-native-alarm-notification: 8f2adb4521bf7ca867278d4c236553e154dbbbc6
|
||||
react-native-alarm-notification: 466e4ad56fbd948ecac26e657f292dca8bf483d5
|
||||
react-native-camera: 5c1fbfecf63b802b8ca4a71c60d30a71550fb348
|
||||
react-native-document-picker: b3e78a8f7fef98b5cb069f20fc35797d55e68e28
|
||||
react-native-geolocation: cbd9d6bd06bac411eed2671810f454d4908484a8
|
||||
|
||||
10
packages/app-mobile/package-lock.json
generated
10
packages/app-mobile/package-lock.json
generated
@@ -4905,6 +4905,11 @@
|
||||
"resolved": "https://registry.npmjs.org/jetifier/-/jetifier-1.6.6.tgz",
|
||||
"integrity": "sha512-JNAkmPeB/GS2tCRqUzRPsTOHpGDah7xP18vGJfIjZC+W2sxEHbxgJxetIjIqhjQ3yYbYNEELkM/spKLtwoOSUQ=="
|
||||
},
|
||||
"joplin-rn-alarm-notification": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/joplin-rn-alarm-notification/-/joplin-rn-alarm-notification-1.0.3.tgz",
|
||||
"integrity": "sha512-HZGDrLmYf6aMVgzk02w4DS9CjaTogE1hnOLdMDsrWkZzRskO6g3bZw+Bwlc63cCX4ZLZeeWIaABzHoWKAbLzpQ=="
|
||||
},
|
||||
"js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
@@ -7097,11 +7102,6 @@
|
||||
"prop-types": "^15.5.10"
|
||||
}
|
||||
},
|
||||
"react-native-alarm-notification": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-alarm-notification/-/react-native-alarm-notification-1.7.1.tgz",
|
||||
"integrity": "sha512-cvfSqCCfw48NyeFTEL5WOF/tkeWLNI7X1mVoEQ/9aY+2fuBtkCfZUoJ7vvOOHeryPbDJrlDNpRWTi3erLphZ+w=="
|
||||
},
|
||||
"react-native-camera": {
|
||||
"version": "3.40.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-camera/-/react-native-camera-3.40.0.tgz",
|
||||
|
||||
2
packages/fork-htmlparser2/package-lock.json
generated
2
packages/fork-htmlparser2/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/fork-htmlparser2",
|
||||
"version": "4.1.24",
|
||||
"version": "4.1.26",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@joplin/fork-htmlparser2",
|
||||
"description": "Fast & forgiving HTML/XML/RSS parser",
|
||||
"version": "4.1.24",
|
||||
"version": "4.1.26",
|
||||
"author": "Felix Boehm <me@feedic.com>",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
2
packages/fork-sax/package-lock.json
generated
2
packages/fork-sax/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/fork-sax",
|
||||
"version": "1.2.28",
|
||||
"version": "1.2.30",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "@joplin/fork-sax",
|
||||
"description": "An evented streaming XML parser in JavaScript",
|
||||
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
|
||||
"version": "1.2.28",
|
||||
"version": "1.2.30",
|
||||
"main": "lib/sax.js",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('./test-utils.js');
|
||||
const ArrayUtils = require('@joplin/lib/ArrayUtils');
|
||||
const ArrayUtils = require('./ArrayUtils');
|
||||
|
||||
describe('ArrayUtils', function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import InMemoryCache from '@joplin/lib/InMemoryCache';
|
||||
import time from '@joplin/lib/time';
|
||||
import InMemoryCache from './InMemoryCache';
|
||||
import time from './time';
|
||||
|
||||
describe('InMemoryCache', function() {
|
||||
|
||||
@@ -343,7 +343,7 @@ export default class JoplinDatabase extends Database {
|
||||
// must be set in the synchronizer too.
|
||||
|
||||
// Note: v16 and v17 don't do anything. They were used to debug an issue.
|
||||
const existingDatabaseVersions = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37];
|
||||
const existingDatabaseVersions = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38];
|
||||
|
||||
let currentVersionIndex = existingDatabaseVersions.indexOf(fromVersion);
|
||||
|
||||
@@ -876,6 +876,18 @@ export default class JoplinDatabase extends Database {
|
||||
queries.push('ALTER TABLE resources ADD COLUMN share_id TEXT NOT NULL DEFAULT ""');
|
||||
}
|
||||
|
||||
if (targetVersion == 38) {
|
||||
queries.push('DROP VIEW tags_with_note_count');
|
||||
queries.push(`CREATE VIEW tags_with_note_count AS
|
||||
SELECT tags.id as id, tags.title as title, tags.created_time as created_time, tags.updated_time as updated_time, COUNT(notes.id) as note_count,
|
||||
SUM(CASE WHEN notes.todo_completed > 0 THEN 1 ELSE 0 END) AS todo_completed_count
|
||||
FROM tags
|
||||
LEFT JOIN note_tags nt on nt.tag_id = tags.id
|
||||
LEFT JOIN notes on notes.id = nt.note_id
|
||||
WHERE notes.id IS NOT NULL
|
||||
GROUP BY tags.id`);
|
||||
}
|
||||
|
||||
const updateVersionQuery = { sql: 'UPDATE version SET version = ?', params: [targetVersion] };
|
||||
|
||||
queries.push(updateVersionQuery);
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
class JoplinError extends Error {
|
||||
constructor(message, code = null, details = null) {
|
||||
super(message);
|
||||
this.code = null;
|
||||
this.details = '';
|
||||
this.code = code;
|
||||
this.details = details;
|
||||
}
|
||||
}
|
||||
exports.default = JoplinError;
|
||||
//# sourceMappingURL=JoplinError.js.map
|
||||
@@ -3,8 +3,11 @@ import { _ } from './locale';
|
||||
const { rtrimSlashes } = require('./path-utils.js');
|
||||
import JoplinError from './JoplinError';
|
||||
import { Env } from './models/Setting';
|
||||
import Logger from './Logger';
|
||||
const { stringify } = require('query-string');
|
||||
|
||||
const logger = Logger.create('JoplinServerApi');
|
||||
|
||||
interface Options {
|
||||
baseUrl(): string;
|
||||
username(): string;
|
||||
@@ -133,71 +136,78 @@ export default class JoplinServerApi {
|
||||
url += stringify(query);
|
||||
}
|
||||
|
||||
let response: any = null;
|
||||
|
||||
if (this.debugRequests_) {
|
||||
console.info('Joplin API Call', `${method} ${url}`, headers, options);
|
||||
console.info(this.requestToCurl_(url, fetchOptions));
|
||||
}
|
||||
|
||||
if (options.source == 'file' && (method == 'POST' || method == 'PUT')) {
|
||||
if (fetchOptions.path) {
|
||||
const fileStat = await shim.fsDriver().stat(fetchOptions.path);
|
||||
if (fileStat) fetchOptions.headers['Content-Length'] = `${fileStat.size}`;
|
||||
}
|
||||
response = await shim.uploadBlob(url, fetchOptions);
|
||||
} else if (options.target == 'string') {
|
||||
if (typeof body === 'string') fetchOptions.headers['Content-Length'] = `${shim.stringByteLength(body)}`;
|
||||
response = await shim.fetch(url, fetchOptions);
|
||||
} else {
|
||||
// file
|
||||
response = await shim.fetchBlob(url, fetchOptions);
|
||||
}
|
||||
|
||||
const responseText = await response.text();
|
||||
|
||||
if (this.debugRequests_) {
|
||||
console.info('Joplin API Response', responseText);
|
||||
}
|
||||
|
||||
// Creates an error object with as much data as possible as it will appear in the log, which will make debugging easier
|
||||
const newError = (message: string, code: number = 0) => {
|
||||
// Gives a shorter response for error messages. Useful for cases where a full HTML page is accidentally loaded instead of
|
||||
// JSON. That way the error message will still show there's a problem but without filling up the log or screen.
|
||||
const shortResponseText = (`${responseText}`).substr(0, 1024);
|
||||
// return new JoplinError(`${method} ${path}: ${message} (${code}): ${shortResponseText}`, code);
|
||||
return new JoplinError(message, code, `${method} ${path}: ${message} (${code}): ${shortResponseText}`);
|
||||
};
|
||||
|
||||
let responseJson_: any = null;
|
||||
const loadResponseJson = async () => {
|
||||
if (!responseText) return null;
|
||||
if (responseJson_) return responseJson_;
|
||||
responseJson_ = JSON.parse(responseText);
|
||||
if (!responseJson_) throw newError('Cannot parse JSON response', response.status);
|
||||
return responseJson_;
|
||||
};
|
||||
|
||||
if (!response.ok) {
|
||||
if (options.target === 'file') throw newError('fetchBlob error', response.status);
|
||||
|
||||
let json = null;
|
||||
try {
|
||||
json = await loadResponseJson();
|
||||
} catch (error) {
|
||||
// Just send back the plain text in newErro()
|
||||
try {
|
||||
if (this.debugRequests_) {
|
||||
logger.debug(this.requestToCurl_(url, fetchOptions));
|
||||
}
|
||||
|
||||
if (json && json.error) {
|
||||
throw newError(`${json.error}`, json.code ? json.code : response.status);
|
||||
let response: any = null;
|
||||
|
||||
if (options.source == 'file' && (method == 'POST' || method == 'PUT')) {
|
||||
if (fetchOptions.path) {
|
||||
const fileStat = await shim.fsDriver().stat(fetchOptions.path);
|
||||
if (fileStat) fetchOptions.headers['Content-Length'] = `${fileStat.size}`;
|
||||
}
|
||||
response = await shim.uploadBlob(url, fetchOptions);
|
||||
} else if (options.target == 'string') {
|
||||
if (typeof body === 'string') fetchOptions.headers['Content-Length'] = `${shim.stringByteLength(body)}`;
|
||||
response = await shim.fetch(url, fetchOptions);
|
||||
} else {
|
||||
// file
|
||||
response = await shim.fetchBlob(url, fetchOptions);
|
||||
}
|
||||
|
||||
throw newError('Unknown error', response.status);
|
||||
const responseText = await response.text();
|
||||
|
||||
if (this.debugRequests_) {
|
||||
logger.debug('Response', responseText);
|
||||
}
|
||||
|
||||
// Creates an error object with as much data as possible as it will appear in the log, which will make debugging easier
|
||||
const newError = (message: string, code: number = 0) => {
|
||||
// Gives a shorter response for error messages. Useful for cases where a full HTML page is accidentally loaded instead of
|
||||
// JSON. That way the error message will still show there's a problem but without filling up the log or screen.
|
||||
const shortResponseText = (`${responseText}`).substr(0, 1024);
|
||||
// return new JoplinError(`${method} ${path}: ${message} (${code}): ${shortResponseText}`, code);
|
||||
return new JoplinError(message, code, `${method} ${path}: ${message} (${code}): ${shortResponseText}`);
|
||||
};
|
||||
|
||||
let responseJson_: any = null;
|
||||
const loadResponseJson = async () => {
|
||||
if (!responseText) return null;
|
||||
if (responseJson_) return responseJson_;
|
||||
responseJson_ = JSON.parse(responseText);
|
||||
if (!responseJson_) throw newError('Cannot parse JSON response', response.status);
|
||||
return responseJson_;
|
||||
};
|
||||
|
||||
if (!response.ok) {
|
||||
if (options.target === 'file') throw newError('fetchBlob error', response.status);
|
||||
|
||||
let json = null;
|
||||
try {
|
||||
json = await loadResponseJson();
|
||||
} catch (error) {
|
||||
// Just send back the plain text in newErro()
|
||||
}
|
||||
|
||||
if (json && json.error) {
|
||||
throw newError(`${json.error}`, json.code ? json.code : response.status);
|
||||
}
|
||||
|
||||
throw newError('Unknown error', response.status);
|
||||
}
|
||||
|
||||
if (options.responseFormat === 'text') return responseText;
|
||||
|
||||
const output = await loadResponseJson();
|
||||
return output;
|
||||
} catch (error) {
|
||||
if (error.code !== 404) {
|
||||
logger.warn(this.requestToCurl_(url, fetchOptions));
|
||||
logger.warn(error);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (options.responseFormat === 'text') return responseText;
|
||||
|
||||
const output = await loadResponseJson();
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
const StringUtils = require('@joplin/lib/string-utils');
|
||||
const StringUtils = require('./string-utils');
|
||||
|
||||
describe('StringUtils', function() {
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
|
||||
const { fileContentEqual, setupDatabase, revisionService, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('./test-utils.js');
|
||||
const TaskQueue = require('@joplin/lib/TaskQueue.js');
|
||||
const { setupDatabaseAndSynchronizer, sleep, switchClient } = require('./testing/test-utils.js');
|
||||
const TaskQueue = require('./TaskQueue.js');
|
||||
|
||||
describe('TaskQueue', function() {
|
||||
|
||||
22
packages/lib/database.test.js
Normal file
22
packages/lib/database.test.js
Normal file
@@ -0,0 +1,22 @@
|
||||
const { setupDatabaseAndSynchronizer, switchClient } = require('./testing/test-utils.js');
|
||||
const BaseModel = require('./BaseModel').default;
|
||||
|
||||
describe('database', function() {
|
||||
beforeEach(async (done) => {
|
||||
await setupDatabaseAndSynchronizer(1);
|
||||
await switchClient(1);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should not modify cached field names', (async () => {
|
||||
const db = BaseModel.db();
|
||||
|
||||
const fieldNames = db.tableFieldNames('notes');
|
||||
const fieldCount = fieldNames.length;
|
||||
fieldNames.push('type_');
|
||||
|
||||
expect(fieldCount).toBeGreaterThan(0);
|
||||
expect(db.tableFieldNames('notes').length).toBe(fieldCount);
|
||||
}));
|
||||
|
||||
});
|
||||
@@ -1,8 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
const { checkThrow } = require('./test-utils.js');
|
||||
const eventManager = require('@joplin/lib/eventManager').default;
|
||||
const { checkThrow } = require('./testing/test-utils.js');
|
||||
const eventManager = require('./eventManager').default;
|
||||
|
||||
describe('eventManager', function() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { afterAllCleanUp, setupDatabaseAndSynchronizer, switchClient, fileApi } from './test-utils';
|
||||
import { afterAllCleanUp, setupDatabaseAndSynchronizer, switchClient, fileApi } from './testing/test-utils';
|
||||
|
||||
describe('file-api-driver', function() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import FsDriverNode from '@joplin/lib/fs-driver-node';
|
||||
import shim from '@joplin/lib/shim';
|
||||
const { expectThrow } = require('./test-utils.js');
|
||||
import FsDriverNode from './fs-driver-node';
|
||||
import shim from './shim';
|
||||
const { expectThrow } = require('./testing/test-utils.js');
|
||||
|
||||
// On Windows, path.resolve is going to convert a path such as
|
||||
// /tmp/file.txt to c:\tmp\file.txt
|
||||
@@ -1,4 +1,4 @@
|
||||
import htmlUtils from '@joplin/lib/htmlUtils';
|
||||
import htmlUtils from './htmlUtils';
|
||||
|
||||
describe('htmlUtils', function() {
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import { NoteEntity, ResourceEntity, TagEntity } from '@joplin/lib/services/database/types';
|
||||
import shim from '@joplin/lib/shim';
|
||||
import { NoteEntity, ResourceEntity, TagEntity } from './services/database/types';
|
||||
import shim from './shim';
|
||||
|
||||
const fs = require('fs-extra');
|
||||
const os = require('os');
|
||||
const { filename } = require('@joplin/lib/path-utils');
|
||||
const { setupDatabaseAndSynchronizer, switchClient, expectNotThrow } = require('./test-utils.js');
|
||||
const { enexXmlToMd } = require('@joplin/lib/import-enex-md-gen.js');
|
||||
const { importEnex } = require('@joplin/lib/import-enex');
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import Tag from '@joplin/lib/models/Tag';
|
||||
import Resource from '@joplin/lib/models/Resource';
|
||||
const { filename } = require('./path-utils');
|
||||
const { setupDatabaseAndSynchronizer, switchClient, expectNotThrow, supportDir } = require('./testing/test-utils.js');
|
||||
const { enexXmlToMd } = require('./import-enex-md-gen.js');
|
||||
const { importEnex } = require('./import-enex');
|
||||
import Note from './models/Note';
|
||||
import Tag from './models/Tag';
|
||||
import Resource from './models/Resource';
|
||||
|
||||
const enexSampleBaseDir = `${__dirname}/enex_to_md`;
|
||||
const enexSampleBaseDir = `${supportDir}/../enex_to_md`;
|
||||
|
||||
describe('EnexToMd', function() {
|
||||
|
||||
@@ -10,4 +10,7 @@ module.exports = {
|
||||
],
|
||||
|
||||
testEnvironment: 'node',
|
||||
|
||||
setupFilesAfterEnv: [`${__dirname}/jest.setup.js`],
|
||||
slowTestThreshold: 40,
|
||||
};
|
||||
|
||||
9
packages/lib/jest.setup.js
Normal file
9
packages/lib/jest.setup.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const { afterEachCleanUp } = require('./testing/test-utils.js');
|
||||
const { shimInit } = require('./shim-init-node.js');
|
||||
const sharp = require('sharp');
|
||||
|
||||
shimInit(sharp, null);
|
||||
|
||||
global.afterEach(async () => {
|
||||
await afterEachCleanUp();
|
||||
});
|
||||
@@ -7,10 +7,18 @@ const MarkdownIt = require('markdown-it');
|
||||
const listRegex = /^(\s*)([*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]\s))(\s*)/;
|
||||
const emptyListRegex = /^(\s*)([*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s+)$/;
|
||||
|
||||
export enum MarkdownTableJustify {
|
||||
Left = 'left',
|
||||
Center = 'center',
|
||||
Right = 'right,',
|
||||
}
|
||||
|
||||
export interface MarkdownTableHeader {
|
||||
name: string;
|
||||
label: string;
|
||||
filter?: Function;
|
||||
disableEscape?: boolean;
|
||||
justify?: MarkdownTableJustify;
|
||||
}
|
||||
|
||||
export interface MarkdownTableRow {
|
||||
@@ -120,26 +128,38 @@ const markdownUtils = {
|
||||
createMarkdownTable(headers: MarkdownTableHeader[], rows: MarkdownTableRow[]): string {
|
||||
const output = [];
|
||||
|
||||
const minCellWidth = 5;
|
||||
|
||||
const headersMd = [];
|
||||
const lineMd = [];
|
||||
for (let i = 0; i < headers.length; i++) {
|
||||
const h = headers[i];
|
||||
headersMd.push(stringPadding(h.label, 3, ' ', stringPadding.RIGHT));
|
||||
lineMd.push('---');
|
||||
headersMd.push(stringPadding(h.label, minCellWidth, ' ', stringPadding.RIGHT));
|
||||
|
||||
const justify = h.justify ? h.justify : MarkdownTableJustify.Left;
|
||||
|
||||
if (justify === MarkdownTableJustify.Left) {
|
||||
lineMd.push('-----');
|
||||
} else if (justify === MarkdownTableJustify.Center) {
|
||||
lineMd.push(':---:');
|
||||
} else {
|
||||
lineMd.push('----:');
|
||||
}
|
||||
}
|
||||
|
||||
output.push(headersMd.join(' | '));
|
||||
output.push(lineMd.join(' | '));
|
||||
output.push(`| ${headersMd.join(' | ')} |`);
|
||||
output.push(`| ${lineMd.join(' | ')} |`);
|
||||
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
const row = rows[i];
|
||||
const rowMd = [];
|
||||
for (let j = 0; j < headers.length; j++) {
|
||||
const h = headers[j];
|
||||
const valueMd = markdownUtils.escapeTableCell(h.filter ? h.filter(row[h.name]) : row[h.name]);
|
||||
rowMd.push(stringPadding(valueMd, 3, ' ', stringPadding.RIGHT));
|
||||
const value = (h.filter ? h.filter(row[h.name]) : row[h.name]) || '';
|
||||
const valueMd = h.disableEscape ? value : markdownUtils.escapeTableCell(value);
|
||||
rowMd.push(stringPadding(valueMd, minCellWidth, ' ', stringPadding.RIGHT));
|
||||
}
|
||||
output.push(rowMd.join(' | '));
|
||||
output.push(`| ${rowMd.join(' | ')} |`);
|
||||
}
|
||||
|
||||
return output.join('\n');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
const markdownUtils = require('@joplin/lib/markdownUtils').default;
|
||||
const markdownUtils = require('./markdownUtils').default;
|
||||
|
||||
describe('markdownUtils', function() {
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('./test-utils.js');
|
||||
const mimeUtils = require('@joplin/lib/mime-utils.js').mime;
|
||||
const mimeUtils = require('./mime-utils.js').mime;
|
||||
|
||||
describe('mimeUils', function() {
|
||||
|
||||
@@ -1,20 +1,6 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('./test-utils.js');
|
||||
const Folder = require('@joplin/lib/models/Folder').default;
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
const BaseItem = require('@joplin/lib/models/BaseItem').default;
|
||||
const Resource = require('@joplin/lib/models/Resource').default;
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
|
||||
async function allItems() {
|
||||
const folders = await Folder.all();
|
||||
const notes = await Note.all();
|
||||
return folders.concat(notes);
|
||||
}
|
||||
const { setupDatabaseAndSynchronizer, switchClient } = require('../testing/test-utils.js');
|
||||
const Folder = require('../models/Folder').default;
|
||||
const Note = require('../models/Note').default;
|
||||
|
||||
describe('models_BaseItem', function() {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { setupDatabaseAndSynchronizer, switchClient, createFolderTree } from './test-utils';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
import { allNotesFolders } from './test-utils-synchronizer';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import shim from '@joplin/lib/shim';
|
||||
import Resource from '@joplin/lib/models/Resource';
|
||||
import { FolderEntity, NoteEntity, ResourceEntity } from '@joplin/lib/services/database/types';
|
||||
import ResourceService from '@joplin/lib/services/ResourceService';
|
||||
import { setupDatabaseAndSynchronizer, switchClient, createFolderTree, supportDir } from '../testing/test-utils';
|
||||
import Folder from '../models/Folder';
|
||||
import { allNotesFolders } from '../testing/test-utils-synchronizer';
|
||||
import Note from '../models/Note';
|
||||
import shim from '../shim';
|
||||
import Resource from '../models/Resource';
|
||||
import { FolderEntity, NoteEntity, ResourceEntity } from '../services/database/types';
|
||||
import ResourceService from '../services/ResourceService';
|
||||
|
||||
const testImagePath = `${__dirname}/../tests/support/photo.jpg`;
|
||||
const testImagePath = `${supportDir}/photo.jpg`;
|
||||
|
||||
describe('models_Folder.sharing', function() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { FolderEntity } from '@joplin/lib/services/database/types';
|
||||
import { createNTestNotes, setupDatabaseAndSynchronizer, sleep, switchClient, checkThrowAsync, createFolderTree } from './test-utils';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import { FolderEntity } from '../services/database/types';
|
||||
import { createNTestNotes, setupDatabaseAndSynchronizer, sleep, switchClient, checkThrowAsync, createFolderTree } from '../testing/test-utils';
|
||||
import Folder from './Folder';
|
||||
import Note from './Note';
|
||||
|
||||
async function allItems() {
|
||||
const folders = await Folder.all();
|
||||
@@ -1,14 +1,9 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { fileContentEqual, revisionService, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('./test-utils.js');
|
||||
const SearchEngine = require('@joplin/lib/services/searchengine/SearchEngine').default;
|
||||
const ResourceService = require('@joplin/lib/services/ResourceService').default;
|
||||
const ItemChangeUtils = require('@joplin/lib/services/ItemChangeUtils').default;
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const ItemChange = require('@joplin/lib/models/ItemChange').default;
|
||||
const { revisionService, setupDatabaseAndSynchronizer, db, switchClient } = require('../testing/test-utils.js');
|
||||
const SearchEngine = require('../services/searchengine/SearchEngine').default;
|
||||
const ResourceService = require('../services/ResourceService').default;
|
||||
const ItemChangeUtils = require('../services/ItemChangeUtils').default;
|
||||
const Note = require('../models/Note').default;
|
||||
const ItemChange = require('../models/ItemChange').default;
|
||||
|
||||
let searchEngine = null;
|
||||
|
||||
@@ -23,7 +18,7 @@ describe('models_ItemChange', function() {
|
||||
});
|
||||
|
||||
it('should delete old changes that have been processed', (async () => {
|
||||
const n1 = await Note.save({ title: 'abcd efgh' }); // 3
|
||||
await Note.save({ title: 'abcd efgh' });
|
||||
|
||||
await ItemChange.waitForAllSaved();
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import BaseModel from '@joplin/lib/BaseModel';
|
||||
import shim from '@joplin/lib/shim';
|
||||
import markdownUtils from '@joplin/lib/markdownUtils';
|
||||
const { sortedIds, createNTestNotes, setupDatabaseAndSynchronizer, switchClient, checkThrowAsync } = require('./test-utils.js');
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import Tag from '@joplin/lib/models/Tag';
|
||||
const ArrayUtils = require('@joplin/lib/ArrayUtils.js');
|
||||
import Setting from './Setting';
|
||||
import BaseModel from '../BaseModel';
|
||||
import shim from '../shim';
|
||||
import markdownUtils from '../markdownUtils';
|
||||
import { sortedIds, createNTestNotes, setupDatabaseAndSynchronizer, switchClient, checkThrowAsync, supportDir } from '../testing/test-utils';
|
||||
import Folder from './Folder';
|
||||
import Note from './Note';
|
||||
import Tag from './Tag';
|
||||
const ArrayUtils = require('../ArrayUtils.js');
|
||||
|
||||
async function allItems() {
|
||||
const folders = await Folder.all();
|
||||
@@ -30,15 +30,15 @@ describe('models_Note', function() {
|
||||
expect(items.length).toBe(1);
|
||||
expect(items[0].id).toBe(note1.id);
|
||||
|
||||
await shim.attachFileToNote(note2, `${__dirname}/../tests/support/photo.jpg`);
|
||||
await shim.attachFileToNote(note2, `${supportDir}/photo.jpg`);
|
||||
note2 = await Note.load(note2.id);
|
||||
items = await Note.linkedItems(note2.body);
|
||||
expect(items.length).toBe(2);
|
||||
expect(items[0].type_).toBe(BaseModel.TYPE_NOTE);
|
||||
expect(items[1].type_).toBe(BaseModel.TYPE_RESOURCE);
|
||||
|
||||
const resource2 = await shim.createResourceFromPath(`${__dirname}/../tests/support/photo.jpg`);
|
||||
const resource3 = await shim.createResourceFromPath(`${__dirname}/../tests/support/photo.jpg`);
|
||||
const resource2 = await shim.createResourceFromPath(`${supportDir}/photo.jpg`);
|
||||
const resource3 = await shim.createResourceFromPath(`${supportDir}/photo.jpg`);
|
||||
note2.body += `<img alt="bla" src=":/${resource2.id}"/>`;
|
||||
note2.body += `<img src=':/${resource3.id}' />`;
|
||||
items = await Note.linkedItems(note2.body);
|
||||
@@ -228,9 +228,9 @@ describe('models_Note', function() {
|
||||
it('should convert resource paths from internal to external paths', (async () => {
|
||||
const resourceDirName = Setting.value('resourceDirName');
|
||||
const resourceDir = Setting.value('resourceDir');
|
||||
const r1 = await shim.createResourceFromPath(`${__dirname}/../tests/support/photo.jpg`);
|
||||
const r2 = await shim.createResourceFromPath(`${__dirname}/../tests/support/photo.jpg`);
|
||||
const r3 = await shim.createResourceFromPath(`${__dirname}/../tests/support/welcome.pdf`);
|
||||
const r1 = await shim.createResourceFromPath(`${supportDir}/photo.jpg`);
|
||||
const r2 = await shim.createResourceFromPath(`${supportDir}/photo.jpg`);
|
||||
const r3 = await shim.createResourceFromPath(`${supportDir}/welcome.pdf`);
|
||||
const note1 = await Note.save({ title: 'note1' });
|
||||
const t1 = r1.updated_time;
|
||||
const t2 = r2.updated_time;
|
||||
@@ -1,20 +1,7 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { sortedIds, createNTestNotes, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('./test-utils.js');
|
||||
const Folder = require('@joplin/lib/models/Folder').default;
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const ArrayUtils = require('@joplin/lib/ArrayUtils.js');
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
|
||||
async function allItems() {
|
||||
const folders = await Folder.all();
|
||||
const notes = await Note.all();
|
||||
return folders.concat(notes);
|
||||
}
|
||||
const time = require('../time').default;
|
||||
const { setupDatabaseAndSynchronizer, switchClient } = require('../testing/test-utils.js');
|
||||
const Folder = require('../models/Folder').default;
|
||||
const Note = require('../models/Note').default;
|
||||
|
||||
describe('models_Note_CustomSortOrder', function() {
|
||||
beforeEach(async (done) => {
|
||||
@@ -1,15 +1,10 @@
|
||||
/* eslint-disable no-unused-vars, require-atomic-updates */
|
||||
const { supportDir, setupDatabaseAndSynchronizer, switchClient } = require('../testing/test-utils.js');
|
||||
const Folder = require('../models/Folder').default;
|
||||
const Note = require('../models/Note').default;
|
||||
const Resource = require('../models/Resource').default;
|
||||
const shim = require('../shim').default;
|
||||
|
||||
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('./test-utils.js');
|
||||
const Folder = require('@joplin/lib/models/Folder').default;
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
const Resource = require('@joplin/lib/models/Resource').default;
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
|
||||
const testImagePath = `${__dirname}/../tests/support/photo.jpg`;
|
||||
const testImagePath = `${supportDir}/photo.jpg`;
|
||||
|
||||
describe('models_Resource', function() {
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('./test-utils.js');
|
||||
const Folder = require('@joplin/lib/models/Folder').default;
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
const NoteTag = require('@joplin/lib/models/NoteTag').default;
|
||||
const Tag = require('@joplin/lib/models/Tag').default;
|
||||
const Revision = require('@joplin/lib/models/Revision').default;
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
const { setupDatabaseAndSynchronizer, switchClient } = require('../testing/test-utils.js');
|
||||
const Note = require('../models/Note').default;
|
||||
const Revision = require('../models/Revision').default;
|
||||
|
||||
describe('models_Revision', function() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Setting, { SettingSectionSource } from '@joplin/lib/models/Setting';
|
||||
import { setupDatabaseAndSynchronizer, switchClient, expectThrow, expectNotThrow, msleep } from './test-utils';
|
||||
import Setting, { SettingSectionSource } from '../models/Setting';
|
||||
import { setupDatabaseAndSynchronizer, switchClient, expectThrow, expectNotThrow, msleep } from '../testing/test-utils';
|
||||
import * as fs from 'fs-extra';
|
||||
import Logger from '@joplin/lib/Logger';
|
||||
import Logger from '../Logger';
|
||||
|
||||
async function loadSettingsFromFile(): Promise<any> {
|
||||
return JSON.parse(await fs.readFile(Setting.settingFilePath, 'utf8'));
|
||||
@@ -476,20 +476,6 @@ class Setting extends BaseModel {
|
||||
description: () => emptyDirWarning,
|
||||
storage: SettingStorage.File,
|
||||
},
|
||||
// 'sync.9.directory': {
|
||||
// value: 'Apps/Joplin',
|
||||
// type: SettingItemType.String,
|
||||
// section: 'sync',
|
||||
// show: (settings: any) => {
|
||||
// return settings['sync.target'] == SyncTargetRegistry.nameToId('joplinServer');
|
||||
// },
|
||||
// filter: value => {
|
||||
// return value ? ltrimSlashes(rtrimSlashes(value)) : '';
|
||||
// },
|
||||
// public: true,
|
||||
// label: () => _('Joplin Server Directory'),
|
||||
// storage: SettingStorage.File,
|
||||
// },
|
||||
'sync.9.username': {
|
||||
value: '',
|
||||
type: SettingItemType.String,
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('./test-utils.js');
|
||||
const Folder = require('@joplin/lib/models/Folder').default;
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
const NoteTag = require('@joplin/lib/models/NoteTag').default;
|
||||
const Tag = require('@joplin/lib/models/Tag').default;
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
const { setupDatabaseAndSynchronizer, switchClient, checkThrowAsync } = require('../testing/test-utils.js');
|
||||
const Folder = require('../models/Folder').default;
|
||||
const Note = require('../models/Note').default;
|
||||
const Tag = require('../models/Tag').default;
|
||||
|
||||
describe('models_Tag', function() {
|
||||
|
||||
@@ -58,11 +51,20 @@ describe('models_Tag', function() {
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
const note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
const note2 = await Note.save({ title: 'ma 2nd note', parent_id: folder1.id });
|
||||
const todo1 = await Note.save({ title: 'todo 1', parent_id: folder1.id, is_todo: 1, todo_completed: 1590085027710 });
|
||||
await Tag.setNoteTagsByTitles(note1.id, ['un']);
|
||||
await Tag.setNoteTagsByTitles(note2.id, ['un']);
|
||||
await Tag.setNoteTagsByTitles(todo1.id, ['un']);
|
||||
|
||||
let tags = await Tag.allWithNotes();
|
||||
expect(tags.length).toBe(1);
|
||||
expect(tags[0].note_count).toBe(3);
|
||||
expect(tags[0].todo_completed_count).toBe(1);
|
||||
|
||||
await Note.delete(todo1.id);
|
||||
|
||||
tags = await Tag.allWithNotes();
|
||||
expect(tags.length).toBe(1);
|
||||
expect(tags[0].note_count).toBe(2);
|
||||
|
||||
await Note.delete(note1.id);
|
||||
@@ -81,6 +83,8 @@ describe('models_Tag', function() {
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
const note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
const note2 = await Note.save({ title: 'ma 2nd note', parent_id: folder1.id });
|
||||
const todo1 = await Note.save({ title: 'todo 2', parent_id: folder1.id, is_todo: 1, todo_completed: 1590085027710 });
|
||||
const todo2 = await Note.save({ title: 'todo 2', parent_id: folder1.id, is_todo: 1 });
|
||||
const tag = await Tag.save({ title: 'mytag' });
|
||||
await Tag.addNote(tag.id, note1.id);
|
||||
|
||||
@@ -90,6 +94,12 @@ describe('models_Tag', function() {
|
||||
await Tag.addNote(tag.id, note2.id);
|
||||
tagWithCount = await Tag.loadWithCount(tag.id);
|
||||
expect(tagWithCount.note_count).toBe(2);
|
||||
|
||||
await Tag.addNote(tag.id, todo1.id);
|
||||
await Tag.addNote(tag.id, todo2.id);
|
||||
tagWithCount = await Tag.loadWithCount(tag.id);
|
||||
expect(tagWithCount.note_count).toBe(4);
|
||||
expect(tagWithCount.todo_completed_count).toBe(1);
|
||||
}));
|
||||
|
||||
it('should get common tags for set of notes', (async () => {
|
||||
@@ -97,7 +107,7 @@ describe('models_Tag', function() {
|
||||
const taga = await Tag.save({ title: 'mytaga' });
|
||||
const tagb = await Tag.save({ title: 'mytagb' });
|
||||
const tagc = await Tag.save({ title: 'mytagc' });
|
||||
const tagd = await Tag.save({ title: 'mytagd' });
|
||||
await Tag.save({ title: 'mytagd' });
|
||||
|
||||
const note0 = await Note.save({ title: 'ma note 0', parent_id: folder1.id });
|
||||
const note1 = await Note.save({ title: 'ma note 1', parent_id: folder1.id });
|
||||
@@ -138,6 +148,7 @@ describe('models_Tag', function() {
|
||||
expect(commonTagIds.includes(tagb.id)).toBe(true);
|
||||
|
||||
commonTags = await Tag.commonTagsByNoteIds([note3.id]);
|
||||
|
||||
commonTagIds = commonTags.map(t => t.id);
|
||||
expect(commonTags.length).toBe(3);
|
||||
expect(commonTagIds.includes(taga.id)).toBe(true);
|
||||
@@ -1,5 +1,5 @@
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import time from '@joplin/lib/time';
|
||||
import Setting from '../models/Setting';
|
||||
import time from '../time';
|
||||
|
||||
describe('dateFormats', function() {
|
||||
|
||||
374
packages/lib/package-lock.json
generated
374
packages/lib/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/lib",
|
||||
"version": "2.0.0",
|
||||
"version": "2.0.2",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -777,6 +777,15 @@
|
||||
"@babel/types": "^7.3.0"
|
||||
}
|
||||
},
|
||||
"@types/fs-extra": {
|
||||
"version": "9.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.11.tgz",
|
||||
"integrity": "sha512-mZsifGG4QeQ7hlkhO56u7zt/ycBgGxSVsFI/6lGTU34VtwkiqrrSDgw0+ygs8kFGWcXnFQWMrzF2h7TtDFNixA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/graceful-fs": {
|
||||
"version": "4.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.4.tgz",
|
||||
@@ -1014,6 +1023,12 @@
|
||||
"typical": "^2.6.1"
|
||||
}
|
||||
},
|
||||
"array-flatten": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-3.0.0.tgz",
|
||||
"integrity": "sha512-zPMVc3ZYlGLNk4mpK1NzP2wg0ml9t7fUgDsayR5Y5rSzxQilzR9FGu/EH2jQOcKSAeAfWeylyW8juy3OkWRvNA==",
|
||||
"dev": true
|
||||
},
|
||||
"array-unique": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
|
||||
@@ -1265,6 +1280,40 @@
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz",
|
||||
"integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ=="
|
||||
},
|
||||
"bl": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"buffer": "^5.5.0",
|
||||
"inherits": "^2.0.4",
|
||||
"readable-stream": "^3.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"buffer": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
||||
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.1.13"
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"block-stream": {
|
||||
"version": "0.0.9",
|
||||
"resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
|
||||
@@ -1494,6 +1543,16 @@
|
||||
"source-map": "~0.6.0"
|
||||
}
|
||||
},
|
||||
"clean-html": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/clean-html/-/clean-html-1.5.0.tgz",
|
||||
"integrity": "sha512-eDu0vN44ZBvoEU0oRIKwWPIccGWXtdnUNmKJuTukZ1de00Uoqavb5pfIMKiC7/r+knQ5RbvAjGuVZiN3JwJL4Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"htmlparser2": "^3.8.2",
|
||||
"minimist": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"cliss": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/cliss/-/cliss-0.0.2.tgz",
|
||||
@@ -1788,6 +1847,15 @@
|
||||
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
|
||||
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
|
||||
},
|
||||
"decompress-response": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
|
||||
"integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mimic-response": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"deep-extend": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
|
||||
@@ -1882,6 +1950,55 @@
|
||||
"integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==",
|
||||
"dev": true
|
||||
},
|
||||
"dom-serializer": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
|
||||
"integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"entities": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"domelementtype": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
|
||||
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==",
|
||||
"dev": true
|
||||
},
|
||||
"entities": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
|
||||
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"domelementtype": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
|
||||
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
|
||||
"dev": true
|
||||
},
|
||||
"domhandler": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
|
||||
"integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"domelementtype": "1"
|
||||
}
|
||||
},
|
||||
"domutils": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
|
||||
"integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dom-serializer": "0",
|
||||
"domelementtype": "1"
|
||||
}
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||
@@ -1930,6 +2047,12 @@
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"entities": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
|
||||
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
|
||||
"dev": true
|
||||
},
|
||||
"error-ex": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
|
||||
@@ -2071,6 +2194,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"expand-template": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
|
||||
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
|
||||
"dev": true
|
||||
},
|
||||
"expect": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz",
|
||||
@@ -2284,6 +2413,12 @@
|
||||
"map-cache": "^0.2.2"
|
||||
}
|
||||
},
|
||||
"fs-constants": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
||||
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
|
||||
"dev": true
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
|
||||
@@ -2404,6 +2539,12 @@
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"github-from-package": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
|
||||
"integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=",
|
||||
"dev": true
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||
@@ -2563,6 +2704,33 @@
|
||||
"uglify-js": "3.4.x"
|
||||
}
|
||||
},
|
||||
"htmlparser2": {
|
||||
"version": "3.10.1",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
|
||||
"integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"domelementtype": "^1.3.1",
|
||||
"domhandler": "^2.3.0",
|
||||
"domutils": "^1.5.1",
|
||||
"entities": "^1.1.1",
|
||||
"inherits": "^2.0.1",
|
||||
"readable-stream": "^3.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.0.tgz",
|
||||
@@ -3994,6 +4162,15 @@
|
||||
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz",
|
||||
"integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw="
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"magicli": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/magicli/-/magicli-0.0.8.tgz",
|
||||
@@ -4120,6 +4297,12 @@
|
||||
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
||||
"dev": true
|
||||
},
|
||||
"mimic-response": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
|
||||
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
|
||||
"dev": true
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
@@ -4162,6 +4345,12 @@
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
},
|
||||
"mkdirp-classic": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
||||
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
|
||||
"dev": true
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.29.1",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
||||
@@ -4219,6 +4408,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"napi-build-utils": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
|
||||
"integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
|
||||
"dev": true
|
||||
},
|
||||
"natural-compare": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||
@@ -4249,6 +4444,23 @@
|
||||
"lower-case": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"node-abi": {
|
||||
"version": "2.26.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.26.0.tgz",
|
||||
"integrity": "sha512-ag/Vos/mXXpWLLAYWsAoQdgS+gW7IwvgMLOgqopm/DbzAjazLltzgzpVMsFlgmo9TzG5hGXeaBZx2AI731RIsQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"semver": "^5.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node-addon-api": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.0.tgz",
|
||||
@@ -4387,6 +4599,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"noop-logger": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz",
|
||||
"integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=",
|
||||
"dev": true
|
||||
},
|
||||
"nopt": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
|
||||
@@ -4788,6 +5006,28 @@
|
||||
"integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
|
||||
"dev": true
|
||||
},
|
||||
"prebuild-install": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.2.tgz",
|
||||
"integrity": "sha512-PzYWIKZeP+967WuKYXlTOhYBgGOvTRSfaKI89XnfJ0ansRAH7hDU45X+K+FZeI1Wb/7p/NnuctPH3g0IqKUuSQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"detect-libc": "^1.0.3",
|
||||
"expand-template": "^2.0.3",
|
||||
"github-from-package": "0.0.0",
|
||||
"minimist": "^1.2.3",
|
||||
"mkdirp-classic": "^0.5.3",
|
||||
"napi-build-utils": "^1.0.1",
|
||||
"node-abi": "^2.21.0",
|
||||
"noop-logger": "^0.1.1",
|
||||
"npmlog": "^4.0.1",
|
||||
"pump": "^3.0.0",
|
||||
"rc": "^1.2.7",
|
||||
"simple-get": "^3.0.3",
|
||||
"tar-fs": "^2.0.0",
|
||||
"tunnel-agent": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"prelude-ls": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
|
||||
@@ -5440,6 +5680,77 @@
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
||||
},
|
||||
"sharp": {
|
||||
"version": "0.26.3",
|
||||
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.26.3.tgz",
|
||||
"integrity": "sha512-NdEJ9S6AMr8Px0zgtFo1TJjMK/ROMU92MkDtYn2BBrDjIx3YfH9TUyGdzPC+I/L619GeYQc690Vbaxc5FPCCWg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"array-flatten": "^3.0.0",
|
||||
"color": "^3.1.3",
|
||||
"detect-libc": "^1.0.3",
|
||||
"node-addon-api": "^3.0.2",
|
||||
"npmlog": "^4.1.2",
|
||||
"prebuild-install": "^6.0.0",
|
||||
"semver": "^7.3.2",
|
||||
"simple-get": "^4.0.0",
|
||||
"tar-fs": "^2.1.1",
|
||||
"tunnel-agent": "^0.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"color": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz",
|
||||
"integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^1.9.1",
|
||||
"color-string": "^1.5.4"
|
||||
}
|
||||
},
|
||||
"decompress-response": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
|
||||
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mimic-response": "^3.1.0"
|
||||
}
|
||||
},
|
||||
"mimic-response": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
|
||||
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node-addon-api": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.0.tgz",
|
||||
"integrity": "sha512-kcwSAWhPi4+QzAtsL2+2s/awvDo2GKLsvMCwNRxb5BUshteXU8U97NCyvQDsGKs/m0He9WcG4YWew/BnuLx++w==",
|
||||
"dev": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.3.5",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"simple-get": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.0.tgz",
|
||||
"integrity": "sha512-ZalZGexYr3TA0SwySsr5HlgOOinS4Jsa8YB2GJ6lUNAazyAu4KG/VmzMTwAt2YVXzzVj8QmefmAonZIK2BSGcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"decompress-response": "^6.0.0",
|
||||
"once": "^1.3.1",
|
||||
"simple-concat": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shebang-command": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
|
||||
@@ -5465,6 +5776,23 @@
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
|
||||
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
|
||||
},
|
||||
"simple-concat": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
|
||||
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"simple-get": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
|
||||
"integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"decompress-response": "^4.2.0",
|
||||
"once": "^1.3.1",
|
||||
"simple-concat": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"simple-swizzle": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
|
||||
@@ -6029,6 +6357,44 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"tar-fs": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
|
||||
"integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chownr": "^1.1.1",
|
||||
"mkdirp-classic": "^0.5.2",
|
||||
"pump": "^3.0.0",
|
||||
"tar-stream": "^2.1.4"
|
||||
}
|
||||
},
|
||||
"tar-stream": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
|
||||
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bl": "^4.0.3",
|
||||
"end-of-stream": "^1.4.1",
|
||||
"fs-constants": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^3.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tcp-port-used": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-0.1.2.tgz",
|
||||
@@ -6600,6 +6966,12 @@
|
||||
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "15.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/lib",
|
||||
"version": "2.0.0",
|
||||
"version": "2.0.2",
|
||||
"description": "Joplin Core library",
|
||||
"author": "Laurent Cozic",
|
||||
"homepage": "",
|
||||
@@ -16,17 +16,20 @@
|
||||
"test-ci": "npm run test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "^9.0.6",
|
||||
"@types/jest": "^26.0.15",
|
||||
"@types/node": "^14.14.6",
|
||||
"clean-html": "^1.5.0",
|
||||
"jest": "^26.6.3",
|
||||
"sharp": "^0.26.2",
|
||||
"typescript": "^4.0.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@joplin/fork-htmlparser2": "^4.1.24",
|
||||
"@joplin/fork-sax": "^1.2.28",
|
||||
"@joplin/fork-htmlparser2": "^4.1.26",
|
||||
"@joplin/fork-sax": "^1.2.30",
|
||||
"@joplin/renderer": "^1.8.2",
|
||||
"@joplin/turndown": "^4.0.46",
|
||||
"@joplin/turndown-plugin-gfm": "^1.0.28",
|
||||
"@joplin/turndown": "^4.0.48",
|
||||
"@joplin/turndown-plugin-gfm": "^1.0.30",
|
||||
"async-mutex": "^0.1.3",
|
||||
"aws-sdk": "^2.588.0",
|
||||
"base-64": "^0.1.0",
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
|
||||
const { extractExecutablePath, quotePath, unquotePath, friendlySafeFilename, toFileProtocolPath } = require('@joplin/lib/path-utils');
|
||||
const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('./test-utils.js');
|
||||
const { extractExecutablePath, quotePath, unquotePath, friendlySafeFilename, toFileProtocolPath } = require('./path-utils');
|
||||
|
||||
describe('pathUtils', function() {
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
const { setupDatabaseAndSynchronizer, switchClient, createNTestNotes, createNTestFolders, createNTestTags } = require('./test-utils.js');
|
||||
const Folder = require('@joplin/lib/models/Folder').default;
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
const Tag = require('@joplin/lib/models/Tag').default;
|
||||
const reducer = require('@joplin/lib/reducer').default;
|
||||
const { defaultState, stateUtils, MAX_HISTORY } = require('@joplin/lib/reducer');
|
||||
const { ALL_NOTES_FILTER_ID } = require('@joplin/lib/reserved-ids');
|
||||
const { setupDatabaseAndSynchronizer, switchClient, createNTestNotes, createNTestFolders, createNTestTags } = require('./testing/test-utils.js');
|
||||
const reducer = require('./reducer').default;
|
||||
const { defaultState, MAX_HISTORY } = require('./reducer');
|
||||
const { ALL_NOTES_FILTER_ID } = require('./reserved-ids');
|
||||
|
||||
function initTestState(folders, selectedFolderIndex, notes, selectedNoteIndexes, tags = null, selectedTagIndex = null) {
|
||||
let state = defaultState;
|
||||
@@ -86,19 +81,13 @@ function getIds(items, indexes = null) {
|
||||
return ids;
|
||||
}
|
||||
|
||||
let insideBeforeEach = false;
|
||||
|
||||
describe('reducer', function() {
|
||||
|
||||
beforeEach(async (done) => {
|
||||
insideBeforeEach = true;
|
||||
|
||||
await setupDatabaseAndSynchronizer(1);
|
||||
await switchClient(1);
|
||||
|
||||
done();
|
||||
|
||||
insideBeforeEach = false;
|
||||
});
|
||||
|
||||
// tests for NOTE_DELETE
|
||||
@@ -560,7 +549,6 @@ describe('reducer', function() {
|
||||
// select the 1st folder and the 1st note
|
||||
let state = initTestState(folders, 0, notes, [0]);
|
||||
|
||||
const idx = 0;
|
||||
for (let i = 0; i < 2 * MAX_HISTORY; i++) {
|
||||
state = goToNote(notes, [i % 5], state);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import { reg } from '@joplin/lib/registry';
|
||||
import Setting from './models/Setting';
|
||||
import { reg } from './registry';
|
||||
|
||||
const sync = {
|
||||
start: jest.fn().mockReturnValue({}),
|
||||
@@ -1,10 +1,10 @@
|
||||
import MenuUtils from '@joplin/lib/services/commands/MenuUtils';
|
||||
import ToolbarButtonUtils from '@joplin/lib/services/commands/ToolbarButtonUtils';
|
||||
import CommandService, { CommandDeclaration, CommandRuntime } from '@joplin/lib/services/CommandService';
|
||||
import stateToWhenClauseContext from '@joplin/lib/services/commands/stateToWhenClauseContext';
|
||||
import KeymapService from '@joplin/lib/services/KeymapService';
|
||||
import MenuUtils from '../services/commands/MenuUtils';
|
||||
import ToolbarButtonUtils from '../services/commands/ToolbarButtonUtils';
|
||||
import CommandService, { CommandDeclaration, CommandRuntime } from '../services/CommandService';
|
||||
import stateToWhenClauseContext from '../services/commands/stateToWhenClauseContext';
|
||||
import KeymapService from '../services/KeymapService';
|
||||
|
||||
const { setupDatabaseAndSynchronizer, switchClient, expectThrow, expectNotThrow } = require('./test-utils.js');
|
||||
const { setupDatabaseAndSynchronizer, switchClient, expectThrow, expectNotThrow } = require('../testing/test-utils.js');
|
||||
|
||||
interface TestCommand {
|
||||
declaration: CommandDeclaration;
|
||||
@@ -1,18 +1,12 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
/* eslint-disable no-unused-vars, @typescript-eslint/no-unused-vars, prefer-const */
|
||||
|
||||
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('./test-utils.js');
|
||||
const Folder = require('@joplin/lib/models/Folder').default;
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
const Tag = require('@joplin/lib/models/Tag').default;
|
||||
const Database = require('@joplin/lib/database').default;
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const BaseItem = require('@joplin/lib/models/BaseItem').default;
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const MasterKey = require('@joplin/lib/models/MasterKey').default;
|
||||
const SyncTargetRegistry = require('@joplin/lib/SyncTargetRegistry.js');
|
||||
const EncryptionService = require('@joplin/lib/services/EncryptionService').default;
|
||||
const { fileContentEqual, setupDatabaseAndSynchronizer, supportDir, switchClient, objectsEqual, checkThrowAsync } = require('../testing/test-utils.js');
|
||||
const Folder = require('../models/Folder').default;
|
||||
const Note = require('../models/Note').default;
|
||||
const Setting = require('../models/Setting').default;
|
||||
const BaseItem = require('../models/BaseItem').default;
|
||||
const MasterKey = require('../models/MasterKey').default;
|
||||
const EncryptionService = require('../services/EncryptionService').default;
|
||||
|
||||
let service = null;
|
||||
|
||||
@@ -256,7 +250,7 @@ describe('services_EncryptionService', function() {
|
||||
masterKey = await MasterKey.save(masterKey);
|
||||
await service.loadMasterKey_(masterKey, '123456', true);
|
||||
|
||||
const sourcePath = `${__dirname}/../tests/support/photo.jpg`;
|
||||
const sourcePath = `${supportDir}/photo.jpg`;
|
||||
const encryptedPath = `${Setting.value('tempDir')}/photo.crypted`;
|
||||
const decryptedPath = `${Setting.value('tempDir')}/photo.jpg`;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
const { tempFilePath } = require('./test-utils.js');
|
||||
const KeymapService = require('@joplin/lib/services/KeymapService').default;
|
||||
const { tempFilePath } = require('../testing/test-utils.js');
|
||||
const KeymapService = require('../services/KeymapService').default;
|
||||
const keymapService = KeymapService.instance();
|
||||
keymapService.initialize([]);
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
|
||||
const { fileContentEqual, setupDatabase, revisionService, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('./test-utils.js');
|
||||
const KvStore = require('@joplin/lib/services/KvStore').default;
|
||||
const { setupDatabaseAndSynchronizer, db, switchClient } = require('../testing/test-utils.js');
|
||||
const KvStore = require('../services/KvStore').default;
|
||||
|
||||
function setupStore() {
|
||||
const store = KvStore.instance();
|
||||
@@ -1,13 +1,13 @@
|
||||
import time from '@joplin/lib/time';
|
||||
import NoteResource from '@joplin/lib/models/NoteResource';
|
||||
import ResourceService from '@joplin/lib/services/ResourceService';
|
||||
import shim from '@joplin/lib/shim';
|
||||
import time from '../time';
|
||||
import NoteResource from '../models/NoteResource';
|
||||
import ResourceService from '../services/ResourceService';
|
||||
import shim from '../shim';
|
||||
|
||||
const { resourceService, decryptionWorker, encryptionService, loadEncryptionMasterKey, allSyncTargetItemsEncrypted, setupDatabaseAndSynchronizer, db, synchronizer, switchClient } = require('./test-utils.js');
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import Resource from '@joplin/lib/models/Resource';
|
||||
import SearchEngine from '@joplin/lib/services/searchengine/SearchEngine';
|
||||
const { resourceService, decryptionWorker, supportDir, encryptionService, loadEncryptionMasterKey, allSyncTargetItemsEncrypted, setupDatabaseAndSynchronizer, db, synchronizer, switchClient } = require('../testing/test-utils.js');
|
||||
import Folder from '../models/Folder';
|
||||
import Note from '../models/Note';
|
||||
import Resource from '../models/Resource';
|
||||
import SearchEngine from '../services/searchengine/SearchEngine';
|
||||
|
||||
describe('services_ResourceService', function() {
|
||||
|
||||
@@ -23,7 +23,7 @@ describe('services_ResourceService', function() {
|
||||
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
note1 = await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
note1 = await shim.attachFileToNote(note1, `${supportDir}/photo.jpg`);
|
||||
const resource1 = (await Resource.all())[0];
|
||||
const resourcePath = Resource.fullPath(resource1);
|
||||
|
||||
@@ -55,7 +55,7 @@ describe('services_ResourceService', function() {
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
const note2 = await Note.save({ title: 'ma deuxième note', parent_id: folder1.id });
|
||||
note1 = await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
note1 = await shim.attachFileToNote(note1, `${supportDir}/photo.jpg`);
|
||||
const resource1 = (await Resource.all())[0];
|
||||
|
||||
await service.indexNoteResources();
|
||||
@@ -75,7 +75,7 @@ describe('services_ResourceService', function() {
|
||||
|
||||
it('should not delete a resource that has never been associated with any note, because it probably means the resource came via sync, and associated note has not arrived yet', (async () => {
|
||||
const service = new ResourceService();
|
||||
await shim.createResourceFromPath(`${__dirname}/../tests/support/photo.jpg`);
|
||||
await shim.createResourceFromPath(`${supportDir}/photo.jpg`);
|
||||
|
||||
await service.indexNoteResources();
|
||||
await service.deleteOrphanResources(0);
|
||||
@@ -88,7 +88,7 @@ describe('services_ResourceService', function() {
|
||||
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
note1 = await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
note1 = await shim.attachFileToNote(note1, `${supportDir}/photo.jpg`);
|
||||
const resource1 = (await Resource.all())[0];
|
||||
|
||||
await service.indexNoteResources();
|
||||
@@ -107,7 +107,7 @@ describe('services_ResourceService', function() {
|
||||
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
const note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
await shim.attachFileToNote(note1, `${supportDir}/photo.jpg`);
|
||||
|
||||
await service.indexNoteResources();
|
||||
|
||||
@@ -143,7 +143,7 @@ describe('services_ResourceService', function() {
|
||||
await encryptionService().loadMasterKeysFromSettings();
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
const note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`); // R1
|
||||
await shim.attachFileToNote(note1, `${supportDir}/photo.jpg`); // R1
|
||||
await resourceService().indexNoteResources();
|
||||
await synchronizer().start();
|
||||
expect(await allSyncTargetItemsEncrypted()).toBe(true);
|
||||
@@ -156,7 +156,7 @@ describe('services_ResourceService', function() {
|
||||
await decryptionWorker().start();
|
||||
{
|
||||
const n1 = await Note.load(note1.id);
|
||||
await shim.attachFileToNote(n1, `${__dirname}/../tests/support/photo.jpg`); // R2
|
||||
await shim.attachFileToNote(n1, `${supportDir}/photo.jpg`); // R2
|
||||
}
|
||||
await synchronizer().start();
|
||||
|
||||
@@ -173,7 +173,7 @@ describe('services_ResourceService', function() {
|
||||
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
note1 = await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
note1 = await shim.attachFileToNote(note1, `${supportDir}/photo.jpg`);
|
||||
await resourceService().indexNoteResources();
|
||||
const bodyWithResource = note1.body;
|
||||
await Note.save({ id: note1.id, body: '' });
|
||||
@@ -198,7 +198,7 @@ describe('services_ResourceService', function() {
|
||||
// const service = new ResourceService();
|
||||
|
||||
// let note = await Note.save({});
|
||||
// note = await shim.attachFileToNote(note, `${__dirname}/../tests/support/photo.jpg`);
|
||||
// note = await shim.attachFileToNote(note, `${supportDir}/photo.jpg`);
|
||||
// const resource = (await Resource.all())[0];
|
||||
|
||||
// const noteIds = await NoteResource.associatedNoteIds(resource.id);
|
||||
@@ -1,18 +1,13 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
/* eslint-disable no-unused-vars, @typescript-eslint/no-unused-vars, prefer-const */
|
||||
|
||||
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { fileContentEqual, setupDatabase, revisionService, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('./test-utils.js');
|
||||
const Folder = require('@joplin/lib/models/Folder').default;
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
const NoteTag = require('@joplin/lib/models/NoteTag').default;
|
||||
const ItemChange = require('@joplin/lib/models/ItemChange').default;
|
||||
const Tag = require('@joplin/lib/models/Tag').default;
|
||||
const Revision = require('@joplin/lib/models/Revision').default;
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const RevisionService = require('@joplin/lib/services/RevisionService').default;
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
const time = require('../time').default;
|
||||
const { revisionService, setupDatabaseAndSynchronizer, switchClient } = require('../testing/test-utils.js');
|
||||
const Setting = require('../models/Setting').default;
|
||||
const Note = require('../models/Note').default;
|
||||
const ItemChange = require('../models/ItemChange').default;
|
||||
const Revision = require('../models/Revision').default;
|
||||
const BaseModel = require('../BaseModel').default;
|
||||
const RevisionService = require('../services/RevisionService').default;
|
||||
|
||||
describe('services_Revision', function() {
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import InteropService from '@joplin/lib/services/interop/InteropService';
|
||||
import { CustomExportContext, CustomImportContext, Module, ModuleType } from '@joplin/lib/services/interop/types';
|
||||
import shim from '@joplin/lib/shim';
|
||||
import InteropService from '../../services/interop/InteropService';
|
||||
import { CustomExportContext, CustomImportContext, Module, ModuleType } from '../../services/interop/types';
|
||||
import shim from '../../shim';
|
||||
|
||||
const { fileContentEqual, setupDatabaseAndSynchronizer, switchClient, checkThrowAsync, exportDir } = require('./test-utils.js');
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import Tag from '@joplin/lib/models/Tag';
|
||||
import Resource from '@joplin/lib/models/Resource';
|
||||
const { fileContentEqual, setupDatabaseAndSynchronizer, switchClient, checkThrowAsync, exportDir, supportDir } = require('../../testing/test-utils.js');
|
||||
import Folder from '../../models/Folder';
|
||||
import Note from '../../models/Note';
|
||||
import Tag from '../../models/Tag';
|
||||
import Resource from '../../models/Resource';
|
||||
const fs = require('fs-extra');
|
||||
const ArrayUtils = require('@joplin/lib/ArrayUtils');
|
||||
const ArrayUtils = require('../../ArrayUtils');
|
||||
|
||||
async function recreateExportDir() {
|
||||
const dir = exportDir();
|
||||
@@ -209,7 +209,7 @@ describe('services_InteropService', function() {
|
||||
const filePath = `${exportDir()}/test.jex`;
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
await shim.attachFileToNote(note1, `${supportDir}/photo.jpg`);
|
||||
note1 = await Note.load(note1.id);
|
||||
let resourceIds = await Note.linkedResourceIds(note1.body);
|
||||
const resource1 = await Resource.load(resourceIds[0]);
|
||||
@@ -499,7 +499,7 @@ describe('services_InteropService', function() {
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
const note1 = await Note.save({ title: 'note1', parent_id: folder1.id });
|
||||
await Note.save({ title: 'note2', parent_id: folder1.id });
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
await shim.attachFileToNote(note1, `${supportDir}/photo.jpg`);
|
||||
|
||||
const filePath = `${exportDir()}/example.test`;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import InteropService from '@joplin/lib/services/interop/InteropService';
|
||||
import { PluginStates } from '@joplin/lib/services/plugins/reducer';
|
||||
import { setupDatabaseAndSynchronizer, switchClient, exportDir } from './test-utils';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import InteropService from '../../services/interop/InteropService';
|
||||
import { PluginStates } from '../../services/plugins/reducer';
|
||||
import { setupDatabaseAndSynchronizer, switchClient, exportDir } from '../../testing/test-utils';
|
||||
import Folder from '../../models/Folder';
|
||||
import Note from '../../models/Note';
|
||||
import * as fs from 'fs-extra';
|
||||
import { tempFilePath } from './test-utils';
|
||||
import { ContentScriptType } from '@joplin/lib/services/plugins/api/types';
|
||||
import { tempFilePath } from '../../testing/test-utils';
|
||||
import { ContentScriptType } from '../../services/plugins/api/types';
|
||||
|
||||
async function recreateExportDir() {
|
||||
const dir = exportDir();
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
|
||||
const fs = require('fs-extra');
|
||||
const { setupDatabaseAndSynchronizer, switchClient, exportDir } = require('./test-utils.js');
|
||||
const InteropService_Exporter_Md = require('@joplin/lib/services/interop/InteropService_Exporter_Md').default;
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const Folder = require('@joplin/lib/models/Folder').default;
|
||||
const Resource = require('@joplin/lib/models/Resource').default;
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
const { setupDatabaseAndSynchronizer, switchClient, exportDir, supportDir } = require('../../testing/test-utils.js');
|
||||
const InteropService_Exporter_Md = require('../../services/interop/InteropService_Exporter_Md').default;
|
||||
const BaseModel = require('../../BaseModel').default;
|
||||
const Folder = require('../../models/Folder').default;
|
||||
const Resource = require('../../models/Resource').default;
|
||||
const Note = require('../../models/Note').default;
|
||||
const shim = require('../../shim').default;
|
||||
|
||||
describe('services_InteropService_Exporter_Md', function() {
|
||||
|
||||
@@ -43,7 +43,7 @@ describe('services_InteropService_Exporter_Md', function() {
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'note1', parent_id: folder1.id });
|
||||
const note2 = await Note.save({ title: 'note2', parent_id: folder1.id });
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
await shim.attachFileToNote(note1, `${supportDir}/photo.jpg`);
|
||||
note1 = await Note.load(note1.id);
|
||||
queueExportItem(BaseModel.TYPE_FOLDER, folder1.id);
|
||||
queueExportItem(BaseModel.TYPE_NOTE, note1);
|
||||
@@ -52,7 +52,7 @@ describe('services_InteropService_Exporter_Md', function() {
|
||||
|
||||
const folder2 = await Folder.save({ title: 'folder2' });
|
||||
let note3 = await Note.save({ title: 'note3', parent_id: folder2.id });
|
||||
await shim.attachFileToNote(note3, `${__dirname}/../tests/support/photo.jpg`);
|
||||
await shim.attachFileToNote(note3, `${supportDir}/photo.jpg`);
|
||||
note3 = await Note.load(note3.id);
|
||||
queueExportItem(BaseModel.TYPE_FOLDER, folder2.id);
|
||||
queueExportItem(BaseModel.TYPE_NOTE, note3);
|
||||
@@ -138,7 +138,7 @@ describe('services_InteropService_Exporter_Md', function() {
|
||||
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'note1', parent_id: folder1.id });
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
await shim.attachFileToNote(note1, `${supportDir}/photo.jpg`);
|
||||
note1 = await Note.load(note1.id);
|
||||
queueExportItem(BaseModel.TYPE_FOLDER, folder1.id);
|
||||
queueExportItem(BaseModel.TYPE_NOTE, note1);
|
||||
@@ -147,7 +147,7 @@ describe('services_InteropService_Exporter_Md', function() {
|
||||
|
||||
const folder2 = await Folder.save({ title: 'folder2', parent_id: folder1.id });
|
||||
let note2 = await Note.save({ title: 'note2', parent_id: folder2.id });
|
||||
await shim.attachFileToNote(note2, `${__dirname}/../tests/support/photo.jpg`);
|
||||
await shim.attachFileToNote(note2, `${supportDir}/photo.jpg`);
|
||||
note2 = await Note.load(note2.id);
|
||||
queueExportItem(BaseModel.TYPE_FOLDER, folder2.id);
|
||||
queueExportItem(BaseModel.TYPE_NOTE, note2);
|
||||
@@ -243,14 +243,14 @@ describe('services_InteropService_Exporter_Md', function() {
|
||||
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'note1', parent_id: folder1.id });
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
await shim.attachFileToNote(note1, `${supportDir}/photo.jpg`);
|
||||
note1 = await Note.load(note1.id);
|
||||
queueExportItem(BaseModel.TYPE_NOTE, note1);
|
||||
const resource1 = await Resource.load((await Note.linkedResourceIds(note1.body))[0]);
|
||||
|
||||
const folder2 = await Folder.save({ title: 'folder2', parent_id: folder1.id });
|
||||
let note2 = await Note.save({ title: 'note2', parent_id: folder2.id });
|
||||
await shim.attachFileToNote(note2, `${__dirname}/../tests/support/photo.jpg`);
|
||||
await shim.attachFileToNote(note2, `${supportDir}/photo.jpg`);
|
||||
note2 = await Note.load(note2.id);
|
||||
queueExportItem(BaseModel.TYPE_NOTE, note2);
|
||||
const resource2 = await Resource.load((await Note.linkedResourceIds(note2.body))[0]);
|
||||
@@ -1,8 +1,21 @@
|
||||
import Logger from '../../Logger';
|
||||
import shim from '../../shim';
|
||||
import { PluginManifest } from './utils/types';
|
||||
const md5 = require('md5');
|
||||
const compareVersions = require('compare-versions');
|
||||
|
||||
const logger = Logger.create('RepositoryApi');
|
||||
|
||||
interface ReleaseAsset {
|
||||
name: string;
|
||||
browser_download_url: string;
|
||||
}
|
||||
|
||||
interface Release {
|
||||
upload_url: string;
|
||||
assets: ReleaseAsset[];
|
||||
}
|
||||
|
||||
export default class RepositoryApi {
|
||||
|
||||
// As a base URL, this class can support either a remote repository or a
|
||||
@@ -14,6 +27,7 @@ export default class RepositoryApi {
|
||||
// Later on, other repo types could be supported.
|
||||
private baseUrl_: string;
|
||||
private tempDir_: string;
|
||||
private release_: Release = null;
|
||||
private manifests_: PluginManifest[] = null;
|
||||
|
||||
public constructor(baseUrl: string, tempDir: string) {
|
||||
@@ -21,7 +35,12 @@ export default class RepositoryApi {
|
||||
this.tempDir_ = tempDir;
|
||||
}
|
||||
|
||||
public async loadManifests() {
|
||||
public async initialize() {
|
||||
await this.loadManifests();
|
||||
await this.loadRelease();
|
||||
}
|
||||
|
||||
private async loadManifests() {
|
||||
const manifestsText = await this.fetchText('manifests.json');
|
||||
try {
|
||||
const manifests = JSON.parse(manifestsText);
|
||||
@@ -34,6 +53,27 @@ export default class RepositoryApi {
|
||||
}
|
||||
}
|
||||
|
||||
private get githubApiUrl(): string {
|
||||
// https://github.com/joplin/plugins
|
||||
// https://api.github.com/repos/joplin/plugins/releases
|
||||
return this.baseUrl_.replace(/^(https:\/\/)(github\.com\/)(.*)$/, '$1api.$2repos/$3');
|
||||
}
|
||||
|
||||
private async loadRelease() {
|
||||
this.release_ = null;
|
||||
|
||||
if (this.isLocalRepo) return;
|
||||
|
||||
try {
|
||||
const response = await fetch(`${this.githubApiUrl}/releases`);
|
||||
const releases = await response.json();
|
||||
if (!releases.length) throw new Error('No release was found');
|
||||
this.release_ = releases[0];
|
||||
} catch (error) {
|
||||
logger.warn('Could not load release - files will be downloaded from the repository directly:', error);
|
||||
}
|
||||
}
|
||||
|
||||
private get isLocalRepo(): boolean {
|
||||
return this.baseUrl_.indexOf('http') !== 0;
|
||||
}
|
||||
@@ -46,15 +86,34 @@ export default class RepositoryApi {
|
||||
}
|
||||
}
|
||||
|
||||
private fileUrl(relativePath: string): string {
|
||||
private assetFileUrl(pluginId: string): string {
|
||||
if (this.release_) {
|
||||
const asset = this.release_.assets.find(asset => {
|
||||
const s = asset.name.split('@');
|
||||
s.pop();
|
||||
const id = s.join('@');
|
||||
return id === pluginId;
|
||||
});
|
||||
|
||||
if (asset) return asset.browser_download_url;
|
||||
|
||||
logger.warn(`Could not get plugin from release: ${pluginId}`);
|
||||
}
|
||||
|
||||
// If we couldn't get the plugin file from the release, get it directly
|
||||
// from the repository instead.
|
||||
return this.repoFileUrl(`plugins/${pluginId}/plugin.jpl`);
|
||||
}
|
||||
|
||||
private repoFileUrl(relativePath: string): string {
|
||||
return `${this.contentBaseUrl}/${relativePath}`;
|
||||
}
|
||||
|
||||
private async fetchText(path: string): Promise<string> {
|
||||
if (this.isLocalRepo) {
|
||||
return shim.fsDriver().readFile(this.fileUrl(path), 'utf8');
|
||||
return shim.fsDriver().readFile(this.repoFileUrl(path), 'utf8');
|
||||
} else {
|
||||
return shim.fetchText(this.fileUrl(path));
|
||||
return shim.fetchText(this.repoFileUrl(path));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +145,7 @@ export default class RepositoryApi {
|
||||
const manifest = manifests.find(m => m.id === pluginId);
|
||||
if (!manifest) throw new Error(`No manifest for plugin ID "${pluginId}"`);
|
||||
|
||||
const fileUrl = this.fileUrl(`plugins/${manifest.id}/plugin.jpl`);
|
||||
const fileUrl = this.assetFileUrl(manifest.id); // this.repoFileUrl(`plugins/${manifest.id}/plugin.jpl`);
|
||||
const hash = md5(Date.now() + Math.random());
|
||||
const targetPath = `${this.tempDir_}/${hash}_${manifest.id}.jpl`;
|
||||
|
||||
|
||||
@@ -48,10 +48,8 @@ export interface Command {
|
||||
* Currently the supported context variables aren't documented, but you can
|
||||
* find the list below:
|
||||
*
|
||||
* - [Global When
|
||||
* Clauses](https://github.com/laurent22/joplin/blob/dev/packages/lib/services/commands/stateToWhenClauseContext.ts).
|
||||
* - [Desktop app When
|
||||
* Clauses](https://github.com/laurent22/joplin/blob/dev/packages/app-desktop/services/commands/stateToWhenClauseContext.ts).
|
||||
* - [Global When Clauses](https://github.com/laurent22/joplin/blob/dev/packages/lib/services/commands/stateToWhenClauseContext.ts)
|
||||
* - [Desktop app When Clauses](https://github.com/laurent22/joplin/blob/dev/packages/app-desktop/services/commands/stateToWhenClauseContext.ts)
|
||||
*
|
||||
* Note: Commands are enabled by default unless you use this property.
|
||||
*/
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { PaginationOrderDir } from '@joplin/lib/models/utils/types';
|
||||
import Api, { RequestMethod } from '@joplin/lib/services/rest/Api';
|
||||
import shim from '@joplin/lib/shim';
|
||||
import { PaginationOrderDir } from '../../models/utils/types';
|
||||
import Api, { RequestMethod } from '../../services/rest/Api';
|
||||
import shim from '../../shim';
|
||||
|
||||
const { setupDatabaseAndSynchronizer, switchClient, checkThrowAsync, db, msleep } = require('./test-utils.js');
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
import Resource from '@joplin/lib/models/Resource';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import Tag from '@joplin/lib/models/Tag';
|
||||
import NoteTag from '@joplin/lib/models/NoteTag';
|
||||
import ResourceService from '@joplin/lib/services/ResourceService';
|
||||
import SearchEngine from '@joplin/lib/services/searchengine/SearchEngine';
|
||||
const { setupDatabaseAndSynchronizer, switchClient, checkThrowAsync, db, msleep, supportDir } = require('../../testing/test-utils.js');
|
||||
import Folder from '../../models/Folder';
|
||||
import Resource from '../../models/Resource';
|
||||
import Note from '../../models/Note';
|
||||
import Tag from '../../models/Tag';
|
||||
import NoteTag from '../../models/NoteTag';
|
||||
import ResourceService from '../../services/ResourceService';
|
||||
import SearchEngine from '../../services/searchengine/SearchEngine';
|
||||
|
||||
const createFolderForPagination = async (num: number, time: number) => {
|
||||
await Folder.save({
|
||||
@@ -327,7 +327,7 @@ describe('services_rest_Api', function() {
|
||||
}));
|
||||
|
||||
it('should not compress images uploaded through resource api', (async () => {
|
||||
const originalImagePath = `${__dirname}/../tests/support/photo-large.png`;
|
||||
const originalImagePath = `${supportDir}/photo-large.png`;
|
||||
await api.route(RequestMethod.POST, 'resources', null, JSON.stringify({
|
||||
title: 'testing resource',
|
||||
}), [
|
||||
@@ -764,7 +764,7 @@ describe('services_rest_Api', function() {
|
||||
|
||||
it('should return the notes associated with a resource', (async () => {
|
||||
const note = await Note.save({});
|
||||
await shim.attachFileToNote(note, `${__dirname}/../tests/support/photo.jpg`);
|
||||
await shim.attachFileToNote(note, `${supportDir}/photo.jpg`);
|
||||
const resource = (await Resource.all())[0];
|
||||
|
||||
const resourceService = new ResourceService();
|
||||
@@ -778,7 +778,7 @@ describe('services_rest_Api', function() {
|
||||
|
||||
it('should return the resources associated with a note', (async () => {
|
||||
const note = await Note.save({});
|
||||
await shim.attachFileToNote(note, `${__dirname}/../tests/support/photo.jpg`);
|
||||
await shim.attachFileToNote(note, `${supportDir}/photo.jpg`);
|
||||
const resource = (await Resource.all())[0];
|
||||
|
||||
const r = await api.route(RequestMethod.GET, `notes/${note.id}/resources`);
|
||||
@@ -1,13 +1,10 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
/* eslint prefer-const: 0*/
|
||||
/* eslint-disable no-unused-vars, @typescript-eslint/no-unused-vars, prefer-const */
|
||||
|
||||
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync, restoreDate } = require('./test-utils.js');
|
||||
const SearchEngine = require('@joplin/lib/services/searchengine/SearchEngine').default;
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
const ItemChange = require('@joplin/lib/models/ItemChange').default;
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const { setupDatabaseAndSynchronizer, db, sleep, switchClient } = require('../../testing/test-utils.js');
|
||||
const SearchEngine = require('../../services/searchengine/SearchEngine').default;
|
||||
const Note = require('../../models/Note').default;
|
||||
const ItemChange = require('../../models/ItemChange').default;
|
||||
const Setting = require('../../models/Setting').default;
|
||||
|
||||
let engine = null;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { setupDatabaseAndSynchronizer, db, switchClient } from './test-utils.js';
|
||||
import SearchEngine from '@joplin/lib/services/searchengine/SearchEngine';
|
||||
import SearchEngineUtils from '@joplin/lib/services/searchengine/SearchEngineUtils';
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
import { setupDatabaseAndSynchronizer, db, switchClient } from '../../testing/test-utils.js';
|
||||
import SearchEngine from '../../services/searchengine/SearchEngine';
|
||||
import SearchEngineUtils from '../../services/searchengine/SearchEngineUtils';
|
||||
import Setting from '../../models/Setting';
|
||||
const Note = require('../../models/Note').default;
|
||||
|
||||
|
||||
let searchEngine: any = null;
|
||||
@@ -1,18 +1,13 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
/* eslint prefer-const: 0*/
|
||||
/* eslint-disable no-unused-vars, @typescript-eslint/no-unused-vars, prefer-const */
|
||||
|
||||
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, createNTestNotes, switchClient, createNTestFolders } = require('./test-utils.js');
|
||||
const SearchEngine = require('@joplin/lib/services/searchengine/SearchEngine').default;
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
const Folder = require('@joplin/lib/models/Folder').default;
|
||||
const Tag = require('@joplin/lib/models/Tag').default;
|
||||
const ItemChange = require('@joplin/lib/models/ItemChange').default;
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const Resource = require('@joplin/lib/models/Resource').default;
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
const ResourceService = require('@joplin/lib/services/ResourceService').default;
|
||||
const time = require('../../time').default;
|
||||
const { setupDatabaseAndSynchronizer, supportDir, db, createNTestNotes, switchClient } = require('../../testing/test-utils.js');
|
||||
const SearchEngine = require('../../services/searchengine/SearchEngine').default;
|
||||
const Note = require('../../models/Note').default;
|
||||
const Folder = require('../../models/Folder').default;
|
||||
const Tag = require('../../models/Tag').default;
|
||||
const shim = require('../../shim').default;
|
||||
const ResourceService = require('../../services/ResourceService').default;
|
||||
|
||||
|
||||
let engine = null;
|
||||
@@ -697,10 +692,10 @@ describe('services_SearchFilter', function() {
|
||||
await engine.syncTables();
|
||||
|
||||
// let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
n1 = await shim.attachFileToNote(n1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
n1 = await shim.attachFileToNote(n1, `${supportDir}/photo.jpg`);
|
||||
// const resource1 = (await Resource.all())[0];
|
||||
|
||||
n4 = await shim.attachFileToNote(n4, `${__dirname}/../tests/support/welcome.pdf`);
|
||||
n4 = await shim.attachFileToNote(n4, `${supportDir}/welcome.pdf`);
|
||||
|
||||
await service.indexNoteResources();
|
||||
|
||||
@@ -803,13 +798,13 @@ describe('services_SearchFilter', function() {
|
||||
it('should support negating notebooks', (async () => {
|
||||
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
let n1 = await Note.save({ title: 'task1', body: 'foo', parent_id: folder1.id });
|
||||
let n2 = await Note.save({ title: 'task2', body: 'bar', parent_id: folder1.id });
|
||||
const n1 = await Note.save({ title: 'task1', body: 'foo', parent_id: folder1.id });
|
||||
const n2 = await Note.save({ title: 'task2', body: 'bar', parent_id: folder1.id });
|
||||
|
||||
|
||||
const folder2 = await Folder.save({ title: 'folder2' });
|
||||
let n3 = await Note.save({ title: 'task3', body: 'baz', parent_id: folder2.id });
|
||||
let n4 = await Note.save({ title: 'task4', body: 'blah', parent_id: folder2.id });
|
||||
const n3 = await Note.save({ title: 'task3', body: 'baz', parent_id: folder2.id });
|
||||
const n4 = await Note.save({ title: 'task4', body: 'blah', parent_id: folder2.id });
|
||||
|
||||
|
||||
await engine.syncTables();
|
||||
@@ -830,18 +825,18 @@ describe('services_SearchFilter', function() {
|
||||
it('should support both inclusion and exclusion of notebooks together', (async () => {
|
||||
|
||||
const parentFolder = await Folder.save({ title: 'parent' });
|
||||
let n1 = await Note.save({ title: 'task1', body: 'foo', parent_id: parentFolder.id });
|
||||
let n2 = await Note.save({ title: 'task2', body: 'bar', parent_id: parentFolder.id });
|
||||
const n1 = await Note.save({ title: 'task1', body: 'foo', parent_id: parentFolder.id });
|
||||
const n2 = await Note.save({ title: 'task2', body: 'bar', parent_id: parentFolder.id });
|
||||
|
||||
|
||||
const subFolder = await Folder.save({ title: 'child', parent_id: parentFolder.id });
|
||||
let n3 = await Note.save({ title: 'task3', body: 'baz', parent_id: subFolder.id });
|
||||
let n4 = await Note.save({ title: 'task4', body: 'blah', parent_id: subFolder.id });
|
||||
const n3 = await Note.save({ title: 'task3', body: 'baz', parent_id: subFolder.id });
|
||||
const n4 = await Note.save({ title: 'task4', body: 'blah', parent_id: subFolder.id });
|
||||
|
||||
|
||||
await engine.syncTables();
|
||||
|
||||
let rows = await engine.search('notebook:parent -notebook:child');
|
||||
const rows = await engine.search('notebook:parent -notebook:child');
|
||||
expect(rows.length).toBe(2);
|
||||
expect(ids(rows)).toContain(n1.id);
|
||||
expect(ids(rows)).toContain(n2.id);
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
const filterParser = require('@joplin/lib/services/searchengine/filterParser.js').default;
|
||||
// import filterParser from '@joplin/lib/services/searchengine/filterParser.js';
|
||||
const filterParser = require('../../services/searchengine/filterParser.js').default;
|
||||
// import filterParser from '../../services/searchengine/filterParser.js';
|
||||
|
||||
const makeTerm = (name, value, negated, quoted = false, wildcard = false) => {
|
||||
if (name === 'text') { return { name, value, negated, quoted, wildcard }; }
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user