diff --git a/docs/adr/2026_07_bounded_remote_activity.md b/docs/adr/2026_07_bounded_remote_activity.md index 3f8498d3..07fcf60e 100644 --- a/docs/adr/2026_07_bounded_remote_activity.md +++ b/docs/adr/2026_07_bounded_remote_activity.md @@ -37,9 +37,9 @@ The Obsidian host injects the screen wake-lock manager from the `octagonal-wheel Finite replication enters both counts only after readiness checks have succeeded and leaves them after `openReplication(..., continuous: false, ...)` settles. A successful completion has reached the latest sequence in that operation's scope and is therefore an authoritative quiescence boundary for chunk retrieval. A failed operation does not prove latest state, but can no longer deliver documents from that attempt. Failure handling runs afterwards so a mismatch or recovery dialogue does not retain the activity. This includes the direct start-up synchronisation path as well as manual, event-driven, and periodic calls through `ReplicationService`. The unbounded continuous channel does not enter either boundary, but its finite initial pull-only catch-up does; the one-shot parameter fallback chain remains inside that boundary. -Delivery into the local database and application to the Obsidian Vault are deliberately separate lifetimes. A mobile device can have only a short opportunity to obtain remote data, while applying a large downloaded batch to the Vault is durable, offline-capable work which can continue or resume later. The replication-result queue and its recovery snapshot therefore remain outside `boundedRemoteActivityCount`. Finite remote activity ends when the transfer operation settles, even when the `📥` queue still contains documents awaiting Vault application. +Delivery into the local database and application to the Obsidian Vault are deliberately separate lifetimes. Finite remote activity ends when the transfer operation settles, even when the `📥` queue still contains documents awaiting Vault application. The Obsidian host tracks that queue through a separate `boundedLocalApplicationActivityCount`, so local Vault writes do not increment either remote-activity count or keep the `📲` indicator visible. -This separation also keeps the activity indicators truthful: `📲` describes a finite remote operation and must not remain active solely because local Vault writes are pending. The existing replication-result count continues to describe that local queue. If a future feature offers screen-awake protection while applying downloaded documents, it must use a separately typed local-application activity or power-policy boundary, preserve the current behaviour by default, and avoid incrementing either remote-activity count. +Applying downloaded document changes enters one local-application boundary from the first queued document until the queue and its in-progress set are both empty. The final empty recovery snapshot is attempted before the boundary settles; snapshot failure is logged and still releases the boundary. Additional batches share the existing boundary. Suspending replication-result processing releases it, and resuming reacquires it while work remains. The same host activity runner supplies best-effort Wake Lock protection, while the visibility lifecycle waits for both remote and local bounded activity to finish. Manual P2P commands which bypass `ReplicationService` enter the broad boundary. Direct P2P pull and push entry points are therefore both protected as finite remote work, covering the Obsidian panes, CLI, and Webapp. A pull or bidirectional synchronisation also enters the narrower finite-replication boundary because it can place documents in the local database. A push-only request remains broad-only: it cannot satisfy a local missing-chunk read and must not present itself as a delivery source. Automatic synchronisation on peer discovery, a pull requested by a remote peer, and a watched pull following a peer progress notification enter both boundaries because each can deliver local documents. A normal P2P peer-selection dialogue represents one broad finite session: it remains inside the boundary while waiting for a peer and while the person may perform repeated synchronisations, then settles when the dialogue closes and any in-flight synchronisation has finished. Closing without synchronising returns a failed result and releases the boundary. The 'Start Sync & Close' action completes its synchronisation before closing. This deliberately protects peer discovery and selection, because display sleep can interrupt discovery or connection establishment and require the person to start detection again. It may therefore retain a Wake Lock longer than the network transfer alone. A transfer performed inside that session temporarily adds a nested activity; the count remains a logical-operation count rather than a connection total. @@ -76,6 +76,8 @@ P2P does not yet contribute to the physical-request count because it does not ha The platform activity runner remains injected. Common library and headless consumers can omit it while retaining the same bounded activity count and operation semantics. +The Obsidian-specific `ObsidianReplicatorService` owns `boundedLocalApplicationActivityCount` and reuses the injected activity runner. It is deliberately absent from the common service contract: CLI and Webapp processing continue directly, while the Obsidian host uses the count for Wake Lock and visibility-lifecycle policy without changing remote-operation reporting. + ## Non-Goals - Do not count continuous replication as a bounded activity. @@ -85,11 +87,11 @@ The platform activity runner remains injected. Common library and headless consu - Do not guarantee protection against operating-system suspension, closing a laptop lid, forced termination, network loss, or a user-initiated sleep action. - Do not add a lifecycle timeout which would abort an unusually slow rebuild. A genuinely stalled operation may postpone LiveSync's visibility suspension until it settles, but the platform may still suspend or terminate background work. - Do not broaden `keepReplicationActiveInBackground`; it remains an opt-in desktop policy for continuous and periodic operation after finite work has ended. -- Do not include offline scans, unrelated local storage reflection, or the durable replication-result queue in this boundary. They are offline-capable and require a separate decision if activity reporting or power policy is added later. +- Do not include offline scans, unrelated local storage reflection, or the durable replication-result queue in either remote-activity count. The queue uses its separate local-application boundary. ## Verification -Before changing the transfer/application separation, add a deterministic regression scenario which leaves downloaded documents queued after finite transfer settles, verifies that remote activity has ended, persists the queued state, and resumes Vault application after suspension or restart. An optional local-application Wake Lock feature requires its own enabled and disabled cases; existing remote-operation E2E is not evidence for that separate policy. +Before changing the transfer/application separation, keep deterministic coverage which leaves downloaded documents queued after finite transfer settles, verifies that remote activity has ended, and retains the separate local-application boundary until Vault application and the final recovery snapshot settle. Unit tests cover: @@ -106,6 +108,8 @@ Unit tests cover: - remote chunk fetching remaining inside the shared boundary from synchronous queue acceptance through local persistence and terminal notification; - missing-chunk waiters rechecking local storage when observed per-identifier claims and finite replication have settled; - the finite-replication count excluding other bounded work; +- replicated document application sharing one local boundary, settling after the final recovery snapshot, and releasing around processing suspension; +- local application activity leaving both remote-activity counts unchanged; - standard, fast, remote, and combined rebuild activity boundaries; - Rebuilder-owned confirmation and completion dialogues remaining outside rebuild activity; - fallback from fast fetch avoiding a nested activity boundary; @@ -125,5 +129,5 @@ The exact Fancy Kit screen wake-lock behaviour is covered by its package and Har - One finite activity definition drives Wake Lock, lifecycle protection, and status UI without coupling common library code to Obsidian or browser globals. - Callers can observe accurate logical activity even in CLI and Webapp hosts which do not inject a Wake Lock implementation. - Rebuild operations now retain Wake Lock and lifecycle protection across their longest interruption-sensitive phases without retaining them for Rebuilder-owned pre-operation or completion dialogues. Post-reset P2P discovery and selection remain protected as an intentional part of completing the rebuild. -- Downloaded documents may remain in the durable Vault-application queue after remote activity has ended, allowing transfer and offline application to follow different mobile lifetimes without presenting local writes as communication. +- Downloaded documents may remain in the durable Vault-application queue after remote activity has ended, while a separate local-application boundary retains best-effort Wake Lock and lifecycle protection without presenting local writes as communication. - Users can now distinguish the lifetime of a finite remote operation from approximate request activity within it. diff --git a/package-lock.json b/package-lock.json index db72e1a8..205f5065 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "markdown-it": "^14.2.0", "minimatch": "^10.2.5", "obsidian": "^1.13.1", - "octagonal-wheels": "^0.1.51", + "octagonal-wheels": "^0.1.52", "qrcode-generator": "^1.4.4", "xxhash-wasm-102": "npm:xxhash-wasm@^1.0.2" }, @@ -11532,9 +11532,9 @@ "license": "MIT" }, "node_modules/octagonal-wheels": { - "version": "0.1.51", - "resolved": "https://registry.npmjs.org/octagonal-wheels/-/octagonal-wheels-0.1.51.tgz", - "integrity": "sha512-KTlfqKPjobHJg/t3A539srnFf+VHr1aXkHSmsNDDpiI5UFC7FamZ95dWpJfGE2EI/HULR5hveQDgkazmz8SAcg==", + "version": "0.1.52", + "resolved": "https://registry.npmjs.org/octagonal-wheels/-/octagonal-wheels-0.1.52.tgz", + "integrity": "sha512-9WJN2UveNh90Op1S07cIso1WyNrQbO/unibDLfUGnpomIcU4g6F+p8reZHW0Ed8sGzKF5qGnQp991Y9MB1TwNg==", "license": "MIT", "dependencies": { "idb": "^8.0.3" @@ -15928,7 +15928,7 @@ "dependencies": { "chokidar": "^4.0.0", "minimatch": "^10.2.5", - "octagonal-wheels": "^0.1.51", + "octagonal-wheels": "^0.1.52", "pouchdb-adapter-http": "^9.0.0", "pouchdb-adapter-leveldb": "^9.0.0", "pouchdb-core": "^9.0.0", @@ -15951,7 +15951,7 @@ "name": "livesync-webapp", "version": "1.0.1-webapp", "dependencies": { - "octagonal-wheels": "^0.1.51" + "octagonal-wheels": "^0.1.52" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^7.1.2", @@ -15963,7 +15963,7 @@ "src/apps/webpeer": { "version": "1.0.1-webpeer", "dependencies": { - "octagonal-wheels": "^0.1.51" + "octagonal-wheels": "^0.1.52" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^7.1.2", diff --git a/package.json b/package.json index c18b4835..40e420c6 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "test:e2e:obsidian:dialog-mounts": "tsx test/e2e-obsidian/scripts/dialog-mounts.ts", "test:e2e:obsidian:conflict-dialog-policy": "tsx test/e2e-obsidian/scripts/conflict-dialog-policy.ts", "test:e2e:obsidian:revision-repair": "tsx test/e2e-obsidian/scripts/revision-repair.ts", + "test:e2e:obsidian:document-history-nav": "tsx test/e2e-obsidian/scripts/document-history-nav.ts", "test:e2e:obsidian:settings-ui": "tsx test/e2e-obsidian/scripts/settings-ui.ts", "test:e2e:obsidian:review-harness": "tsx test/e2e-obsidian/scripts/review-harness.ts", "test:e2e:obsidian:p2p-pane": "tsx test/e2e-obsidian/scripts/p2p-pane.ts", @@ -182,7 +183,7 @@ "markdown-it": "^14.2.0", "minimatch": "^10.2.5", "obsidian": "^1.13.1", - "octagonal-wheels": "^0.1.51", + "octagonal-wheels": "^0.1.52", "qrcode-generator": "^1.4.4", "xxhash-wasm-102": "npm:xxhash-wasm@^1.0.2" }, diff --git a/src/apps/cli/package.json b/src/apps/cli/package.json index d152f6dc..23b7bcb0 100644 --- a/src/apps/cli/package.json +++ b/src/apps/cli/package.json @@ -37,7 +37,7 @@ "dependencies": { "chokidar": "^4.0.0", "minimatch": "^10.2.5", - "octagonal-wheels": "^0.1.51", + "octagonal-wheels": "^0.1.52", "pouchdb-adapter-http": "^9.0.0", "pouchdb-adapter-leveldb": "^9.0.0", "pouchdb-core": "^9.0.0", diff --git a/src/apps/webapp/package.json b/src/apps/webapp/package.json index 8e3c990c..2e3bae4d 100644 --- a/src/apps/webapp/package.json +++ b/src/apps/webapp/package.json @@ -15,7 +15,7 @@ "test:browser": "deno test -A --no-check --frozen --config ../../../test/browser-apps/deno.json --lock ../../../test/browser-apps/deno.lock ../../../test/browser-apps/webapp/browser-smoke.test.ts" }, "dependencies": { - "octagonal-wheels": "^0.1.51" + "octagonal-wheels": "^0.1.52" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^7.1.2", diff --git a/src/apps/webpeer/package.json b/src/apps/webpeer/package.json index b6d04532..e0e0ddb0 100644 --- a/src/apps/webpeer/package.json +++ b/src/apps/webpeer/package.json @@ -15,7 +15,7 @@ "test:browser": "deno test -A --no-check --frozen --config ../../../test/browser-apps/deno.json --lock ../../../test/browser-apps/deno.lock ../../../test/browser-apps/webpeer/browser-smoke.test.ts" }, "dependencies": { - "octagonal-wheels": "^0.1.51" + "octagonal-wheels": "^0.1.52" }, "devDependencies": { "eslint-plugin-svelte": "^3.19.0", diff --git a/src/common/messages/LiveSyncProvisionalMessages.ts b/src/common/messages/LiveSyncProvisionalMessages.ts index d9a4f5b2..0392fae4 100644 --- a/src/common/messages/LiveSyncProvisionalMessages.ts +++ b/src/common/messages/LiveSyncProvisionalMessages.ts @@ -94,10 +94,8 @@ export const liveSyncProvisionalEnglishMessages = { "🧩 Missing chunks: ${COUNT}": "🧩 Missing chunks: ${COUNT}", "📦 DB: recorded ${RECORDED} B · decoded ${DECODED} B · Δsize ${DIFFERENCE} B": "📦 DB: recorded ${RECORDED} B · decoded ${DECODED} B · Δsize ${DIFFERENCE} B", - "📦 DB: recorded ${RECORDED} B · decoded unavailable": - "📦 DB: recorded ${RECORDED} B · decoded unavailable", - "📁 Vault: ${VAULT} B · Δsize vs DB ${DIFFERENCE} B": - "📁 Vault: ${VAULT} B · Δsize vs DB ${DIFFERENCE} B", + "📦 DB: recorded ${RECORDED} B · decoded unavailable": "📦 DB: recorded ${RECORDED} B · decoded unavailable", + "📁 Vault: ${VAULT} B · Δsize vs DB ${DIFFERENCE} B": "📁 Vault: ${VAULT} B · Δsize vs DB ${DIFFERENCE} B", "🕒 DB ${DATABASE_TIME} · Vault ${VAULT_TIME} · Δtime ${DIFFERENCE} ms (${RELATION})": "🕒 DB ${DATABASE_TIME} · Vault ${VAULT_TIME} · Δtime ${DIFFERENCE} ms (${RELATION})", "✅ Matches Vault": "✅ Matches Vault", @@ -130,8 +128,7 @@ export const liveSyncProvisionalEnglishMessages = { "More actions for revision ${REVISION}": "More actions for revision ${REVISION}", "More actions for ${FILE}": "More actions for ${FILE}", "Show revision history": "Show revision history", - "Store Vault file as a new local database document": - "Store Vault file as a new local database document", + "Store Vault file as a new local database document": "Store Vault file as a new local database document", "Copy database information": "Copy database information", "Recreate chunks for current Vault files": "Recreate chunks for current Vault files", "Recreate chunks from the files currently present in this Vault. This cannot reconstruct unavailable historical or conflict content.": @@ -140,8 +137,7 @@ export const liveSyncProvisionalEnglishMessages = { "Resolve every conflict by modification time? This logically deletes every version except the newest one and cannot recover content which is already unavailable.": "Resolve every conflict by modification time? This logically deletes every version except the newest one and cannot recover content which is already unavailable.", "Resolve all conflicts by the newest version": "Resolve all conflicts by the newest version", - "Inspect conflicts and file/database differences": - "Inspect conflicts and file/database differences", + "Inspect conflicts and file/database differences": "Inspect conflicts and file/database differences", "Scan every Vault file and live local-database revision for conflicts, missing chunks, and differences. Each result provides actions for the exact revision.": "Scan every Vault file and live local-database revision for conflicts, missing chunks, and differences. Each result provides actions for the exact revision.", "Begin inspection": "Begin inspection", diff --git a/src/common/messages/combinedMessages.prod.ts b/src/common/messages/combinedMessages.prod.ts index 19bc43de..dceb6835 100644 --- a/src/common/messages/combinedMessages.prod.ts +++ b/src/common/messages/combinedMessages.prod.ts @@ -83,7 +83,7 @@ export const allMessages: Readonly [!INFO]- The connected devices have been detected as follows:\n${devices}": { def: "> [!INFO]- The connected devices have been detected as follows:\n${devices}", + es: "> [!INFO]- Se han detectado los siguientes dispositivos conectados:\n${devices}", ja: "> [!INFO]- 次の接続済みデバイスが検出されました:\n${devices}", ko: "> [!INFO]- 다음 연결된 기기가 감지되었습니다:\n${devices}", ru: "> [!INFO]- Обнаружены следующие подключённые устройства:\n${devices}", @@ -228,7 +229,7 @@ export const allMessages: Readonly Storage": { def: "Database -> Storage", + es: "Base de datos -> Almacenamiento", + ko: "데이터베이스 -> 스토리지", "zh-tw": "資料庫 -> 儲存空間", }, "Database Adapter": { @@ -1068,7 +1089,7 @@ export const allMessages: Readonly [!MORE]-\n> Si vous l'utilisez depuis de nombreuses années, il peut y avoir des fragments non référencés — des déchets, en somme — accumulés dans la base. Nous recommandons donc de tout reconstruire. Cela réduira probablement beaucoup la taille.\n>\n> Si le volume de votre coffre augmente simplement, il est préférable de tout reconstruire après avoir organisé les fichiers. Self-hosted LiveSync ne supprime pas réellement les données même si vous les effacez, afin d'accélérer le processus. Ceci est documenté grossièrement [ici](https://github.com/vrtmrz/obsidian-livesync/blob/main/docs/tech_info.md).\n>\n> Si cela ne vous dérange pas, vous pouvez augmenter la limite de notification de 100 Mo. C'est le cas si vous l'exécutez sur votre propre serveur. Il reste toutefois préférable de tout reconstruire de temps en temps.\n>\n\n> [!WARNING]\n> Si vous tout reconstruisez, assurez-vous que tous les appareils sont synchronisés. Le plug-in fusionnera autant que possible cependant.\n", he: "**מסד הנתונים שלך הולך וגדל!** אל תדאג, אנחנו יכולים לטפל בזה עכשיו. הזמן שנשאר עד לאזול המקום באחסון המרוחק.\n\n| גודל נמדד | גודל מוגדר |\n| --- | --- |\n| ${estimatedSize} | ${maxSize} |\n\n> [!MORE]-\n> אם אתה משתמש בפלאגין כבר שנים רבות, ייתכן שנצברו נתחים לא מקושרים — כלומר, זבל — במסד הנתונים. לכן, אנו ממליצים לבנות הכל מחדש. ככל הנראה מסד הנתונים יהיה קטן בהרבה לאחר מכן.\n>\n> אם נפח הכספת שלך פשוט גדל, עדיף לבנות מחדש לאחר ארגון הקבצים. Self-hosted LiveSync אינו מוחק נתונים בפועל גם כאשר אתה מוחק קבצים כדי להאיץ את התהליך. הדבר [מתועד בפירוט](https://github.com/vrtmrz/obsidian-livesync/blob/main/docs/tech_info.md).\n>\n> אם אינך מוטרד מהגידול, ניתן להגדיל את סף ההתראה ב-100MB. הדבר מתאים אם השרת הוא שלך. עם זאת, מומלץ לבנות מחדש מעת לעת.\n>\n\n> [!WARNING]\n> אם תבנה מחדש, ודא שכל המכשירים מסונכרנים. הפלאגין ינסה למזג כמה שניתן.\n", ja: "**データベースが大きくなっています!** でも心配しないでください。リモートストレージの容量が不足する前に対応できます。\n\n| 測定サイズ | 設定サイズ |\n| --- | --- |\n| ${estimatedSize} | ${maxSize} |\n\n> [!MORE]-\n> 長年使用している場合、参照されていないチャンク(つまりゴミ)がデータベースに蓄積している可能性があります。そのため、すべてを再構築することをお勧めします。おそらくかなり小さくなるでしょう。\n>\n> 単純に保管庫の容量が増えている場合は、事前にファイルを整理してからすべてを再構築するのが良いでしょう。Self-hosted LiveSyncは処理速度を上げるため、削除しても実際のデータを削除しません。これはおおまかに[documentation](https://github.com/vrtmrz/obsidian-livesync/blob/main/docs/tech_info.md)に記載されています。\n>\n> 増加を気にしない場合は、通知制限を100MB単位で増やすことができます。これは自分のサーバーで実行している場合に適しています。ただし、定期的にすべてを再構築する方が良いでしょう。\n>\n\n> [!WARNING]\n> すべてを再構築する場合は、すべてのデバイスが同期されていることを確認してください。もちろん、プラグインは可能な限り解決しようと努力はしますけど...\n", - ko: "**데이터베이스 용량이 점점 커지고 있습니다!** 하지만 걱정하지 마세요. 아직 원격 스토리지 공간이 완전히 부족해진 건 아닙니다.\n\n| 측정된 크기 | 설정된 한도 |\n| --- | --- |\n| ${estimatedSize} | ${maxSize} |\n\n> [!MORE]-\n> 오랜 기간 사용했다면 참조되지 않는 청크, 즉 '쓰레기 데이터'가 쌓였을 수 있습니다. 이 경우 전체 재구성을 권장합니다. 용량이 훨씬 줄어들 수 있습니다.\n>\n> 단순히 볼트 자체 용량이 커지고 있는 것이라면, 먼저 파일을 정리한 후 전체를 재구성하는 것이 좋습니다. Self-hosted LiveSync는 처리 속도를 위해 삭제해도 실제 데이터를 바로 지우지 않습니다. 이 내용은 [기술 문서](https://github.com/vrtmrz/obsidian-livesync/blob/main/docs/tech_info.md)에 간략히 정리되어 있습니다.\n>\n> 용량 증가가 괜찮다면 알림 임계치를 100MB 단위로 높일 수 있습니다. 직접 서버를 운영하는 경우에 적합한 방법입니다. 다만, 가끔은 전체 재구성을 해주는 것이 바람직합니다.\n\n> [!WARNING]\n> 전체 재구성을 실행할 경우, 모든 기기가 반드시 동기화되어 있어야 합니다. 플러그인이 최대한 병합하려고 시도하긴 하지만 완전하지 않을 수 있습니다.", + ko: "**데이터베이스 용량이 점점 커지고 있습니다!** 하지만 걱정하지 마세요. 지금 대응할 수 있습니다. 원격 스토리지 공간이 부족해지기까지 남은 시간입니다.\n\n| 측정된 크기 | 설정된 한도 |\n| --- | --- |\n| ${estimatedSize} | ${maxSize} |\n\n> [!MORE]-\n> 오랜 기간 사용했다면 참조되지 않는 청크, 즉 쓰레기 데이터가 데이터베이스에 쌓였을 수 있습니다. 이 경우 전체 재구축을 권장합니다. 용량이 훨씬 줄어들 것입니다.\n>\n> 단순히 보관함 용량이 커지고 있는 것이라면, 파일을 정리한 뒤에 전체를 재구축하는 것이 좋습니다. Self-hosted LiveSync는 처리 속도를 위해 파일을 삭제해도 실제 데이터를 바로 지우지 않습니다. 이 내용은 [기술 문서](https://github.com/vrtmrz/obsidian-livesync/blob/main/docs/tech_info.md)에 간략히 정리되어 있습니다.\n>\n> 용량 증가가 괜찮다면 알림 한도를 100MB 단위로 높일 수 있습니다. 직접 서버를 운영하는 경우에 적합한 방법입니다. 다만 가끔은 전체를 재구축해 주는 것이 좋습니다.\n>\n\n> [!WARNING]\n> 전체 재구축을 실행할 때는 모든 기기가 동기화되어 있는지 확인해 주세요. 플러그인이 최대한 병합하려고 시도하기는 합니다.\n", ru: "Ваша база данных увеличивается! Но не волнуйтесь, мы можем решить это сейчас.", zh: "**您的数据库正在变大!** 但别担心,我们现在可以解决它。在远程存储空间用完之前还有时间。\n\n| 测量大小 | 配置大小 |\n| --- | --- |\n| ${estimatedSize} | ${maxSize} |\n\n> [!MORE]-\n> 如果您已经使用了很多年,数据库中可能会积累未引用的 chunks——也就是垃圾。因此,我们建议重建所有内容。它可能会变得小得多。\n>\n> 如果您的库容量只是在增加,最好在整理文件后重建所有内容。即使您为了加速过程删除了文件,Self-hosted LiveSync 也不会删除实际数据。这大致[有文档记录](https://github.com/vrtmrz/obsidian-livesync/blob/main/docs/tech_info.md)。\n>\n> 如果您不介意增加,可以将通知限制增加 100MB。如果您在自己的服务器上运行,就是这种情况。但是,最好还是不时地重建所有内容。\n>\n\n> [!WARNING]\n> 如果您执行重建所有内容,请确保所有设备都已同步。尽管如此,插件会尽可能地合并\n", }, @@ -3320,15 +3406,19 @@ export const allMessages: Readonly [!MORE]-\n> - 0 : Ne pas avertir sur la taille de stockage.\n> Recommandé si vous avez suffisamment d'espace sur le stockage distant, surtout en auto-hébergement. Vous pouvez vérifier la taille et reconstruire manuellement.\n> - 800 : Avertir si la taille du stockage distant dépasse 800 Mo.\n> Recommandé si vous utilisez fly.io avec une limite de 1 Go ou IBM Cloudant.\n> - 2000 : Avertir si la taille du stockage distant dépasse 2 Go.\n\nSi la limite est atteinte, il nous sera proposé de l'augmenter étape par étape.\n", he: "ניתן להגדיר אזהרת קיבולת מקסימלית של מסד הנתונים, **כדי לנקוט פעולה לפני שנגמר המקום באחסון המרוחד**.\nהאם להפעיל זאת?\n\n> [!MORE]-\n> - 0: אל תזהיר על גודל האחסון.\n> מומלץ אם יש לך מספיק מקום באחסון המרוחד, בעיקר אם השרת הוא שלך. ניתן לבדוק את גודל האחסון ולבנות מחדש ידנית.\n> - 800: הזהר אם גודל האחסון המרוחד עולה על 800MB.\n> מומלץ אם אתה משתמש ב-fly.io עם מגבלת 1GB או ב-IBM Cloudant.\n> - 2000: הזהר אם גודל האחסון המרוחד עולה על 2GB.\n\nאם הגענו למגבלה, תתבקש להרחיב את הסף בהדרגה.\n", ja: "リモートストレージの容量が不足する前に対策を講じるため、**最大データベース容量の警告**を設定できます。\nこれを有効にしますか?\n\n> [!MORE]-\n> - 0: ストレージサイズについて警告しない。\n> 自宅サーバーなど、リモートストレージに十分な容量がある場合に推奨されます。ストレージサイズを確認し、手動で再構築できます。\n> - 800: リモートストレージサイズが800MBを超えたら警告。\n> 1GB制限のfly.ioやIBM Cloudantを使用している場合に推奨されます。\n> - 2000: リモートストレージサイズが2GBを超えたら警告。\n\n制限に達した場合、段階的に制限を増やすよう求められます。\n", - ko: "**원격 스토리지 공간이 부족해지기 전에 미리 조치할 수 있도록** 데이터베이스 용량 경고를 설정할 수 있습니다.\n이 기능을 활성화하시겠습니까?\n\n> [!MORE]-\n> - 0: 스토리지 용량에 대한 경고 없음\n> 자체 서버를 사용하는 등 여유 공간이 충분한 경우에 권장됩니다. 스토리지 용량을 직접 확인하고 수동으로 재구성할 수 있습니다.\n> - 800: 원격 스토리지 용량이 800MB를 초과하면 경고\n> 1GB 제한이 있는 fly.io나 IBM Cloudant 사용 시 권장됩니다.\n> - 2000: 원격 스토리지 용량이 2GB를 초과하면 경고\n\n설정한 용량 한도에 도달하면, 단계적으로 경고 한도를 늘릴지 여부를 묻게 됩니다.\n", + ko: "**원격 스토리지 공간이 부족해지기 전에 미리 조치할 수 있도록** 데이터베이스 용량 경고를 설정할 수 있습니다.\n이 기능을 활성화하시겠습니까?\n\n> [!MORE]-\n> - 0: 스토리지 용량을 경고하지 않습니다.\n> 직접 서버를 운영하는 등 원격 스토리지에 여유 공간이 충분한 경우에 권장합니다. 스토리지 용량을 직접 확인하고 수동으로 재구축할 수 있습니다.\n> - 800: 원격 스토리지 용량이 800MB를 초과하면 경고합니다.\n> 1GB 제한이 있는 fly.io나 IBM Cloudant를 사용하는 경우에 권장합니다.\n> - 2000: 원격 스토리지 용량이 2GB를 초과하면 경고합니다.\n\n한도에 도달하면 한도를 단계적으로 늘릴지 여쭤보겠습니다.\n", ru: "Можно установить предупреждение о максимальной ёмкости базы данных.", zh: "我们可以设置一个最大数据库容量警告,**以便在远程存储空间耗尽前采取行动**。\n您想启用这个功能吗?\n\n> [!MORE]-\n> - 0: 不警告存储大小。\n> 如果您在远程存储(尤其是自托管)上有足够的空间,则推荐此选项。您可以手动检查存储大小并重建。\n> - 800: 如果远程存储大小超过 800MB 则发出警告。\n> 如果您使用的是 fly.io(1GB 限制) 或 IBM Cloudant,则推荐此选项。\n> - 2000: 如果远程存储大小超过 2GB 则发出警告。\n\n如果达到限制,系统会要求我们逐步增大限制\n", }, "moduleCheckRemoteSize.noticeExceeded": { def: "Remote storage size is ${measuredSize}, above the configured ${notifySize} notification threshold. {HERE}", + es: "El tamaño del almacenamiento remoto es de ${measuredSize}, por encima del umbral de aviso configurado de ${notifySize}. {HERE}", + ko: "원격 스토리지 크기 ${measuredSize}이(가) 설정된 알림 임계값 ${notifySize}을(를) 초과했습니다. {HERE}", }, "moduleCheckRemoteSize.noticeNotConfigured": { def: "Remote storage size notifications are not configured. {HERE}", + es: "Los avisos sobre el tamaño del almacenamiento remoto no están configurados. {HERE}", + ko: "원격 스토리지 크기 알림이 설정되어 있지 않습니다. {HERE}", }, "moduleCheckRemoteSize.option2GB": { def: "2GB (Standard)", @@ -3402,6 +3492,8 @@ export const allMessages: Readonly [!DETAILS]-\n> Ces indicateurs sont définis par le plug-in lors d'une reconstruction ou d'une récupération. Si le processus se termine anormalement, ils peuvent rester activés involontairement.\n> Si vous n'êtes pas certain, vous pouvez relancer ces processus. Veillez à sauvegarder votre coffre.\n", he: "Self-hosted LiveSync הוגדר להתעלם מאירועים מסוימים. האם זה נכון?\n\n| סוג | סטטוס | הערה |\n|:---:|:---:|---|\n| אירועי אחסון | ${fileWatchingStatus} | כל שינוי יתעלם |\n| אירועי מסד נתונים | ${parseReplicationStatus} | כל שינוי מסונכרן יידחה |\n\nהאם לחדש אותם ולהפעיל מחדש את Obsidian?\n\n> [!DETAILS]-\n> דגלים אלה מוגדרים על ידי הפלאגין במהלך בנייה מחדש או משיכה. אם התהליך הסתיים בצורה לא תקינה, ייתכן שהם נשארו כלא מכוון.\n> אם אינך בטוח, ניתן לנסות להריץ מחדש את התהליכים. ודא שיש לך גיבוי של הכספת.\n", ja: "Self-hosted LiveSyncは一部のイベントを無視するように設定されています。これは正しいですか?\n\n| タイプ | ステータス | メモ |\n|:---:|:---:|---|\n| ストレージイベント | ${fileWatchingStatus} | すべての変更が無視されます |\n| データベースイベント | ${parseReplicationStatus} | すべての同期された変更が延期されます |\n\nこれらを再開してObsidianを再起動しますか?\n\n> [!DETAILS]-\n> これらのフラグは、プラグインが再構築またはフェッチ中に設定されます。プロセスが異常終了した場合、意図せず保持されることがあります。\n> 不明な場合は、これらのプロセスを再実行してみてください。必ず保管庫をバックアップしてください。\n", - ko: "Self-hosted LiveSync가 일부 이벤트를 무시하도록 설정되어 있습니다. 이 설정이 맞습니까?\n\n| 유형 | 상태 | 설명 |\n|:---:|:---:|---|\n| 스토리지 이벤트 | ${fileWatchingStatus} | 모든 수정 사항이 무시됩니다 |\n| 데이터베이스 이벤트 | ${parseReplicationStatus} | 모든 동기화 변경이 지연됩니다 |\n\n이벤트 감지를 다시 활성화하고 Obsidian을 재시작하시겠습니까?\n\n> [!DETAILS]-\n> 이러한 설정은 플러그인이 재구성 또는 데이터 가져오기 중에 자동으로 설정한 것입니다. 프로세스가 비정상적으로 종료되면 이 상태가 의도치 않게 유지될 수 있습니다.\n> 상태가 확실하지 않다면 이 과정을 다시 실행해 보세요. 재시작 전에 반드시 볼트를 백업해 주세요.", + ko: "Self-hosted LiveSync가 일부 이벤트를 무시하도록 설정되어 있습니다. 이 설정이 맞습니까?\n\n| 유형 | 상태 | 설명 |\n|:---:|:---:|---|\n| 스토리지 이벤트 | ${fileWatchingStatus} | 모든 수정 사항이 무시됩니다 |\n| 데이터베이스 이벤트 | ${parseReplicationStatus} | 모든 동기화 변경이 지연됩니다 |\n\n이벤트 감지를 다시 활성화하고 Obsidian을 재시작하시겠습니까?\n\n> [!DETAILS]-\n> 이 플래그는 플러그인이 재구축하거나 가져오는 동안 설정한 것입니다. 처리가 비정상적으로 종료되면 의도치 않게 남아 있을 수 있습니다.\n> 확실하지 않다면 해당 처리를 다시 실행해 보세요. 반드시 보관함을 백업해 두시기 바랍니다.\n", ru: "Self-hosted LiveSync has been configured to ignore some events. Is this correct?\n\n| Type | Status | Note |\n|:---:|:---:|---|\n| Storage Events | ${fileWatchingStatus} | Every modification will be ignored |\n| Database Events | ${parseReplicationStatus} | Every synchronised change will be postponed |\n\nDo you want to resume them and restart Obsidian?\n\n> [!DETAILS]-\n> These flags are set by the plug-in while rebuilding, or fetching. If the process ends abnormally, it may be kept unintended.\n> If you are not sure, you can try to rerun these processes. Make sure to back your vault up.\n", zh: "Self-hosted LiveSync 已被配置为忽略某些事件。这样对吗?\n\n| 类型 | 状态 | 说明 |\n|:---:|:---:|---|\n| 存储事件 | ${fileWatchingStatus} | 所有修改都将被忽略 |\n| 数据库事件 | ${parseReplicationStatus} | 所有同步的更改都将被推迟 |\n\n您想恢复它们并重启 Obsidian 吗?\n\n> [!DETAILS]-\n> 这些标志是在重建或获取时由插件设置的。如果过程异常结束,它们可能会被无意中保留。\n> 如果您不确定,可以尝试重新运行这些过程。请确保备份您的库。\n", }, @@ -3589,7 +3681,7 @@ export const allMessages: Readonly ${key} défini à ${value}", he: "תצורת CouchDB: ${title} -> הגדר ${key} ל-${value}", ja: "CouchDB設定: ${title} -> ${key}を${value}に設定", - ko: "CouchDB 구성: ${title} -> ${key}를 ${value}로 설정", + ko: "CouchDB 구성: ${title} -> ${key}을(를) ${value}(으)로 설정", ru: "Конфигурация CouchDB: title -> Установить key в value", zh: "CouchDB 配置:${title} -> 设置 ${key} 为 ${value}", }, @@ -4894,6 +5024,7 @@ export const allMessages: Readonly\nLégende\n\n| Symbole | Signification |\n|: ------ :| ------- |\n| ⇔ | À jour |\n| ⇄ | Synchroniser pour équilibrer |\n| ⇐,⇒ | Transférer pour écraser |\n| ⇠,⇢ | Transférer pour écraser depuis l'autre côté |\n\n\n\n## ${OPTION_REBUILD_BOTH}\nEn bref : 📄 ⇒¹ 💻 ⇒² 🛰️ ⇢ⁿ 💻 ⇄ⁿ⁺¹ 📄\nReconstruit les bases locale et distante à partir des fichiers existants de cet appareil.\nCeci provoque un verrouillage des autres appareils, qui devront effectuer une récupération.\n## ${OPTION_FETCH}\nEn bref : 📄 ⇄² 💻 ⇐¹ 🛰️ ⇔ 💻 ⇔ 📄\nInitialise la base locale et la reconstruit à partir des données récupérées depuis la base distante.\nCe cas inclut également celui où vous avez reconstruit la base distante.\n## ${OPTION_ONLY_SETTING}\nNe stocker que les paramètres. **Attention : cela peut entraîner une corruption des données** ; une reconstruction de la base est généralement nécessaire.", he: "נדרשת בנייה מחדש של מסדי הנתונים כדי להחיל את השינויים. אנא בחר את השיטה.\n\n
\nמקרא\n\n| סמל | משמעות |\n|: ------ :| ------- |\n| ⇔ | מעודכן |\n| ⇄ | סנכרן לאיזון |\n| ⇐,⇒ | העבר לדריסה |\n| ⇠,⇢ | העבר לדריסה מהצד השני |\n\n
\n\n## ${OPTION_REBUILD_BOTH}\nבמבט: 📄 ⇒¹ 💻 ⇒² 🛰️ ⇢ⁿ 💻 ⇄ⁿ⁺¹ 📄\nבנה מחדש גם את מסד הנתונים המקומי וגם המרוחד תוך שימוש בקבצים קיימים ממכשיר זה.\nפעולה זו תנעל מכשירים אחרים שיצטרכו לבצע משיכה.\n## ${OPTION_FETCH}\nבמבט: 📄 ⇄² 💻 ⇐¹ 🛰️ ⇔ 💻 ⇔ 📄\nאתחל את מסד הנתונים המקומי ובנה אותו מחדש תוך שימוש בנתונים שנמשכו ממסד הנתונים המרוחד.\nכולל את המקרה שבו בנית מחדש את מסד הנתונים המרוחד.\n## ${OPTION_ONLY_SETTING}\nשמור רק את ההגדרות. **זהירות: עלול לגרום לפגיעה בנתונים**; בנייה מחדש של מסד הנתונים נדרשת בדרך כלל.", ja: "変更を適用するにはデータベースの再構築が必要です。変更を適用する方法を選択してください。\n\n
\n凡例\n\n| 記号 | 意味 |\n|: ------ :| ------- |\n| ⇔ | 最新 |\n| ⇄ | 同期してバランスを取る |\n| ⇐,⇒ | 上書きするため転送 |\n| ⇠,⇢ | 反対側から上書きするため転送 |\n\n
\n\n## ${OPTION_REBUILD_BOTH}\n概要: 📄 ⇒¹ 💻 ⇒² 🛰️ ⇢ⁿ 💻 ⇄ⁿ⁺¹ 📄\nこのデバイスの既存ファイルを使用してローカルとリモートの両方のデータベースを再構築します。\n他のデバイスはロックアウトされ、フェッチが必要です。\n## ${OPTION_FETCH}\n概要: 📄 ⇄² 💻 ⇐¹ 🛰️ ⇔ 💻 ⇔ 📄\nローカルデータベースを初期化し、リモートデータベースから取得したデータを使用して再構築します。\nリモートデータベースを再構築した場合も含まれます。\n## ${OPTION_ONLY_SETTING}\n設定のみを保存します。**注意: データ破損につながる可能性があります**。通常、データベースの再構築が必要です。", - ko: "변경사항을 적용하려면 데이터베이스를 재구축해야 합니다. 아래 중 한 가지 방법을 선택해 주세요.\n\n
\n범례\n\n| 기호 | 의미 |\n|: ------ :| ------- |\n| ⇔ | 최신 상태 |\n| ⇄ | 동기화 균형 유지 |\n| ⇐,⇒ | 덮어쓰기 방식의 전송 |\n| ⇠,⇢ | 상대편에서 가져와 덮어쓰기 |\n\n
\n\n## ${OPTION_REBUILD_BOTH}\n개요: 📄 ⇒¹ 💻 ⇒² 🛰️ ⇢ⁿ 💻 ⇄ⁿ⁺¹ 📄\n이 기기의 기존 파일을 기반으로 로컬과 원격 데이터베이스를 모두 재구축합니다.\n이 과정에서 다른 기기는 일시적으로 접근이 제한되며, 가져오기 작업을 별도로 수행해야 합니다.\n\n## ${OPTION_FETCH}\n개요: 📄 ⇄² 💻 ⇐¹ 🛰️ ⇔ 💻 ⇔ 📄\n로컬 데이터베이스를 초기화한 후, 원격 데이터베이스에서 데이터를 가져와 재구축합니다.\n이는 원격 측에서 데이터베이스를 먼저 재구축한 경우에도 해당됩니다.\n\n## ${OPTION_ONLY_SETTING}\n설정만 저장합니다. **⚠️ 주의: 이 방법은 데이터 손상을 일으킬 수 있습니다.** 일반적으로는 전체 데이터베이스 재구축이 필요합니다.", + ko: "변경 사항을 적용하려면 데이터베이스를 재구축해야 합니다. 변경 사항을 적용할 방법을 선택해 주세요.\n\n
\n범례\n\n| 기호 | 의미 |\n|: ------ :| ------- |\n| ⇔ | 최신 상태 |\n| ⇄ | 양쪽을 맞추는 동기화 |\n| ⇐,⇒ | 덮어쓰기 전송 |\n| ⇠,⇢ | 반대편에서 덮어쓰기 전송 |\n\n
\n\n## ${OPTION_REBUILD_BOTH}\n한눈에 보기: 📄 ⇒¹ 💻 ⇒² 🛰️ ⇢ⁿ 💻 ⇄ⁿ⁺¹ 📄\n이 기기의 기존 파일을 사용해 로컬과 원격 데이터베이스를 모두 재구축합니다.\n이 경우 다른 기기는 잠기며, 가져오기를 수행해야 합니다.\n## ${OPTION_FETCH}\n한눈에 보기: 📄 ⇄² 💻 ⇐¹ 🛰️ ⇔ 💻 ⇔ 📄\n로컬 데이터베이스를 초기화한 뒤, 원격 데이터베이스에서 가져온 데이터로 재구축합니다.\n원격 데이터베이스를 이미 재구축한 경우도 여기에 해당합니다.\n## ${OPTION_ONLY_SETTING}\n설정만 저장합니다. **주의: 데이터가 손상될 수 있습니다.** 일반적으로는 데이터베이스 재구축이 필요합니다.", ru: "Требуется перестроение баз данных для применения изменений.", zh: "需要重建数据库以应用更改。请选择应用更改的方法。\n\n
\n图例\n\n| 符号 | 含义 |\n|: ------ :| ------- |\n| ⇔ | 最新 |\n| ⇄ | 同步以平衡 |\n| ⇐,⇒ | 传输以覆盖 |\n| ⇠,⇢ | 从另一侧传输以覆盖 |\n\n
\n\n## ${OPTION_REBUILD_BOTH}\n概览:📄 ⇒¹ 💻 ⇒² 🛰️ ⇢ⁿ 💻 ⇄ⁿ⁺¹ 📄\n使用此设备的现有文件重建本地和远程数据库。\n这将导致其他设备被锁定,并且它们需要执行获取操作。\n## ${OPTION_FETCH}\n概览:📄 ⇄² 💻 ⇐¹ 🛰️ ⇔ 💻 ⇔ 📄\n初始化本地数据库并使用从远程数据库获取的数据重建它。\n这种情况包括您已经重建了远程数据库的情况。\n## ${OPTION_ONLY_SETTING}\n仅存储设置。**注意:这可能导致数据损坏**;通常需要重建数据库", }, @@ -5388,7 +5521,7 @@ export const allMessages: Readonly${to}", he: "⚠ CORS Origin אינו תואם ${from}->${to}", ja: "⚠ CORS Originが一致しません ${from}->${to}", - ko: "⚠ CORS 원점이 일치하지 않습니다 {from}->{to}", + ko: "⚠ CORS 출처가 일치하지 않습니다 ${from}->${to}", ru: "⚠ CORS Origin не совпадает from->to", zh: "⚠ CORS 源不匹配 {from}->{to}", }, @@ -6106,7 +6245,7 @@ export const allMessages: Readonly[!INFO]- Details\n> ## Create a local database once before fetching.\n> **Low Traffic**, **High CPU**, **Low Risk**\n> This option first creates a local database using existing local files before fetching data from the remote source.\n> If matching files exist both locally and remotely, only the differences between them will be transferred.\n> However, files present in both locations will initially be handled as conflicted files. They will be resolved automatically if they are not actually conflicted, but this process may take time.\n> This is generally the safest method, minimizing data loss risk.\n> ## Create local file chunks before fetching.\n> **Low Traffic**, **Moderate CPU**, **Low to Moderate Risk** (depending operation)\n> This option first creates chunks from local files for the database, then fetches data. Consequently, only chunks missing locally are transferred. However, all metadata is taken from the remote source.\n> Local files are then compared against this metadata at launch. The content considered newer will overwrite the older one (by modified time). This outcome is then synchronised back to the remote database.\n> This is generally safe if local files are genuinely the latest timestamp. However, it can cause problems if a file has a newer timestamp but older content (like the initial `welcome.md`).\n> This uses less CPU and faster than \"Create a local database once before fetching\", but it may lead to data loss if not used carefully.\n> ## Fetch everything from the remote.\n> **High Traffic**, **Low CPU**, **Low to Moderate Risk** (depending operation)\n> All things will be fetched from the remote.\n> Similar to the Create local file chunks before fetching, but all chunks are fetched from the remote source.\n> This is the most traditional way to fetch, typically consuming the most network traffic and time. It also carries a similar risk of overwriting remote files to the 'Create local file chunks before fetching' option.\n> However, it is often considered the most stable method because it is the longest-established and most straightforward approach.", + es: "¿Cómo quieres obtener los datos?\n- Crear una base de datos local antes de obtener los datos.\n **Poco tráfico**, **mucha CPU**, **riesgo bajo**\n Recomendado si...\n - Los archivos podrían ser inconsistentes\n - No hay demasiados archivos\n- Crear los chunks de los archivos locales antes de obtener los datos.\n **Poco tráfico**, **CPU moderada**, **riesgo bajo o moderado**\n Recomendado si...\n - Los archivos son probablemente consistentes\n - Tienes muchos archivos\n- Obtener todo del remoto.\n **Mucho tráfico**, **poca CPU**, **riesgo bajo o moderado**\n\n>[!INFO]- Detalles\n> ## Crear una base de datos local antes de obtener los datos.\n> **Poco tráfico**, **mucha CPU**, **riesgo bajo**\n> Esta opción crea primero una base de datos local a partir de los archivos locales existentes antes de obtener los datos del remoto.\n> Si un archivo existe tanto en local como en remoto, solo se transferirán las diferencias.\n> Sin embargo, los archivos presentes en ambos sitios se tratarán inicialmente como archivos en conflicto. Se resolverán automáticamente si en realidad no lo están, pero el proceso puede tardar.\n> En general es el método más seguro y el que menos riesgo de pérdida de datos conlleva.\n> ## Crear los chunks de los archivos locales antes de obtener los datos.\n> **Poco tráfico**, **CPU moderada**, **riesgo bajo o moderado** (según la operación)\n> Esta opción crea primero los chunks de los archivos locales para la base de datos y después obtiene los datos. Así solo se transfieren los chunks que faltan en local. Aun así, todos los metadatos se toman del remoto.\n> Al iniciar, los archivos locales se comparan con esos metadatos. El contenido considerado más reciente sobrescribirá al más antiguo (según la fecha de modificación) y el resultado se sincroniza de vuelta a la base de datos remota.\n> Es seguro si los archivos locales son realmente los de fecha más reciente, pero puede dar problemas si un archivo tiene una fecha más nueva y un contenido más antiguo (como el `welcome.md` inicial).\n> Usa menos CPU y es más rápido que «Crear una base de datos local antes de obtener los datos», pero puede provocar pérdida de datos si no se usa con cuidado.\n> ## Obtener todo del remoto.\n> **Mucho tráfico**, **poca CPU**, **riesgo bajo o moderado** (según la operación)\n> Se obtiene todo del remoto.\n> Similar a Crear los chunks de los archivos locales antes de obtener los datos, pero todos los chunks se descargan del remoto.\n> Es la forma más tradicional de obtener los datos y normalmente la que más tráfico y tiempo consume. Conlleva un riesgo de sobrescribir archivos remotos parecido al de «Crear los chunks de los archivos locales antes de obtener los datos».\n> Aun así, suele considerarse el método más estable, por ser el más antiguo y directo.", fr: "Comment voulez-vous récupérer ?\n- Créer une base locale avant de récupérer.\n **Trafic faible**, **CPU élevé**, **Risque faible**\n Recommandé si ...\n - Fichiers possiblement incohérents\n - Fichiers peu nombreux\n- Créer des fragments de fichiers locaux avant de récupérer.\n **Trafic faible**, **CPU modéré**, **Risque faible à modéré**\n Recommandé si ...\n - Fichiers probablement cohérents\n - Vous avez beaucoup de fichiers.\n- Tout récupérer depuis le distant.\n **Trafic élevé**, **CPU faible**, **Risque faible à modéré**\n\n>[!INFO]- Détails\n> ## Créer une base locale avant de récupérer.\n> **Trafic faible**, **CPU élevé**, **Risque faible**\n> Cette option crée d'abord une base locale à partir des fichiers locaux existants avant de récupérer les données depuis la source distante.\n> Si des fichiers correspondants existent à la fois localement et à distance, seules les différences entre eux seront transférées.\n> Toutefois, les fichiers présents aux deux emplacements seront initialement traités comme en conflit. Ils seront résolus automatiquement s'ils ne le sont pas réellement, mais ce processus peut prendre du temps.\n> C'est généralement la méthode la plus sûre, minimisant le risque de perte de données.\n> ## Créer des fragments de fichiers locaux avant de récupérer.\n> **Trafic faible**, **CPU modéré**, **Risque faible à modéré** (selon l'opération)\n> Cette option crée d'abord des fragments à partir des fichiers locaux pour la base, puis récupère les données. Par conséquent, seuls les fragments manquants localement sont transférés. Cependant, toutes les métadonnées sont prises de la source distante.\n> Les fichiers locaux sont ensuite comparés à ces métadonnées au lancement. Le contenu considéré comme plus récent écrasera le plus ancien (selon la date de modification). Le résultat est ensuite synchronisé vers la base distante.\n> C'est généralement sûr si les fichiers locaux ont bien l'horodatage le plus récent. Cela peut toutefois poser problème si un fichier a un horodatage plus récent mais un contenu plus ancien (comme le `welcome.md` initial).\n> Cette méthode utilise moins de CPU et est plus rapide que « Créer une base locale avant de récupérer », mais peut entraîner une perte de données si elle n'est pas utilisée avec précaution.\n> ## Tout récupérer depuis le distant.\n> **Trafic élevé**, **CPU faible**, **Risque faible à modéré** (selon l'opération)\n> Tout sera récupéré depuis le distant.\n> Similaire à Créer des fragments de fichiers locaux avant de récupérer, mais tous les fragments sont récupérés depuis la source distante.\n> C'est la façon la plus traditionnelle de récupérer, consommant généralement le plus de trafic réseau et de temps. Elle comporte également un risque similaire d'écraser les fichiers distants à l'option « Créer des fragments de fichiers locaux avant de récupérer ».\n> Elle est toutefois souvent considérée comme la méthode la plus stable car c'est la plus ancienne et la plus directe.", he: 'כיצד ברצונך למשוך?\n- %{RedFlag.Fetch.Method.FetchSafer}.\n **תעבורה נמוכה**, **מעבד גבוה**, **סיכון נמוך**\n מומלץ אם...\n - קבצים עשויים להיות לא עקביים\n - אין הרבה קבצים\n- %{RedFlag.Fetch.Method.FetchSmoother}.\n **תעבורה נמוכה**, **מעבד בינוני**, **סיכון נמוך עד בינוני**\n מומלץ אם...\n - הקבצים ככל הנראה עקביים\n - יש לך הרבה קבצים.\n- %{RedFlag.Fetch.Method.FetchTraditional}.\n **תעבורה גבוהה**, **מעבד נמוך**, **סיכון נמוך עד בינוני**\n\n>[!INFO]- פרטים\n> ## %{RedFlag.Fetch.Method.FetchSafer}.\n> **תעבורה נמוכה**, **מעבד גבוה**, **סיכון נמוך**\n> אפשרות זו יוצרת תחילה מסד נתונים מקומי תוך שימוש בקבצים מקומיים קיימים לפני משיכת נתונים מהמקור המרוחד.\n> אם קיימים קבצים תואמים גם מקומית וגם מרחוק, רק ההפרשים ביניהם יועברו.\n> עם זאת, קבצים הקיימים בשני המקומות יטופלו תחילה כקבצים מתנגשים. הם ייפתרו אוטומטית אם לא מתנגשים בפועל, אך תהליך זה עשוי לקחת זמן.\n> זוהי בדרך כלל השיטה הבטוחה ביותר, ממזערת סיכון לאובדן נתונים.\n> ## %{RedFlag.Fetch.Method.FetchSmoother}.\n> **תעבורה נמוכה**, **מעבד בינוני**, **סיכון נמוך עד בינוני** (תלוי בפעולה)\n> אפשרות זו יוצרת תחילה נתחים מקבצים מקומיים למסד הנתונים, ואז מושכת נתונים. כתוצאה מכך, רק נתחים חסרים מקומית מועברים. עם זאת, כל המטה-נתונים נלקחים מהמקור המרוחד.\n> קבצים מקומיים נבדקים לאחר מכן מול מטה-נתונים אלה בעת ההפעלה. התוכן שנחשב חדש יותר ידרוס את הישן יותר (לפי זמן שינוי).\n> בדרך כלל בטוח אם הקבצים המקומיים הם אכן חדשים ביותר. עם זאת, עלול לגרום לבעיות אם לקובץ יש חותמת זמן חדשה יותר אך תוכן ישן יותר (כמו `welcome.md` ראשוני).\n> שיטה זו משתמשת בפחות מעבד ומהירה יותר מ-"%{RedFlag.Fetch.Method.FetchSafer}", אך עלולה להוביל לאובדן נתונים אם לא משתמשים בה בזהירות.\n> ## %{RedFlag.Fetch.Method.FetchTraditional}.\n> **תעבורה גבוהה**, **מעבד נמוך**, **סיכון נמוך עד בינוני** (תלוי בפעולה)\n> הכל יימשך מהשרת המרוחד.\n> דומה ל-%{RedFlag.Fetch.Method.FetchSmoother}, אך כל הנתחים נמשכים מהמקור המרוחד.\n> זוהי הדרך המסורתית ביותר למשיכה, צורכת בדרך כלל את רוב תעבורת הרשת והזמן.\n> עם זאת, היא נחשבת לעתים קרובות לשיטה היציבה ביותר מכיוון שהיא הוותיקה והישירה ביותר.', ja: "どのようにフェッチしますか?\n- フェッチ前にローカルデータベースを作成\n **低トラフィック**, **高CPU負荷**, **低リスク**\n 推奨条件...\n - ファイルの整合性に不安がある\n - ファイル数がそれほど多くない\n- フェッチ前にローカルファイルチャンクを作成\n **低トラフィック**, **中程CPU負荷**, **低~中リスク**\n 推奨条件...\n - ファイルがおそらく整合している\n - ファイル数が多い\n- リモートからすべてをフェッチ\n **高トラフィック**, **低CPU負荷**, **低~中リスク**\n\n>[!INFO]- 詳細\n> ## フェッチ前にローカルデータベースを作成\n> **低トラフィック**, **高CPU負荷**, **低リスク**\n> このオプションは、リモートからデータをフェッチする前に、既存のローカルファイルを使用してローカルデータベースを作成します。\n> ローカルとリモートの両方に一致するファイルがある場合、差分のみが転送されます。\n> ただし、両方の場所に存在するファイルは最初は競合ファイルとして処理されます。実際に競合していなければ自動的に解決されますが、この処理には時間がかかる場合があります。\n> これは一般的に最も安全な方法で、データ損失のリスクを最小限に抑えます。\n> ## フェッチ前にローカルファイルチャンクを作成\n> **低トラフィック**, **中程CPU負荷**, **低~中リスク**(操作による)\n> このオプションは、最初にローカルファイルからデータベース用のチャンクを作成し、その後データをフェッチします。そのため、ローカルにないチャンクのみが転送されます。ただし、すべてのメタデータはリモートから取得されます。\n> ローカルファイルは起動時にこのメタデータと比較されます。新しいと判断されたコンテンツ(更新日時による)が古いものを上書きします。この結果はリモートデータベースに同期されます。\n> ローカルファイルが本当に最新のタイムスタンプであれば一般的に安全です。ただし、ファイルのタイムスタンプが新しくてもコンテンツが古い場合(初期の`welcome.md`など)は問題が発生する可能性があります。\n> これは\"フェッチ前にローカルデータベースを作成\"よりCPU使用量が少なく高速ですが、注意しないとデータ損失につながる可能性があります。\n> ## リモートからすべてをフェッチ\n> **高トラフィック**, **低CPU負荷**, **低~中リスク**(操作による)\n> すべてのデータがリモートからフェッチされます。\n> フェッチ前にローカルファイルチャンクを作成と似ていますが、すべてのチャンクがリモートからフェッチされます。\n> これは最も従来のフェッチ方法で、通常最もネットワークトラフィックと時間を消費します。'フェッチ前にローカルファイルチャンクを作成'オプションと同様のリモートファイル上書きのリスクがあります。\n> ただし、最も歴史があり簡単なアプローチであるため、最も安定した方法と見なされることが多いです。", - ko: "어떻게 가져오시겠습니까?\n- 가져오기 전에 로컬 데이터베이스를 한 번 생성. (권장)\n **낮은 트래픽**, **높은 CPU**, **낮은 위험**\n- 가져오기 전에 로컬 파일 청크 생성.\n **낮은 트래픽**, **보통 CPU**, **낮음에서 보통 위험**\n- 원격에서 모든 것 가져오기.\n **높은 트래픽**, **낮은 CPU**, **낮음에서 보통 위험**\n\n>[!INFO]- 세부 사항\n> ## 가져오기 전에 로컬 데이터베이스를 한 번 생성. (권장)\n> **낮은 트래픽**, **높은 CPU**, **낮은 위험**\n> 이 옵션은 원격 소스에서 데이터를 가져오기 전에 기존 로컬 파일을 사용하여 로컬 데이터베이스를 먼저 생성합니다.\n> 로컬과 원격 모두에 일치하는 파일이 있으면 둘 사이의 차이점만 전송됩니다.\n> 하지만 두 위치 모두에 있는 파일은 초기에 충돌 파일로 처리됩니다. 실제로 충돌하지 않는다면 자동으로 해결되지만 이 과정은 시간이 걸릴 수 있습니다.\n> 이는 일반적으로 가장 안전한 방법으로 데이터 손실 위험을 최소화합니다.\n> ## 가져오기 전에 로컬 파일 청크 생성.\n> **낮은 트래픽**, **보통 CPU**, **낮음에서 보통 위험** (작업에 따라)\n> 이 옵션은 먼저 로컬 파일에서 데이터베이스용 청크를 생성한 다음 데이터를 가져옵니다. 따라서 로컬에 없는 청크만 전송됩니다. 하지만 모든 메타데이터는 원격 소스에서 가져옵니다.\n> 그런 다음 로컬 파일이 시작 시 이 메타데이터와 비교됩니다. 더 새로운 것으로 간주되는 콘텐츠가 오래된 것을 덮어씁니다(수정 시간 기준). 이 결과는 원격 데이터베이스에 다시 동기화됩니다.\n> 로컬 파일이 실제로 최신 타임스탬프라면 일반적으로 안전합니다. 하지만 파일이 더 새로운 타임스탬프를 가지고 있지만 더 오래된 콘텐츠를 가지고 있다면(초기 `welcome.md`처럼) 문제가 발생할 수 있습니다.\n> 이는 \"가져오기 전에 로컬 데이터베이스를 한 번 생성\"보다 CPU를 덜 사용하고 더 빠르지만 주의 깊게 사용하지 않으면 데이터 손실로 이어질 수 있습니다.\n> ## 원격에서 모든 것 가져오기.\n> **높은 트래픽**, **낮은 CPU**, **낮음에서 보통 위험** (작업에 따라)\n> 모든 것이 원격에서 가져와집니다.\n> 가져오기 전에 로컬 파일 청크 생성와 유사하지만 모든 청크가 원격 소스에서 가져와집니다.\n> 이는 가장 전통적인 가져오기 방법으로 일반적으로 가장 많은 네트워크 트래픽과 시간을 소모합니다. 또한 '가져오기 전에 로컬 파일 청크 생성' 옵션과 유사하게 원격 파일을 덮어쓸 위험이 있습니다.\n> 하지만 가장 오래되고 가장 직접적인 접근 방식이기 때문에 종종 가장 안정적인 방법으로 간주됩니다.", + ko: "어떻게 가져오시겠습니까?\n- 가져오기 전에 로컬 데이터베이스를 한 번 생성.\n **낮은 트래픽**, **높은 CPU**, **낮은 위험**\n 다음의 경우에 권장합니다.\n - 파일이 일관되지 않을 가능성이 있음\n - 파일이 그리 많지 않음\n- 가져오기 전에 로컬 파일 청크 생성.\n **낮은 트래픽**, **보통 CPU**, **낮음~보통 위험**\n 다음의 경우에 권장합니다.\n - 파일이 대체로 일관됨\n - 파일이 많음\n- 원격에서 모든 것 가져오기.\n **높은 트래픽**, **낮은 CPU**, **낮음~보통 위험**\n\n>[!INFO]- 자세히\n> ## 가져오기 전에 로컬 데이터베이스를 한 번 생성.\n> **낮은 트래픽**, **높은 CPU**, **낮은 위험**\n> 원격에서 데이터를 가져오기 전에 기존 로컬 파일로 로컬 데이터베이스를 먼저 만듭니다.\n> 로컬과 원격 양쪽에 일치하는 파일이 있으면 둘 사이의 차이만 전송됩니다.\n> 다만 양쪽에 모두 있는 파일은 처음에 충돌 파일로 처리됩니다. 실제로 충돌하지 않는다면 자동으로 해결되지만, 이 과정에 시간이 걸릴 수 있습니다.\n> 일반적으로 가장 안전한 방법이며 데이터 손실 위험이 가장 낮습니다.\n> ## 가져오기 전에 로컬 파일 청크 생성.\n> **낮은 트래픽**, **보통 CPU**, **낮음~보통 위험** (작업에 따라 다름)\n> 먼저 로컬 파일로 데이터베이스용 청크를 만든 다음 데이터를 가져옵니다. 따라서 로컬에 없는 청크만 전송됩니다. 다만 메타데이터는 모두 원격에서 가져옵니다.\n> 그다음 시작 시점에 로컬 파일을 이 메타데이터와 비교합니다. 수정 시각을 기준으로 더 새롭다고 판단된 내용이 오래된 쪽을 덮어씁니다. 그 결과는 다시 원격 데이터베이스로 동기화됩니다.\n> 로컬 파일이 실제로 가장 최신 타임스탬프를 가지고 있다면 대체로 안전합니다. 하지만 타임스탬프는 더 새롭지만 내용은 더 오래된 파일(처음 만들어지는 `welcome.md` 같은)이 있으면 문제가 생길 수 있습니다.\n> \"가져오기 전에 로컬 데이터베이스를 한 번 생성\"보다 CPU를 적게 쓰고 더 빠르지만, 주의해서 사용하지 않으면 데이터가 손실될 수 있습니다.\n> ## 원격에서 모든 것 가져오기.\n> **높은 트래픽**, **낮은 CPU**, **낮음~보통 위험** (작업에 따라 다름)\n> 모든 것을 원격에서 가져옵니다.\n> 가져오기 전에 로컬 파일 청크 생성와 비슷하지만, 모든 청크를 원격에서 가져옵니다.\n> 가장 전통적인 가져오기 방식으로, 보통 네트워크 트래픽과 시간을 가장 많이 소모합니다. 또한 '가져오기 전에 로컬 파일 청크 생성' 옵션과 마찬가지로 원격 파일을 덮어쓸 위험이 있습니다.\n> 다만 가장 오래되고 단순한 방식이기 때문에 가장 안정적인 방법으로 여겨지는 경우가 많습니다.", ru: "Как вы хотите загрузить?", zh: "How do you want to fetch?\n- Create a local database once before fetching.\n **Low Traffic**, **High CPU**, **Low Risk**\n Recommended if ...\n - Files possibly inconsistent\n - Files were not so much\n- Create local file chunks before fetching.\n **Low Traffic**, **Moderate CPU**, **Low to Moderate Risk**\n Recommended if ...\n - Files probably consistent\n - You have a lot of files.\n- Fetch everything from the remote.\n **High Traffic**, **Low CPU**, **Low to Moderate Risk**\n\n>[!INFO]- Details\n> ## Create a local database once before fetching.\n> **Low Traffic**, **High CPU**, **Low Risk**\n> This option first creates a local database using existing local files before fetching data from the remote source.\n> If matching files exist both locally and remotely, only the differences between them will be transferred.\n> However, files present in both locations will initially be handled as conflicted files. They will be resolved automatically if they are not actually conflicted, but this process may take time.\n> This is generally the safest method, minimizing data loss risk.\n> ## Create local file chunks before fetching.\n> **Low Traffic**, **Moderate CPU**, **Low to Moderate Risk** (depending operation)\n> This option first creates chunks from local files for the database, then fetches data. Consequently, only chunks missing locally are transferred. However, all metadata is taken from the remote source.\n> Local files are then compared against this metadata at launch. The content considered newer will overwrite the older one (by modified time). This outcome is then synchronised back to the remote database.\n> This is generally safe if local files are genuinely the latest timestamp. However, it can cause problems if a file has a newer timestamp but older content (like the initial `welcome.md`).\n> This uses less CPU and faster than \"Create a local database once before fetching\", but it may lead to data loss if not used carefully.\n> ## Fetch everything from the remote.\n> **High Traffic**, **Low CPU**, **Low to Moderate Risk** (depending operation)\n> All things will be fetched from the remote.\n> Similar to the Create local file chunks before fetching, but all chunks are fetched from the remote source.\n> This is the most traditional way to fetch, typically consuming the most network traffic and time. It also carries a similar risk of overwriting remote files to the 'Create local file chunks before fetching' option.\n> However, it is often considered the most stable method because it is the longest-established and most straightforward approach.", }, "RedFlag.Fetch.Method.FetchSafer": { def: "Create a local database once before fetching", + es: "Crear una base de datos local antes de obtener los datos", fr: "Créer une base locale avant de récupérer", he: "צור מסד נתונים מקומי לפני המשיכה", ja: "フェッチ前にローカルデータベースを作成", @@ -6835,6 +7009,7 @@ export const allMessages: Readonly[!POUR VOS YEUX SEULEMENT]-\n>
\n>\n> ### Clé publique\n> ```\n${public_key}\n> ```\n>\n> ### Clé privée\n> ```\n${private_key}\n> ```\n>\n>
\n\n>[!Les deux pour copier]-\n>\n>
\n>\n> ```\n${public_key}\n${private_key}\n> ```\n>\n>
\n\n', he: 'יצרנו זוג מפתחות!\n\nהערה: זוג מפתחות זה לא יוצג שוב. אנא שמור אותו במקום בטוח. אם אבד לך, יהיה צורך לייצר זוג מפתחות חדש.\nהערה 2: המפתח הציבורי הוא בפורמט spki, והמפתח הפרטי הוא בפורמט pkcs8. לנוחות, שורות חדשות ממוירות ל-`\\n` במפתח הציבורי.\nהערה 3: יש להגדיר את המפתח הציבורי במסד הנתונים המרוחד, ואת המפתח הפרטי במכשירים המקומיים.\n\n>[!FOR YOUR EYES ONLY]-\n>
\n>\n> ### מפתח ציבורי\n> ```\n${public_key}\n> ```\n>\n> ### מפתח פרטי\n> ```\n${private_key}\n> ```\n>\n>
\n\n>[!Both for copying]-\n>\n>
\n>\n> ```\n${public_key}\n${private_key}\n> ```\n>\n>
\n\n', ja: 'キーペアを生成しました!\n\n注意: このキーペアは再度表示されません。安全な場所に保存してください。紛失した場合は、新しいキーペアを生成する必要があります。\n注意2: 公開鍵はspki形式、秘密鍵はpkcs8形式です。利便性のため、公開鍵の改行は`\\n`に変換されています。\n注意3: 公開鍵はリモートデータベースに、秘密鍵はローカルデバイスに設定してください。\n\n>[!FOR YOUR EYES ONLY]-\n>
\n>\n> ### 公開鍵\n> ```\n${public_key}\n> ```\n>\n> ### 秘密鍵\n> ```\n${private_key}\n> ```\n>\n>
\n\n>[!Both for copying]-\n>\n>
\n>\n> ```\n${public_key}\n${private_key}\n> ```\n>\n>
\n\n', - ko: '키 페어를 생성했습니다!\n\n참고: 이 키 페어는 다시 표시되지 않습니다. 안전한 곳에 저장해 주세요. 분실하면 새 키 페어를 생성해야 합니다.\n참고 2: 공개 키는 spki 형식이고, 개인 키는 pkcs8 형식입니다. 편의상 공개 키의 줄 바꿈은 `\\n`으로 변환됩니다.\n참고 3: 공개 키는 원격 데이터베이스에서 구성되어야 하고, 개인 키는 로컬 기기에서 구성되어야 합니다.\n\n>[!FOR YOUR EYES ONLY]-\n>
\n>\n> ### 공개 키\n> ```\n${public_key}\n> ```\n>\n> ### 개인 키\n> ```\n${private_key}\n> ```\n>\n>
\n\n>[!Both for copying]-\n>\n>
\n>\n> ```\n${public_key}\n${private_key}\n> ```\n>\n>
\n\n\n', + ko: '키 페어를 생성했습니다!\n\n참고: 이 키 페어는 다시 표시되지 않습니다. 안전한 곳에 저장해 주세요. 분실하면 새 키 페어를 생성해야 합니다.\n참고 2: 공개 키는 spki 형식이고, 개인 키는 pkcs8 형식입니다. 편의를 위해 공개 키의 줄 바꿈은 `\\n`으로 변환됩니다.\n참고 3: 공개 키는 원격 데이터베이스에, 개인 키는 로컬 기기에 설정해야 합니다.\n\n>[!FOR YOUR EYES ONLY]-\n>
\n>\n> ### 공개 키\n> ```\n${public_key}\n> ```\n>\n> ### 개인 키\n> ```\n${private_key}\n> ```\n>\n>
\n\n>[!Both for copying]-\n>\n>
\n>\n> ```\n${public_key}\n${private_key}\n> ```\n>\n>
\n\n', ru: "Мы сгенерировали пару ключей!", zh: '我们已经生成了一组密钥对!\n\n注意:这组密钥对之后将不会再次显示。请务必妥善保管;如果丢失,你需要重新生成新的密钥对。\n注意 2:公钥采用 spki 格式,私钥采用 pkcs8 格式。为方便复制,公钥中的换行会被转换为 `\\n`。\n注意 3:公钥应配置在远端数据库中,私钥应配置在本地设备上。\n\n>[!仅限本人查看]-\n>
\n>\n> ### 公钥\n> ```\n${public_key}\n> ```\n>\n> ### 私钥\n> ```\n${private_key}\n> ```\n>\n>
\n\n>[!整段复制]-\n>\n>
\n>\n> ```\n${public_key}\n${private_key}\n> ```\n>\n>
', "zh-tw": @@ -7711,6 +7919,7 @@ export const allMessages: Readonly[!FOR YOUR EYES ONLY]-\n>
${qr_image}
', + es: 'Hemos generado un código QR para transferir los ajustes. Escanéalo con tu móvil u otro dispositivo.\nNota: el código QR no está cifrado, así que ten cuidado al abrirlo.\n\n>[!SOLO PARA TUS OJOS]-\n>
${qr_image}
', fr: "Nous avons généré un QR code pour transférer les paramètres. Scannez-le avec votre téléphone ou un autre appareil.\nNote : le QR code n'est pas chiffré, soyez prudent en l'affichant.\n\n>[!POUR VOS YEUX SEULEMENT]-\n>
${qr_image}
", he: 'יצרנו קוד QR להעברת ההגדרות. אנא סרוק את קוד ה-QR עם הטלפון או מכשיר אחר.\nהערה: קוד ה-QR אינו מוצפן, אז היה זהיר בפתיחתו.\n\n>[!FOR YOUR EYES ONLY]-\n>
${qr_image}
', ja: '設定を転送するためのQRコードを生成しました。スマートフォンや他のデバイスでQRコードをスキャンしてください。\n注意: QRコードは暗号化されていないため、開く際は注意してください。\n\n>[!FOR YOUR EYES ONLY]-\n>
${qr_image}
', @@ -7961,7 +8209,7 @@ export const allMessages: Readonly Database": { def: "Storage -> Database", + es: "Almacenamiento -> Base de datos", + ko: "스토리지 -> 데이터베이스", "zh-tw": "儲存空間 -> 資料庫", }, "Strongly Recommended": { @@ -8494,7 +8751,7 @@ export const allMessages: Readonly[!TIP]\n> If you want to synchronise all settings, please use `Sync settings via markdown` after applying minimal configuration with this feature.\n\n${additionalMessage}", + es: "\nLos ajustes de la base de datos remota son los siguientes. Los han configurado otros dispositivos que se han sincronizado con este al menos una vez.\n\nSi quieres usar estos ajustes, selecciona Usar los ajustes configurados.\nSi prefieres conservar los de este dispositivo, selecciona Descartar.\n\n${table}\n\n>[!TIP]\n> Si quieres sincronizar todos los ajustes, usa «Sync settings via markdown» después de aplicar la configuración mínima con esta función.\n\n${additionalMessage}", fr: "\nLes paramètres de la base distante sont les suivants. Ces valeurs sont configurées par d'autres appareils, synchronisés au moins une fois avec celui-ci.\n\nPour utiliser ces paramètres, sélectionnez Utiliser les paramètres configurés.\nPour conserver les paramètres de cet appareil, sélectionnez Ignorer.\n\n${table}\n\n>[!ASTUCE]\n> Pour synchroniser tous les paramètres, utilisez « Synchroniser les paramètres via markdown » après application de la configuration minimale avec cette fonctionnalité.\n\n${additionalMessage}", he: "\nההגדרות במסד הנתונים המרוחד הן כדלקמן. ערכים אלה הוגדרו על ידי מכשירים אחרים, אשר סונכרנו עם מכשיר זה לפחות פעם אחת.\n\nאם ברצונך להשתמש בהגדרות אלה, אנא בחר %{TweakMismatchResolve.Action.UseConfigured}.\nאם ברצונך לשמור את הגדרות מכשיר זה, אנא בחר %{TweakMismatchResolve.Action.Dismiss}.\n\n${table}\n\n>[!TIP]\n> אם ברצונך לסנכרן את כל ההגדרות, אנא השתמש ב-`סנכרון הגדרות דרך Markdown` לאחר החלת תצורה מינימלית עם תכונה זו.\n\n${additionalMessage}", ja: "\nリモートデータベースの設定は以下の通りです。これらの値は、このデバイスと少なくとも1回同期された他のデバイスによって設定されています。\n\nこれらの設定を使用する場合は、設定済みの設定を使用を選択してください。\nこのデバイスの設定を維持する場合は、無視を選択してください。\n\n${table}\n\n>[!TIP]\n> すべての設定を同期したい場合は、この機能で最小限の設定を適用した後、`Sync settings via markdown`を使用してください。\n\n${additionalMessage}", @@ -9014,6 +9290,7 @@ export const allMessages: Readonly[!NOTICE]\n> Some changes are compatible but may consume extra storage and transfer volumes. A rebuild is recommended. However, a rebuild may not be performed at present, but may be implemented in future maintenance.\n> ***Please ensure that you have time and are connected to a stable network to apply!***", + es: "\n>[!NOTICE]\n> Algunos cambios son compatibles, pero pueden consumir almacenamiento y transferencia de más. Se recomienda reconstruir. De momento puede que no se reconstruya, pero podría hacerse en un mantenimiento futuro.\n> ***Asegúrate de tener tiempo y una red estable antes de aplicarlo.***", fr: "\n>[!AVIS]\n> Certains changements sont compatibles mais peuvent consommer du stockage et du trafic supplémentaires. Une reconstruction est recommandée. Cependant, elle peut ne pas être effectuée maintenant, mais pourra l'être lors d'une maintenance future.\n> ***Assurez-vous d'avoir du temps et une connexion stable pour appliquer !***", he: "\n>[!NOTICE]\n> חלק מהשינויים תואמים אך עלולים לצרוך אחסון ותעבורה נוספים. מומלצת בנייה מחדש. עם זאת, ייתכן שבנייה מחדש לא תתבצע כעת, אך תיושם בתחזוקה עתידית.\n> ***ודא שיש לך זמן ושאתה מחובר לרשת יציבה לפני ההחלה!***", ja: "\n>[!NOTICE]\n> 一部の変更は互換性がありますが、追加のストレージと転送量を消費する可能性があります。再構築をお勧めします。ただし、再構築は現時点では実行されない場合がありますが、将来のメンテナンスで実装される可能性があります。\n> ***適用には時間と安定したネットワーク接続が必要です!***", @@ -9038,6 +9320,7 @@ export const allMessages: Readonly[!WARNING]\n> Some remote configurations are not compatible with the local database of this device. Rebuilding the local database will be required.\n> ***Please ensure that you have time and are connected to a stable network to apply!***", + es: "\n>[!WARNING]\n> Algunas configuraciones remotas no son compatibles con la base de datos local de este dispositivo. Habrá que reconstruirla.\n> ***Asegúrate de tener tiempo y una red estable antes de aplicarlo.***", fr: "\n>[!AVERTISSEMENT]\n> Certaines configurations distantes ne sont pas compatibles avec la base locale de cet appareil. Une reconstruction de la base locale sera requise.\n> ***Assurez-vous d'avoir du temps et une connexion stable pour appliquer !***", he: "\n>[!WARNING]\n> חלק מהתצורות המרוחקות אינן תואמות למסד הנתונים המקומי של מכשיר זה. נדרשת בנייה מחדש של מסד הנתונים המקומי.\n> ***ודא שיש לך זמן ושאתה מחובר לרשת יציבה לפני ההחלה!***", ja: "\n>[!WARNING]\n> 一部のリモート設定はこのデバイスのローカルデータベースと互換性がありません。ローカルデータベースの再構築が必要です。\n> ***適用には時間と安定したネットワーク接続が必要です!***", @@ -9047,6 +9330,7 @@ export const allMessages: Readonly[!NOTICE]\n> We have detected that some of the values are different to make incompatible the local database with the remote database.\n> Some changes are compatible but may consume extra storage and transfer volumes. A rebuild is recommended. However, a rebuild may not be performed at present, but may be implemented in future maintenance.\n> If you want to rebuild, it takes a few minutes or more. **Make sure it is safe to perform it now.**", + es: "\n>[!NOTICE]\n> Hemos detectado que algunos valores difieren de forma que hacen incompatible la base de datos local con la remota.\n> Algunos cambios son compatibles, pero pueden consumir almacenamiento y transferencia de más. Se recomienda reconstruir. De momento puede que no se reconstruya, pero podría hacerse en un mantenimiento futuro.\n> Si decides reconstruir, tardará unos minutos o más. **Asegúrate de que es seguro hacerlo ahora.**", fr: "\n>[!AVIS]\n> Nous avons détecté que certaines valeurs diffèrent et rendent la base locale incompatible avec la base distante.\n> Certains changements sont compatibles mais peuvent consommer du stockage et du trafic supplémentaires. Une reconstruction est recommandée. Cependant, elle peut ne pas être effectuée maintenant, mais pourra l'être lors d'une maintenance future.\n> Si vous souhaitez reconstruire, cela prend quelques minutes ou plus. **Assurez-vous qu'il est sûr de le faire maintenant.**", he: "\n>[!NOTICE]\n> זיהינו שחלק מהערכים שונים, מה שגורם לאי-תאימות בין מסד הנתונים המקומי למרוחד.\n> חלק מהשינויים תואמים אך עלולים לצרוך אחסון ותעבורה נוספים. מומלצת בנייה מחדש. עם זאת, ייתכן שבנייה מחדש לא תתבצע כעת, אך תיושם בתחזוקה עתידית.\n> אם ברצונך לבנות מחדש, הדבר ייקח כמה דקות או יותר. **ודא שבטוח לבצע זאת עכשיו.**", ja: "\n>[!NOTICE]\n> ローカルデータベースとリモートデータベースの非互換性を引き起こす値の違いが検出されました。\n> 一部の変更は互換性がありますが、追加のストレージと転送量を消費する可能性があります。再構築をお勧めします。ただし、再構築は現時点では実行されない場合がありますが、将来のメンテナンスで実装される可能性があります。\n> 再構築を行う場合は数分以上かかります。**今実行しても安全か確認してください。**", @@ -9056,6 +9340,7 @@ export const allMessages: Readonly[!WARNING]\n> We have detected that some of the values are different to make incompatible the local database with the remote database.\n> Either local or remote rebuilds are required. Both of them takes a few minutes or more. **Make sure it is safe to perform it now.**", + es: "\n>[!WARNING]\n> Hemos detectado que algunos valores difieren de forma que hacen incompatible la base de datos local con la remota.\n> Hay que reconstruir la local o la remota. Ambas cosas tardan unos minutos o más. **Asegúrate de que es seguro hacerlo ahora.**", fr: "\n>[!AVERTISSEMENT]\n> Nous avons détecté que certaines valeurs diffèrent et rendent la base locale incompatible avec la base distante.\n> Une reconstruction locale ou distante est nécessaire. L'une comme l'autre prend quelques minutes ou plus. **Assurez-vous qu'il est sûr de le faire maintenant.**", he: "\n>[!WARNING]\n> זיהינו שחלק מהערכים שונים, מה שגורם לאי-תאימות בין מסד הנתונים המקומי למרוחד.\n> נדרשת בנייה מחדש של המסד המקומי או המרוחד. שניהם ייקחו כמה דקות או יותר. **ודא שבטוח לבצע זאת עכשיו.**", ja: "\n>[!WARNING]\n> ローカルデータベースとリモートデータベースの非互換性を引き起こす値の違いが検出されました。\n> ローカルまたはリモートの再構築が必要です。どちらも数分以上かかります。**今実行しても安全か確認してください。**", @@ -9065,6 +9350,7 @@ export const allMessages: Readonly Storage", + es: "Base de datos -> Almacenamiento", + ko: "데이터베이스 -> 스토리지", zh: "数据库 -> 存储", }, "Ui.Settings.Hatch.DeleteCustomizationSyncData": { def: "Delete all customization sync data", + es: "Eliminar todos los datos de la sincronización de personalizaciones", + ko: "모든 사용자 설정 동기화 데이터 삭제", zh: "删除所有自定义同步数据", }, "Ui.Settings.Hatch.GeneratedReport": { def: "Generated report", + es: "Informe generado", + ko: "생성된 보고서", zh: "已生成的报告", }, "Ui.Settings.Hatch.Missing": { def: "Missing", + es: "Falta", + ko: "누락됨", zh: "缺失", }, "Ui.Settings.Hatch.ModifiedSize": { def: "Modified: ${modified}, Size: ${size}", + es: "Modificado: ${modified}, tamaño: ${size}", + ko: "수정: ${modified}, 크기: ${size}", zh: "修改时间:${modified},大小:${size}", }, "Ui.Settings.Hatch.ModifiedSizeActual": { def: "Modified: ${modified}, Size: ${size} (actual size: ${actualSize})", + es: "Modificado: ${modified}, tamaño: ${size} (tamaño real: ${actualSize})", + ko: "수정: ${modified}, 크기: ${size} (실제 크기: ${actualSize})", zh: "修改时间:${modified},大小:${size}(实际大小:${actualSize})", }, "Ui.Settings.Hatch.PrepareIssueReport": { def: "Prepare the 'report' to create an issue", + es: "Preparar el «informe» para abrir una incidencia", + ko: "이슈 생성을 위한 '보고서' 준비", zh: "准备用于提交问题的报告", }, "Ui.Settings.Hatch.RecoveryAndRepair": { def: "Recovery and Repair", + es: "Recuperación y reparación", + ko: "복구 및 수리", zh: "恢复与修复", }, "Ui.Settings.Hatch.RecreateAll": { def: "Recreate all", + es: "Recrear todo", + ko: "모두 다시 생성", zh: "全部重建", }, "Ui.Settings.Hatch.RecreateMissingChunks": { def: "Recreate missing chunks for all files", + es: "Recrear los chunks que faltan de todos los archivos", + ko: "모든 파일의 누락된 청크 다시 생성", zh: "为所有文件重新创建缺失的数据块", }, "Ui.Settings.Hatch.RecreateMissingChunksDesc": { def: "This will recreate chunks for all files. If there were missing chunks, this may fix the errors.", + es: "Recrea los chunks de todos los archivos. Si faltaban chunks, esto puede corregir los errores.", + ko: "모든 파일의 청크를 다시 생성합니다. 누락된 청크가 있었다면 이 작업으로 오류가 해결될 수 있습니다.", zh: "此操作会为所有文件重新创建数据块。如果存在缺失的数据块,可能会修复相关错误。", }, "Ui.Settings.Hatch.ResetPanel": { def: "Reset", + es: "Restablecer", + ko: "재설정", zh: "重置", }, "Ui.Settings.Hatch.ResetRemoteUsage": { def: "Reset notification threshold and check the remote database usage", + es: "Restablecer el umbral de aviso y comprobar el uso de la base de datos remota", + ko: "알림 임계값을 초기화하고 원격 데이터베이스 사용량 확인", zh: "重置通知阈值并检查远程数据库使用情况", }, "Ui.Settings.Hatch.ResetRemoteUsageDesc": { def: "Reset the remote storage size threshold and check the remote storage size again.", + es: "Restablece el umbral de tamaño del almacenamiento remoto y vuelve a comprobar su tamaño.", + ko: "원격 저장소 크기 임계값을 초기화하고 원격 저장소 크기를 다시 확인합니다.", zh: "重置远程存储大小阈值,并再次检查远程存储大小。", }, "Ui.Settings.Hatch.ResolveAllConflictedFiles": { def: "Resolve all conflicted files by the newer one", + es: "Resolver todos los archivos en conflicto con el más reciente", + ko: "충돌한 모든 파일을 최신 버전으로 해결", zh: "使用较新的版本解决所有冲突文件", }, "Ui.Settings.Hatch.ResolveAllConflictedFilesDesc": { def: "Resolve all conflicted files by the newer one. Caution: This will overwrite the older one, and cannot resurrect the overwritten one.", + es: "Resuelve todos los archivos en conflicto quedándose con el más reciente. Atención: esto sobrescribe el más antiguo y no se puede recuperar.", + ko: "충돌한 모든 파일을 더 최신 버전으로 해결합니다. 주의: 이전 버전은 덮어써지며 복원할 수 없습니다.", zh: "使用较新的版本解决所有冲突文件。注意:此操作会覆盖较旧版本,且无法恢复被覆盖的内容。", }, "Ui.Settings.Hatch.RunDoctor": { def: "Run Doctor", + es: "Ejecutar el Doctor", + ko: "진단 실행", zh: "运行诊断", }, "Ui.Settings.Hatch.ScanBrokenFiles": { def: "Scan for broken files", + es: "Buscar archivos dañados", + ko: "손상된 파일 검사", zh: "扫描损坏文件", }, "Ui.Settings.Hatch.ScramSwitches": { def: "Scram Switches", + es: "Interruptores de emergencia", + ko: "긴급 정지 스위치", zh: "紧急开关", }, "Ui.Settings.Hatch.ShowHistory": { def: "Show history", + es: "Mostrar el historial", + ko: "기록 표시", zh: "查看历史", }, "Ui.Settings.Hatch.StorageLabel": { def: "Storage: ${details}", + es: "Almacenamiento: ${details}", + ko: "스토리지: ${details}", zh: "存储:${details}", }, "Ui.Settings.Hatch.StorageToDatabase": { def: "Storage -> Database", + es: "Almacenamiento -> Base de datos", + ko: "스토리지 -> 데이터베이스", zh: "存储 -> 数据库", }, "Ui.Settings.Hatch.VerifyAndRepairAllFiles": { def: "Verify and repair all files", + es: "Verificar y reparar todos los archivos", + ko: "모든 파일 검증 및 복구", zh: "校验并修复所有文件", }, "Ui.Settings.Hatch.VerifyAndRepairAllFilesDesc": { def: "Compare the content of files between the local database and storage. If they do not match, you will be asked which one to keep.", + es: "Compara el contenido de los archivos entre la base de datos local y el almacenamiento. Si no coinciden, se te preguntará cuál conservar.", + ko: "로컬 데이터베이스와 스토리지의 파일 내용을 비교합니다. 일치하지 않으면 어느 쪽을 유지할지 묻습니다.", zh: "比较本地数据库与存储中的文件内容。如果内容不一致,系统会询问你保留哪一份。", }, "Ui.Settings.Maintenance.Cleanup": { def: "Perform cleanup", + es: "Realizar limpieza", + ko: "정리 실행", zh: "执行清理", }, "Ui.Settings.Maintenance.CleanupDesc": { def: "Reduces storage space by discarding all non-latest revisions. This requires the same amount of free space on the remote server and the local client.", + es: "Reduce el espacio de almacenamiento descartando todas las revisiones que no sean la última. Requiere la misma cantidad de espacio libre en el servidor remoto y en el cliente local.", + ko: "최신 버전이 아닌 모든 리비전을 제거하여 저장 공간을 줄입니다. 이 작업을 수행하려면 원격 서버와 로컬 클라이언트에 동일한 양의 여유 공간이 필요합니다.", zh: "丢弃所有非最新修订版本,以减少存储空间占用。此操作要求远程服务器和本地客户端都具备同等大小的可用空间。", }, "Ui.Settings.Maintenance.DeleteLocalDatabase": { def: "Delete local database to reset or uninstall Self-hosted LiveSync", + es: "Eliminar la base de datos local para restablecer o desinstalar Self-hosted LiveSync", + ko: "Self-hosted LiveSync를 초기화하거나 제거하기 위해 로컬 데이터베이스를 삭제", zh: "删除本地数据库以重置或卸载 Self-hosted LiveSync", }, "Ui.Settings.Maintenance.EmergencyRestart": { def: "Emergency restart", + es: "Reinicio de emergencia", + ko: "긴급 재시작", zh: "紧急重启", }, "Ui.Settings.Maintenance.EmergencyRestartDesc": { def: "Disable all synchronisation and restart.", + es: "Desactiva toda la sincronización y reinicia.", + ko: "모든 동기화를 비활성화하고 재시작합니다.", zh: "禁用所有同步并重新启动。", }, "Ui.Settings.Maintenance.FreshStartWipe": { def: "Fresh Start Wipe", + es: "Borrado para empezar de cero", + ko: "초기화 후 새로 시작", zh: "全新开始清空", }, "Ui.Settings.Maintenance.FreshStartWipeDesc": { def: "Delete all data on the remote server.", + es: "Elimina todos los datos del servidor remoto.", + ko: "원격 서버의 모든 데이터를 삭제합니다.", zh: "删除远程服务器上的所有数据。", }, "Ui.Settings.Maintenance.GarbageCollection": { def: "Garbage Collection V3 (Beta)", + es: "Recolección de basura V3 (beta)", + ko: "가비지 컬렉션 V3 (Beta)", zh: "垃圾回收 V3(测试版)", }, "Ui.Settings.Maintenance.GarbageCollectionAction": { def: "Perform Garbage Collection", + es: "Realizar la recolección de basura", + ko: "가비지 컬렉션 실행", zh: "执行垃圾回收", }, "Ui.Settings.Maintenance.GarbageCollectionDesc": { def: "Perform Garbage Collection to remove unused chunks and reduce database size.", + es: "Realiza una recolección de basura para eliminar los chunks sin usar y reducir el tamaño de la base de datos.", + ko: "사용하지 않는 청크를 제거하고 데이터베이스 크기를 줄이기 위해 가비지 컬렉션을 실행합니다.", zh: "执行垃圾回收以移除未使用的数据块并减少数据库大小。", }, "Ui.Settings.Maintenance.LockServer": { def: "Lock Server", + es: "Bloquear el servidor", + ko: "서버 잠금", zh: "锁定服务器", }, "Ui.Settings.Maintenance.LockServerDesc": { def: "Lock the remote server to prevent synchronisation with other devices.", + es: "Bloquea el servidor remoto para impedir la sincronización con otros dispositivos.", + ko: "다른 기기와 동기화되지 않도록 원격 서버를 잠급니다.", zh: "锁定远程服务器,防止与其他设备继续同步。", }, "Ui.Settings.Maintenance.OverwriteRemote": { def: "Overwrite remote", + es: "Sobrescribir el remoto", + ko: "원격 덮어쓰기", zh: "覆盖远程端", }, "Ui.Settings.Maintenance.OverwriteRemoteDesc": { def: "Overwrite remote with local DB and passphrase.", + es: "Sobrescribe el remoto con la base de datos local y la frase de contraseña.", + ko: "로컬 DB와 패스프레이즈로 원격을 덮어씁니다.", zh: "使用本地数据库和密码短语覆盖远程端数据。", }, "Ui.Settings.Maintenance.OverwriteServerData": { def: "Overwrite Server Data with This Device's Files", + es: "Sobrescribir los datos del servidor con los archivos de este dispositivo", + ko: "이 기기의 파일로 서버 데이터를 덮어쓰기", zh: "用此设备的文件覆盖服务器数据", }, "Ui.Settings.Maintenance.OverwriteServerDataDesc": { def: "Rebuild the local and remote database with files from this device.", + es: "Reconstruye la base de datos local y la remota con los archivos de este dispositivo.", + ko: "이 기기의 파일로 로컬과 원격 데이터베이스를 재구축합니다.", zh: "使用此设备上的文件重建本地和远程数据库。", }, "Ui.Settings.Maintenance.PurgeAllJournalCounter": { def: "Purge all journal counter", + es: "Purgar todos los contadores del diario", + ko: "모든 저널 카운터 삭제", zh: "清空全部日志计数器", }, "Ui.Settings.Maintenance.PurgeAllJournalCounterDesc": { def: "Purge all download and upload caches.", + es: "Purga todas las cachés de descarga y de subida.", + ko: "모든 다운로드 및 업로드 캐시를 제거합니다.", zh: "清空所有下载与上传缓存。", }, "Ui.Settings.Maintenance.RebuildingOperations": { def: "Rebuilding Operations (Remote Only)", + es: "Operaciones de reconstrucción (solo remoto)", + ko: "재구축 작업 (원격 전용)", zh: "重建操作(仅远程端)", }, "Ui.Settings.Maintenance.Resend": { def: "Resend", + es: "Reenviar", + ko: "다시 보내기", zh: "重新发送", }, "Ui.Settings.Maintenance.ResendDesc": { def: "Resend all chunks to the remote.", + es: "Reenvía todos los chunks al remoto.", + ko: "모든 청크를 원격으로 다시 보냅니다.", zh: "将所有数据块重新发送到远程端。", }, "Ui.Settings.Maintenance.Reset": { def: "Reset", + es: "Restablecer", + ko: "재설정", zh: "重置", }, "Ui.Settings.Maintenance.ResetAllJournalCounter": { def: "Reset all journal counter", + es: "Restablecer todos los contadores del diario", + ko: "모든 저널 카운터 재설정", zh: "重置全部日志计数器", }, "Ui.Settings.Maintenance.ResetAllJournalCounterDesc": { def: "Initialise all journal history. On the next sync, every item will be received and sent again.", + es: "Inicializa todo el historial del diario. En la próxima sincronización se volverán a recibir y enviar todos los elementos.", + ko: "모든 저널 기록을 초기화합니다. 다음 동기화 때 모든 항목을 다시 주고받습니다.", zh: "初始化全部日志历史。下次同步时,所有项目都会重新接收并重新发送。", }, "Ui.Settings.Maintenance.ResetJournalReceived": { def: "Reset journal received history", + es: "Restablecer el historial de recepción del diario", + ko: "저널 수신 기록 재설정", zh: "重置日志接收历史", }, "Ui.Settings.Maintenance.ResetJournalReceivedDesc": { def: "Initialise journal received history. On the next sync, every item except those sent by this device will be downloaded again.", + es: "Inicializa el historial de recepción del diario. En la próxima sincronización se volverán a descargar todos los elementos salvo los enviados por este dispositivo.", + ko: "저널 수신 기록을 초기화합니다. 다음 동기화 때 이 기기가 보낸 항목을 제외한 모든 항목을 다시 내려받습니다.", zh: "初始化日志接收历史。下次同步时,除当前设备发送的项目外,其余项目都会重新下载。", }, "Ui.Settings.Maintenance.ResetJournalSent": { def: "Reset journal sent history", + es: "Restablecer el historial de envío del diario", + ko: "저널 송신 기록 재설정", zh: "重置日志发送历史", }, "Ui.Settings.Maintenance.ResetJournalSentDesc": { def: "Initialise journal sent history. On the next sync, every item except those received by this device will be sent again.", + es: "Inicializa el historial de envío del diario. En la próxima sincronización se volverán a enviar todos los elementos salvo los recibidos por este dispositivo.", + ko: "저널 송신 기록을 초기화합니다. 다음 동기화 때 이 기기가 받은 항목을 제외한 모든 항목을 다시 보냅니다.", zh: "初始化日志发送历史。下次同步时,除当前设备已接收的项目外,其余项目都会重新发送。", }, "Ui.Settings.Maintenance.ResetLocalSyncInfo": { def: "Reset Synchronisation information", + es: "Restablecer la información de sincronización", + ko: "동기화 정보 재설정", zh: "重置同步信息", }, "Ui.Settings.Maintenance.ResetLocalSyncInfoDesc": { def: "Restore or reconstruct local database from remote.", + es: "Restaura o reconstruye la base de datos local a partir del remoto.", + ko: "원격에서 로컬 데이터베이스를 복원하거나 재구축합니다.", zh: "从远程端恢复或重建本地数据库。", }, "Ui.Settings.Maintenance.ResetReceived": { def: "Reset received", + es: "Restablecer lo recibido", + ko: "수신 기록 재설정", zh: "重置接收记录", }, "Ui.Settings.Maintenance.ResetSentHistory": { def: "Reset sent history", + es: "Restablecer el historial de envíos", + ko: "송신 기록 재설정", zh: "重置发送记录", }, "Ui.Settings.Maintenance.ResetThisDevice": { def: "Reset Synchronisation on This Device", + es: "Restablecer la sincronización en este dispositivo", + ko: "이 기기의 동기화 재설정", zh: "重置此设备上的同步状态", }, "Ui.Settings.Maintenance.ScheduleAndRestart": { def: "Schedule and Restart", + es: "Programar y reiniciar", + ko: "예약 후 재시작", zh: "计划执行并重启", }, "Ui.Settings.Maintenance.Scram": { def: "Scram!", + es: "¡Parada de emergencia!", + ko: "긴급 정지", zh: "紧急处理", }, "Ui.Settings.Maintenance.SendChunks": { def: "Send chunks", + es: "Enviar los chunks", + ko: "청크 보내기", zh: "发送数据块", }, "Ui.Settings.Maintenance.Syncing": { def: "Syncing", + es: "Sincronización", + ko: "동기화", zh: "同步", }, "Ui.Settings.Maintenance.WarningLockedReadyAction": { def: "I am ready, unlock the database", + es: "Estoy listo, desbloquear la base de datos", + ko: "준비되었습니다. 데이터베이스 잠금 해제", zh: "我已准备好,立即解锁数据库", }, "Ui.Settings.Maintenance.WarningLockedReadyText": { def: "To prevent unwanted vault corruption, the remote database has been locked for synchronisation. (This device is marked as 'resolved'.) When all your devices are marked as 'resolved', unlock the database. This warning will continue to appear until replication confirms the device is resolved.", + es: "Para evitar que el vault se corrompa, la base de datos remota se ha bloqueado para la sincronización. (Este dispositivo está marcado como «resuelto».) Cuando todos tus dispositivos estén marcados como «resueltos», desbloquea la base de datos. Este aviso seguirá apareciendo hasta que la replicación confirme que el dispositivo está resuelto.", + ko: "의도치 않은 보관함 손상을 막기 위해 원격 데이터베이스가 동기화 잠금 상태입니다. (이 기기는 '해결됨'으로 표시되어 있습니다.) 모든 기기가 '해결됨'으로 표시되면 데이터베이스 잠금을 해제하세요. 이 경고는 복제를 통해 기기가 해결되었음이 확인될 때까지 계속 표시됩니다.", zh: "为防止意外的数据仓库损坏,远程数据库已被锁定,暂停同步。(此设备已被标记为“已确认”)当你的所有设备都标记为“已确认”后,再解锁数据库。在复制过程确认此设备已完成确认之前,此警告会持续显示。", }, "Ui.Settings.Maintenance.WarningLockedResolveAction": { def: "I have made a backup, mark this device as resolved", + es: "He hecho una copia de seguridad, marcar este dispositivo como resuelto", + ko: "백업했습니다. 이 기기를 해결됨으로 표시", zh: "我已完成备份,将此设备标记为“已确认”", }, "Ui.Settings.Maintenance.WarningLockedResolveText": { def: "The remote database is locked for synchronisation to prevent vault corruption because this device is not marked as 'resolved'. Please back up your vault, reset the local database, and select 'Mark this device as resolved'. This warning will persist until replication confirms the device is resolved.", + es: "La base de datos remota está bloqueada para la sincronización a fin de evitar que el vault se corrompa, porque este dispositivo no está marcado como «resuelto». Haz una copia de seguridad de tu vault, restablece la base de datos local y selecciona «Marcar este dispositivo como resuelto». Este aviso seguirá apareciendo hasta que la replicación confirme que el dispositivo está resuelto.", + ko: "이 기기가 '해결됨'으로 표시되어 있지 않아, 보관함 손상을 막기 위해 원격 데이터베이스가 동기화 잠금 상태입니다. 보관함을 백업하고 로컬 데이터베이스를 재설정한 뒤 '이 기기를 해결됨으로 표시'를 선택해 주세요. 이 경고는 복제를 통해 기기가 해결되었음이 확인될 때까지 계속 표시됩니다.", zh: "为防止数据仓库损坏,由于此设备尚未标记为“已确认”,远程数据库已被锁定,暂停同步。请先备份你的仓库、重置本地数据库,然后选择“将此设备标记为已确认”。在复制过程确认此设备已完成确认之前,此警告会持续显示。", }, "Ui.Settings.Maintenance.WriteRedFlagAndRestart": { def: "Flag and restart", + es: "Marcar y reiniciar", + ko: "표시 후 재시작", zh: "标记并重启", }, "Ui.Settings.Patches.CompatibilityConflict": { def: "Compatibility (Conflict Behaviour)", + es: "Compatibilidad (comportamiento ante conflictos)", + ko: "호환성 (충돌 동작)", zh: "兼容性(冲突行为)", }, "Ui.Settings.Patches.CompatibilityDatabase": { def: "Compatibility (Database structure)", + es: "Compatibilidad (estructura de la base de datos)", + ko: "호환성 (데이터베이스 구조)", zh: "兼容性(数据库结构)", }, "Ui.Settings.Patches.CompatibilityInternalApi": { def: "Compatibility (Internal API Usage)", + es: "Compatibilidad (uso de la API interna)", + ko: "호환성 (내부 API 사용)", zh: "兼容性(内部 API 使用)", }, "Ui.Settings.Patches.CompatibilityMetadata": { def: "Compatibility (Metadata)", + es: "Compatibilidad (metadatos)", + ko: "호환성 (메타데이터)", zh: "兼容性(元数据)", }, "Ui.Settings.Patches.CompatibilityRemote": { def: "Compatibility (Remote Database)", + es: "Compatibilidad (base de datos remota)", + ko: "호환성 (원격 데이터베이스)", zh: "兼容性(远程数据库)", }, "Ui.Settings.Patches.CompatibilityTrouble": { def: "Compatibility (Trouble addressed)", + es: "Compatibilidad (problemas resueltos)", + ko: "호환성 (문제 대응)", zh: "兼容性(已处理问题)", }, "Ui.Settings.Patches.CurrentAdapter": { def: "Current adapter: ${adapter}", + es: "Adaptador actual: ${adapter}", + ko: "현재 어댑터: ${adapter}", zh: "当前适配器:${adapter}", }, "Ui.Settings.Patches.DatabaseAdapter": { def: "Database Adapter", + es: "Adaptador de base de datos", + ko: "데이터베이스 어댑터", zh: "数据库适配器", }, "Ui.Settings.Patches.DatabaseAdapterDesc": { def: "Select the database adapter to use.", + es: "Selecciona el adaptador de base de datos que se va a usar.", + ko: "사용할 데이터베이스 어댑터를 선택합니다.", zh: "选择要使用的数据库适配器。", }, "Ui.Settings.Patches.EdgeCaseBehaviour": { def: "Edge case addressing (Behaviour)", + es: "Casos límite (comportamiento)", + ko: "특수 상황 처리 (동작)", zh: "边界情况处理(行为)", }, "Ui.Settings.Patches.EdgeCaseDatabase": { def: "Edge case addressing (Database)", + es: "Casos límite (base de datos)", + ko: "특수 상황 처리 (데이터베이스)", zh: "边界情况处理(数据库)", }, "Ui.Settings.Patches.EdgeCaseProcessing": { def: "Edge case addressing (Processing)", + es: "Casos límite (procesamiento)", + ko: "특수 상황 처리 (처리)", zh: "边界情况处理(处理流程)", }, "Ui.Settings.Patches.IndexedDbWarning": { def: "The IndexedDB adapter often offers superior performance in certain scenarios, but it has been found to cause memory leaks when used with LiveSync mode. When using LiveSync mode, please use the IDB adapter instead.", + es: "El adaptador IndexedDB suele ofrecer mejor rendimiento en ciertos casos, pero se ha comprobado que provoca fugas de memoria con el modo LiveSync. Si usas el modo LiveSync, utiliza en su lugar el adaptador IDB.", + ko: "IndexedDB 어댑터는 특정 상황에서 더 나은 성능을 보이는 경우가 많지만, LiveSync 모드에서 사용하면 메모리 누수를 일으키는 것으로 확인되었습니다. LiveSync 모드를 사용할 때는 IDB 어댑터를 사용해 주세요.", zh: "IndexedDB 适配器在某些场景下通常具有更好的性能,但在 LiveSync 模式下已发现可能导致内存泄漏。使用 LiveSync 模式时,请改用 IDB 适配器。", }, "Ui.Settings.Patches.MigratingToIdb": { def: "Migrating all data to IDB...", + es: "Migrando todos los datos a IDB...", + ko: "모든 데이터를 IDB로 마이그레이션하는 중...", zh: "正在将所有数据迁移到 IDB...", }, "Ui.Settings.Patches.MigratingToIndexedDb": { def: "Migrating all data to IndexedDB...", + es: "Migrando todos los datos a IndexedDB...", + ko: "모든 데이터를 IndexedDB로 마이그레이션하는 중...", zh: "正在将所有数据迁移到 IndexedDB...", }, "Ui.Settings.Patches.MigrationIdbCompleted": { def: "Migration to IDB completed. Obsidian will be restarted with the new configuration immediately.", + es: "Migración a IDB completada. Obsidian se reiniciará de inmediato con la nueva configuración.", + ko: "IDB로 마이그레이션이 완료되었습니다. 새 구성을 적용하기 위해 Obsidian이 곧 재시작됩니다.", zh: "已完成迁移到 IDB。Obsidian 将立即使用新配置重新启动。", }, "Ui.Settings.Patches.MigrationIdbCompletedFollowUp": { def: "Migration to IDB completed. Please switch the adapter and restart Obsidian.", + es: "Migración a IDB completada. Cambia el adaptador y reinicia Obsidian.", + ko: "IDB로 마이그레이션이 완료되었습니다. 어댑터를 전환하고 Obsidian을 재시작해 주세요.", zh: "已完成迁移到 IDB。请切换适配器并重新启动 Obsidian。", }, "Ui.Settings.Patches.MigrationIndexedDbCompleted": { def: "Migration to IndexedDB completed. Obsidian will be restarted with the new configuration immediately.", + es: "Migración a IndexedDB completada. Obsidian se reiniciará de inmediato con la nueva configuración.", + ko: "IndexedDB로 마이그레이션이 완료되었습니다. 새 구성을 적용하기 위해 Obsidian이 곧 재시작됩니다.", zh: "已完成迁移到 IndexedDB。Obsidian 将立即使用新配置重新启动。", }, "Ui.Settings.Patches.MigrationIndexedDbCompletedFollowUp": { def: "Migration to IndexedDB completed. Please switch the adapter and restart Obsidian.", + es: "Migración a IndexedDB completada. Cambia el adaptador y reinicia Obsidian.", + ko: "IndexedDB로 마이그레이션이 완료되었습니다. 어댑터를 전환하고 Obsidian을 재시작해 주세요.", zh: "已完成迁移到 IndexedDB。请切换适配器并重新启动 Obsidian。", }, "Ui.Settings.Patches.MigrationWarning": { def: "Changing this setting requires migrating existing data, which may take some time, and restarting Obsidian. Please make sure to back up your data before proceeding.", + es: "Cambiar este ajuste requiere migrar los datos existentes, lo que puede tardar un rato, y reiniciar Obsidian. Asegúrate de hacer una copia de seguridad de tus datos antes de continuar.", + ko: "이 설정을 변경하려면 기존 데이터를 마이그레이션하고(시간이 다소 걸릴 수 있습니다) Obsidian을 재시작해야 합니다. 진행하기 전에 반드시 데이터를 백업해 주세요.", zh: "修改此设置需要迁移现有数据(可能需要一些时间)并重新启动 Obsidian。请先备份你的数据后再继续。", }, "Ui.Settings.Patches.OperationToIdb": { def: "to IDB", + es: "a IDB", + ko: "IDB로", zh: "迁移到 IDB", }, "Ui.Settings.Patches.OperationToIndexedDb": { def: "to IndexedDB", + es: "a IndexedDB", + ko: "IndexedDB로", zh: "迁移到 IndexedDB", }, "Ui.Settings.Patches.Remediation": { def: "Remediation", + es: "Remediación", + ko: "복구 조치", zh: "修正", }, "Ui.Settings.Patches.RemediationChanged": { def: "Remediation Setting Changed", + es: "Se ha cambiado el ajuste de remediación", + ko: "복구 설정이 변경됨", zh: "修正设置已更改", }, "Ui.Settings.Patches.RemediationNoLimit": { def: "No limit configured", + es: "Sin límite configurado", + ko: "제한이 설정되지 않음", zh: "未设置限制", }, "Ui.Settings.Patches.RemediationRestarting": { def: "Remediation setting changed. Restarting Obsidian...", + es: "Se ha cambiado el ajuste de remediación. Reiniciando Obsidian...", + ko: "복구 조치 설정이 변경되었습니다. Obsidian을 재시작하는 중...", zh: "修正设置已更改,正在重新启动 Obsidian...", }, "Ui.Settings.Patches.RemediationRestartLater": { def: "Later", + es: "Más tarde", + ko: "나중에", zh: "稍后", }, "Ui.Settings.Patches.RemediationRestartMessage": { def: "Restarting Obsidian is strongly recommended. Until restart, some changes may not take effect, and the display may be inconsistent. Are you sure you want to restart now?", + es: "Se recomienda encarecidamente reiniciar Obsidian. Hasta que lo hagas, puede que algunos cambios no surtan efecto y que la interfaz se muestre de forma inconsistente. ¿Seguro que quieres reiniciar ahora?", + ko: "Obsidian을 재시작하는 것을 강력히 권장합니다. 재시작하기 전까지는 일부 변경 사항이 적용되지 않거나 화면이 일관되지 않게 표시될 수 있습니다. 지금 재시작하시겠습니까?", zh: "强烈建议重新启动 Obsidian。在重启之前,部分更改可能不会生效,界面显示也可能不一致。确定要现在重启吗?", }, "Ui.Settings.Patches.RemediationRestartNow": { def: "Restart Now", + es: "Reiniciar ahora", + ko: "지금 재시작", zh: "立即重启", }, "Ui.Settings.Patches.RemediationSuffixChanged": { def: "Suffix has been changed. Reopening database...", + es: "El sufijo ha cambiado. Reabriendo la base de datos...", + ko: "접미사가 변경되었습니다. 데이터베이스를 다시 여는 중...", zh: "后缀已更改,正在重新打开数据库...", }, "Ui.Settings.Patches.RemediationWithValue": { def: "Limit: ${date} (${timestamp})", + es: "Límite: ${date} (${timestamp})", + ko: "제한: ${date} (${timestamp})", zh: "限制:${date}(${timestamp})", }, "Ui.Settings.Patches.RemoteDatabaseSunset": { def: "Remote Database Tweak (In sunset)", + es: "Ajuste fino de la base de datos remota (en desuso)", + ko: "원격 데이터베이스 조정 (폐기 예정)", zh: "远程数据库调整(即将弃用)", }, "Ui.Settings.Patches.SwitchToIDB": { def: "Switch to IDB", + es: "Cambiar a IDB", + ko: "IDB로 전환", zh: "切换到 IDB", }, "Ui.Settings.Patches.SwitchToIndexedDb": { def: "Switch to IndexedDB", + es: "Cambiar a IndexedDB", + ko: "IndexedDB로 전환", zh: "切换到 IndexedDB", }, "Ui.Settings.PowerUsers.ConfigurationEncryption": { def: "Configuration Encryption", + es: "Cifrado de la configuración", + ko: "구성 암호화", zh: "配置加密", }, "Ui.Settings.PowerUsers.ConnectionTweak": { def: "CouchDB Connection Tweak", + es: "Ajuste fino de la conexión con CouchDB", + ko: "CouchDB 연결 조정", zh: "CouchDB 连接调整", }, "Ui.Settings.PowerUsers.ConnectionTweakDesc": { def: "If you reached the payload size limit when using IBM Cloudant, please decrease batch size and batch limit to a lower value.", + es: "Si alcanzas el límite de tamaño de carga al usar IBM Cloudant, reduce el tamaño de lote y el límite de lote.", + ko: "IBM Cloudant를 사용하다가 페이로드 크기 제한에 도달했다면, 배치 크기와 배치 개수 제한을 더 낮은 값으로 줄여 주세요.", zh: "如果你在使用 IBM Cloudant 时遇到负载大小限制,请将 batch size 和 batch limit 调低。", }, "Ui.Settings.PowerUsers.Default": { def: "Default", + es: "Predeterminado", + ko: "기본값", zh: "默认", }, "Ui.Settings.PowerUsers.Developer": { def: "Developer", + es: "Desarrollo", + ko: "개발자", zh: "开发者", }, "Ui.Settings.PowerUsers.EncryptSensitiveConfig": { def: "Encrypt sensitive configuration items", + es: "Cifrar los elementos sensibles de la configuración", + ko: "민감한 구성 항목 암호화", zh: "加密敏感配置项", }, "Ui.Settings.PowerUsers.PromptPassphraseEveryLaunch": { def: "Ask for a passphrase at every launch", + es: "Solicitar la frase de contraseña en cada inicio", + ko: "시작할 때마다 패스프레이즈 묻기", zh: "每次启动时询问密码短语", }, "Ui.Settings.PowerUsers.UseCustomPassphrase": { def: "Use a custom passphrase", + es: "Usar una frase de contraseña personalizada", + ko: "사용자 지정 패스프레이즈 사용", zh: "使用自定义密码短语", }, "Ui.Settings.Remote.Activate": { def: "Activate", + es: "Activar", + ko: "활성화", zh: "启用", }, "Ui.Settings.Remote.ActiveSuffix": { def: " (Active)", + es: " (activo)", + ko: " (활성)", zh: "(当前启用)", }, "Ui.Settings.Remote.AddConnection": { def: "Add new connection", + es: "Añadir conexión", + ko: "연결 추가", zh: "新增连接", }, "Ui.Settings.Remote.AddRemoteDefaultName": { def: "New Remote", + es: "Remoto nuevo", + ko: "새 원격", zh: "新远程端", }, "Ui.Settings.Remote.ConfigureAndChangeRemote": { def: "Configure and change remote", + es: "Configurar y cambiar el remoto", + ko: "원격 구성 및 변경", zh: "配置并切换远程端", }, "Ui.Settings.Remote.ConfigureE2EE": { def: "Configure E2EE", + es: "Configurar el E2EE", + ko: "E2EE 구성", zh: "配置端到端加密", }, "Ui.Settings.Remote.ConfigureRemote": { def: "Configure Remote", + es: "Configurar el remoto", + ko: "원격 구성", zh: "配置远程端", }, "Ui.Settings.Remote.DeleteRemoteConfirm": { def: "Delete remote configuration '${name}'?", + es: "¿Eliminar la configuración remota «${name}»?", + ko: "'${name}' 원격 구성을 삭제할까요?", zh: "确定要删除远程配置“${name}”吗?", }, "Ui.Settings.Remote.DeleteRemoteTitle": { def: "Delete Remote Configuration", + es: "Eliminar la configuración remota", + ko: "원격 구성 삭제", zh: "删除远程配置", }, "Ui.Settings.Remote.DisplayName": { def: "Display name", + es: "Nombre visible", + ko: "표시 이름", zh: "显示名称", }, "Ui.Settings.Remote.DuplicateRemote": { def: "Duplicate remote", + es: "Duplicar el remoto", + ko: "원격 구성 복사", zh: "复制远程配置", }, "Ui.Settings.Remote.DuplicateRemoteSuffix": { def: "${name} (Copy)", + es: "${name} (copia)", + ko: "${name} (사본)", zh: "${name}(副本)", }, "Ui.Settings.Remote.E2EEConfiguration": { def: "E2EE Configuration", + es: "Configuración del E2EE", + ko: "E2EE 구성", zh: "端到端加密配置", }, "Ui.Settings.Remote.Export": { def: "Export", + es: "Exportar", + ko: "내보내기", zh: "导出", }, "Ui.Settings.Remote.FetchRemoteSettings": { def: "Fetch remote settings", + es: "Obtener los ajustes remotos", + ko: "원격 설정 가져오기", zh: "获取远程设置", }, "Ui.Settings.Remote.ImportConnection": { def: "Import connection", + es: "Importar conexión", + ko: "연결 가져오기", zh: "导入连接", }, "Ui.Settings.Remote.ImportConnectionPrompt": { def: "Paste a connection string", + es: "Pega una cadena de conexión", + ko: "연결 문자열 붙여넣기", zh: "粘贴连接字符串", }, "Ui.Settings.Remote.ImportedCouchDb": { def: "Imported CouchDB", + es: "CouchDB importado", + ko: "가져온 CouchDB", zh: "已导入的 CouchDB", }, "Ui.Settings.Remote.ImportedRemote": { def: "Remote", + es: "Remoto", + ko: "원격", zh: "远程端", }, "Ui.Settings.Remote.MoreActions": { def: "More actions", + es: "Más acciones", + ko: "추가 작업", zh: "更多操作", }, "Ui.Settings.Remote.PeerToPeerPanel": { def: "Peer-to-Peer Synchronisation", + es: "Sincronización punto a punto", + ko: "피어 투 피어(P2P) 동기화", zh: "点对点同步", }, "Ui.Settings.Remote.RemoteConfigurationPrefix": { def: "Remote configuration", + es: "Configuración remota", + ko: "원격 구성", zh: "远程配置", }, "Ui.Settings.Remote.RemoteDatabases": { def: "Remote Databases", + es: "Bases de datos remotas", + ko: "원격 데이터베이스", zh: "远程数据库", }, "Ui.Settings.Remote.RemoteName": { def: "Remote name", + es: "Nombre del remoto", + ko: "원격 이름", zh: "远程名称", }, "Ui.Settings.Remote.RemoteNameCouchDb": { def: "CouchDB ${host}", + es: "CouchDB ${host}", + ko: "CouchDB ${host}", zh: "CouchDB ${host}", }, "Ui.Settings.Remote.RemoteNameP2P": { def: "P2P ${room}", + es: "P2P ${room}", + ko: "P2P ${room}", zh: "P2P ${room}", }, "Ui.Settings.Remote.RemoteNameS3": { def: "S3 ${bucket}", + es: "S3 ${bucket}", + ko: "S3 ${bucket}", zh: "S3 ${bucket}", }, "Ui.Settings.Remote.Rename": { def: "Rename", + es: "Cambiar el nombre", + ko: "이름 바꾸기", zh: "重命名", }, "Ui.Settings.Selector.AddDefaultPatterns": { def: "Add default patterns", + es: "Añadir patrones predeterminados", + ko: "기본 패턴 추가", zh: "添加默认模式", }, "Ui.Settings.Selector.CrossPlatform": { def: "Cross-platform", + es: "Multiplataforma", + ko: "크로스 플랫폼", zh: "跨平台", }, "Ui.Settings.Selector.Default": { def: "Default", + es: "Predeterminado", + ko: "기본값", zh: "默认", }, "Ui.Settings.Selector.HiddenFiles": { def: "Hidden Files", + es: "Archivos ocultos", + ko: "숨김 파일", zh: "隐藏文件", }, "Ui.Settings.Selector.IgnorePatterns": { def: "Ignore patterns", + es: "Patrones de exclusión", + ko: "무시 패턴", zh: "忽略模式", }, "Ui.Settings.Selector.NonSynchronisingFiles": { def: "Non-Synchronising files", + es: "Archivos que no se sincronizan", + ko: "동기화하지 않는 파일", zh: "不同步文件", }, "Ui.Settings.Selector.NonSynchronisingFilesDesc": { def: "(RegExp) If this is set, any changes to local and remote files that match this will be skipped.", + es: "(RegExp) Si se establece, se omitirá cualquier cambio en archivos locales y remotos que coincida con este patrón.", + ko: "(정규식) 설정하면 이 패턴과 일치하는 로컬 및 원격 파일 변경은 모두 건너뜁니다.", zh: "(RegExp)如果设置了该项,则本地和远程中匹配这些规则的文件变更将被跳过。", }, "Ui.Settings.Selector.NormalFiles": { def: "Normal Files", + es: "Archivos normales", + ko: "일반 파일", zh: "普通文件", }, "Ui.Settings.Selector.OverwritePatterns": { def: "Overwrite patterns", + es: "Patrones de sobrescritura", + ko: "덮어쓰기 패턴", zh: "覆盖模式", }, "Ui.Settings.Selector.OverwritePatternsDesc": { def: "Patterns to match files for overwriting instead of merging", + es: "Patrones de los archivos que se sobrescriben en lugar de combinarse", + ko: "병합 대신 덮어쓸 파일을 판별하는 패턴", zh: "匹配后将执行覆盖而非合并的文件模式", }, "Ui.Settings.Selector.SynchronisingFiles": { def: "Synchronising files", + es: "Archivos que se sincronizan", + ko: "동기화할 파일", zh: "同步文件", }, "Ui.Settings.Selector.SynchronisingFilesDesc": { def: "(RegExp) Empty to sync all files. Set a regular expression filter to limit synchronised files.", + es: "(RegExp) Déjalo vacío para sincronizar todos los archivos. Define un filtro como expresión regular para limitar los archivos sincronizados.", + ko: "(정규식) 비워 두면 모든 파일을 동기화합니다. 정규식 필터를 지정하면 동기화할 파일을 제한할 수 있습니다.", zh: "(RegExp)留空则同步所有文件。可设置正则表达式以限制需要同步的文件。", }, "Ui.Settings.Selector.TargetPatterns": { def: "Target patterns", + es: "Patrones de inclusión", + ko: "대상 패턴", zh: "目标模式", }, "Ui.Settings.Selector.TargetPatternsDesc": { def: "Patterns to match files for syncing", + es: "Patrones de los archivos que se van a sincronizar", + ko: "동기화할 파일을 판별하는 패턴", zh: "用于匹配需要同步文件的模式", }, "Ui.Settings.Setup.RerunWizardButton": { def: "Rerun Wizard", + es: "Volver a ejecutar el asistente", + ko: "마법사 다시 실행", zh: "重新运行向导", }, "Ui.Settings.Setup.RerunWizardDesc": { def: "Rerun the onboarding wizard to set up Self-hosted LiveSync again.", + es: "Vuelve a ejecutar el asistente de configuración inicial para configurar Self-hosted LiveSync de nuevo.", + ko: "온보딩 마법사를 다시 실행하여 Self-hosted LiveSync를 다시 설정합니다.", zh: "重新运行引导向导,再次设置 Self-hosted LiveSync。", }, "Ui.Settings.Setup.RerunWizardName": { def: "Rerun Onboarding Wizard", + es: "Volver a ejecutar el asistente de configuración inicial", + ko: "온보딩 마법사 다시 실행", zh: "重新运行引导向导", }, "Ui.Settings.SyncSettings.Fetch": { def: "Fetch", + es: "Obtener", + ko: "가져오기", zh: "获取", }, "Ui.Settings.SyncSettings.Merge": { def: "Merge", + es: "Combinar", + ko: "병합", zh: "合并", }, "Ui.Settings.SyncSettings.Overwrite": { def: "Overwrite", + es: "Sobrescribir", + ko: "덮어쓰기", zh: "覆盖", }, "Ui.SetupWizard.Common.Back": { def: "No, please take me back", + es: "No, volver atrás", + ko: "아니요, 이전으로 돌아가겠습니다", zh: "不,带我返回", }, "Ui.SetupWizard.Common.Cancel": { def: "Cancel", + es: "Cancelar", + ko: "취소", zh: "取消", }, "Ui.SetupWizard.Common.ProceedSelectOption": { def: "Please select an option to proceed", + es: "Selecciona una opción para continuar", + ko: "계속하려면 항목을 선택해 주세요", zh: "请选择一个选项后继续", }, "Ui.SetupWizard.Intro.ExistingOption": { def: "I am adding a device to an existing synchronisation setup", + es: "Estoy añadiendo un dispositivo a una configuración de sincronización existente", + ko: "기존 동기화 구성에 기기를 추가합니다", zh: "将此设备加入已有同步配置", }, "Ui.SetupWizard.Intro.ExistingOptionDesc": { def: "Select this if you are already using synchronisation on another computer or smartphone. Use this option to connect this device to that existing setup.", + es: "Elige esto si ya usas la sincronización en otro ordenador o móvil. Usa esta opción para conectar este dispositivo a esa configuración existente.", + ko: "다른 컴퓨터나 스마트폰에서 이미 동기화를 사용 중이라면 선택하세요. 이 기기를 기존 구성에 연결할 때 사용합니다.", zh: "如果你已经在另一台电脑或手机上使用同步,请选择此项。此选项用于将当前设备连接到既有同步配置。", }, "Ui.SetupWizard.Intro.Guidance": { def: "We will now guide you through a few questions to simplify the synchronisation setup.", + es: "Te guiaremos con unas cuantas preguntas para simplificar la configuración de la sincronización.", + ko: "동기화 설정을 간단히 마칠 수 있도록 몇 가지 질문으로 안내해 드리겠습니다.", zh: "接下来我们会通过几个问题,帮助你更轻松地完成同步配置。", }, "Ui.SetupWizard.Intro.NewOption": { def: "I am setting this up for the first time", + es: "Lo estoy configurando por primera vez", + ko: "처음으로 설정합니다", zh: "首次设置同步", }, "Ui.SetupWizard.Intro.NewOptionDesc": { def: "Select this if you are configuring this device as the first synchronisation device.", + es: "Elige esto si estás configurando este dispositivo como el primero de la sincronización.", + ko: "이 기기를 첫 번째 동기화 기기로 설정한다면 선택하세요.", zh: "如果你正把这台设备作为第一台同步设备进行配置,请选择此项。", }, "Ui.SetupWizard.Intro.ProceedExisting": { def: "Yes, I want to add this device to my existing synchronisation", + es: "Sí, quiero añadir este dispositivo a mi sincronización existente", + ko: "예, 이 기기를 기존 동기화 구성에 추가하겠습니다", zh: "是的,我要将此设备加入现有同步", }, "Ui.SetupWizard.Intro.ProceedNew": { def: "Yes, I want to set up a new synchronisation", + es: "Sí, quiero configurar una sincronización nueva", + ko: "예, 새 동기화를 설정하겠습니다", zh: "是的,我要开始新的同步配置", }, "Ui.SetupWizard.Intro.Question": { def: "First, please select the option that best describes your current situation.", + es: "Primero, selecciona la opción que mejor describa tu situación actual.", + ko: "먼저 현재 상황에 가장 잘 맞는 항목을 선택해 주세요.", zh: "首先,请选择最符合你当前情况的选项。", }, "Ui.SetupWizard.Intro.Title": { def: "Welcome to Self-hosted LiveSync", + es: "Bienvenido a Self-hosted LiveSync", + ko: "Self-hosted LiveSync에 오신 것을 환영합니다", zh: "欢迎使用 Self-hosted LiveSync", }, "Ui.SetupWizard.Invitation.Start": { def: "Start setup", + es: "Comenzar la configuración", + ko: "설정 시작", }, "Ui.SetupWizard.OutroAskUserMode.CompatibleOption": { def: "The remote is already set up, and the configuration is compatible (or became compatible through this operation).", + es: "El remoto ya está configurado y la configuración es compatible (o pasa a serlo con esta operación).", + ko: "원격이 이미 설정되어 있고, 구성도 호환됩니다(또는 이번 작업으로 호환되었습니다).", zh: "远程端已配置完成,且当前配置兼容(或已通过本次操作变为兼容)。", }, "Ui.SetupWizard.OutroAskUserMode.CompatibleOptionDesc": { def: "Unless you are certain, selecting this option is risky. It assumes the server configuration is compatible with this device. If that is not the case, data loss may occur. Please make sure you understand the consequences.", + es: "Si no estás seguro, elegir esta opción es arriesgado. Da por supuesto que la configuración del servidor es compatible con este dispositivo. Si no lo es, puede haber pérdida de datos. Asegúrate de entender las consecuencias.", + ko: "확신이 없다면 이 옵션을 선택하는 것은 위험합니다. 서버 구성이 이 기기와 호환된다고 가정하기 때문에, 그렇지 않을 경우 데이터가 손실될 수 있습니다. 결과를 충분히 이해한 뒤에 선택해 주세요.", zh: "除非你非常确定,否则选择此项存在风险。它假定服务器配置与当前设备兼容。如果事实并非如此,可能会导致数据丢失。请确认你了解后果。", }, "Ui.SetupWizard.OutroAskUserMode.ExistingOption": { def: "My remote server is already set up. I want to join this device.", + es: "Mi servidor remoto ya está configurado. Quiero añadir este dispositivo.", + ko: "원격 서버가 이미 설정되어 있습니다. 이 기기를 참여시키려고 합니다.", zh: "远程服务器已经配置完成,我想让此设备加入同步。", }, "Ui.SetupWizard.OutroAskUserMode.ExistingOptionDesc": { def: "Selecting this option will make this device join the existing server. You need to fetch the existing synchronisation data from the server to this device.", + es: "Al elegir esta opción, este dispositivo se unirá al servidor existente. Tendrás que obtener del servidor los datos de sincronización ya existentes.", + ko: "이 옵션을 선택하면 이 기기가 기존 서버에 참여합니다. 서버에 있는 기존 동기화 데이터를 이 기기로 가져와야 합니다.", zh: "选择此项后,此设备会加入已有服务器。你需要将服务器上的现有同步数据获取到此设备。", }, "Ui.SetupWizard.OutroAskUserMode.Guidance": { def: "The connection to the server has been configured successfully. As the next step, the local database, in other words the synchronisation information, must be rebuilt.", + es: "La conexión con el servidor se ha configurado correctamente. Como paso siguiente hay que reconstruir la base de datos local, es decir, la información de sincronización.", + ko: "서버 연결이 정상적으로 구성되었습니다. 다음 단계로, 로컬 데이터베이스 즉 동기화 정보를 재구축해야 합니다.", zh: "服务器连接已成功配置。下一步需要重建本地数据库,也就是同步状态信息。", }, "Ui.SetupWizard.OutroAskUserMode.NewOption": { def: "I am setting up a new server for the first time / I want to reset my existing server.", + es: "Estoy configurando un servidor nuevo por primera vez / quiero restablecer mi servidor actual.", + ko: "서버를 처음 설정합니다 / 기존 서버를 초기화하려고 합니다.", zh: "我是第一次配置新服务器 / 我想重置现有服务器。", }, "Ui.SetupWizard.OutroAskUserMode.NewOptionDesc": { def: "Selecting this option will initialise the server using the current data on this device. Any existing data on the server will be completely overwritten.", + es: "Al elegir esta opción, el servidor se inicializará con los datos actuales de este dispositivo. Cualquier dato existente en el servidor se sobrescribirá por completo.", + ko: "이 옵션을 선택하면 이 기기의 현재 데이터로 서버를 초기화합니다. 서버에 있던 기존 데이터는 완전히 덮어써집니다.", zh: "选择此项后,服务器会使用当前设备上的数据进行初始化。服务器上的现有数据将被完全覆盖。", }, "Ui.SetupWizard.OutroAskUserMode.ProceedApplySettings": { def: "Apply the settings", + es: "Aplicar los ajustes", + ko: "설정 적용", zh: "应用这些设置", }, "Ui.SetupWizard.OutroAskUserMode.ProceedNext": { def: "Proceed to the next step.", + es: "Continuar al paso siguiente.", + ko: "다음 단계로 진행합니다.", zh: "继续下一步", }, "Ui.SetupWizard.OutroAskUserMode.Question": { def: "Please select your situation.", + es: "Selecciona tu situación.", + ko: "현재 상황을 선택해 주세요.", zh: "请选择你的当前情况。", }, "Ui.SetupWizard.OutroAskUserMode.Title": { def: "Mostly Complete: Decision Required", + es: "Casi terminado: se requiere una decisión", + ko: "거의 완료: 선택이 필요합니다", zh: "即将完成:还需要做出选择", }, "Ui.SetupWizard.OutroNewP2PUser.GuidanceNotice": { def: "P2P has no central server copy to overwrite. This step prepares only this device; keep it online when another device fetches its initial data.", + es: "En P2P no hay una copia en un servidor central que sobrescribir. Este paso prepara solo este dispositivo; mantenlo conectado cuando otro dispositivo obtenga sus datos iniciales.", + ko: "P2P에는 덮어쓸 중앙 서버 사본이 없습니다. 이 단계는 이 기기만 준비하며, 다른 기기가 초기 데이터를 가져올 때는 이 기기를 온라인 상태로 유지해 주세요.", }, "Ui.SetupWizard.OutroNewP2PUser.GuidancePrimary": { def: "The peer-to-peer connection has been configured successfully. Next, the local LiveSync database will be built from the current files in this Vault.", + es: "La conexión punto a punto se ha configurado correctamente. A continuación, la base de datos local de LiveSync se construirá a partir de los archivos actuales de este Vault.", + ko: "Peer-to-Peer 연결이 정상적으로 구성되었습니다. 다음 단계로, 이 보관함의 현재 파일을 사용해 로컬 LiveSync 데이터베이스를 만듭니다.", }, "Ui.SetupWizard.OutroNewP2PUser.Important": { def: "PLEASE NOTE", + es: "TEN EN CUENTA", + ko: "유의해 주세요", }, "Ui.SetupWizard.OutroNewP2PUser.Proceed": { def: "Restart and Prepare This Device", + es: "Reiniciar y preparar este dispositivo", + ko: "재시작하고 이 기기 준비", }, "Ui.SetupWizard.OutroNewP2PUser.Question": { def: "Please select the button below to restart and proceed to the local initialisation confirmation.", + es: "Pulsa el botón de abajo para reiniciar y pasar a la confirmación de la inicialización local.", + ko: "재시작하고 로컬 초기화 확인 단계로 넘어가려면 아래 버튼을 선택해 주세요.", }, "Ui.SetupWizard.OutroNewP2PUser.Title": { def: "Setup Complete: Preparing This P2P Device", + es: "Configuración completada: preparando este dispositivo P2P", + ko: "설정 완료: 이 P2P 기기 준비", }, "Ui.SetupWizard.OutroNewUser.GuidancePrimary": { def: "The connection to the server has been configured successfully. As the next step, the synchronisation data on the server will be built from the current data on this device.", + es: "La conexión con el servidor se ha configurado correctamente. Como paso siguiente, los datos de sincronización del servidor se construirán a partir de los datos actuales de este dispositivo.", + ko: "서버 연결이 정상적으로 구성되었습니다. 다음 단계로, 이 기기의 현재 데이터를 사용해 서버의 동기화 데이터를 만듭니다.", zh: "服务器连接已成功配置。下一步将根据当前设备上的数据,在服务器端建立同步数据。", }, "Ui.SetupWizard.OutroNewUser.GuidanceWarning": { def: "After restarting, the data on this device will be uploaded to the server as the master copy. Please note that any unintended data currently on the server will be completely overwritten.", + es: "Tras reiniciar, los datos de este dispositivo se subirán al servidor como copia maestra. Ten en cuenta que cualquier dato no deseado que haya ahora en el servidor se sobrescribirá por completo.", + ko: "재시작하면 이 기기의 데이터가 원본으로서 서버에 업로드됩니다. 현재 서버에 있는 데이터는 의도치 않은 것이라도 완전히 덮어써지므로 유의해 주세요.", zh: "重启后,当前设备上的数据会作为主副本上传到服务器。请注意,服务器上现有的非预期数据将被完全覆盖。", }, "Ui.SetupWizard.OutroNewUser.Important": { def: "IMPORTANT", + es: "IMPORTANTE", + ko: "중요", zh: "重要", }, "Ui.SetupWizard.OutroNewUser.Proceed": { def: "Restart and Initialise Server", + es: "Reiniciar e inicializar el servidor", + ko: "재시작하고 서버 초기화", zh: "重启并初始化服务器", }, "Ui.SetupWizard.OutroNewUser.Question": { def: "Please select the button below to restart and proceed to the final confirmation.", + es: "Pulsa el botón de abajo para reiniciar y pasar a la confirmación final.", + ko: "재시작하고 마지막 확인 단계로 넘어가려면 아래 버튼을 선택해 주세요.", zh: "请选择下方按钮,重启并进入最终确认步骤。", }, "Ui.SetupWizard.OutroNewUser.Title": { def: "Setup Complete: Preparing to Initialise Server", + es: "Configuración completada: preparando la inicialización del servidor", + ko: "설정 완료: 서버 초기화 준비", zh: "设置完成:准备初始化服务器", }, "Ui.SetupWizard.RebuildEverythingP2P.ConfirmLocalReset": { def: "I understand that this resets only this device's local synchronisation database.", + es: "Entiendo que esto restablece únicamente la base de datos de sincronización local de este dispositivo.", + ko: "이 작업이 이 기기의 로컬 동기화 데이터베이스만 초기화한다는 것을 이해했습니다.", }, "Ui.SetupWizard.RebuildEverythingP2P.ConfirmLocalResetNote": { def: "The files currently in this Vault are used to rebuild it.", + es: "Se usarán los archivos que hay ahora en este Vault para reconstruirla.", + ko: "현재 이 보관함에 있는 파일을 사용해 재구축합니다.", }, "Ui.SetupWizard.RebuildEverythingP2P.ConfirmTitle": { def: "⚠️ Please Confirm the Following", + es: "⚠️ Confirma lo siguiente", + ko: "⚠️ 다음 내용을 확인해 주세요", }, "Ui.SetupWizard.RebuildEverythingP2P.Guidance": { def: "This procedure will discard the local LiveSync database on this device and rebuild it from the current files in this Vault. It does not delete or overwrite data on another device.", + es: "Este procedimiento descartará la base de datos local de LiveSync de este dispositivo y la reconstruirá a partir de los archivos actuales de este Vault. No elimina ni sobrescribe datos de otro dispositivo.", + ko: "이 절차는 이 기기의 로컬 LiveSync 데이터베이스를 삭제하고, 이 보관함의 현재 파일로 재구축합니다. 다른 기기의 데이터는 삭제하거나 덮어쓰지 않습니다.", }, "Ui.SetupWizard.RebuildEverythingP2P.Note": { def: "Keep this device online after initialisation so that another device can fetch the Vault from it.", + es: "Mantén este dispositivo conectado después de la inicialización para que otro dispositivo pueda obtener el Vault desde él.", + ko: "초기화 후에도 다른 기기가 이 기기에서 보관함을 가져올 수 있도록 이 기기를 온라인 상태로 유지해 주세요.", }, "Ui.SetupWizard.RebuildEverythingP2P.Proceed": { def: "I Understand, Prepare This Device", + es: "Lo entiendo, preparar este dispositivo", + ko: "이해했습니다, 이 기기 준비", }, "Ui.SetupWizard.RebuildEverythingP2P.Title": { def: "Final Confirmation: Prepare This Device for P2P", + es: "Confirmación final: preparar este dispositivo para P2P", + ko: "최종 확인: P2P를 위한 이 기기 준비", }, "Ui.SetupWizard.SelectExisting.Guidance": { def: "You are adding this device to an existing synchronisation setup.", + es: "Estás añadiendo este dispositivo a una configuración de sincronización existente.", + ko: "이 기기를 기존 동기화 구성에 추가합니다.", zh: "你正在将此设备加入已有同步配置。", }, "Ui.SetupWizard.SelectExisting.ManualOption": { def: "Configure a remote manually", + es: "Configurar un remoto manualmente", + ko: "서버 정보를 수동으로 입력", zh: "手动输入服务器信息", }, "Ui.SetupWizard.SelectExisting.ManualOptionDesc": { def: "Configure the same remote as your other devices again manually. This is intended only for advanced users.", + es: "Vuelve a configurar manualmente el mismo remoto que en tus otros dispositivos. Está pensado solo para usuarios avanzados.", + ko: "다른 기기와 동일한 서버 정보를 다시 직접 입력합니다. 숙련된 사용자 전용입니다.", zh: "手动重新配置与你其他设备相同的服务器信息。此方式仅适用于高级用户。", }, "Ui.SetupWizard.SelectExisting.ProceedManual": { def: "Proceed with manual configuration", + es: "Continuar con la configuración manual", + ko: "서버 정보를 알고 있으니 직접 입력하겠습니다", zh: "我知道服务器信息,让我手动输入", }, "Ui.SetupWizard.SelectExisting.ProceedQr": { def: "Scan the QR code displayed on an active device using this device's camera.", + es: "Escanea con la cámara de este dispositivo el código QR mostrado en un dispositivo activo.", + ko: "이 기기의 카메라로 사용 중인 기기에 표시된 QR 코드를 스캔하세요.", zh: "使用本设备摄像头扫描活动设备上显示的二维码", }, "Ui.SetupWizard.SelectExisting.ProceedSetupUri": { def: "Proceed with Setup URI", + es: "Continuar con el Setup URI", + ko: "Setup URI로 계속", zh: "使用 Setup URI 继续", }, "Ui.SetupWizard.SelectExisting.QrOption": { def: "Scan a QR Code (Recommended for mobile)", + es: "Escanear un código QR (recomendado en móvil)", + ko: "QR 코드 스캔(모바일 권장)", zh: "扫描二维码(移动端推荐)", }, "Ui.SetupWizard.SelectExisting.QrOptionDesc": { def: "Scan the QR code displayed on an active device using this device's camera.", + es: "Escanea con la cámara de este dispositivo el código QR mostrado en un dispositivo activo.", + ko: "이 기기의 카메라로 사용 중인 기기에 표시된 QR 코드를 스캔하세요.", zh: "使用本设备摄像头扫描活动设备上显示的二维码。", }, "Ui.SetupWizard.SelectExisting.Question": { def: "Please select a method to import the settings from another device.", + es: "Selecciona un método para importar los ajustes desde otro dispositivo.", + ko: "다른 기기에서 설정을 가져올 방법을 선택해 주세요.", zh: "请选择一种从其他设备导入设置的方法。", }, "Ui.SetupWizard.SelectExisting.SetupUriOption": { def: "Use a Setup URI (Recommended)", + es: "Usar un Setup URI (recomendado)", + ko: "Setup URI 사용(권장)", zh: "使用 Setup URI(推荐)", }, "Ui.SetupWizard.SelectExisting.SetupUriOptionDesc": { def: "Paste the Setup URI generated from one of your active devices.", + es: "Pega el Setup URI generado en uno de tus dispositivos activos.", + ko: "사용 중인 기기 중 하나에서 생성한 Setup URI를 붙여 넣으세요.", zh: "粘贴从某台已启用设备生成的 Setup URI。", }, "Ui.SetupWizard.SelectExisting.Title": { def: "Device Setup Method", + es: "Método de configuración del dispositivo", + ko: "기기 설정 방법", zh: "设备设置方式", }, "Ui.SetupWizard.SelectNew.Guidance": { def: "We will now configure the synchronisation connection.", + es: "Vamos a configurar la conexión de sincronización.", + ko: "이제 서버 구성을 진행하겠습니다.", zh: "接下来将继续配置服务器连接信息。", }, "Ui.SetupWizard.SelectNew.ManualOption": { def: "Configure a remote manually", + es: "Configurar un remoto manualmente", + ko: "서버 정보를 수동으로 입력", zh: "手动输入服务器信息", }, "Ui.SetupWizard.SelectNew.ManualOptionDesc": { def: "This is an advanced option for users who do not have a Setup URI or who want to configure detailed settings. You can also use it for P2P synchronisation instead of CouchDB or S3-compatible Object Storage.", + es: "Es una opción avanzada para quienes no tienen un Setup URI o quieren ajustar la configuración en detalle. También puedes usarla para la sincronización P2P en lugar de CouchDB o de un almacenamiento de objetos compatible con S3.", + ko: "Setup URI가 없거나 세부 설정을 직접 구성하려는 사용자를 위한 고급 옵션입니다.", zh: "如果你没有 Setup URI,或希望自行配置更详细的参数,可选择此高级选项。", }, "Ui.SetupWizard.SelectNew.ProceedManual": { def: "Proceed with manual configuration", + es: "Continuar con la configuración manual", + ko: "서버 정보를 알고 있으니 직접 입력하겠습니다", zh: "我知道服务器信息,让我手动输入", }, "Ui.SetupWizard.SelectNew.ProceedSetupUri": { def: "Proceed with Setup URI", + es: "Continuar con el Setup URI", + ko: "Setup URI로 계속", zh: "使用 Setup URI 继续", }, "Ui.SetupWizard.SelectNew.Question": { def: "How would you like to configure this synchronisation connection?", + es: "¿Cómo quieres configurar esta conexión de sincronización?", + ko: "서버 연결을 어떻게 구성하시겠습니까?", zh: "你希望如何配置服务器连接?", }, "Ui.SetupWizard.SelectNew.SetupUriOption": { def: "Use a Setup URI (Recommended)", + es: "Usar un Setup URI (recomendado)", + ko: "Setup URI 사용(권장)", zh: "使用 Setup URI(推荐)", }, "Ui.SetupWizard.SelectNew.SetupUriOptionDesc": { def: "A Setup URI is a single string containing connection and authentication details. When one is available from a setup script, it provides a simple and secure configuration method.", + es: "Un Setup URI es una única cadena que contiene los datos de conexión y autenticación. Cuando un script de instalación te proporciona uno, es la forma más sencilla y segura de configurarlo.", + ko: "Setup URI는 서버 주소와 인증 정보를 담은 하나의 문자열입니다. 서버 설치 스크립트가 URI를 생성했다면, 간단하고 안전하게 구성할 수 있는 방법입니다.", zh: "Setup URI 是一段包含服务器地址和认证信息的文本。如果你的服务器安装脚本已经生成了它,这是最简单且安全的配置方式。", }, "Ui.SetupWizard.SelectNew.Title": { def: "Connection Method", + es: "Método de conexión", + ko: "연결 방법", zh: "连接方式", }, "Ui.SetupWizard.SetupRemote.BucketOption": { def: "S3-compatible Object Storage", + es: "Almacenamiento de objetos compatible con S3", + ko: "S3/MinIO/R2 객체 스토리지", zh: "S3/MinIO/R2 对象存储", }, "Ui.SetupWizard.SetupRemote.BucketOptionDesc": { def: "Synchronisation using journal files. You must already have an S3-compatible Object Storage service set up, such as Amazon S3, MinIO, or Cloudflare R2.", + es: "Sincronización mediante archivos de diario. Necesitas tener ya un servicio de almacenamiento de objetos compatible con S3, como Amazon S3, MinIO o Cloudflare R2.", + ko: "저널 파일을 사용하는 동기화 방식입니다. S3/MinIO/R2 호환 객체 스토리지 서비스를 미리 구성해 두어야 합니다.", zh: "使用日志文件进行同步。你需要先准备好兼容 S3/MinIO/R2 的对象存储服务。", }, "Ui.SetupWizard.SetupRemote.CouchDbOptionDesc": { def: "This is the most suitable synchronisation method for the current design. All features are available. You must already have a CouchDB instance set up.", + es: "Es el método de sincronización más adecuado para el diseño actual y ofrece todas las funciones. Necesitas tener ya una instancia de CouchDB en marcha.", + ko: "현재 설계에 가장 적합한 동기화 방식입니다. 모든 기능을 사용할 수 있습니다. CouchDB 인스턴스를 미리 구성해 두어야 합니다.", zh: "这是当前设计下最适合的同步方式,所有功能都可用。你需要先准备好 CouchDB 实例。", }, "Ui.SetupWizard.SetupRemote.Guidance": { def: "Select the remote type for this synchronisation setup.", + es: "Selecciona el tipo de remoto para esta configuración de sincronización.", + ko: "연결할 서버 유형을 선택해 주세요.", zh: "请选择你要连接的服务器类型。", }, "Ui.SetupWizard.SetupRemote.P2POption": { def: "Peer-to-Peer (P2P)", + es: "Punto a punto (P2P)", + ko: "Peer-to-Peer 전용", zh: "仅点对点", }, "Ui.SetupWizard.SetupRemote.P2POptionDesc": { def: "This enables direct synchronisation between devices. No server is required, but both devices must be online at the same time and some features may be limited. Internet connectivity is required only for signalling, not for data transfer.", + es: "Permite la sincronización directa entre dispositivos. No hace falta servidor, pero ambos dispositivos deben estar conectados a la vez y algunas funciones pueden estar limitadas. Solo se necesita internet para la señalización, no para transferir los datos.", + ko: "기기 간에 직접 동기화하는 방식입니다. 서버는 필요 없지만 두 기기가 동시에 온라인 상태여야 하며, 일부 기능은 제한될 수 있습니다. 인터넷 연결은 시그널링에만 필요하고 데이터 전송에는 필요하지 않습니다.", zh: "启用设备之间的直接同步。无需服务器,但两台设备必须同时在线,且部分功能可能受限。互联网连接仅用于信令,不用于传输数据。", }, "Ui.SetupWizard.SetupRemote.ProceedBucket": { def: "Continue to Object Storage setup", + es: "Continuar con la configuración del almacenamiento de objetos", + ko: "S3/MinIO/R2 설정으로 계속", zh: "继续配置 S3/MinIO/R2", }, "Ui.SetupWizard.SetupRemote.ProceedCouchDb": { def: "Continue to CouchDB setup", + es: "Continuar con la configuración de CouchDB", + ko: "CouchDB 설정으로 계속", zh: "继续配置 CouchDB", }, "Ui.SetupWizard.SetupRemote.ProceedP2P": { def: "Continue to P2P setup", + es: "Continuar con la configuración de P2P", + ko: "Peer-to-Peer 전용 설정으로 계속", zh: "继续配置仅点对点模式", }, "Ui.SetupWizard.SetupRemote.Title": { def: "Choose a synchronisation remote", + es: "Elige un remoto de sincronización", + ko: "서버 정보 입력", zh: "输入服务器信息", }, "Unique name between all synchronized devices. To edit this setting, please disable customization sync once.": { @@ -10188,7 +11012,7 @@ export const allMessages: Readonly [!INFO]- The connected devices have been detected as follows:\n${devices}": "> [!INFO]- Se han detectado los siguientes dispositivos conectados:\n${devices}", "⚠️ Important Notice": "⚠️ Aviso importante", "⚠️ Please Confirm the Following": "⚠️ Confirma lo siguiente", "✔ SELECT": "✔ SELECCIONAR", @@ -42,6 +43,7 @@ "Access Key ID": "ID de clave de acceso", "Action": "Acción", "Activate": "Activar", + "Active Remote Configuration": "Configuración remota activa", "Add default patterns": "Añadir patrones predeterminados", "Add new connection": "Añadir conexión", "AddOn Module (ConfigSync) has not been loaded. This is very unexpected situation. Please report this issue.": "El módulo complementario (ConfigSync) no se ha cargado. Esta situación es muy inesperada. Informa de este problema.", @@ -52,11 +54,15 @@ "After restarting, the database on this device will be rebuilt using data from the server. If there are any unsynchronised files in this vault, conflicts may occur with the server data.": "Tras reiniciar, la base de datos de este dispositivo se reconstruirá con los datos del servidor. Si hay archivos sin sincronizar en este vault, pueden producirse conflictos con los datos del servidor.", "After that, synchronise to a brand new vault on each other device with the new remote one by one.": "Después, sincroniza con un vault totalmente nuevo en cada uno de los demás dispositivos, uno por uno, usando el nuevo remoto.", "All checks passed successfully!": "¡Todas las comprobaciones se han superado correctamente!", + "All devices have the same progress value (${progress}). Your devices seem to be synchronised. And be able to proceed with Garbage Collection.": "Todos los dispositivos tienen el mismo valor de progreso (${progress}). Parece que están sincronizados, por lo que se puede continuar con la recolección de basura.", "All the same or non-existent": "Todo igual o inexistente", "Allow in session": "Permitir en esta sesión", "Allow permanently": "Permitir permanentemente", "Also, please note that if you are using Peer-to-Peer synchronization, this configuration will be used when you switch to other methods and connect to a remote server in the future.": "Además, si usas sincronización punto a punto, esta configuración se aplicará cuando en el futuro cambies a otros métodos y te conectes a un servidor remoto.", "Always prompt merge conflicts": "Siempre preguntar en conflictos", + "Analyse": "Analizar", + "Analyse database usage": "Analizar el uso de la base de datos", + "Analyse database usage and generate a TSV report for diagnosis yourself. You can paste the generated report with any spreadsheet you like.": "Analiza el uso de la base de datos y genera un informe TSV para que puedas diagnosticarlo tú mismo. Puedes pegar el informe generado en la hoja de cálculo que prefieras.", "Apply All Selected": "Aplicar todo lo seleccionado", "Apply Latest Change if Conflicting": "Aplicar último cambio en conflictos", "Apply preset configuration": "Aplicar configuración predefinida", @@ -78,7 +84,10 @@ "Bucket Name": "Nombre del bucket", "by resetting the remote, you will be informed on other devices.": "al restablecer el remoto, se te avisará en los demás dispositivos.", "Cancel": "Cancelar", + "Cancel Garbage Collection": "Cancelar la recolección de basura", "Changing the encryption algorithm will prevent access to any data previously encrypted with a different algorithm. Ensure that all your devices are configured to use the same algorithm to maintain access to your data.": "Cambiar el algoritmo de cifrado impedirá acceder a los datos cifrados previamente con otro algoritmo. Asegúrate de que todos tus dispositivos usen el mismo algoritmo para no perder el acceso a tus datos.", + "Changing this setting requires migrating existing data (a bit time may be taken) and restarting Obsidian. Please make sure to back up your data before proceeding.": "Cambiar este ajuste requiere migrar los datos existentes (puede tardar un poco) y reiniciar Obsidian. Asegúrate de hacer una copia de seguridad de tus datos antes de continuar.", + "Check": "Comprobar", "Check and convert non-path-obfuscated files": "Comprobar y convertir archivos sin ofuscación de ruta", "Check for documents that have not been converted to path-obfuscated IDs and convert them if necessary.": "Comprueba los documentos que aún no se hayan convertido a identificadores con ruta ofuscada y conviértelos si es necesario.", "Checking connection... Please wait.": "Comprobando la conexión... Espera un momento.", @@ -91,6 +100,10 @@ "Comma separated `.gitignore, .dockerignore`": "Separados por comas: `.gitignore, .dockerignore`", "Command": "Comando", "Communicating": "Comunicando", + "Compaction in progress on remote database...": "Compactación en curso en la base de datos remota...", + "Compaction on remote database completed successfully.": "La compactación de la base de datos remota se ha completado correctamente.", + "Compaction on remote database failed.": "La compactación de la base de datos remota ha fallado.", + "Compaction on remote database timed out.": "La compactación de la base de datos remota ha superado el tiempo de espera.", "Compare file": "Comparar archivo", "Compare the content of files between on local database and storage. If not matched, you will be asked which one you want to keep.": "Compara el contenido de los archivos entre la base de datos local y el almacenamiento. Si no coinciden, se te preguntará cuál deseas conservar.", "Compatibility (Conflict Behaviour)": "Compatibilidad (comportamiento de conflictos)", @@ -99,6 +112,7 @@ "Compatibility (Metadata)": "Compatibilidad (metadatos)", "Compatibility (Remote Database)": "Compatibilidad (base de datos remota)", "Compatibility (Trouble addressed)": "Compatibilidad (problemas corregidos)", + "Compute revisions for chunks": "Calcular revisiones para los chunks", "Compute revisions for chunks (Previous behaviour)": "Calcular revisiones para chunks (comportamiento anterior)", "Configuration": "Configuración", "Configuration Encryption": "Cifrado de configuración", @@ -118,6 +132,7 @@ "Continue to Peer-to-Peer only setup": "Continuar con la configuración solo Peer-to-Peer", "Continue to S3/MinIO/R2 setup": "Continuar con la configuración de S3/MinIO/R2", "Copy": "Copiar", + "Copy Report to clipboard": "Copiar el informe al portapapeles", "CouchDB Configuration": "Configuración de CouchDB", "CouchDB Connection Tweak": "Ajustes de conexión de CouchDB", "Create P2P remote": "Crear remoto P2P", @@ -128,6 +143,7 @@ "Customization Sync (Beta3)": "Sincronización de personalización (Beta3)", "Data Compression": "Compresión de datos", "Data to Copy": "Datos a copiar", + "Database -> Storage": "Base de datos -> Almacenamiento", "Database Adapter": "Adaptador de base de datos", "Database Name": "Nombre de la base de datos", "Database suffix": "Sufijo de base de datos", @@ -153,6 +169,7 @@ "desktop": "equipo de escritorio", "Detected Peers": "Pares detectados", "Developer": "Desarrollador", + "Device": "Dispositivo", "device name": "nombre del dispositivo", "Device name": "Nombre del dispositivo", "Device name to identify the device. Please use shorter one for the stable peer detection, i.e., \"iphone-16\" or \"macbook-2021\".": "Nombre para identificar el dispositivo. Usa uno corto para que la detección de pares sea estable, por ejemplo «iphone-16» o «macbook-2021».", @@ -160,6 +177,9 @@ "Device Setup Method": "Método de configuración del dispositivo", "Devices:": "Dispositivos:", "Diagnostic RTCPeerConnection is enabled": "El RTCPeerConnection de diagnóstico está habilitado", + "dialog.yourLanguageAvailable": "Self-hosted LiveSync tenía traducciones para tu idioma, así que se ha activado el ajuste %{Display language}.\n\nNota: no todos los mensajes están traducidos. ¡Esperamos tus contribuciones!\nNota 2: si abres una incidencia, **vuelve antes a %{lang-def}** y luego haz las capturas de pantalla y recoge los mensajes y registros. Puedes hacerlo desde el diálogo de ajustes.\n¡Que lo disfrutes!", + "dialog.yourLanguageAvailable.btnRevertToDefault": "Mantener %{lang-def}", + "dialog.yourLanguageAvailable.Title": " ¡Hay traducción disponible!", "Diff": "Diferencias", "Different": "Distinto", "Disables all synchronization and restart.": "Desactiva toda la sincronización y reinicia la aplicación.", @@ -172,6 +192,27 @@ "Do not keep metadata of deleted files.": "No conservar metadatos de archivos borrados", "Do not split chunks in the background": "No dividir chunks en segundo plano", "Do not use internal API": "No usar API interna", + "Doctor.Button.DismissThisVersion": "No, y no volver a preguntar hasta la próxima versión", + "Doctor.Button.Fix": "Corregirlo", + "Doctor.Button.FixButNoRebuild": "Corregirlo, pero sin reconstruir", + "Doctor.Button.No": "No", + "Doctor.Button.Skip": "Dejarlo como está", + "Doctor.Button.Yes": "Sí", + "Doctor.Dialogue.Main": "¡Hola! El Doctor de configuración se ha activado por ${activateReason}.\nPor desgracia, se han detectado algunos ajustes como posibles problemas.\nTranquilo: los resolveremos uno a uno.\n\nPara que lo sepas de antemano, te preguntaremos por los siguientes puntos.\n\n${issues}\n\n¿Empezamos?", + "Doctor.Dialogue.MainFix": "\n## ${name}\n\n| Actual | Ideal |\n|:---:|:---:|\n| ${current} | ${ideal} |\n\n**Nivel de recomendación:** ${level}\n\n### ¿Por qué se ha detectado?\n\n${reason}\n\n${note}\n\n¿Ajustarlo al valor ideal?", + "Doctor.Dialogue.Title": "Doctor de configuración de Self-hosted LiveSync", + "Doctor.Dialogue.TitleAlmostDone": "¡Casi hemos terminado!", + "Doctor.Dialogue.TitleFix": "Corregir el problema ${current}/${total}", + "Doctor.Level.Must": "Obligatorio", + "Doctor.Level.Necessary": "Necesario", + "Doctor.Level.Optional": "Opcional", + "Doctor.Level.Recommended": "Recomendado", + "Doctor.Message.NoIssues": "¡No se ha detectado ningún problema!", + "Doctor.Message.RebuildLocalRequired": "¡Atención! Hay que reconstruir la base de datos local para aplicar esto.", + "Doctor.Message.RebuildRequired": "¡Atención! Hay que reconstruir para aplicar esto.", + "Doctor.Message.SomeSkipped": "Hemos dejado algunos problemas sin resolver. ¿Quieres que te lo pregunte de nuevo en el próximo inicio?", + "Doctor.RULES.E2EE_V02500.REASON": "El cifrado de extremo a extremo es ahora más robusto y más rápido. Además, una nueva revisión del código reveló que el E2EE anterior estaba comprometido, por lo que conviene aplicarlo cuanto antes. Lamentamos de veras las molestias. Este ajuste no es compatible con versiones anteriores: todos los dispositivos sincronizados deben actualizarse a la v0.25.0 o superior. No es necesario reconstruir (los datos se convertirán al nuevo formato durante la transferencia), pero se recomienda hacerlo siempre que sea posible.", + "Document History": "Historial del documento", "Duplicate": "Duplicar", "Duplicate remote": "Duplicar remoto", "E2EE Configuration": "Configuración de E2EE", @@ -217,11 +258,15 @@ "Error during testAndFixSettings: ${reason}": "Error durante testAndFixSettings: ${reason}", "Experimental Settings": "Ajustes experimentales", "Export": "Exportar", + "Failed to connect to remote for compaction.": "No se pudo conectar al remoto para la compactación.", + "Failed to connect to remote for compaction. ${reason}": "No se pudo conectar al remoto para la compactación. ${reason}", "Failed to connect to the server: ${reason}": "No se pudo conectar al servidor: ${reason}", "Failed to connect to the server. Please check your settings.": "No se pudo conectar al servidor. Revisa tus ajustes.", "Failed to connect to the signalling relay: ${reason}": "No se pudo conectar al relé de señalización: ${reason}", "Failed to create replicator instance.": "No se pudo crear la instancia del replicador.", "Failed to parse Setup-URI.": "No se pudo interpretar el Setup-URI.", + "Failed to start one-shot replication before Garbage Collection. Garbage Collection Cancelled.": "No se pudo iniciar la replicación puntual previa a la recolección de basura. Recolección de basura cancelada.", + "Failed to start replication after Garbage Collection.": "No se pudo iniciar la replicación después de la recolección de basura.", "Failed:": "Fallidas:", "Fetch": "Obtener", "Fetch chunks on demand": "Obtener chunks bajo demanda", @@ -231,6 +276,7 @@ "Fetching status...": "Obteniendo el estado...", "File integrity": "Integridad de archivos", "File to resolve conflict": "Archivo para resolver el conflicto", + "File to view History": "Archivo cuyo historial se va a ver", "Filename": "Nombre de archivo", "Final Confirmation: Overwrite Server Data with This Device's Files": "Confirmación final: sobrescribir los datos del servidor con los archivos de este dispositivo", "First, please select the option that best describes your current situation.": "Primero, seleccione la opción que describa mejor su situación actual。", @@ -242,7 +288,13 @@ "Forces the file to be synced when opened.": "Forzar sincronización al abrir archivo", "Fresh Start Wipe": "Borrado para reinicio completo", "Furthermore, if conflicts are already present in the server data, they will be synchronised to this device as they are, and you will need to resolve them locally.": "Además, si ya hay conflictos en los datos del servidor, se sincronizarán tal cual a este dispositivo y tendrás que resolverlos localmente.", + "Garbage Collection cancelled by user.": "Recolección de basura cancelada por el usuario.", + "Garbage Collection completed. Deleted chunks: ${deletedChunks} / ${totalChunks}. Time taken: ${seconds} seconds.": "Recolección de basura completada. Chunks eliminados: ${deletedChunks} / ${totalChunks}. Tiempo empleado: ${seconds} segundos.", + "Garbage Collection Confirmation": "Confirmación de la recolección de basura", "Garbage Collection V3 (Beta)": "Recolección de basura V3 (Beta)", + "Garbage Collection: Found ${unusedChunks} unused chunks to delete.": "Recolección de basura: se han encontrado ${unusedChunks} chunks sin usar para eliminar.", + "Garbage Collection: Scanned ${scanned} / ~${docCount}": "Recolección de basura: analizados ${scanned} / ~${docCount}", + "Garbage Collection: Scanning completed. Total chunks: ${totalChunks}, Used chunks: ${usedChunks}": "Recolección de basura: análisis completado. Chunks totales: ${totalChunks}, chunks en uso: ${usedChunks}", "Gathering information...": "Recopilando información...", "Generate Random ID": "Generar un ID aleatorio", "Group ID": "ID de grupo", @@ -250,8 +302,10 @@ "Have you created a backup before proceeding?": "¿Has creado una copia de seguridad antes de continuar?", "Hidden file synchronization have been temporarily disabled. Please enable them after the fetching, if you need them.": "La sincronización de archivos ocultos se ha desactivado temporalmente. Vuelve a activarla después de la obtención si la necesitas.", "Hidden Files": "Archivos ocultos", + "Hide completely": "Ocultar por completo", "Hide not applicable items": "Ocultar elementos no aplicables", "Higher (${local} > ${remote})": "Superior (${local} > ${remote})", + "Highlight diff": "Resaltar las diferencias", "How to display network errors when the sync server is unreachable.": "Cómo mostrar los errores de red cuando el servidor de sincronización no está disponible.", "How would you like to configure the connection to your server?": "¿Cómo desea configurar la conexión con su servidor?", "However, This should not be enabled if you want to increase your secrecy more.": "Sin embargo, esto no debería habilitarse si quieres aumentar aún más tu privacidad.", @@ -283,10 +337,12 @@ "If you cannot avoid CORS issues, you might want to try this option. It uses Obsidian's internal API to communicate with the CouchDB server. Not compliant with web standards, but works. Note that this might break in future Obsidian versions.": "Si no puedes evitar problemas de CORS, prueba esta opción. Usa la API interna de Obsidian para comunicarse con el servidor CouchDB. No cumple los estándares web, pero funciona. Ten en cuenta que podría dejar de funcionar en versiones futuras de Obsidian.", "If you cannot avoid CORS issues, you might want to try this option. It uses Obsidian's internal API to communicate with the S3 server. Not compliant with web standards, but works. Note that this might break in future Obsidian versions.": "Si no puedes evitar problemas de CORS, prueba esta opción. Usa la API interna de Obsidian para comunicarse con el servidor S3. No cumple los estándares web, pero funciona. Ten en cuenta que podría dejar de funcionar en versiones futuras de Obsidian.", "If you have unsynchronised changes in your Vault on this device, they will likely diverge from the server's versions after the reset. This may result in a large number of file conflicts.": "Si tienes cambios sin sincronizar en el Vault de este dispositivo, es probable que divergan de las versiones del servidor tras el restablecimiento. Esto puede provocar un gran número de conflictos de archivos.", + "If you reached the payload size limit when using IBM Cloudant, please decrease batch size and batch limit to a lower value.": "Si alcanzas el límite de tamaño de carga al usar IBM Cloudant, reduce el tamaño de lote y el límite de lote.", "If you understand the risks and still wish to proceed, select so.": "Si entiendes los riesgos y aun así quieres continuar, indícalo.", "If you want to store the data in a specific folder within the bucket, you can specify a folder prefix here. Otherwise, leave it blank to store data at the root of the bucket.": "Si quieres guardar los datos en una carpeta concreta del bucket, indica aquí un prefijo de carpeta. Si no, déjalo vacío para guardarlos en la raíz del bucket.", "If you want to use `LiveSync`, you should broadcast changes. All `watching` peers which detects this will start the replication for fetching.": "Si quieres usar `LiveSync`, debes difundir los cambios. Todos los pares que estén `observando` y lo detecten iniciarán la replicación para obtenerlos.", "Ignore": "Ignorar", + "Ignore and Proceed": "Ignorar y continuar", "Ignore files": "Archivos a ignorar", "Ignore patterns": "Patrones de exclusión", "Import connection": "Importar conexión", @@ -297,6 +353,8 @@ "Incubate Chunks in Document": "Incubar chunks en documento", "Initial Action": "Acción inicial", "Initialise all journal history, On the next sync, every item will be received and sent.": "Restablece todo el historial del diario. En la próxima sincronización se recibirán y enviarán todos los elementos.", + "Initialise journal received history. On the next sync, every item except this device sent will be downloaded again.": "Inicializa el historial de recepción del diario. En la próxima sincronización se volverán a descargar todos los elementos salvo los enviados por este dispositivo.", + "Initialise journal sent history. On the next sync, every item except this device received will be sent again.": "Inicializa el historial de envío del diario. En la próxima sincronización se volverán a enviar todos los elementos salvo los recibidos por este dispositivo.", "Interval (sec)": "Intervalo (segundos)", "INVERTED": "INVERTIDO", "Issue detection log:": "Registro de detección de problemas:", @@ -308,11 +366,22 @@ "JWT Key": "Clave JWT", "JWT Key ID (kid)": "ID de clave JWT (kid)", "JWT Subject (sub)": "Sujeto JWT (sub)", + "K.exp": "Experimental", + "K.long_p2p_sync": "%{title_p2p_sync}", + "K.P2P": "%{Peer} a %{Peer}", + "K.Peer": "par", + "K.ScanCustomization": "Buscar personalizaciones", + "K.short_p2p_sync": "Sincronización P2P", + "K.title_p2p_sync": "Sincronización punto a punto", "Keep empty folder": "Mantener carpetas vacías", + "lang_def": "Predeterminado", "lang-de": "Alemán", + "lang-def": "%{lang_def}", "lang-es": "Español", "lang-fr": "Français", + "lang-he": "Hebreo", "lang-ja": "Japonés", + "lang-ko": "Coreano", "lang-ru": "Ruso", "lang-zh": "Chino simplificado", "lang-zh-tw": "Chino tradicional", @@ -331,6 +400,7 @@ "liveSyncReplicator.liveSyncBegin": "Inicio de LiveSync...", "liveSyncReplicator.lockRemoteDb": "Bloquear base de datos remota para prevenir corrupción de datos", "liveSyncReplicator.markDeviceResolved": "Marcar este dispositivo como 'resuelto'.", + "liveSyncReplicator.mismatchedTweakDetected": "Se han detectado discrepancias en la configuración entre dispositivos. Ejecutar una replicación manual intentará resolverlo.", "liveSyncReplicator.oneShotSyncBegin": "Inicio de sincronización OneShot... (${syncMode})", "liveSyncReplicator.remoteDbCorrupted": "La base de datos remota es más nueva o está dañada, asegúrese de tener la última versión de self-hosted-livesync instalada", "liveSyncReplicator.remoteDbCreatedOrConnected": "Base de datos remota creada o conectada", @@ -369,6 +439,7 @@ "Memory cache size (by total items)": "Tamaño caché memoria (por ítems)", "Merge": "Fusionar", "Minimum delay for batch database updating": "Retraso mínimo para actualización por lotes", + "Minimum interval for syncing": "Intervalo mínimo de sincronización", "Mixed": "Mixto", "moduleCheckRemoteSize.logCheckingStorageSizes": "Comprobando tamaños de almacenamiento", "moduleCheckRemoteSize.logCurrentStorageSize": "Tamaño del almacenamiento remoto: ${measuredSize}", @@ -377,6 +448,8 @@ "moduleCheckRemoteSize.msgConfirmRebuild": "Esto puede llevar un poco de tiempo. ¿Realmente quieres reconstruir todo ahora?", "moduleCheckRemoteSize.msgDatabaseGrowing": "**¡Tu base de datos está creciendo!** Pero no te preocupes, podemos abordarlo ahora. El tiempo antes de quedarse sin espacio en el almacenamiento remoto.\n\n| Tamaño medido | Tamaño configurado |\n| --- | --- |\n| ${estimatedSize} | ${maxSize} |\n\n> [!MORE]-\n> Si lo has estado utilizando durante muchos años, puede haber fragmentos no referenciados - es decir, basura - acumulándose en la base de datos. Por lo tanto, recomendamos reconstruir todo. Probablemente se volverá mucho más pequeño.\n>\n> Si el volumen de tu bóveda simplemente está aumentando, es mejor reconstruir todo después de organizar los archivos. Self-hosted LiveSync no elimina los datos reales incluso si los eliminas para acelerar el proceso. Está aproximadamente [documentado](https://github.com/vrtmrz/obsidian-livesync/blob/main/docs/tech_info.md).\n>\n> Si no te importa el aumento, puedes aumentar el límite de notificación en 100 MB. Este es el caso si lo estás ejecutando en tu propio servidor. Sin embargo, es mejor reconstruir todo de vez en cuando.\n>\n\n> [!WARNING]\n> Si realizas la reconstrucción completa, asegúrate de que todos los dispositivos estén sincronizados. El complemento fusionará tanto como sea posible, sin embargo.\n", "moduleCheckRemoteSize.msgSetDBCapacity": "Podemos configurar una advertencia de capacidad máxima de base de datos, **para tomar medidas antes de quedarse sin espacio en el almacenamiento remoto**.\n¿Quieres habilitar esto?\n\n> [!MORE]-\n> - 0: No advertir sobre el tamaño del almacenamiento.\n> Esto es recomendado si tienes suficiente espacio en el almacenamiento remoto, especialmente si lo tienes autoalojado. Y puedes comprobar el tamaño del almacenamiento y reconstruir manualmente.\n> - 800: Advertir si el tamaño del almacenamiento remoto supera los 800 MB.\n> Esto es recomendado si estás usando fly.io con un límite de 1 GB o IBM Cloudant.\n> - 2000: Advertir si el tamaño del almacenamiento remoto supera los 2 GB.\n\nSi hemos alcanzado el límite, se nos pedirá que aumentemos el límite paso a paso.\n", + "moduleCheckRemoteSize.noticeExceeded": "El tamaño del almacenamiento remoto es de ${measuredSize}, por encima del umbral de aviso configurado de ${notifySize}. {HERE}", + "moduleCheckRemoteSize.noticeNotConfigured": "Los avisos sobre el tamaño del almacenamiento remoto no están configurados. {HERE}", "moduleCheckRemoteSize.option2GB": "2GB (Estándar)", "moduleCheckRemoteSize.option800MB": "800MB (Cloudant, fly.io)", "moduleCheckRemoteSize.optionAskMeLater": "Pregúntame más tarde", @@ -384,6 +457,7 @@ "moduleCheckRemoteSize.optionIncreaseLimit": "aumentar a ${newMax}MB", "moduleCheckRemoteSize.optionNoWarn": "No, nunca advertir por favor", "moduleCheckRemoteSize.optionRebuildAll": "Reconstruir todo ahora", + "moduleCheckRemoteSize.optionReview": "Revisar las opciones", "moduleCheckRemoteSize.titleDatabaseSizeLimitExceeded": "El tamaño del almacenamiento remoto superó el límite", "moduleCheckRemoteSize.titleDatabaseSizeNotify": "Configuración de notificación de tamaño de base de datos", "moduleInputUIObsidian.defaultTitleConfirmation": "Confirmación", @@ -406,6 +480,18 @@ "moduleLocalDatabase.logWaitingForReady": "Esperando a que la base de datos esté lista...", "moduleLog.showLog": "Mostrar registro", "moduleMigration.docUri": "https://github.com/vrtmrz/obsidian-livesync/blob/main/README_ES.md#how-to-use", + "moduleMigration.fix0256.buttons.checkItLater": "Comprobarlo más tarde", + "moduleMigration.fix0256.buttons.DismissForever": "Ya lo he corregido, no volver a preguntar", + "moduleMigration.fix0256.buttons.fix": "Corregir", + "moduleMigration.fix0256.message": "Debido a un error reciente (en la v0.25.6), puede que algunos archivos no se hayan guardado correctamente en la base de datos de sincronización.\nHemos analizado tus archivos y hemos encontrado algunos que hay que corregir.\n\n**Archivos que se pueden corregir:**\n\n${files}\n\nEstos archivos tienen en el almacenamiento un original cuyo tamaño coincide, por lo que es probable que se puedan recuperar.\nPodemos usarlos para corregir la base de datos: pulsa el botón «Corregir» de abajo.\n\n${messageUnrecoverable}\n\nSi quieres volver a ejecutarlo, puedes hacerlo desde Hatch.\n", + "moduleMigration.fix0256.messageUnrecoverable": "**Archivos que no se pueden corregir en este dispositivo:**\n\n${filesNotRecoverable}\n\nEstos archivos tienen metadatos inconsistentes y no se pueden corregir en este dispositivo (por lo general no podemos determinar cuál es el correcto).\nPara restaurarlos, comprueba tus otros dispositivos (también con esta función) o restáuralos manualmente desde una copia de seguridad.\n", + "moduleMigration.fix0256.title": "Se han detectado archivos dañados", + "moduleMigration.insecureChunkExist.buttons.fetch": "Ya he reconstruido el remoto. Obtener desde el remoto", + "moduleMigration.insecureChunkExist.buttons.later": "Lo haré más tarde", + "moduleMigration.insecureChunkExist.buttons.rebuild": "Reconstruir todo", + "moduleMigration.insecureChunkExist.laterMessage": "¡Te recomendamos encarecidamente solucionarlo cuanto antes!", + "moduleMigration.insecureChunkExist.message": "Algunos chunks no se almacenan de forma segura y no están cifrados en las bases de datos.\n**Reconstruye la base de datos para solucionarlo**.\n\nSi tu base de datos remota no está configurada con SSL o usa credenciales poco seguras, **corres el riesgo de exponer datos sensibles**.\n\nNota: actualiza Self-hosted LiveSync a la v0.25.6 o superior en todos tus dispositivos y haz una copia de seguridad fiable de tu vault.\nNota 2: reconstruir todo y obtener los datos consume algo de tiempo y de tráfico; hazlo en horas de poco uso y con una conexión de red estable.\n", + "moduleMigration.insecureChunkExist.title": "¡Se han encontrado chunks no seguros!", "moduleMigration.logBulkSendCorrupted": "El envío de fragmentos en bloque se ha habilitado, sin embargo, esta función se ha corrompido. Disculpe las molestias. Deshabilitado automáticamente.", "moduleMigration.logFetchRemoteTweakFailed": "Error al obtener los valores de ajuste remoto", "moduleMigration.logLocalDatabaseNotReady": "¡Algo salió mal! La base de datos local no está lista", @@ -427,6 +513,14 @@ "moduleMigration.optionKeepPreviousBehaviour": "Mantener comportamiento anterior", "moduleMigration.optionManualSetup": "Configurarlo todo manualmente", "moduleMigration.optionNoAskAgain": "No, por favor pregúntame de nuevo", + "moduleMigration.optionNoSetupUri": "No, no tengo", + "moduleMigration.optionRemindNextLaunch": "Recordármelo en el próximo inicio", + "moduleMigration.optionSetupViaP2P": "Usar %{short_p2p_sync} para configurarlo", + "moduleMigration.optionSetupWizard": "Llévame al asistente de configuración", + "moduleMigration.optionYesFetchAgain": "Sí, obtener de nuevo", + "moduleMigration.titleCaseSensitivity": "Distinción de mayúsculas y minúsculas", + "moduleMigration.titleRecommendSetupUri": "Recomendación de usar un Setup URI", + "moduleMigration.titleWelcome": "Bienvenido a Self-hosted LiveSync", "moduleObsidianMenu.replicate": "Replicar", "More actions": "Más acciones", "Mostly Complete: Decision Required": "Casi terminado: se requiere una decisión", @@ -438,12 +532,15 @@ "New Remote": "Nuevo remoto", "Newer (${diff})": "Más nuevo (${diff})", "No checks have been performed yet.": "Todavía no se ha realizado ninguna comprobación.", + "No connected device information found. Cancelling Garbage Collection.": "No se ha encontrado información de dispositivos conectados. Se cancela la recolección de basura.", "No Connection": "Sin conexión", "No devices available. Waiting for other devices to connect...": "No hay dispositivos disponibles. Esperando a que se conecten otros dispositivos...", "No Items.": "Sin elementos.", "No limit configured": "Sin límite configurado", "NO PREVIEW": "SIN VISTA PREVIA", "No, please take me back": "No, volver atrás", + "Node ID": "ID de nodo", + "Node Information Missing": "Falta la información del nodo", "Non-Synchronising files": "Archivos no sincronizados", "Normal Files": "Archivos normales", "Not all messages have been translated. And, please revert to \"Default\" when reporting errors.": "No todos los mensajes están traducidos. Por favor, vuelva a \"Predeterminado\" al reportar errores.", @@ -459,6 +556,7 @@ "Number of changes to sync at a time. Defaults to 50. Minimum is 2.": "Número de cambios a sincronizar simultáneamente. Default 50, mínimo 2", "Obfuscate Properties": "Ofuscar propiedades", "Obfuscating properties (e.g., path of file, size, creation and modification dates) adds an additional layer of security by making it harder to identify the structure and names of your files and folders on the remote server. This helps protect your privacy and makes it more difficult for unauthorized users to infer information about your data.": "Ofuscar las propiedades (p. ej., la ruta del archivo, el tamaño y las fechas de creación y modificación) añade una capa extra de seguridad, ya que dificulta identificar la estructura y los nombres de tus archivos y carpetas en el servidor remoto. Esto ayuda a proteger tu privacidad y hace más difícil que usuarios no autorizados deduzcan información sobre tus datos.", + "Obsidian version": "Versión de Obsidian", "obsidianLiveSyncSettingTab.btnApply": "Aplicar", "obsidianLiveSyncSettingTab.btnCheck": "Verificar", "obsidianLiveSyncSettingTab.btnCopy": "Copiar", @@ -487,6 +585,7 @@ "obsidianLiveSyncSettingTab.errCorsNotAllowingCredentials": "CORS no permite credenciales", "obsidianLiveSyncSettingTab.errCorsOrigins": "❗ cors.origins es incorrecto", "obsidianLiveSyncSettingTab.errEnableCors": "❗ httpd.enable_cors es incorrecto", + "obsidianLiveSyncSettingTab.errEnableCorsChttpd": "❗ chttpd.enable_cors es incorrecto", "obsidianLiveSyncSettingTab.errMaxDocumentSize": "❗ couchdb.max_document_size es bajo)", "obsidianLiveSyncSettingTab.errMaxRequestSize": "❗ chttpd.max_http_request_size es bajo)", "obsidianLiveSyncSettingTab.errMissingWwwAuth": "❗ httpd.WWW-Authenticate falta", @@ -531,6 +630,7 @@ "obsidianLiveSyncSettingTab.msgDiscardConfirmation": "¿Realmente deseas descartar las configuraciones y bases de datos existentes?", "obsidianLiveSyncSettingTab.msgDone": "--Hecho--", "obsidianLiveSyncSettingTab.msgEnableCors": "Configurar httpd.enable_cors", + "obsidianLiveSyncSettingTab.msgEnableCorsChttpd": "Establecer chttpd.enable_cors", "obsidianLiveSyncSettingTab.msgEnableEncryptionRecommendation": "Recomendamos habilitar el cifrado de extremo a extremo y la obfuscación de ruta. ¿Estás seguro de querer continuar sin cifrado?", "obsidianLiveSyncSettingTab.msgFetchConfigFromRemote": "¿Quieres obtener la configuración del servidor remoto?", "obsidianLiveSyncSettingTab.msgGenerateSetupURI": "¡Todo listo! ¿Quieres generar un URI de configuración para configurar otros dispositivos?", @@ -571,6 +671,7 @@ "obsidianLiveSyncSettingTab.okCorsOriginMatched": "✔ Origen de CORS correcto", "obsidianLiveSyncSettingTab.okCorsOrigins": "✔ cors.origins está correcto.", "obsidianLiveSyncSettingTab.okEnableCors": "✔ httpd.enable_cors está correcto.", + "obsidianLiveSyncSettingTab.okEnableCorsChttpd": "✔ chttpd.enable_cors es correcto.", "obsidianLiveSyncSettingTab.okMaxDocumentSize": "✔ couchdb.max_document_size está correcto.", "obsidianLiveSyncSettingTab.okMaxRequestSize": "✔ chttpd.max_http_request_size está correcto.", "obsidianLiveSyncSettingTab.okRequireValidUser": "✔ chttpd.require_valid_user está correcto.", @@ -595,6 +696,8 @@ "obsidianLiveSyncSettingTab.panelPrivacyEncryption": "Privacidad y Cifrado", "obsidianLiveSyncSettingTab.panelRemoteConfiguration": "Configuración remota", "obsidianLiveSyncSettingTab.panelSetup": "Configuración", + "obsidianLiveSyncSettingTab.serverVersion": "Información del servidor: ${info}", + "obsidianLiveSyncSettingTab.titleActiveRemoteServer": "Servidor remoto activo", "obsidianLiveSyncSettingTab.titleAppearance": "Apariencia", "obsidianLiveSyncSettingTab.titleConflictResolution": "Resolución de conflictos", "obsidianLiveSyncSettingTab.titleCongratulations": "¡Felicidades!", @@ -647,6 +750,24 @@ "Overwrite Server Data with This Device's Files": "Sobrescribir los datos del servidor con los archivos de este dispositivo", "P2P Configuration": "Configuración P2P", "P2P Status": "Estado P2P", + "P2P.AskPassphraseForDecrypt": "El par remoto ha compartido la configuración. Introduce la frase de contraseña para descifrarla.", + "P2P.AskPassphraseForShare": "El par remoto ha solicitado la configuración de este dispositivo. Introduce la frase de contraseña para compartirla. Puedes ignorar la solicitud cancelando este diálogo.", + "P2P.DisabledButNeed": "%{title_p2p_sync} está desactivada. ¿Seguro que quieres activarla?", + "P2P.FailedToOpen": "No se pudo abrir la conexión P2P con el servidor de señalización.", + "P2P.NoAutoSyncPeers": "No se han encontrado pares de sincronización automática. Configúralos en el panel de %{long_p2p_sync}.", + "P2P.NoKnownPeers": "No se ha detectado ningún par; esperando a que se conecten otros...", + "P2P.Note.description": " Este replicador permite sincronizar el vault con otros dispositivos\nmediante una conexión punto a punto. Así se puede sincronizar con nuestros otros dispositivos sin usar un servicio en la nube.\nEl replicador se basa en Trystero. Usa además un servidor de señalización para establecer la conexión entre dispositivos. Ese servidor sirve para intercambiar la información de conexión y no conoce (ni debería almacenar) ninguno de nuestros datos.\n\nCualquiera puede alojar el servidor de señalización: es simplemente un relé Nostr. Por comodidad y para poder comprobar el comportamiento del replicador, vrtmrz aloja una instancia. Puedes usar ese servidor experimental o cualquier otro.\n\nPor cierto, aunque el servidor de señalización no almacene nuestros datos, sí puede ver la información de conexión de algunos de nuestros dispositivos. Tenlo en cuenta y ten precaución al usar un servidor de terceros.", + "P2P.Note.important_note": "Replicador punto a punto.", + "P2P.Note.important_note_sub": "Esta función sigue siendo muy experimental. Asegúrate de tener una copia de seguridad de tus datos antes de usarla. Y nos alegraría mucho que quisieras contribuir a su desarrollo.", + "P2P.Note.Summary": "¿Qué es esta función? (incluye notas importantes; léelas al menos una vez)", + "P2P.NotEnabled": "%{title_p2p_sync} no está activada. No se puede abrir una conexión nueva.", + "P2P.P2PReplication": "Replicación %{P2P}", + "P2P.PaneTitle": "%{long_p2p_sync}", + "P2P.ReplicatorInstanceMissing": "No se encuentra el replicador de sincronización P2P; puede que no esté configurado o activado.", + "P2P.SeemsOffline": "El par ${name} parece estar desconectado; se omite.", + "P2P.SyncAlreadyRunning": "La sincronización P2P ya está en marcha.", + "P2P.SyncCompleted": "Sincronización P2P completada.", + "P2P.SyncStartedWith": "Se ha iniciado la sincronización P2P con ${name}.", "paneMaintenance.markDeviceResolvedAfterBackup": "Marcar el dispositivo como resuelto después de hacer una copia de seguridad", "paneMaintenance.remoteLockedAndDeviceNotAccepted": "La base de datos remota está bloqueada y este dispositivo aún no ha sido aceptado.", "paneMaintenance.remoteLockedResolvedDevice": "La base de datos remota está bloqueada, pero este dispositivo ya fue aceptado.", @@ -675,14 +796,18 @@ "Periodic Sync interval": "Intervalo de sincronización periódica", "PERMANENT": "PERMANENTE", "Pick a file to resolve conflict": "Elegir un archivo para resolver el conflicto", + "Pick a file to show history": "Elige un archivo para ver su historial", "Please be aware that the End-to-End Encryption passphrase is not validated until the synchronisation process actually commences. This is a security measure designed to protect your data.": "Ten en cuenta que la frase de contraseña del cifrado de extremo a extremo no se valida hasta que comienza realmente la sincronización. Es una medida de seguridad para proteger tus datos.", "Please configure your end-to-end encryption settings.": "Configura los ajustes de cifrado de extremo a extremo.", + "Please disable 'Read chunks online' in settings to use Garbage Collection.": "Desactiva «Leer chunks en línea» en los ajustes para poder usar la recolección de basura.", + "Please enable 'Compute revisions for chunks' in settings to use Garbage Collection.": "Activa «Calcular revisiones para los chunks» en los ajustes para poder usar la recolección de basura.", "Please enter the CouchDB server information below.": "Introduce a continuación los datos del servidor CouchDB.", "Please enter the details required to connect to your S3/MinIO/R2 compatible object storage service.": "Introduce los datos necesarios para conectarte a tu servicio de almacenamiento de objetos compatible con S3/MinIO/R2.", "Please enter the Peer-to-Peer Synchronisation information below.": "Introduce a continuación los datos de la sincronización punto a punto.", "Please enter the Setup URI that was generated during server installation or on another device, along with the vault passphrase.": "Introduce el Setup URI generado durante la instalación del servidor o en otro dispositivo, junto con la frase de contraseña del vault.", "Please follow the steps below to import settings from your existing device.": "Sigue los pasos siguientes para importar los ajustes desde tu dispositivo actual.", "PLEASE NOTE": "TEN EN CUENTA", + "Please select 'Cancel' explicitly to cancel this operation.": "Selecciona «Cancelar» de forma explícita para cancelar esta operación.", "Please select a method to import the settings from another device.": "Seleccione un método para importar la configuración desde otro dispositivo。", "Please select an active P2P remote configuration to change P2P sync targets.": "Selecciona una configuración remota P2P activa para cambiar los destinos de sincronización P2P.", "Please select an option to proceed": "Seleccione una opción para continuar", @@ -693,20 +818,38 @@ "Please set device name to identify this device. This name should be unique among your devices. While not configured, we cannot enable this feature.": "Define un nombre para identificar este dispositivo. Debe ser único entre tus dispositivos. Mientras no esté configurado, no podremos habilitar esta función.", "Please set this device name": "Define el nombre de este dispositivo", "Please understand that this is intended behaviour.": "Comprende que este es el comportamiento previsto.", + "Plug-in version": "Versión del complemento", "Plugins": "Complementos", + "Prepare the 'report' to create an issue": "Preparar el «informe» para abrir una incidencia", "Presets": "Preconfiguraciones", "Prevent fetching configuration from server": "Impedir la obtención de la configuración desde el servidor", "Proceed": "Continuar", + "Proceed Garbage Collection": "Continuar con la recolección de basura", "Proceed to the next step.": "Continuar al paso siguiente.", "Proceed with Setup URI": "Continuar con el URI de configuración", + "Proceeding with Garbage Collection, ignoring missing nodes.": "Se continúa con la recolección de basura, ignorando los nodos ausentes.", + "Proceeding with Garbage Collection.": "Se continúa con la recolección de basura.", "Process small files in the foreground": "Procesar archivos pequeños en primer plano", + "Progress": "Progreso", + "Property Encryption": "Cifrado de propiedades", "PureJS fallback (Fast, W/O WebAssembly)": "Alternativa PureJS (rápida, sin WebAssembly)", "Purge all download/upload cache.": "Purga toda la caché de descarga y carga.", "Purge all journal counter": "Purgar todos los contadores del diario", "Rebuild local and remote database with local files.": "Reconstruye la base de datos local y remota usando los archivos locales.", "Rebuilding Operations (Remote Only)": "Operaciones de reconstrucción (solo remoto)", + "Recovery and Repair": "Recuperación y reparación", "Recreate all": "Recrear todo", "Recreate missing chunks for all files": "Recrear fragmentos faltantes para todos los archivos", + "RedFlag.Fetch.Method.Desc": "¿Cómo quieres obtener los datos?\n- %{RedFlag.Fetch.Method.FetchSafer}.\n **Poco tráfico**, **mucha CPU**, **riesgo bajo**\n Recomendado si...\n - Los archivos podrían ser inconsistentes\n - No hay demasiados archivos\n- %{RedFlag.Fetch.Method.FetchSmoother}.\n **Poco tráfico**, **CPU moderada**, **riesgo bajo o moderado**\n Recomendado si...\n - Los archivos son probablemente consistentes\n - Tienes muchos archivos\n- %{RedFlag.Fetch.Method.FetchTraditional}.\n **Mucho tráfico**, **poca CPU**, **riesgo bajo o moderado**\n\n>[!INFO]- Detalles\n> ## %{RedFlag.Fetch.Method.FetchSafer}.\n> **Poco tráfico**, **mucha CPU**, **riesgo bajo**\n> Esta opción crea primero una base de datos local a partir de los archivos locales existentes antes de obtener los datos del remoto.\n> Si un archivo existe tanto en local como en remoto, solo se transferirán las diferencias.\n> Sin embargo, los archivos presentes en ambos sitios se tratarán inicialmente como archivos en conflicto. Se resolverán automáticamente si en realidad no lo están, pero el proceso puede tardar.\n> En general es el método más seguro y el que menos riesgo de pérdida de datos conlleva.\n> ## %{RedFlag.Fetch.Method.FetchSmoother}.\n> **Poco tráfico**, **CPU moderada**, **riesgo bajo o moderado** (según la operación)\n> Esta opción crea primero los chunks de los archivos locales para la base de datos y después obtiene los datos. Así solo se transfieren los chunks que faltan en local. Aun así, todos los metadatos se toman del remoto.\n> Al iniciar, los archivos locales se comparan con esos metadatos. El contenido considerado más reciente sobrescribirá al más antiguo (según la fecha de modificación) y el resultado se sincroniza de vuelta a la base de datos remota.\n> Es seguro si los archivos locales son realmente los de fecha más reciente, pero puede dar problemas si un archivo tiene una fecha más nueva y un contenido más antiguo (como el `welcome.md` inicial).\n> Usa menos CPU y es más rápido que «%{RedFlag.Fetch.Method.FetchSafer}», pero puede provocar pérdida de datos si no se usa con cuidado.\n> ## %{RedFlag.Fetch.Method.FetchTraditional}.\n> **Mucho tráfico**, **poca CPU**, **riesgo bajo o moderado** (según la operación)\n> Se obtiene todo del remoto.\n> Similar a %{RedFlag.Fetch.Method.FetchSmoother}, pero todos los chunks se descargan del remoto.\n> Es la forma más tradicional de obtener los datos y normalmente la que más tráfico y tiempo consume. Conlleva un riesgo de sobrescribir archivos remotos parecido al de «%{RedFlag.Fetch.Method.FetchSmoother}».\n> Aun así, suele considerarse el método más estable, por ser el más antiguo y directo.", + "RedFlag.Fetch.Method.FetchSafer": "Crear una base de datos local antes de obtener los datos", + "RedFlag.Fetch.Method.FetchSmoother": "Crear los chunks de los archivos locales antes de obtener los datos", + "RedFlag.Fetch.Method.FetchTraditional": "Obtener todo del remoto", + "RedFlag.Fetch.Method.Title": "¿Cómo quieres obtener los datos?", + "RedFlag.FetchRemoteConfig.Buttons.Cancel": "No, usar los ajustes locales", + "RedFlag.FetchRemoteConfig.Buttons.Fetch": "Sí, obtener y aplicar los ajustes remotos", + "RedFlag.FetchRemoteConfig.Message": "¿Quieres obtener y aplicar en este dispositivo los ajustes de preferencias guardados en el remoto?", + "RedFlag.FetchRemoteConfig.Title": "Obtener la configuración remota", + "Reduces storage space by discarding all non-latest revisions. This requires the same amount of free space on the remote server and the local client.": "Reduce el espacio de almacenamiento descartando todas las revisiones que no sean la última. Requiere la misma cantidad de espacio libre en el servidor remoto y en el cliente local.", "Reducing the frequency with which on-disk changes are reflected into the DB": "Reducir frecuencia de actualizaciones de disco a BD", "Refresh": "Actualizar", "Region": "Región", @@ -724,8 +867,23 @@ "Replicate now": "Replicar ahora", "Replicating": "Replicando", "Replicating...": "Replicando...", + "Replicator.Dialogue.Locked.Action.Dismiss": "Cancelar para volver a confirmarlo", + "Replicator.Dialogue.Locked.Action.Fetch": "Restablecer la sincronización en este dispositivo", + "Replicator.Dialogue.Locked.Action.Unlock": "Desbloquear la base de datos remota", + "Replicator.Dialogue.Locked.Message": "La base de datos remota está bloqueada porque se ha reconstruido en uno de los dispositivos.\nPor eso se pide a este dispositivo que no se conecte, para evitar corromper la base de datos.\n\nHay tres opciones posibles:\n\n- %{Replicator.Dialogue.Locked.Action.Fetch}\n La más recomendable y fiable. Descarta la base de datos local y vuelve a tomar toda la información de sincronización del remoto. En la mayoría de los casos se puede hacer sin riesgo, aunque lleva algo de tiempo y conviene hacerlo con una red estable.\n- %{Replicator.Dialogue.Locked.Action.Unlock}\n Solo se puede usar si ya estamos sincronizados de forma fiable por otros métodos de replicación. Esto no significa simplemente tener los mismos archivos. Si no estás seguro, evítala.\n- %{Replicator.Dialogue.Locked.Action.Dismiss}\n Cancela la operación. Se volverá a preguntar en la próxima solicitud.\n", + "Replicator.Dialogue.Locked.Message.Fetch": "Se ha programado la obtención completa. El complemento se reiniciará para llevarla a cabo.", + "Replicator.Dialogue.Locked.Message.Unlocked": "La base de datos remota se ha desbloqueado. Vuelve a intentar la operación.", + "Replicator.Dialogue.Locked.Title": "Bloqueada", + "Replicator.Message.Cleaned": "Se está limpiando la base de datos; la replicación se ha cancelado", + "Replicator.Message.InitialiseFatalError": "No hay ningún replicador disponible; se trata de un error grave.", + "Replicator.Message.Pending": "Hay eventos de archivo pendientes. La replicación se ha cancelado.", + "Replicator.Message.SomeModuleFailed": "La replicación se ha cancelado por el fallo de algún módulo", + "Replicator.Message.VersionUpFlash": "Se ha detectado una actualización. Abre el diálogo de ajustes y consulta el registro de cambios. La replicación se ha cancelado.", "Requires restart of Obsidian": "Requiere reiniciar Obsidian", "Requires restart of Obsidian.": "Requiere reiniciar Obsidian", + "Rerun Onboarding Wizard": "Volver a ejecutar el asistente de configuración inicial", + "Rerun the onboarding wizard to set up Self-hosted LiveSync again.": "Vuelve a ejecutar el asistente de configuración inicial para configurar Self-hosted LiveSync de nuevo.", + "Rerun Wizard": "Volver a ejecutar el asistente", "Resend": "Reenviar", "Resend all chunks to the remote.": "Reenvía todos los chunks al remoto.", "Reset": "Restablecer", @@ -734,10 +892,12 @@ "Reset and Resume Synchronisation": "Restablecer y reanudar la sincronización", "Reset journal received history": "Restablecer historial de recepción del diario", "Reset journal sent history": "Restablecer historial de envío del diario", + "Reset notification threshold and check the remote database usage": "Restablecer el umbral de aviso y comprobar el uso de la base de datos remota", "Reset received": "Restablecer recepción", "Reset sent history": "Restablecer historial de envío", "Reset Synchronisation information": "Restablecer información de sincronización", "Reset Synchronisation on This Device": "Restablecer sincronización en este dispositivo", + "Reset the remote storage size threshold and check the remote storage size again.": "Restablece el umbral de tamaño del almacenamiento remoto y vuelve a comprobar su tamaño.", "Resolve All": "Resolver todo", "Resolve all conflicted files": "Resolver todos los archivos en conflicto", "Resolve All conflicted files by the newer one": "Resolver todos los archivos en conflicto con la versión más reciente", @@ -745,12 +905,14 @@ "Restart and Fetch Data": "Reiniciar y obtener los datos", "Restart and Initialise Server": "Reiniciar e inicializar el servidor", "Restart Now": "Reiniciar ahora", + "Restarting Obsidian is strongly recommended. Until restart, some changes may not take effect, and display may be inconsistent. Are you sure to restart now?": "Se recomienda encarecidamente reiniciar Obsidian. Hasta que lo hagas, puede que algunos cambios no surtan efecto y que la interfaz se muestre de forma inconsistente. ¿Seguro que quieres reiniciar ahora?", "Restore or reconstruct local database from remote.": "Restaura o reconstruye la base de datos local desde el remoto.", "Rev": "Rev", "Revert changes": "Revertir cambios", "Revoke": "Revocar", "Room ID": "ID de sala", "Room ID suffix:": "Sufijo del ID de sala:", + "Run Doctor": "Ejecutar el Doctor", "S3/MinIO/R2 Configuration": "Configuración de S3/MinIO/R2", "S3/MinIO/R2 Object Storage": "Almacenamiento de objetos S3/MinIO/R2", "Same": "Igual", @@ -765,11 +927,13 @@ "Scan customization before replicating.": "Escanear personalización antes de replicar", "Scan customization every 1 minute.": "Escanear personalización cada 1 minuto", "Scan customization periodically": "Escanear personalización periódicamente", + "Scan for Broken files": "Buscar archivos dañados", "Scan for hidden files before replication": "Escanear archivos ocultos antes de replicar", "Scan hidden files periodically": "Escanear archivos ocultos periódicamente", "Scan QR Code": "Escanear código QR", "Scan the QR code displayed on an active device using this device's camera.": "Escanee con la cámara de este dispositivo el código QR mostrado en un dispositivo activo。", "Schedule and Restart": "Programar y reiniciar", + "Scram Switches": "Interruptores de emergencia", "Scram!": "Medidas de emergencia", "Seconds, 0 to disable": "Segundos, 0 para desactivar", "Seconds. Saving to the local database will be delayed until this value after we stop typing or saving.": "Segundos. Guardado en BD local se retrasará hasta este valor tras dejar de escribir/guardar", @@ -790,21 +954,44 @@ "SESSION": "SESIÓN", "Setting.GenerateKeyPair.Desc": "Hemos generado un par de claves.\n\nNota: Este par de claves no volverá a mostrarse. Guárdalo en un lugar seguro. Si lo pierdes, tendrás que generar uno nuevo.\nNota 2: La clave pública está en formato spki y la clave privada en formato pkcs8. Para mayor comodidad, los saltos de línea de la clave pública se convierten en `\\n`.\nNota 3: La clave pública debe configurarse en la base de datos remota y la clave privada en los dispositivos locales.\n\n>[!SOLO PARA TUS OJOS]-\n>
\n>\n> ### Clave pública\n> ```\n${public_key}\n> ```\n>\n> ### Clave privada\n> ```\n${private_key}\n> ```\n>\n>
\n\n>[!Ambas para copiar]-\n>\n>
\n>\n> ```\n${public_key}\n${private_key}\n> ```\n>\n>
", "Setting.GenerateKeyPair.Title": "¡Se ha generado un nuevo par de claves!", + "Setting.TroubleShooting": "Resolución de problemas", + "Setting.TroubleShooting.Doctor": "Doctor de ajustes", + "Setting.TroubleShooting.Doctor.Desc": "Detecta ajustes no óptimos. (Igual que durante la migración)", + "Setting.TroubleShooting.ScanBrokenFiles": "Buscar archivos dañados", + "Setting.TroubleShooting.ScanBrokenFiles.Desc": "Busca archivos que no se hayan guardado correctamente en la base de datos.", + "SettingTab.Message.AskRebuild": "Tus cambios requieren obtener los datos de la base de datos remota. ¿Quieres continuar?", "Setup Complete: Preparing to Fetch Synchronisation Data": "Configuración completada: preparando la obtención de los datos de sincronización", "Setup Complete: Preparing to Initialise Server": "Configuración completada: preparando la inicialización del servidor", + "Setup URI dialog cancelled.": "Se ha cancelado el diálogo del Setup URI.", "Setup-URI": "Setup-URI", "Setup.> [!INFO]- The connected devices have been detected as follows:\n${devices}": "> [!INFO]- Se detectaron los siguientes dispositivos conectados:\n${devices}", "Setup.All devices have the same progress value (${progress}). Your devices seem to be synchronised. And be able to proceed with Garbage Collection.": "Todos los dispositivos tienen el mismo valor de progreso (${progress}). Parece que tus dispositivos están sincronizados y se puede continuar con la recolección de basura.", + "Setup.Apply.Buttons.ApplyAndFetch": "Aplicar y obtener", + "Setup.Apply.Buttons.ApplyAndMerge": "Aplicar y combinar", + "Setup.Apply.Buttons.ApplyAndRebuild": "Aplicar y reconstruir", + "Setup.Apply.Buttons.Cancel": "Descartar y cancelar", + "Setup.Apply.Buttons.OnlyApply": "Solo aplicar", + "Setup.Apply.Message": "La nueva configuración está lista. Vamos a aplicarla.\nHay varias formas de hacerlo:\n\n- Aplicar y obtener\n Configura este dispositivo como cliente nuevo. Tras aplicarla, sincroniza desde el servidor remoto.\n- Aplicar y combinar\n Para un dispositivo que ya tiene los archivos. Procesa los archivos locales y transfiere las diferencias. Pueden surgir conflictos.\n- Aplicar y reconstruir\n Reconstruye el remoto a partir de los archivos locales. Se hace normalmente si el servidor se ha corrompido o si se quiere empezar de cero.\n Los demás dispositivos quedarán bloqueados y tendrán que volver a obtener los datos.\n- Solo aplicar\n Solo aplica la configuración. Pueden surgir conflictos si hace falta reconstruir.", + "Setup.Apply.Title": "Aplicar la nueva configuración de ${method}", + "Setup.Apply.WarningRebuildRecommended": "NOTA: tras ajustar la configuración se ha determinado que hace falta reconstruir; no se recomienda «solo importar».", "Setup.Cancel Garbage Collection": "Cancelar la recolección de basura", "Setup.Compaction in progress on remote database...": "La compactación está en curso en la base de datos remota...", "Setup.Compaction on remote database completed successfully.": "La compactación en la base de datos remota se completó correctamente.", "Setup.Compaction on remote database failed.": "La compactación en la base de datos remota falló.", "Setup.Compaction on remote database timed out.": "La compactación en la base de datos remota agotó el tiempo de espera.", "Setup.Device": "Dispositivo", + "Setup.Doctor.Buttons.No": "No, usar los ajustes del URI tal cual", + "Setup.Doctor.Buttons.Yes": "Sí, consultar al doctor", + "Setup.Doctor.Message": "Self-hosted LiveSync tiene ya una historia larga y algunos ajustes recomendados han cambiado.\n\nLa configuración inicial es un momento muy bueno para revisarlos.\n\n¿Quieres ejecutar el Doctor para comprobar si los ajustes importados son los óptimos respecto al estado actual?", + "Setup.Doctor.Title": "¿Quieres consultar al doctor?", "Setup.Failed to connect to remote for compaction.": "No se pudo conectar a la base de datos remota para la compactación.", "Setup.Failed to connect to remote for compaction. ${reason}": "No se pudo conectar a la base de datos remota para la compactación. ${reason}", "Setup.Failed to start one-shot replication before Garbage Collection. Garbage Collection Cancelled.": "No se pudo iniciar la replicación de una sola vez antes de la recolección de basura. La recolección de basura se canceló.", "Setup.Failed to start replication after Garbage Collection.": "No se pudo iniciar la replicación después de la recolección de basura.", + "Setup.FetchRemoteConf.Buttons.Fetch": "Sí, obtener la configuración", + "Setup.FetchRemoteConf.Buttons.Skip": "No, usar los ajustes del URI", + "Setup.FetchRemoteConf.Message": "Si ya hemos sincronizado alguna vez con otro dispositivo, la base de datos remota guarda los valores de configuración adecuados para los dispositivos sincronizados. El complemento querría recuperarlos para lograr una configuración más sólida.\n\nAntes hay que asegurar una cosa: ¿estamos en una situación en la que se puede acceder a la red de forma segura y recuperar los ajustes?\n\nNota: normalmente puedes hacerlo sin riesgo si tu base de datos remota se sirve con un certificado SSL y tu red no está comprometida.", + "Setup.FetchRemoteConf.Title": "¿Obtener la configuración de la base de datos remota?", "Setup.Garbage Collection cancelled by user.": "El usuario canceló la recolección de basura.", "Setup.Garbage Collection completed. Deleted chunks: ${deletedChunks} / ${totalChunks}. Time taken: ${seconds} seconds.": "Recolección de basura completada. Chunks eliminados: ${deletedChunks} / ${totalChunks}. Tiempo empleado: ${seconds} segundos.", "Setup.Garbage Collection Confirmation": "Confirmación de recolección de basura", @@ -828,6 +1015,7 @@ "Setup.Proceeding with Garbage Collection, ignoring missing nodes.": "Continuando con la recolección de basura e ignorando los nodos faltantes.", "Setup.Proceeding with Garbage Collection.": "Continuando con la recolección de basura.", "Setup.Progress": "Progreso", + "Setup.QRCode": "Hemos generado un código QR para transferir los ajustes. Escanéalo con tu móvil u otro dispositivo.\nNota: el código QR no está cifrado, así que ten cuidado al abrirlo.\n\n>[!SOLO PARA TUS OJOS]-\n>
${qr_image}
", "Setup.RemoteE2EE.AdvancedTitle": "Avanzado", "Setup.RemoteE2EE.AlgorithmWarning": "Cambiar el algoritmo de cifrado impedirá el acceso a cualquier dato cifrado anteriormente con otro algoritmo. Asegúrate de que todos tus dispositivos estén configurados para usar el mismo algoritmo y así mantener el acceso a tus datos.", "Setup.RemoteE2EE.ButtonCancel": "Cancelar", @@ -854,6 +1042,8 @@ "Setup.ScanQRCode.Step4": "En este dispositivo, cambia a la cámara o usa un escáner QR para escanear el código mostrado.", "Setup.ScanQRCode.Title": "Escanear código QR", "Setup.Setup URI dialog cancelled.": "Se canceló el diálogo de Setup URI.", + "Setup.ShowQRCode": "Mostrar el código QR", + "Setup.ShowQRCode.Desc": "Muestra un código QR para transferir los ajustes.", "Setup.Some devices have differing progress values (max: ${maxProgress}, min: ${minProgress}).\nThis may indicate that some devices have not completed synchronisation, which could lead to conflicts. Strongly recommend confirming that all devices are synchronised before proceeding.": "Algunos dispositivos tienen valores de progreso diferentes (máx.: ${maxProgress}, mín.: ${minProgress}).\nEsto puede indicar que algunos dispositivos no han completado la sincronización, lo que podría causar conflictos. Se recomienda encarecidamente confirmar que todos los dispositivos estén sincronizados antes de continuar.", "Setup.The following accepted nodes are missing its node information:\n- ${missingNodes}\n\nThis indicates that they have not been connected for some time or have been left on an older version.\nIt is preferable to update all devices if possible. If you have any devices that are no longer in use, you can clear all accepted nodes by locking the remote once.": "Los siguientes nodos aceptados no tienen información del nodo:\n- ${missingNodes}\n\nEsto indica que no se han conectado desde hace algún tiempo o que se han quedado en una versión anterior.\nSi es posible, es preferible actualizar todos los dispositivos. Si tienes dispositivos que ya no se usan, puedes borrar todos los nodos aceptados bloqueando el remoto una vez.", "Setup.titleCaseSensitivity": "Sensibilidad a mayúsculas", @@ -876,6 +1066,8 @@ "Should we prompt you about conflicting files when a file is opened?": "¿Notificar sobre conflictos al abrir archivo?", "Should we prompt you for every single merge, even if we can safely merge automatcially?": "¿Preguntar en cada fusión aunque sea automática?", "Show full banner": "Mostrar banner completo", + "Show history": "Mostrar el historial", + "Show icon only": "Mostrar solo el icono", "Show only notifications": "Mostrar solo notificaciones", "Show status as icons only": "Mostrar estado solo con íconos", "Show status icon instead of file warnings banner": "Mostrar icono de estado en lugar del banner de advertencia de archivos", @@ -886,6 +1078,7 @@ "Signalling Status": "Estado de la señalización", "Skip and close": "Omitir y cerrar", "Snippets": "Fragmentos", + "Some devices have differing progress values (max: ${maxProgress}, min: ${minProgress}).\nThis may indicate that some devices have not completed synchronisation, which could lead to conflicts. Strongly recommend confirming that all devices are synchronised before proceeding.": "Algunos dispositivos tienen valores de progreso distintos (máx.: ${maxProgress}, mín.: ${minProgress}).\nEsto puede indicar que algunos no han terminado de sincronizar, lo que podría provocar conflictos. Se recomienda encarecidamente confirmar que todos los dispositivos están sincronizados antes de continuar.", "Start Broadcasting": "Iniciar difusión", "Start change-broadcasting on Connect": "Iniciar la difusión de cambios al conectar", "Start Sync & Close": "Iniciar sincronización y cerrar", @@ -896,6 +1089,7 @@ "Stop Broadcasting": "Detener difusión", "Stop reflecting database changes to storage files.": "Dejar de reflejar cambios de BD en archivos", "Stop watching for file changes.": "Dejar de monitorear cambios en archivos", + "Storage -> Database": "Almacenamiento -> Base de datos", "Strongly Recommended": "Muy recomendado", "Suppress notification of hidden files change": "Suprimir notificaciones de cambios en archivos ocultos", "Suspend database reflecting": "Suspender reflejo de base de datos", @@ -921,13 +1115,16 @@ "The connection to the server has been configured successfully. As the next step,": "La conexión con el servidor se ha configurado correctamente. Como paso siguiente,", "The delay for consecutive on-demand fetches": "Retraso entre obtenciones consecutivas", "The files in this Vault are almost identical to the server's.": "Los archivos de este Vault son casi idénticos a los del servidor.", + "The following accepted nodes are missing its node information:\n- ${missingNodes}\n\nThis indicates that they have not been connected for some time or have been left on an older version.\nIt is preferable to update all devices if possible. If you have any devices that are no longer in use, you can clear all accepted nodes by locking the remote once.": "A los siguientes nodos aceptados les falta su información de nodo:\n- ${missingNodes}\n\nEsto indica que llevan tiempo sin conectarse o que se han quedado en una versión antigua.\nSi es posible, conviene actualizar todos los dispositivos. Si tienes dispositivos que ya no usas, puedes borrar todos los nodos aceptados bloqueando el remoto una vez.", "The Group ID and passphrase are used to identify your group of devices. Make sure to use the same Group ID and passphrase on all devices you want to synchronise.": "El ID de grupo y la frase de contraseña identifican tu grupo de dispositivos. Usa el mismo ID de grupo y la misma frase de contraseña en todos los dispositivos que quieras sincronizar.", "The Hash algorithm for chunk IDs": "Algoritmo hash para IDs de chunks", + "The IndexedDB adapter often offers superior performance in certain scenarios, but it has been found to cause memory leaks when used with LiveSync mode. When using LiveSync mode, please use IDB adapter instead.": "El adaptador IndexedDB suele ofrecer mejor rendimiento en ciertos casos, pero se ha comprobado que provoca fugas de memoria con el modo LiveSync. Si usas el modo LiveSync, utiliza en su lugar el adaptador IDB.", "the latest synchronisation data will be downloaded from the server to this device.": "se descargarán a este dispositivo los datos de sincronización más recientes del servidor.", "the local database, that is to say the synchronisation information, must be reconstituted.": "hay que reconstruir la base de datos local, es decir, la información de sincronización.", "The maximum duration for which chunks can be incubated within the document. Chunks exceeding this period will graduate to independent chunks.": "Duración máxima para incubar chunks. Excedentes se independizan", "The maximum number of chunks that can be incubated within the document. Chunks exceeding this number will immediately graduate to independent chunks.": "Número máximo de chunks que pueden incubarse en el documento. Excedentes se independizan", "The maximum total size of chunks that can be incubated within the document. Chunks exceeding this size will immediately graduate to independent chunks.": "Tamaño total máximo de chunks incubados. Excedentes se independizan", + "The minimum interval for automatic synchronisation on event.": "Intervalo mínimo para la sincronización automática al producirse un evento.", "The remote is already set up, and the configuration is compatible (or got compatible by this operation).": "El remoto ya está configurado y la configuración es compatible (o pasa a serlo con esta operación).", "The Setup-URI does not appear to be valid. Please check that you have copied it correctly.": "El Setup-URI no parece válido. Comprueba que lo hayas copiado correctamente.", "The Setup-URI is valid and ready to use.": "El Setup-URI es válido y está listo para usarse.", @@ -957,6 +1154,297 @@ "TURN server settings are only necessary if you are behind a strict NAT or firewall that prevents direct P2P connections. In most cases, you can leave these fields blank.": "Los ajustes del servidor TURN solo son necesarios si estás detrás de un NAT estricto o de un cortafuegos que impide las conexiones P2P directas. En la mayoría de los casos puedes dejar estos campos vacíos.", "TURN Server URLs (comma-separated)": "URL de servidores TURN (separadas por comas)", "TURN Username": "Usuario de TURN", + "TweakMismatchResolve.Action.DisableAutoAcceptCompatible": "Desactivar la aceptación automática", + "TweakMismatchResolve.Action.Dismiss": "Descartar", + "TweakMismatchResolve.Action.EnableAutoAcceptCompatible": "Activar la aceptación automática", + "TweakMismatchResolve.Action.UseConfigured": "Usar los ajustes configurados", + "TweakMismatchResolve.Action.UseMine": "Actualizar los ajustes de la base de datos remota", + "TweakMismatchResolve.Action.UseMineAcceptIncompatible": "Actualizar los ajustes de la base de datos remota, pero dejarlo como está", + "TweakMismatchResolve.Action.UseMineWithRebuild": "Actualizar los ajustes de la base de datos remota y reconstruir de nuevo", + "TweakMismatchResolve.Action.UseRemote": "Aplicar los ajustes a este dispositivo", + "TweakMismatchResolve.Action.UseRemoteAcceptIncompatible": "Aplicar los ajustes a este dispositivo e ignorar la incompatibilidad", + "TweakMismatchResolve.Action.UseRemoteWithRebuild": "Aplicar los ajustes a este dispositivo y volver a obtener los datos", + "TweakMismatchResolve.Message.AutoAcceptCompatibleUndefined": "\nParece que los ajustes son distintos en cada dispositivo. Ahora se pueden aplicar automáticamente los cambios compatibles a estas configuraciones.\n¿Quieres activar la aceptación automática (`auto-accept`)?", + "TweakMismatchResolve.Message.Main": "\nLos ajustes de la base de datos remota son los siguientes. Los han configurado otros dispositivos que se han sincronizado con este al menos una vez.\n\nSi quieres usar estos ajustes, selecciona %{TweakMismatchResolve.Action.UseConfigured}.\nSi prefieres conservar los de este dispositivo, selecciona %{TweakMismatchResolve.Action.Dismiss}.\n\n${table}\n\n>[!TIP]\n> Si quieres sincronizar todos los ajustes, usa «Sync settings via markdown» después de aplicar la configuración mínima con esta función.\n\n${additionalMessage}", + "TweakMismatchResolve.Message.MainTweakResolving": "Tu configuración no coincide con la del servidor remoto.\n\nLa siguiente configuración debería coincidir:\n\n${table}\n\nIndícanos qué decides.\n\n${additionalMessage}", + "TweakMismatchResolve.Message.mineUpdated": "Se ha ajustado la configuración del dispositivo.", + "TweakMismatchResolve.Message.remoteUpdated": "Se ha actualizado la configuración almacenada en el remoto.", + "TweakMismatchResolve.Message.UseRemote.WarningRebuildRecommended": "\n>[!NOTICE]\n> Algunos cambios son compatibles, pero pueden consumir almacenamiento y transferencia de más. Se recomienda reconstruir. De momento puede que no se reconstruya, pero podría hacerse en un mantenimiento futuro.\n> ***Asegúrate de tener tiempo y una red estable antes de aplicarlo.***", + "TweakMismatchResolve.Message.UseRemote.WarningRebuildRequired": "\n>[!WARNING]\n> Algunas configuraciones remotas no son compatibles con la base de datos local de este dispositivo. Habrá que reconstruirla.\n> ***Asegúrate de tener tiempo y una red estable antes de aplicarlo.***", + "TweakMismatchResolve.Message.WarningIncompatibleRebuildRecommended": "\n>[!NOTICE]\n> Hemos detectado que algunos valores difieren de forma que hacen incompatible la base de datos local con la remota.\n> Algunos cambios son compatibles, pero pueden consumir almacenamiento y transferencia de más. Se recomienda reconstruir. De momento puede que no se reconstruya, pero podría hacerse en un mantenimiento futuro.\n> Si decides reconstruir, tardará unos minutos o más. **Asegúrate de que es seguro hacerlo ahora.**", + "TweakMismatchResolve.Message.WarningIncompatibleRebuildRequired": "\n>[!WARNING]\n> Hemos detectado que algunos valores difieren de forma que hacen incompatible la base de datos local con la remota.\n> Hay que reconstruir la local o la remota. Ambas cosas tardan unos minutos o más. **Asegúrate de que es seguro hacerlo ahora.**", + "TweakMismatchResolve.Table": "| Nombre del valor | Este dispositivo | En el remoto |\n|: --- |: ---- :|: ---- :|\n${rows}\n\n", + "TweakMismatchResolve.Table.Row": "| ${name} | ${self} | ${remote} |", + "TweakMismatchResolve.Title": "Se ha detectado una discrepancia de configuración", + "TweakMismatchResolve.Title.AutoAcceptCompatible": "Aceptación automática disponible", + "TweakMismatchResolve.Title.TweakResolving": "Se ha detectado una discrepancia de configuración", + "TweakMismatchResolve.Title.UseRemoteConfig": "Usar la configuración remota", + "Ui.Common.Signal.Caution": "PRECAUCIÓN", + "Ui.Common.Signal.Danger": "PELIGRO", + "Ui.Common.Signal.Notice": "AVISO", + "Ui.Common.Signal.Warning": "ADVERTENCIA", + "Ui.Settings.Advanced.LocalDatabaseTweak": "Ajuste fino de la base de datos local", + "Ui.Settings.Advanced.MemoryCache": "Caché en memoria", + "Ui.Settings.Advanced.TransferTweak": "Ajuste fino de la transferencia", + "Ui.Settings.Common.Analyse": "Analizar", + "Ui.Settings.Common.Back": "Volver", + "Ui.Settings.Common.Check": "Comprobar", + "Ui.Settings.Common.Configure": "Configurar", + "Ui.Settings.Common.Continue": "Continuar", + "Ui.Settings.Common.Delete": "Eliminar", + "Ui.Settings.Common.Fetch": "Obtener", + "Ui.Settings.Common.Lock": "Bloquear", + "Ui.Settings.Common.Merge": "Combinar", + "Ui.Settings.Common.Open": "Abrir", + "Ui.Settings.Common.Overwrite": "Sobrescribir", + "Ui.Settings.Common.Perform": "Ejecutar", + "Ui.Settings.Common.ResetAll": "Restablecer todo", + "Ui.Settings.Common.ResolveAll": "Resolver todo", + "Ui.Settings.Common.Scan": "Analizar", + "Ui.Settings.Common.Send": "Enviar", + "Ui.Settings.Common.Use": "Usar", + "Ui.Settings.Common.VerifyAll": "Verificar todo", + "Ui.Settings.CustomizationSync.OpenDesc": "Abre el diálogo", + "Ui.Settings.CustomizationSync.Panel": "Sincronización de personalizaciones", + "Ui.Settings.CustomizationSync.WarnChangeDeviceName": "No se puede cambiar el nombre del dispositivo mientras esta función esté activada. Desactívala para poder cambiarlo.", + "Ui.Settings.CustomizationSync.WarnSetDeviceName": "Establece un nombre para identificar este dispositivo. Debe ser único entre tus dispositivos. Mientras no esté configurado, no se puede activar esta función.", + "Ui.Settings.Hatch.AnalyseDatabaseUsage": "Analizar el uso de la base de datos", + "Ui.Settings.Hatch.AnalyseDatabaseUsageDesc": "Analiza el uso de la base de datos y genera un informe TSV para que puedas diagnosticarlo tú mismo. Puedes pegar el informe generado en la hoja de cálculo que prefieras.", + "Ui.Settings.Hatch.BackToNonConfigured": "Volver al estado sin configurar", + "Ui.Settings.Hatch.ConvertNonObfuscated": "Comprobar y convertir los archivos sin ruta ofuscada", + "Ui.Settings.Hatch.ConvertNonObfuscatedDesc": "Comprueba si la base de datos local contiene archivos guardados sin ofuscación de ruta y los convierte si hace falta.", + "Ui.Settings.Hatch.CopyIssueReport": "Copiar el informe al portapapeles", + "Ui.Settings.Hatch.DatabaseLabel": "Base de datos: ${details}", + "Ui.Settings.Hatch.DatabaseToStorage": "Base de datos -> Almacenamiento", + "Ui.Settings.Hatch.DeleteCustomizationSyncData": "Eliminar todos los datos de la sincronización de personalizaciones", + "Ui.Settings.Hatch.GeneratedReport": "Informe generado", + "Ui.Settings.Hatch.Missing": "Falta", + "Ui.Settings.Hatch.ModifiedSize": "Modificado: ${modified}, tamaño: ${size}", + "Ui.Settings.Hatch.ModifiedSizeActual": "Modificado: ${modified}, tamaño: ${size} (tamaño real: ${actualSize})", + "Ui.Settings.Hatch.PrepareIssueReport": "Preparar el «informe» para abrir una incidencia", + "Ui.Settings.Hatch.RecoveryAndRepair": "Recuperación y reparación", + "Ui.Settings.Hatch.RecreateAll": "Recrear todo", + "Ui.Settings.Hatch.RecreateMissingChunks": "Recrear los chunks que faltan de todos los archivos", + "Ui.Settings.Hatch.RecreateMissingChunksDesc": "Recrea los chunks de todos los archivos. Si faltaban chunks, esto puede corregir los errores.", + "Ui.Settings.Hatch.ResetPanel": "Restablecer", + "Ui.Settings.Hatch.ResetRemoteUsage": "Restablecer el umbral de aviso y comprobar el uso de la base de datos remota", + "Ui.Settings.Hatch.ResetRemoteUsageDesc": "Restablece el umbral de tamaño del almacenamiento remoto y vuelve a comprobar su tamaño.", + "Ui.Settings.Hatch.ResolveAllConflictedFiles": "Resolver todos los archivos en conflicto con el más reciente", + "Ui.Settings.Hatch.ResolveAllConflictedFilesDesc": "Resuelve todos los archivos en conflicto quedándose con el más reciente. Atención: esto sobrescribe el más antiguo y no se puede recuperar.", + "Ui.Settings.Hatch.RunDoctor": "Ejecutar el Doctor", + "Ui.Settings.Hatch.ScanBrokenFiles": "Buscar archivos dañados", + "Ui.Settings.Hatch.ScramSwitches": "Interruptores de emergencia", + "Ui.Settings.Hatch.ShowHistory": "Mostrar el historial", + "Ui.Settings.Hatch.StorageLabel": "Almacenamiento: ${details}", + "Ui.Settings.Hatch.StorageToDatabase": "Almacenamiento -> Base de datos", + "Ui.Settings.Hatch.VerifyAndRepairAllFiles": "Verificar y reparar todos los archivos", + "Ui.Settings.Hatch.VerifyAndRepairAllFilesDesc": "Compara el contenido de los archivos entre la base de datos local y el almacenamiento. Si no coinciden, se te preguntará cuál conservar.", + "Ui.Settings.Maintenance.Cleanup": "Realizar limpieza", + "Ui.Settings.Maintenance.CleanupDesc": "Reduce el espacio de almacenamiento descartando todas las revisiones que no sean la última. Requiere la misma cantidad de espacio libre en el servidor remoto y en el cliente local.", + "Ui.Settings.Maintenance.DeleteLocalDatabase": "Eliminar la base de datos local para restablecer o desinstalar Self-hosted LiveSync", + "Ui.Settings.Maintenance.EmergencyRestart": "Reinicio de emergencia", + "Ui.Settings.Maintenance.EmergencyRestartDesc": "Desactiva toda la sincronización y reinicia.", + "Ui.Settings.Maintenance.FreshStartWipe": "Borrado para empezar de cero", + "Ui.Settings.Maintenance.FreshStartWipeDesc": "Elimina todos los datos del servidor remoto.", + "Ui.Settings.Maintenance.GarbageCollection": "Recolección de basura V3 (beta)", + "Ui.Settings.Maintenance.GarbageCollectionAction": "Realizar la recolección de basura", + "Ui.Settings.Maintenance.GarbageCollectionDesc": "Realiza una recolección de basura para eliminar los chunks sin usar y reducir el tamaño de la base de datos.", + "Ui.Settings.Maintenance.LockServer": "Bloquear el servidor", + "Ui.Settings.Maintenance.LockServerDesc": "Bloquea el servidor remoto para impedir la sincronización con otros dispositivos.", + "Ui.Settings.Maintenance.OverwriteRemote": "Sobrescribir el remoto", + "Ui.Settings.Maintenance.OverwriteRemoteDesc": "Sobrescribe el remoto con la base de datos local y la frase de contraseña.", + "Ui.Settings.Maintenance.OverwriteServerData": "Sobrescribir los datos del servidor con los archivos de este dispositivo", + "Ui.Settings.Maintenance.OverwriteServerDataDesc": "Reconstruye la base de datos local y la remota con los archivos de este dispositivo.", + "Ui.Settings.Maintenance.PurgeAllJournalCounter": "Purgar todos los contadores del diario", + "Ui.Settings.Maintenance.PurgeAllJournalCounterDesc": "Purga todas las cachés de descarga y de subida.", + "Ui.Settings.Maintenance.RebuildingOperations": "Operaciones de reconstrucción (solo remoto)", + "Ui.Settings.Maintenance.Resend": "Reenviar", + "Ui.Settings.Maintenance.ResendDesc": "Reenvía todos los chunks al remoto.", + "Ui.Settings.Maintenance.Reset": "Restablecer", + "Ui.Settings.Maintenance.ResetAllJournalCounter": "Restablecer todos los contadores del diario", + "Ui.Settings.Maintenance.ResetAllJournalCounterDesc": "Inicializa todo el historial del diario. En la próxima sincronización se volverán a recibir y enviar todos los elementos.", + "Ui.Settings.Maintenance.ResetJournalReceived": "Restablecer el historial de recepción del diario", + "Ui.Settings.Maintenance.ResetJournalReceivedDesc": "Inicializa el historial de recepción del diario. En la próxima sincronización se volverán a descargar todos los elementos salvo los enviados por este dispositivo.", + "Ui.Settings.Maintenance.ResetJournalSent": "Restablecer el historial de envío del diario", + "Ui.Settings.Maintenance.ResetJournalSentDesc": "Inicializa el historial de envío del diario. En la próxima sincronización se volverán a enviar todos los elementos salvo los recibidos por este dispositivo.", + "Ui.Settings.Maintenance.ResetLocalSyncInfo": "Restablecer la información de sincronización", + "Ui.Settings.Maintenance.ResetLocalSyncInfoDesc": "Restaura o reconstruye la base de datos local a partir del remoto.", + "Ui.Settings.Maintenance.ResetReceived": "Restablecer lo recibido", + "Ui.Settings.Maintenance.ResetSentHistory": "Restablecer el historial de envíos", + "Ui.Settings.Maintenance.ResetThisDevice": "Restablecer la sincronización en este dispositivo", + "Ui.Settings.Maintenance.ScheduleAndRestart": "Programar y reiniciar", + "Ui.Settings.Maintenance.Scram": "¡Parada de emergencia!", + "Ui.Settings.Maintenance.SendChunks": "Enviar los chunks", + "Ui.Settings.Maintenance.Syncing": "Sincronización", + "Ui.Settings.Maintenance.WarningLockedReadyAction": "Estoy listo, desbloquear la base de datos", + "Ui.Settings.Maintenance.WarningLockedReadyText": "Para evitar que el vault se corrompa, la base de datos remota se ha bloqueado para la sincronización. (Este dispositivo está marcado como «resuelto».) Cuando todos tus dispositivos estén marcados como «resueltos», desbloquea la base de datos. Este aviso seguirá apareciendo hasta que la replicación confirme que el dispositivo está resuelto.", + "Ui.Settings.Maintenance.WarningLockedResolveAction": "He hecho una copia de seguridad, marcar este dispositivo como resuelto", + "Ui.Settings.Maintenance.WarningLockedResolveText": "La base de datos remota está bloqueada para la sincronización a fin de evitar que el vault se corrompa, porque este dispositivo no está marcado como «resuelto». Haz una copia de seguridad de tu vault, restablece la base de datos local y selecciona «Marcar este dispositivo como resuelto». Este aviso seguirá apareciendo hasta que la replicación confirme que el dispositivo está resuelto.", + "Ui.Settings.Maintenance.WriteRedFlagAndRestart": "Marcar y reiniciar", + "Ui.Settings.Patches.CompatibilityConflict": "Compatibilidad (comportamiento ante conflictos)", + "Ui.Settings.Patches.CompatibilityDatabase": "Compatibilidad (estructura de la base de datos)", + "Ui.Settings.Patches.CompatibilityInternalApi": "Compatibilidad (uso de la API interna)", + "Ui.Settings.Patches.CompatibilityMetadata": "Compatibilidad (metadatos)", + "Ui.Settings.Patches.CompatibilityRemote": "Compatibilidad (base de datos remota)", + "Ui.Settings.Patches.CompatibilityTrouble": "Compatibilidad (problemas resueltos)", + "Ui.Settings.Patches.CurrentAdapter": "Adaptador actual: ${adapter}", + "Ui.Settings.Patches.DatabaseAdapter": "Adaptador de base de datos", + "Ui.Settings.Patches.DatabaseAdapterDesc": "Selecciona el adaptador de base de datos que se va a usar.", + "Ui.Settings.Patches.EdgeCaseBehaviour": "Casos límite (comportamiento)", + "Ui.Settings.Patches.EdgeCaseDatabase": "Casos límite (base de datos)", + "Ui.Settings.Patches.EdgeCaseProcessing": "Casos límite (procesamiento)", + "Ui.Settings.Patches.IndexedDbWarning": "El adaptador IndexedDB suele ofrecer mejor rendimiento en ciertos casos, pero se ha comprobado que provoca fugas de memoria con el modo LiveSync. Si usas el modo LiveSync, utiliza en su lugar el adaptador IDB.", + "Ui.Settings.Patches.MigratingToIdb": "Migrando todos los datos a IDB...", + "Ui.Settings.Patches.MigratingToIndexedDb": "Migrando todos los datos a IndexedDB...", + "Ui.Settings.Patches.MigrationIdbCompleted": "Migración a IDB completada. Obsidian se reiniciará de inmediato con la nueva configuración.", + "Ui.Settings.Patches.MigrationIdbCompletedFollowUp": "Migración a IDB completada. Cambia el adaptador y reinicia Obsidian.", + "Ui.Settings.Patches.MigrationIndexedDbCompleted": "Migración a IndexedDB completada. Obsidian se reiniciará de inmediato con la nueva configuración.", + "Ui.Settings.Patches.MigrationIndexedDbCompletedFollowUp": "Migración a IndexedDB completada. Cambia el adaptador y reinicia Obsidian.", + "Ui.Settings.Patches.MigrationWarning": "Cambiar este ajuste requiere migrar los datos existentes, lo que puede tardar un rato, y reiniciar Obsidian. Asegúrate de hacer una copia de seguridad de tus datos antes de continuar.", + "Ui.Settings.Patches.OperationToIdb": "a IDB", + "Ui.Settings.Patches.OperationToIndexedDb": "a IndexedDB", + "Ui.Settings.Patches.Remediation": "Remediación", + "Ui.Settings.Patches.RemediationChanged": "Se ha cambiado el ajuste de remediación", + "Ui.Settings.Patches.RemediationNoLimit": "Sin límite configurado", + "Ui.Settings.Patches.RemediationRestarting": "Se ha cambiado el ajuste de remediación. Reiniciando Obsidian...", + "Ui.Settings.Patches.RemediationRestartLater": "Más tarde", + "Ui.Settings.Patches.RemediationRestartMessage": "Se recomienda encarecidamente reiniciar Obsidian. Hasta que lo hagas, puede que algunos cambios no surtan efecto y que la interfaz se muestre de forma inconsistente. ¿Seguro que quieres reiniciar ahora?", + "Ui.Settings.Patches.RemediationRestartNow": "Reiniciar ahora", + "Ui.Settings.Patches.RemediationSuffixChanged": "El sufijo ha cambiado. Reabriendo la base de datos...", + "Ui.Settings.Patches.RemediationWithValue": "Límite: ${date} (${timestamp})", + "Ui.Settings.Patches.RemoteDatabaseSunset": "Ajuste fino de la base de datos remota (en desuso)", + "Ui.Settings.Patches.SwitchToIDB": "Cambiar a IDB", + "Ui.Settings.Patches.SwitchToIndexedDb": "Cambiar a IndexedDB", + "Ui.Settings.PowerUsers.ConfigurationEncryption": "Cifrado de la configuración", + "Ui.Settings.PowerUsers.ConnectionTweak": "Ajuste fino de la conexión con CouchDB", + "Ui.Settings.PowerUsers.ConnectionTweakDesc": "Si alcanzas el límite de tamaño de carga al usar IBM Cloudant, reduce el tamaño de lote y el límite de lote.", + "Ui.Settings.PowerUsers.Default": "Predeterminado", + "Ui.Settings.PowerUsers.Developer": "Desarrollo", + "Ui.Settings.PowerUsers.EncryptSensitiveConfig": "Cifrar los elementos sensibles de la configuración", + "Ui.Settings.PowerUsers.PromptPassphraseEveryLaunch": "Solicitar la frase de contraseña en cada inicio", + "Ui.Settings.PowerUsers.UseCustomPassphrase": "Usar una frase de contraseña personalizada", + "Ui.Settings.Remote.Activate": "Activar", + "Ui.Settings.Remote.ActiveSuffix": " (activo)", + "Ui.Settings.Remote.AddConnection": "Añadir conexión", + "Ui.Settings.Remote.AddRemoteDefaultName": "Remoto nuevo", + "Ui.Settings.Remote.ConfigureAndChangeRemote": "Configurar y cambiar el remoto", + "Ui.Settings.Remote.ConfigureE2EE": "Configurar el E2EE", + "Ui.Settings.Remote.ConfigureRemote": "Configurar el remoto", + "Ui.Settings.Remote.DeleteRemoteConfirm": "¿Eliminar la configuración remota «${name}»?", + "Ui.Settings.Remote.DeleteRemoteTitle": "Eliminar la configuración remota", + "Ui.Settings.Remote.DisplayName": "Nombre visible", + "Ui.Settings.Remote.DuplicateRemote": "Duplicar el remoto", + "Ui.Settings.Remote.DuplicateRemoteSuffix": "${name} (copia)", + "Ui.Settings.Remote.E2EEConfiguration": "Configuración del E2EE", + "Ui.Settings.Remote.Export": "Exportar", + "Ui.Settings.Remote.FetchRemoteSettings": "Obtener los ajustes remotos", + "Ui.Settings.Remote.ImportConnection": "Importar conexión", + "Ui.Settings.Remote.ImportConnectionPrompt": "Pega una cadena de conexión", + "Ui.Settings.Remote.ImportedCouchDb": "CouchDB importado", + "Ui.Settings.Remote.ImportedRemote": "Remoto", + "Ui.Settings.Remote.MoreActions": "Más acciones", + "Ui.Settings.Remote.PeerToPeerPanel": "Sincronización punto a punto", + "Ui.Settings.Remote.RemoteConfigurationPrefix": "Configuración remota", + "Ui.Settings.Remote.RemoteDatabases": "Bases de datos remotas", + "Ui.Settings.Remote.RemoteName": "Nombre del remoto", + "Ui.Settings.Remote.RemoteNameCouchDb": "CouchDB ${host}", + "Ui.Settings.Remote.RemoteNameP2P": "P2P ${room}", + "Ui.Settings.Remote.RemoteNameS3": "S3 ${bucket}", + "Ui.Settings.Remote.Rename": "Cambiar el nombre", + "Ui.Settings.Selector.AddDefaultPatterns": "Añadir patrones predeterminados", + "Ui.Settings.Selector.CrossPlatform": "Multiplataforma", + "Ui.Settings.Selector.Default": "Predeterminado", + "Ui.Settings.Selector.HiddenFiles": "Archivos ocultos", + "Ui.Settings.Selector.IgnorePatterns": "Patrones de exclusión", + "Ui.Settings.Selector.NonSynchronisingFiles": "Archivos que no se sincronizan", + "Ui.Settings.Selector.NonSynchronisingFilesDesc": "(RegExp) Si se establece, se omitirá cualquier cambio en archivos locales y remotos que coincida con este patrón.", + "Ui.Settings.Selector.NormalFiles": "Archivos normales", + "Ui.Settings.Selector.OverwritePatterns": "Patrones de sobrescritura", + "Ui.Settings.Selector.OverwritePatternsDesc": "Patrones de los archivos que se sobrescriben en lugar de combinarse", + "Ui.Settings.Selector.SynchronisingFiles": "Archivos que se sincronizan", + "Ui.Settings.Selector.SynchronisingFilesDesc": "(RegExp) Déjalo vacío para sincronizar todos los archivos. Define un filtro como expresión regular para limitar los archivos sincronizados.", + "Ui.Settings.Selector.TargetPatterns": "Patrones de inclusión", + "Ui.Settings.Selector.TargetPatternsDesc": "Patrones de los archivos que se van a sincronizar", + "Ui.Settings.Setup.RerunWizardButton": "Volver a ejecutar el asistente", + "Ui.Settings.Setup.RerunWizardDesc": "Vuelve a ejecutar el asistente de configuración inicial para configurar Self-hosted LiveSync de nuevo.", + "Ui.Settings.Setup.RerunWizardName": "Volver a ejecutar el asistente de configuración inicial", + "Ui.Settings.SyncSettings.Fetch": "Obtener", + "Ui.Settings.SyncSettings.Merge": "Combinar", + "Ui.Settings.SyncSettings.Overwrite": "Sobrescribir", + "Ui.SetupWizard.Common.Back": "No, volver atrás", + "Ui.SetupWizard.Common.Cancel": "Cancelar", + "Ui.SetupWizard.Common.ProceedSelectOption": "Selecciona una opción para continuar", + "Ui.SetupWizard.Intro.ExistingOption": "Estoy añadiendo un dispositivo a una configuración de sincronización existente", + "Ui.SetupWizard.Intro.ExistingOptionDesc": "Elige esto si ya usas la sincronización en otro ordenador o móvil. Usa esta opción para conectar este dispositivo a esa configuración existente.", + "Ui.SetupWizard.Intro.Guidance": "Te guiaremos con unas cuantas preguntas para simplificar la configuración de la sincronización.", + "Ui.SetupWizard.Intro.NewOption": "Lo estoy configurando por primera vez", + "Ui.SetupWizard.Intro.NewOptionDesc": "Elige esto si estás configurando este dispositivo como el primero de la sincronización.", + "Ui.SetupWizard.Intro.ProceedExisting": "Sí, quiero añadir este dispositivo a mi sincronización existente", + "Ui.SetupWizard.Intro.ProceedNew": "Sí, quiero configurar una sincronización nueva", + "Ui.SetupWizard.Intro.Question": "Primero, selecciona la opción que mejor describa tu situación actual.", + "Ui.SetupWizard.Intro.Title": "Bienvenido a Self-hosted LiveSync", + "Ui.SetupWizard.Invitation.Start": "Comenzar la configuración", + "Ui.SetupWizard.OutroAskUserMode.CompatibleOption": "El remoto ya está configurado y la configuración es compatible (o pasa a serlo con esta operación).", + "Ui.SetupWizard.OutroAskUserMode.CompatibleOptionDesc": "Si no estás seguro, elegir esta opción es arriesgado. Da por supuesto que la configuración del servidor es compatible con este dispositivo. Si no lo es, puede haber pérdida de datos. Asegúrate de entender las consecuencias.", + "Ui.SetupWizard.OutroAskUserMode.ExistingOption": "Mi servidor remoto ya está configurado. Quiero añadir este dispositivo.", + "Ui.SetupWizard.OutroAskUserMode.ExistingOptionDesc": "Al elegir esta opción, este dispositivo se unirá al servidor existente. Tendrás que obtener del servidor los datos de sincronización ya existentes.", + "Ui.SetupWizard.OutroAskUserMode.Guidance": "La conexión con el servidor se ha configurado correctamente. Como paso siguiente hay que reconstruir la base de datos local, es decir, la información de sincronización.", + "Ui.SetupWizard.OutroAskUserMode.NewOption": "Estoy configurando un servidor nuevo por primera vez / quiero restablecer mi servidor actual.", + "Ui.SetupWizard.OutroAskUserMode.NewOptionDesc": "Al elegir esta opción, el servidor se inicializará con los datos actuales de este dispositivo. Cualquier dato existente en el servidor se sobrescribirá por completo.", + "Ui.SetupWizard.OutroAskUserMode.ProceedApplySettings": "Aplicar los ajustes", + "Ui.SetupWizard.OutroAskUserMode.ProceedNext": "Continuar al paso siguiente.", + "Ui.SetupWizard.OutroAskUserMode.Question": "Selecciona tu situación.", + "Ui.SetupWizard.OutroAskUserMode.Title": "Casi terminado: se requiere una decisión", + "Ui.SetupWizard.OutroNewP2PUser.GuidanceNotice": "En P2P no hay una copia en un servidor central que sobrescribir. Este paso prepara solo este dispositivo; mantenlo conectado cuando otro dispositivo obtenga sus datos iniciales.", + "Ui.SetupWizard.OutroNewP2PUser.GuidancePrimary": "La conexión punto a punto se ha configurado correctamente. A continuación, la base de datos local de LiveSync se construirá a partir de los archivos actuales de este Vault.", + "Ui.SetupWizard.OutroNewP2PUser.Important": "TEN EN CUENTA", + "Ui.SetupWizard.OutroNewP2PUser.Proceed": "Reiniciar y preparar este dispositivo", + "Ui.SetupWizard.OutroNewP2PUser.Question": "Pulsa el botón de abajo para reiniciar y pasar a la confirmación de la inicialización local.", + "Ui.SetupWizard.OutroNewP2PUser.Title": "Configuración completada: preparando este dispositivo P2P", + "Ui.SetupWizard.OutroNewUser.GuidancePrimary": "La conexión con el servidor se ha configurado correctamente. Como paso siguiente, los datos de sincronización del servidor se construirán a partir de los datos actuales de este dispositivo.", + "Ui.SetupWizard.OutroNewUser.GuidanceWarning": "Tras reiniciar, los datos de este dispositivo se subirán al servidor como copia maestra. Ten en cuenta que cualquier dato no deseado que haya ahora en el servidor se sobrescribirá por completo.", + "Ui.SetupWizard.OutroNewUser.Important": "IMPORTANTE", + "Ui.SetupWizard.OutroNewUser.Proceed": "Reiniciar e inicializar el servidor", + "Ui.SetupWizard.OutroNewUser.Question": "Pulsa el botón de abajo para reiniciar y pasar a la confirmación final.", + "Ui.SetupWizard.OutroNewUser.Title": "Configuración completada: preparando la inicialización del servidor", + "Ui.SetupWizard.RebuildEverythingP2P.ConfirmLocalReset": "Entiendo que esto restablece únicamente la base de datos de sincronización local de este dispositivo.", + "Ui.SetupWizard.RebuildEverythingP2P.ConfirmLocalResetNote": "Se usarán los archivos que hay ahora en este Vault para reconstruirla.", + "Ui.SetupWizard.RebuildEverythingP2P.ConfirmTitle": "⚠️ Confirma lo siguiente", + "Ui.SetupWizard.RebuildEverythingP2P.Guidance": "Este procedimiento descartará la base de datos local de LiveSync de este dispositivo y la reconstruirá a partir de los archivos actuales de este Vault. No elimina ni sobrescribe datos de otro dispositivo.", + "Ui.SetupWizard.RebuildEverythingP2P.Note": "Mantén este dispositivo conectado después de la inicialización para que otro dispositivo pueda obtener el Vault desde él.", + "Ui.SetupWizard.RebuildEverythingP2P.Proceed": "Lo entiendo, preparar este dispositivo", + "Ui.SetupWizard.RebuildEverythingP2P.Title": "Confirmación final: preparar este dispositivo para P2P", + "Ui.SetupWizard.SelectExisting.Guidance": "Estás añadiendo este dispositivo a una configuración de sincronización existente.", + "Ui.SetupWizard.SelectExisting.ManualOption": "Configurar un remoto manualmente", + "Ui.SetupWizard.SelectExisting.ManualOptionDesc": "Vuelve a configurar manualmente el mismo remoto que en tus otros dispositivos. Está pensado solo para usuarios avanzados.", + "Ui.SetupWizard.SelectExisting.ProceedManual": "Continuar con la configuración manual", + "Ui.SetupWizard.SelectExisting.ProceedQr": "Escanea con la cámara de este dispositivo el código QR mostrado en un dispositivo activo.", + "Ui.SetupWizard.SelectExisting.ProceedSetupUri": "Continuar con el Setup URI", + "Ui.SetupWizard.SelectExisting.QrOption": "Escanear un código QR (recomendado en móvil)", + "Ui.SetupWizard.SelectExisting.QrOptionDesc": "Escanea con la cámara de este dispositivo el código QR mostrado en un dispositivo activo.", + "Ui.SetupWizard.SelectExisting.Question": "Selecciona un método para importar los ajustes desde otro dispositivo.", + "Ui.SetupWizard.SelectExisting.SetupUriOption": "Usar un Setup URI (recomendado)", + "Ui.SetupWizard.SelectExisting.SetupUriOptionDesc": "Pega el Setup URI generado en uno de tus dispositivos activos.", + "Ui.SetupWizard.SelectExisting.Title": "Método de configuración del dispositivo", + "Ui.SetupWizard.SelectNew.Guidance": "Vamos a configurar la conexión de sincronización.", + "Ui.SetupWizard.SelectNew.ManualOption": "Configurar un remoto manualmente", + "Ui.SetupWizard.SelectNew.ManualOptionDesc": "Es una opción avanzada para quienes no tienen un Setup URI o quieren ajustar la configuración en detalle. También puedes usarla para la sincronización P2P en lugar de CouchDB o de un almacenamiento de objetos compatible con S3.", + "Ui.SetupWizard.SelectNew.ProceedManual": "Continuar con la configuración manual", + "Ui.SetupWizard.SelectNew.ProceedSetupUri": "Continuar con el Setup URI", + "Ui.SetupWizard.SelectNew.Question": "¿Cómo quieres configurar esta conexión de sincronización?", + "Ui.SetupWizard.SelectNew.SetupUriOption": "Usar un Setup URI (recomendado)", + "Ui.SetupWizard.SelectNew.SetupUriOptionDesc": "Un Setup URI es una única cadena que contiene los datos de conexión y autenticación. Cuando un script de instalación te proporciona uno, es la forma más sencilla y segura de configurarlo.", + "Ui.SetupWizard.SelectNew.Title": "Método de conexión", + "Ui.SetupWizard.SetupRemote.BucketOption": "Almacenamiento de objetos compatible con S3", + "Ui.SetupWizard.SetupRemote.BucketOptionDesc": "Sincronización mediante archivos de diario. Necesitas tener ya un servicio de almacenamiento de objetos compatible con S3, como Amazon S3, MinIO o Cloudflare R2.", + "Ui.SetupWizard.SetupRemote.CouchDbOptionDesc": "Es el método de sincronización más adecuado para el diseño actual y ofrece todas las funciones. Necesitas tener ya una instancia de CouchDB en marcha.", + "Ui.SetupWizard.SetupRemote.Guidance": "Selecciona el tipo de remoto para esta configuración de sincronización.", + "Ui.SetupWizard.SetupRemote.P2POption": "Punto a punto (P2P)", + "Ui.SetupWizard.SetupRemote.P2POptionDesc": "Permite la sincronización directa entre dispositivos. No hace falta servidor, pero ambos dispositivos deben estar conectados a la vez y algunas funciones pueden estar limitadas. Solo se necesita internet para la señalización, no para transferir los datos.", + "Ui.SetupWizard.SetupRemote.ProceedBucket": "Continuar con la configuración del almacenamiento de objetos", + "Ui.SetupWizard.SetupRemote.ProceedCouchDb": "Continuar con la configuración de CouchDB", + "Ui.SetupWizard.SetupRemote.ProceedP2P": "Continuar con la configuración de P2P", + "Ui.SetupWizard.SetupRemote.Title": "Elige un remoto de sincronización", "Unique name between all synchronized devices. To edit this setting, please disable customization sync once.": "Nombre único entre dispositivos sincronizados. Para editarlo, desactive sincronización de personalización", "Unless you are certain, selecting this options is bit dangerous. It assumes that the server configuration is compatible with this device. If this is not the case, data loss may occur. Please ensure you know what you are doing.": "Si no estás seguro, elegir esta opción es algo arriesgado. Da por supuesto que la configuración del servidor es compatible con este dispositivo. Si no lo es, puede haber pérdida de datos. Asegúrate de saber lo que haces.", "Updating list...": "Actualizando lista...", diff --git a/src/common/messagesJson/ko.json b/src/common/messagesJson/ko.json index 35c8b846..745bb981 100644 --- a/src/common/messagesJson/ko.json +++ b/src/common/messagesJson/ko.json @@ -5,45 +5,49 @@ "(Days passed, 0 to disable automatic-deletion)": "(지난 일수, 0으로 설정하면 자동 삭제 비활성화)", "(ex. Read chunks online) If this option is enabled, LiveSync reads chunks online directly instead of replicating them locally. Increasing Custom chunk size is recommended.": "(예: 청크를 원격에서 읽음) 이 옵션을 활성화하면, LiveSync는 청크를 로컬에 복제하지 않고 원격에서 직접 읽습니다. 커스텀 청크 크기를 키우는 것을 권장합니다.", "(MB) If this is set, changes to local and remote files that are larger than this will be skipped. If the file becomes smaller again, a newer one will be used.": "(MB) 이 값이 설정되면, 이보다 큰 로컬 및 원격 파일의 변경 사항은 건너뜁니다. 파일이 다시 작아지면 더 새로운 파일이 사용됩니다.", - "(Mega chars)": "(메가 문자)", + "(Mega chars)": "(백만 자 단위)", "(Not recommended) If set, credentials will be stored in the file.": "(권장하지 않음) 설정한 경우 자격 증명이 파일에 저장됩니다.", "(Obsolete) Use an old adapter for compatibility": "(사용 중단) 호환성을 위해 이전 어댑터 사용", "(RegExp) Empty to sync all files. Set filter as a regular expression to limit synchronising files.": "(정규식) 비워 두면 모든 파일을 동기화합니다. 정규식을 지정하면 동기화할 파일을 제한할 수 있습니다.", "(RegExp) If this is set, any changes to local and remote files that match this will be skipped.": "(정규식) 설정하면 이 패턴과 일치하는 로컬 및 원격 파일 변경은 모두 건너뜁니다.", - "(Select this if you are already using synchronisation on another computer or smartphone.) This option is suitable if you are new to LiveSync and want to set it up from scratch.": "(다른 컴퓨터나 스마트폰에서 이미 동기화를 사용 중인 경우 선택하세요.) 이 장치를 기존 LiveSync 구성에 추가하려는 경우에 적합합니다。", - "(Select this if you are configuring this device as the first synchronisation device.) This option is suitable if you are new to LiveSync and want to set it up from scratch.": "(이 장치를 첫 번째 동기화 장치로 설정하는 경우 선택하세요.) LiveSync를 처음 사용하며 처음부터 설정하려는 경우에 적합합니다。", + "(Select this if you are already using synchronisation on another computer or smartphone.) This option is suitable if you are new to LiveSync and want to set it up from scratch.": "(다른 컴퓨터나 스마트폰에서 이미 동기화를 사용 중이라면 선택하세요.) 이 기기를 기존 LiveSync 구성에 추가하려는 경우에 적합합니다.", + "(Select this if you are configuring this device as the first synchronisation device.) This option is suitable if you are new to LiveSync and want to set it up from scratch.": "(이 기기를 첫 번째 동기화 기기로 설정한다면 선택하세요.) LiveSync를 처음 사용하며 처음부터 설정하려는 경우에 적합합니다.", "> [!INFO]- The connected devices have been detected as follows:\n${devices}": "> [!INFO]- 다음 연결된 기기가 감지되었습니다:\n${devices}", - "A Setup URI is a single string of text containing your server address and authentication details. Using a URI, if one was generated by your server installation script, provides a simple and secure configuration.": "설정 URI는 서버 주소와 인증 정보를 포함한 단일 문자열입니다. 서버 설치 스크립트가 URI를 생성했다면 이를 사용하면 간단하고 안전하게 구성할 수 있습니다。", + "A Setup URI is a single string of text containing your server address and authentication details. Using a URI, if one was generated by your server installation script, provides a simple and secure configuration.": "Setup URI는 서버 주소와 인증 정보를 담은 하나의 문자열입니다. 서버 설치 스크립트가 URI를 생성했다면, 이를 사용해 간단하고 안전하게 구성할 수 있습니다.", "Access Key": "액세스 키", "Activate": "활성화", + "Active Remote Configuration": "활성 원격 구성", "Add default patterns": "기본 패턴 추가", "Add new connection": "연결 추가", - "All devices have the same progress value (${progress}). Your devices seem to be synchronised. And be able to proceed with Garbage Collection.": "모든 기기의 진행 값이 동일합니다(${progress}). 기기들이 동기화된 것으로 보이므로 Garbage Collection을 진행할 수 있습니다.", + "All devices have the same progress value (${progress}). Your devices seem to be synchronised. And be able to proceed with Garbage Collection.": "모든 기기의 진행 값이 동일합니다(${progress}). 기기들이 동기화된 것으로 보이므로 가비지 컬렉션을 진행할 수 있습니다.", "Always prompt merge conflicts": "항상 병합 충돌 알림", + "Analyse": "분석", "Analyse database usage": "데이터베이스 사용량 분석", "Analyse database usage and generate a TSV report for diagnosis yourself. You can paste the generated report with any spreadsheet you like.": "데이터베이스 사용량을 분석하고 직접 진단할 수 있도록 TSV 보고서를 생성합니다. 생성된 보고서는 원하는 스프레드시트에 붙여 넣어 확인할 수 있습니다.", "Apply Latest Change if Conflicting": "충돌 시 최신 변경 사항 적용", "Apply preset configuration": "프리셋 구성 적용", - "Ask a passphrase at every launch": "시작할 때마다 암호문구 묻기", + "Ask a passphrase at every launch": "시작할 때마다 패스프레이즈 묻기", "Automatically Sync all files when opening Obsidian.": "Obsidian을 열 때 모든 파일을 자동으로 동기화합니다.", "Back": "뒤로", "Back to non-configured": "미구성 상태로 되돌리기", "Batch database update": "일괄 데이터베이스 업데이트", - "Batch limit": "일괄 제한", - "Batch size": "일괄 크기", - "Batch size of on-demand fetching": "필요 시 가져올 청크 묶음 크기", + "Batch limit": "배치 개수 제한", + "Batch size": "배치 크기", + "Batch size of on-demand fetching": "필요 시 가져오기의 배치 크기", "Before v0.17.16, we used an old adapter for the local database. Now the new adapter is preferred. However, it needs local database rebuilding. Please disable this toggle when you have enough time. If leave it enabled, also while fetching from the remote database, you will be asked to disable this.": "v0.17.16 이전에는 로컬 데이터베이스에 이전 어댑터를 사용했습니다. 이제는 새로운 어댑터를 권장합니다. 하지만 로컬 데이터베이스 재구축이 필요합니다. 충분한 시간이 있을 때 이 토글을 비활성화해 주세요. 활성화된 상태로 두면 원격 데이터베이스에서 가져올 때도 이를 비활성화하라는 메시지가 나타납니다.", "Bucket Name": "버킷 이름", "Cancel": "취소", - "Cancel Garbage Collection": "Garbage Collection 취소", + "Cancel Garbage Collection": "가비지 컬렉션 취소", + "Changing this setting requires migrating existing data (a bit time may be taken) and restarting Obsidian. Please make sure to back up your data before proceeding.": "이 설정을 변경하려면 기존 데이터를 마이그레이션하고(시간이 다소 걸릴 수 있습니다) Obsidian을 재시작해야 합니다. 진행하기 전에 반드시 데이터를 백업해 주세요.", + "Check": "확인", "Check and convert non-path-obfuscated files": "경로 난독화되지 않은 파일 검사 및 변환", "Check for documents that have not been converted to path-obfuscated IDs and convert them if necessary.": "아직 경로 난독화 ID로 변환되지 않은 문서를 확인하고 필요하면 변환합니다.", "cmdConfigSync.showCustomizationSync": "사용자 설정 동기화 표시", "Comma separated `.gitignore, .dockerignore`": "쉼표로 구분된 `.gitignore, .dockerignore`", - "Compaction in progress on remote database...": "원격 데이터베이스에서 압축을 진행 중입니다...", - "Compaction on remote database completed successfully.": "원격 데이터베이스 압축이 성공적으로 완료되었습니다.", - "Compaction on remote database failed.": "원격 데이터베이스 압축에 실패했습니다.", - "Compaction on remote database timed out.": "원격 데이터베이스 압축 시간이 초과되었습니다.", + "Compaction in progress on remote database...": "원격 데이터베이스에서 압축 정리를 진행 중입니다...", + "Compaction on remote database completed successfully.": "원격 데이터베이스 압축 정리가 성공적으로 완료되었습니다.", + "Compaction on remote database failed.": "원격 데이터베이스 압축 정리에 실패했습니다.", + "Compaction on remote database timed out.": "원격 데이터베이스 압축 정리 시간이 초과되었습니다.", "Compare the content of files between on local database and storage. If not matched, you will be asked which one you want to keep.": "로컬 데이터베이스와 저장소 간의 파일 내용을 비교합니다. 일치하지 않으면 어떤 쪽을 유지할지 묻게 됩니다.", "Compatibility (Conflict Behaviour)": "호환성 (충돌 동작)", "Compatibility (Database structure)": "호환성 (데이터베이스 구조)", @@ -57,7 +61,7 @@ "Configure And Change Remote": "원격 구성 및 변경", "Configure E2EE": "E2EE 구성", "Configure Remote": "원격 구성", - "Configure the same server information as your other devices again, manually, very advanced users only.": "다른 장치와 동일한 서버 정보를 다시 수동으로 입력합니다. 고급 사용자 전용입니다。", + "Configure the same server information as your other devices again, manually, very advanced users only.": "다른 기기와 동일한 서버 정보를 다시 직접 입력합니다. 숙련된 사용자 전용입니다.", "Connection Method": "연결 방법", "Continue to CouchDB setup": "CouchDB 설정으로 계속", "Continue to Peer-to-Peer only setup": "Peer-to-Peer 전용 설정으로 계속", @@ -67,9 +71,10 @@ "CouchDB Connection Tweak": "CouchDB 연결 조정", "Cross-platform": "크로스 플랫폼", "Current adapter: {adapter}": "현재 어댑터: {adapter}", - "Customization Sync": "사용자 지정 동기화", - "Customization Sync (Beta3)": "사용자 지정 동기화 (Beta3)", + "Customization Sync": "사용자 설정 동기화", + "Customization Sync (Beta3)": "사용자 설정 동기화 (Beta3)", "Data Compression": "데이터 압축", + "Database -> Storage": "데이터베이스 -> 스토리지", "Database Adapter": "데이터베이스 어댑터", "Database Name": "데이터베이스 이름", "Database suffix": "데이터베이스 접미사", @@ -77,7 +82,7 @@ "Delay conflict resolution of inactive files": "비활성 파일의 충돌 해결 지연", "Delay merge conflict prompt for inactive files.": "비활성 파일의 병합 충돌 프롬프트 지연.", "Delete": "삭제", - "Delete all customization sync data": "모든 사용자 정의 동기화 데이터 삭제", + "Delete all customization sync data": "모든 사용자 설정 동기화 데이터 삭제", "Delete all data on the remote server.": "원격 서버의 모든 데이터를 삭제합니다.", "Delete local database to reset or uninstall Self-hosted LiveSync": "Self-hosted LiveSync를 초기화하거나 제거하기 위해 로컬 데이터베이스를 삭제", "Delete old metadata of deleted files on start-up": "시작 시 삭제된 파일의 오래된 메타데이터 삭제", @@ -87,8 +92,8 @@ "Developer": "개발자", "Device": "기기", "Device name": "기기 이름", - "Device Setup Method": "장치 설정 방법", - "dialog.yourLanguageAvailable": "Self-hosted LiveSync에서 귀하의 언어로 번역을 제공하므로 %{Display language} 설정이 활성화되었습니다.\n\n참고: 모든 메시지가 번역되지는 않습니다. 귀하의 기여를 기다리고 있습니다!\n참고 2: 이슈를 생성하는 경우 **%{lang-def}로 되돌린 후** 스크린샷, 메시지, 로그를 가져와 주세요. 이는 설정 대화 상자에서 할 수 있습니다.\n간편하게 사용하실 수 있었으면 좋겠습니다!", + "Device Setup Method": "기기 설정 방법", + "dialog.yourLanguageAvailable": "Self-hosted LiveSync가 사용 중인 언어의 번역을 제공하므로 %{Display Language} 설정이 활성화되었습니다.\n\n참고: 모든 메시지가 번역되어 있지는 않습니다. 여러분의 기여를 기다리고 있습니다!\n참고 2: 이슈를 등록할 때는 **%{lang-def} 로 되돌린 뒤** 스크린샷과 메시지, 로그를 첨부해 주세요. 설정 대화 상자에서 되돌릴 수 있습니다.\n편하게 사용하실 수 있기를 바랍니다!", "dialog.yourLanguageAvailable.btnRevertToDefault": "%{lang-def} 유지", "dialog.yourLanguageAvailable.Title": " 번역을 사용할 수 있습니다!", "Disables all synchronization and restart.": "모든 동기화를 비활성화하고 재시작합니다.", @@ -105,21 +110,23 @@ "Doctor.Button.No": "아니요", "Doctor.Button.Skip": "그대로 두기", "Doctor.Button.Yes": "예", - "Doctor.Dialogue.Main": "안녕하세요! ${activateReason} 로 인해 구성 진단 마법사가 활성화되었습니다!\n그리고 일부 구성이 잠재적인 문제로 감지되었습니다.\n안심하세요. 하나씩 해결해 봅시다.\n\n대상 항목은 다음과 같습니다.\n\n${issues}\n\n시작하시겠습니까?", - "Doctor.Dialogue.MainFix": "**구성 이름:** `${name}`\n**현재 값:** `${current}`, **이상적인 값:** `${ideal}`\n**권장 수준:** ${level}\n**왜 이것이 감지되었나요?**\n${reason}\n\n\n${note}\n\n이상적인 값으로 수정하시겠습니까?", + "Doctor.Dialogue.Main": "안녕하세요! ${activateReason}(으)로 인해 구성 진단 마법사가 실행되었습니다!\n아쉽게도 일부 구성에서 잠재적인 문제가 감지되었습니다.\n걱정하지 마세요. 하나씩 함께 해결해 보겠습니다.\n\n미리 알려드리자면, 다음 항목들에 대해 여쭤보겠습니다.\n\n${issues}\n\n시작할까요?", + "Doctor.Dialogue.MainFix": "\n## ${name}\n\n| 현재 값 | 이상적인 값 |\n|:---:|:---:|\n| ${current} | ${ideal} |\n\n**권장 수준:** ${level}\n\n### 왜 이것이 감지되었나요?\n\n${reason}\n\n${note}\n\n이상적인 값으로 수정할까요?", "Doctor.Dialogue.Title": "Self-hosted LiveSync 구성 진단 마법사", "Doctor.Dialogue.TitleAlmostDone": "거의 완료되었습니다!", "Doctor.Dialogue.TitleFix": "문제 해결 ${current}/${total}", "Doctor.Level.Must": "필수", - "Doctor.Level.Necessary": "필수", + "Doctor.Level.Necessary": "필요", "Doctor.Level.Optional": "선택사항", "Doctor.Level.Recommended": "권장", "Doctor.Message.NoIssues": "문제가 감지되지 않았습니다!", "Doctor.Message.RebuildLocalRequired": "주의! 이를 적용하려면 로컬 데이터베이스 재구축이 필요합니다!", "Doctor.Message.RebuildRequired": "주의! 이를 적용하려면 재구축이 필요합니다!", "Doctor.Message.SomeSkipped": "일부 문제를 그대로 두었습니다. 다음 시작 시 다시 질문할까요?", - "Duplicate": "복제", - "Duplicate remote": "원격 구성 복제", + "Doctor.RULES.E2EE_V02500.REASON": "종단 간 암호화가 더 견고하고 빨라졌습니다. 또한 다시 진행한 코드 검토에서 이전 E2EE에 취약점이 있는 것으로 확인되었기 때문에, 가능한 한 빨리 적용해 주시기 바랍니다. 불편을 드려 대단히 죄송합니다. 그리고 이 설정은 이전 버전과 호환되지 않습니다. 동기화 중인 모든 기기를 v0.25.0 이상으로 업데이트해야 합니다. 재구축은 필요하지 않으며 새로 전송되는 항목부터 새 형식으로 변환됩니다. 다만 가능하다면 재구축하시기를 권장합니다.", + "Document History": "문서 기록", + "Duplicate": "복사본 만들기", + "Duplicate remote": "원격 구성 복사", "E2EE Configuration": "E2EE 구성", "Edge case addressing (Behaviour)": "특수 상황 처리 (동작)", "Edge case addressing (Database)": "특수 상황 처리 (데이터베이스)", @@ -134,73 +141,80 @@ "Enable this option to automatically apply the most recent change to documents even when it conflicts": "이 옵션을 활성화하면 충돌이 있어도 문서에 가장 최근 변경 사항을 자동으로 적용합니다", "Encrypt contents on the remote database. If you use the plugin's synchronization feature, enabling this is recommended.": "원격 데이터베이스의 내용을 암호화합니다. 플러그인의 동기화 기능을 사용하는 경우 활성화를 권장합니다.", "Encrypting sensitive configuration items": "민감한 구성 항목 암호화", - "Encryption phassphrase. If changed, you should overwrite the server's database with the new (encrypted) files.": "패스프레이즈는 암호화에 사용되는 긴 암호 문구입니다. 변경한 경우, 암호화된 새 파일로 서버의 데이터베이스를 덮어써야 합니다.", - "End-to-End Encryption": "종단간 암호화", + "Encryption phassphrase. If changed, you should overwrite the server's database with the new (encrypted) files.": "암호화에 사용할 패스프레이즈입니다. 변경한 경우, 새로 암호화된 파일로 서버의 데이터베이스를 덮어써야 합니다.", + "End-to-End Encryption": "종단 간 암호화", "Endpoint URL": "엔드포인트 URL", - "Enhance chunk size": "청크 크기 향상", + "Enhance chunk size": "청크 크기 확대", "Enter Server Information": "서버 정보 입력", "Enter the server information manually": "서버 정보를 수동으로 입력", "Export": "내보내기", - "Failed to connect to remote for compaction.": "압축을 위해 원격 데이터베이스에 연결하지 못했습니다.", - "Failed to connect to remote for compaction. ${reason}": "압축을 위해 원격 데이터베이스에 연결하지 못했습니다. ${reason}", - "Failed to start one-shot replication before Garbage Collection. Garbage Collection Cancelled.": "Garbage Collection 전에 일회성 복제를 시작하지 못했습니다. Garbage Collection을 취소합니다.", - "Failed to start replication after Garbage Collection.": "Garbage Collection 후 복제를 시작하지 못했습니다.", + "Failed to connect to remote for compaction.": "압축 정리를 위해 원격 데이터베이스에 연결하지 못했습니다.", + "Failed to connect to remote for compaction. ${reason}": "압축 정리를 위해 원격 데이터베이스에 연결하지 못했습니다. ${reason}", + "Failed to start one-shot replication before Garbage Collection. Garbage Collection Cancelled.": "가비지 컬렉션 전에 일회성 복제를 시작하지 못했습니다. 가비지 컬렉션을 취소합니다.", + "Failed to start replication after Garbage Collection.": "가비지 컬렉션 후 복제를 시작하지 못했습니다.", "Fetch": "가져오기", "Fetch chunks on demand": "필요 시 청크 원격 가져오기", "Fetch database with previous behaviour": "이전 동작으로 데이터베이스 가져오기", "Fetch remote settings": "원격 설정 가져오기", "File to resolve conflict": "충돌을 해결할 파일", + "File to view History": "기록을 볼 파일", "Filename": "파일명", - "First, please select the option that best describes your current situation.": "먼저 현재 상황에 가장 잘 맞는 항목을 선택해 주세요。", + "First, please select the option that best describes your current situation.": "먼저 현재 상황에 가장 잘 맞는 항목을 선택해 주세요.", "Flag and restart": "표시 후 재시작", "Forces the file to be synced when opened.": "파일을 열 때 강제로 동기화합니다.", - "Fresh Start Wipe": "새로 시작 지우기", - "Garbage Collection cancelled by user.": "사용자가 Garbage Collection을 취소했습니다.", - "Garbage Collection completed. Deleted chunks: ${deletedChunks} / ${totalChunks}. Time taken: ${seconds} seconds.": "Garbage Collection이 완료되었습니다. 삭제된 청크: ${deletedChunks} / ${totalChunks}. 소요 시간: ${seconds}초.", - "Garbage Collection Confirmation": "Garbage Collection 확인", + "Fresh Start Wipe": "초기화 후 새로 시작", + "Garbage Collection cancelled by user.": "사용자가 가비지 컬렉션을 취소했습니다.", + "Garbage Collection completed. Deleted chunks: ${deletedChunks} / ${totalChunks}. Time taken: ${seconds} seconds.": "가비지 컬렉션이 완료되었습니다. 삭제된 청크: ${deletedChunks} / ${totalChunks}. 소요 시간: ${seconds}초.", + "Garbage Collection Confirmation": "가비지 컬렉션 확인", "Garbage Collection V3 (Beta)": "가비지 컬렉션 V3 (Beta)", - "Garbage Collection: Found ${unusedChunks} unused chunks to delete.": "Garbage Collection: 삭제할 미사용 청크 ${unusedChunks}개를 찾았습니다.", - "Garbage Collection: Scanned ${scanned} / ~${docCount}": "Garbage Collection: ${scanned} / ~${docCount} 스캔됨", - "Garbage Collection: Scanning completed. Total chunks: ${totalChunks}, Used chunks: ${usedChunks}": "Garbage Collection: 스캔 완료. 전체 청크 수: ${totalChunks}, 사용 중인 청크 수: ${usedChunks}", + "Garbage Collection: Found ${unusedChunks} unused chunks to delete.": "가비지 컬렉션: 삭제할 미사용 청크 ${unusedChunks}개를 찾았습니다.", + "Garbage Collection: Scanned ${scanned} / ~${docCount}": "가비지 컬렉션: ${scanned} / ~${docCount} 검사함", + "Garbage Collection: Scanning completed. Total chunks: ${totalChunks}, Used chunks: ${usedChunks}": "가비지 컬렉션: 검사 완료. 전체 청크 수: ${totalChunks}, 사용 중인 청크 수: ${usedChunks}", "Handle files as Case-Sensitive": "파일을 대소문자 구분으로 처리", "Hidden Files": "숨김 파일", + "Hide completely": "완전히 숨기기", + "Highlight diff": "차이 강조", "How to display network errors when the sync server is unreachable.": "동기화 서버에 연결할 수 없을 때 네트워크 오류를 어떻게 표시할지 설정합니다.", "How would you like to configure the connection to your server?": "서버 연결을 어떻게 구성하시겠습니까?", - "I am adding a device to an existing synchronisation setup": "기존 동기화 구성에 장치를 추가합니다", + "I am adding a device to an existing synchronisation setup": "기존 동기화 구성에 기기를 추가합니다", "I am setting this up for the first time": "처음으로 설정합니다", "I know my server details, let me enter them": "서버 정보를 알고 있으니 직접 입력하겠습니다", "If disabled(toggled), chunks will be split on the UI thread (Previous behaviour).": "비활성화(토글)되면 청크는 UI 스레드에서 분할됩니다 (이전 동작).", "If enabled per-filed efficient customization sync will be used. We need a small migration when enabling this. And all devices should be updated to v0.23.18. Once we enabled this, we lost a compatibility with old versions.": "활성화하면 파일별 효율적인 사용자 설정 동기화가 사용됩니다. 이를 활성화할 때 소규모 데이터 구조 전환이 필요합니다. 모든 기기를 v0.23.18로 업데이트해야 합니다. 이를 활성화하면 이전 버전과의 호환성이 사라집니다.", "If enabled, chunks will be split into no more than 100 items. However, dedupe is slightly weaker.": "활성화하면 청크는 최대 100개 항목으로 분할됩니다. 하지만 중복 제거 기능이 약간 약해집니다.", - "If enabled, newly created chunks are temporarily kept within the document, and graduated to become independent chunks once stabilised.": "활성화하면 새로 생성된 변경 기록(청크)은 문서 안에 임시로 보관되며, 일정 조건을 만족하면 자동으로 문서 밖으로 분리되어 저장됩니다.", + "If enabled, newly created chunks are temporarily kept within the document, and graduated to become independent chunks once stabilised.": "활성화하면 새로 생성된 청크가 문서 안에 임시로 보관되며, 안정화된 뒤에 독립된 청크로 분리됩니다.", "If enabled, the ⛔ icon will be shown inside the status instead of the file warnings banner. No details will be shown.": "활성화하면 파일 경고 배너 대신 상태 영역에 ⛔ 아이콘만 표시됩니다. 자세한 내용은 표시되지 않습니다.", "If enabled, the file under 1kb will be processed in the UI thread.": "활성화하면 1kb 미만의 파일은 UI 스레드에서 처리됩니다.", - "If enabled, the notification of hidden files change will be suppressed.": "활성화하면 숨겨진 파일 변경 알림이 억제됩니다.", + "If enabled, the notification of hidden files change will be suppressed.": "활성화하면 숨김 파일 변경 알림이 표시되지 않습니다.", "If this enabled, all chunks will be stored with the revision made from its content. (Previous behaviour)": "이 옵션이 활성화되면 모든 청크는 콘텐츠에서 생성된 리비전과 함께 저장됩니다. (이전 동작)", "If this enabled, All files are handled as case-Sensitive (Previous behaviour).": "이 옵션이 활성화되면 모든 파일이 대소문자를 구분하여 처리됩니다 (이전 동작).", "If this enabled, chunks will be split into semantically meaningful segments. Not all platforms support this feature.": "이 옵션을 활성화하면 청크가 문단이나 의미 단위로 나뉘어 저장됩니다. 단, 이 기능은 일부 플랫폼에서는 지원되지 않을 수 있습니다.", "If this is set, changes to local files which are matched by the ignore files will be skipped. Remote changes are determined using local ignore files.": "이 옵션을 활성화하면, 제외 규칙 파일에 일치하는 로컬 파일의 변경 사항은 건너뜁니다. 원격 변경 여부 또한 로컬의 제외 규칙 파일에 따라 판단됩니다.", "If this option is enabled, PouchDB will hold the connection open for 60 seconds, and if no change arrives in that time, close and reopen the socket, instead of holding it open indefinitely. Useful when a proxy limits request duration but can increase resource usage.": "이 옵션이 활성화되면 PouchDB는 연결을 더이상 무한히 열어두지 않고 60초 동안 유지합니다. 그 시간 내에 변경 사항이 없으면 소켓을 닫고 다시 엽니다. 프록시가 요청 지속 시간을 제한할 때 유용하지만 리소스 사용량이 증가할 수 있습니다.", + "If you reached the payload size limit when using IBM Cloudant, please decrease batch size and batch limit to a lower value.": "IBM Cloudant를 사용하다가 페이로드 크기 제한에 도달했다면, 배치 크기와 배치 개수 제한을 더 낮은 값으로 줄여 주세요.", "Ignore and Proceed": "무시하고 계속", "Ignore files": "제외 규칙 파일", "Ignore patterns": "무시 패턴", "Import connection": "연결 가져오기", - "Incubate Chunks in Document": "문서 내 변경 기록 임시 보관", + "Incubate Chunks in Document": "문서 내 청크 임시 보관", "Initialise all journal history, On the next sync, every item will be received and sent.": "모든 저널 기록을 초기화합니다. 다음 동기화 때 모든 항목을 다시 받고 다시 보냅니다.", + "Initialise journal received history. On the next sync, every item except this device sent will be downloaded again.": "저널 수신 기록을 초기화합니다. 다음 동기화 때 이 기기가 보낸 항목을 제외한 모든 항목을 다시 내려받습니다.", + "Initialise journal sent history. On the next sync, every item except this device received will be sent again.": "저널 송신 기록을 초기화합니다. 다음 동기화 때 이 기기가 받은 항목을 제외한 모든 항목을 다시 보냅니다.", "Interval (sec)": "간격 (초)", "K.exp": "실험 기능", "K.long_p2p_sync": "%{title_p2p_sync} (%{exp})", "K.P2P": "%{Peer}-to-%{Peer}", "K.Peer": "피어", "K.ScanCustomization": "사용자 설정 검색", - "K.short_p2p_sync": "P2P 동기화 (%{exp})", + "K.short_p2p_sync": "P2P 동기화", "K.title_p2p_sync": "피어 투 피어(P2P) 동기화", "Keep empty folder": "빈 폴더 유지", - "lang_def": "Default", + "lang_def": "기본값", "lang-de": "Deutsche", "lang-def": "%{lang_def}", "lang-es": "Español", "lang-fr": "Français", + "lang-he": "עברית", "lang-ja": "日本語", "lang-ko": "한국어", "lang-ru": "Русский", @@ -208,18 +222,19 @@ "lang-zh-tw": "繁體中文", "Later": "나중에", "Limit: {datetime} ({timestamp})": "제한: {datetime} ({timestamp})", - "LiveSync could not handle multiple vaults which have same name without different prefix, This should be automatically configured.": "LiveSync는 서로 다른 접두사 없이 동일한 이름을 가진 여러 볼트를 처리할 수 없습니다. 이는 자동으로 구성되어야 합니다.", + "LiveSync could not handle multiple vaults which have same name without different prefix, This should be automatically configured.": "LiveSync는 접두사로 구분되지 않은 동일한 이름의 보관함을 여러 개 처리할 수 없습니다. 이 값은 자동으로 구성되어야 합니다.", "liveSyncReplicator.beforeLiveSync": "LiveSync 전에 OneShot을 먼저 시작합니다...", "liveSyncReplicator.cantReplicateLowerValue": "더 낮은 값으로 복제할 수 없습니다.", "liveSyncReplicator.checkingLastSyncPoint": "마지막으로 동기화된 지점을 찾고 있습니다.", "liveSyncReplicator.couldNotConnectTo": "${uri}에 연결할 수 없습니다: ${name}\n(${db})", "liveSyncReplicator.couldNotConnectToRemoteDb": "원격 데이터베이스에 연결할 수 없습니다: ${d}", - "liveSyncReplicator.couldNotConnectToServer": "서버에 연결할 수 없습니다.", + "liveSyncReplicator.couldNotConnectToServer": "원격에 대한 연결이 차단되었거나 실패했습니다.", "liveSyncReplicator.couldNotConnectToURI": "${uri}에 연결할 수 없습니다: ${dbRet}", "liveSyncReplicator.couldNotMarkResolveRemoteDb": "원격 데이터베이스를 해결됨으로 표시할 수 없습니다.", "liveSyncReplicator.liveSyncBegin": "LiveSync 시작...", "liveSyncReplicator.lockRemoteDb": "데이터 손상을 방지하기 위해 원격 데이터베이스를 잠급니다", "liveSyncReplicator.markDeviceResolved": "이 기기를 '해결됨'으로 표시합니다.", + "liveSyncReplicator.mismatchedTweakDetected": "기기 간 구성에서 일부 불일치가 감지되었습니다. 수동으로 복제를 실행하면 이 문제를 해결하려고 시도합니다.", "liveSyncReplicator.oneShotSyncBegin": "OneShot 동기화 시작... (${syncMode})", "liveSyncReplicator.remoteDbCorrupted": "원격 데이터베이스가 더 최신이거나 손상되었습니다. 최신 버전의 self-hosted-livesync가 설치되어 있는지 확인하세요", "liveSyncReplicator.remoteDbCreatedOrConnected": "원격 데이터베이스가 생성되거나 연결되었습니다", @@ -228,7 +243,7 @@ "liveSyncReplicator.remoteDbMarkedResolved": "원격 데이터베이스가 해결됨으로 표시되었습니다.", "liveSyncReplicator.replicationClosed": "복제가 종료되었습니다", "liveSyncReplicator.replicationInProgress": "복제가 이미 진행 중입니다", - "liveSyncReplicator.retryLowerBatchSize": "더 낮은 일괄 크기로 재시도: ${batch_size}/${batches_limit}", + "liveSyncReplicator.retryLowerBatchSize": "더 작은 배치 크기로 재시도: ${batch_size}/${batches_limit}", "liveSyncReplicator.unlockRemoteDb": "데이터 손상을 방지하기 위해 원격 데이터베이스를 잠금 해제합니다", "liveSyncSetting.errorNoSuchSettingItem": "해당 설정 항목이 없습니다: ${key}", "liveSyncSetting.originalValue": "원본: ${value}", @@ -240,14 +255,14 @@ "Lock the remote server to prevent synchronization with other devices.": "다른 기기와의 동기화를 방지하기 위해 원격 서버를 잠급니다.", "logPane.autoScroll": "자동 스크롤", "logPane.logWindowOpened": "로그 창이 열렸습니다", - "logPane.pause": "일시 중단", + "logPane.pause": "일시 정지", "logPane.title": "Self-hosted LiveSync 로그", "logPane.wrap": "줄 바꿈", "Maximum delay for batch database updating": "일괄 데이터베이스 업데이트 최대 지연", "Maximum file size": "최대 파일 크기", - "Maximum Incubating Chunk Size": "임시 보관 변경 기록의 최대 크기", - "Maximum Incubating Chunks": "임시 보관 중인 변경 기록 최대 수", - "Maximum Incubation Period": "변경 기록 임시 보관 최대 시간", + "Maximum Incubating Chunk Size": "임시 보관 청크의 최대 크기", + "Maximum Incubating Chunks": "임시 보관 청크의 최대 개수", + "Maximum Incubation Period": "청크 임시 보관 최대 기간", "MB (0 to disable).": "MB (0으로 설정하면 비활성화).", "Memory cache": "메모리 캐시", "Memory cache size (by total characters)": "메모리 캐시 크기 (총 문자 수)", @@ -257,11 +272,13 @@ "Minimum interval for syncing": "동기화 최소 간격", "moduleCheckRemoteSize.logCheckingStorageSizes": "스토리지 크기 확인 중", "moduleCheckRemoteSize.logCurrentStorageSize": "원격 스토리지 크기: ${measuredSize}", - "moduleCheckRemoteSize.logExceededWarning": "원격 스토리지 크기: ${measuredSize}가 ${notifySize}를 초과했습니다", + "moduleCheckRemoteSize.logExceededWarning": "원격 스토리지 크기: ${measuredSize}이(가) ${notifySize}을(를) 초과했습니다", "moduleCheckRemoteSize.logThresholdEnlarged": "임계값이 ${size}MB로 증가되었습니다", "moduleCheckRemoteSize.msgConfirmRebuild": "시간이 꽤 오래 걸릴 수 있습니다. 정말 지금 모든 것을 재구축하시겠습니까?", - "moduleCheckRemoteSize.msgDatabaseGrowing": "**데이터베이스 용량이 점점 커지고 있습니다!** 하지만 걱정하지 마세요. 아직 원격 스토리지 공간이 완전히 부족해진 건 아닙니다.\n\n| 측정된 크기 | 설정된 한도 |\n| --- | --- |\n| ${estimatedSize} | ${maxSize} |\n\n> [!MORE]-\n> 오랜 기간 사용했다면 참조되지 않는 청크, 즉 '쓰레기 데이터'가 쌓였을 수 있습니다. 이 경우 전체 재구성을 권장합니다. 용량이 훨씬 줄어들 수 있습니다.\n>\n> 단순히 볼트 자체 용량이 커지고 있는 것이라면, 먼저 파일을 정리한 후 전체를 재구성하는 것이 좋습니다. Self-hosted LiveSync는 처리 속도를 위해 삭제해도 실제 데이터를 바로 지우지 않습니다. 이 내용은 [기술 문서](https://github.com/vrtmrz/obsidian-livesync/blob/main/docs/tech_info.md)에 간략히 정리되어 있습니다.\n>\n> 용량 증가가 괜찮다면 알림 임계치를 100MB 단위로 높일 수 있습니다. 직접 서버를 운영하는 경우에 적합한 방법입니다. 다만, 가끔은 전체 재구성을 해주는 것이 바람직합니다.\n\n> [!WARNING]\n> 전체 재구성을 실행할 경우, 모든 기기가 반드시 동기화되어 있어야 합니다. 플러그인이 최대한 병합하려고 시도하긴 하지만 완전하지 않을 수 있습니다.", - "moduleCheckRemoteSize.msgSetDBCapacity": "**원격 스토리지 공간이 부족해지기 전에 미리 조치할 수 있도록** 데이터베이스 용량 경고를 설정할 수 있습니다.\n이 기능을 활성화하시겠습니까?\n\n> [!MORE]-\n> - 0: 스토리지 용량에 대한 경고 없음\n> 자체 서버를 사용하는 등 여유 공간이 충분한 경우에 권장됩니다. 스토리지 용량을 직접 확인하고 수동으로 재구성할 수 있습니다.\n> - 800: 원격 스토리지 용량이 800MB를 초과하면 경고\n> 1GB 제한이 있는 fly.io나 IBM Cloudant 사용 시 권장됩니다.\n> - 2000: 원격 스토리지 용량이 2GB를 초과하면 경고\n\n설정한 용량 한도에 도달하면, 단계적으로 경고 한도를 늘릴지 여부를 묻게 됩니다.\n", + "moduleCheckRemoteSize.msgDatabaseGrowing": "**데이터베이스 용량이 점점 커지고 있습니다!** 하지만 걱정하지 마세요. 지금 대응할 수 있습니다. 원격 스토리지 공간이 부족해지기까지 남은 시간입니다.\n\n| 측정된 크기 | 설정된 한도 |\n| --- | --- |\n| ${estimatedSize} | ${maxSize} |\n\n> [!MORE]-\n> 오랜 기간 사용했다면 참조되지 않는 청크, 즉 쓰레기 데이터가 데이터베이스에 쌓였을 수 있습니다. 이 경우 전체 재구축을 권장합니다. 용량이 훨씬 줄어들 것입니다.\n>\n> 단순히 보관함 용량이 커지고 있는 것이라면, 파일을 정리한 뒤에 전체를 재구축하는 것이 좋습니다. Self-hosted LiveSync는 처리 속도를 위해 파일을 삭제해도 실제 데이터를 바로 지우지 않습니다. 이 내용은 [기술 문서](https://github.com/vrtmrz/obsidian-livesync/blob/main/docs/tech_info.md)에 간략히 정리되어 있습니다.\n>\n> 용량 증가가 괜찮다면 알림 한도를 100MB 단위로 높일 수 있습니다. 직접 서버를 운영하는 경우에 적합한 방법입니다. 다만 가끔은 전체를 재구축해 주는 것이 좋습니다.\n>\n\n> [!WARNING]\n> 전체 재구축을 실행할 때는 모든 기기가 동기화되어 있는지 확인해 주세요. 플러그인이 최대한 병합하려고 시도하기는 합니다.\n", + "moduleCheckRemoteSize.msgSetDBCapacity": "**원격 스토리지 공간이 부족해지기 전에 미리 조치할 수 있도록** 데이터베이스 용량 경고를 설정할 수 있습니다.\n이 기능을 활성화하시겠습니까?\n\n> [!MORE]-\n> - 0: 스토리지 용량을 경고하지 않습니다.\n> 직접 서버를 운영하는 등 원격 스토리지에 여유 공간이 충분한 경우에 권장합니다. 스토리지 용량을 직접 확인하고 수동으로 재구축할 수 있습니다.\n> - 800: 원격 스토리지 용량이 800MB를 초과하면 경고합니다.\n> 1GB 제한이 있는 fly.io나 IBM Cloudant를 사용하는 경우에 권장합니다.\n> - 2000: 원격 스토리지 용량이 2GB를 초과하면 경고합니다.\n\n한도에 도달하면 한도를 단계적으로 늘릴지 여쭤보겠습니다.\n", + "moduleCheckRemoteSize.noticeExceeded": "원격 스토리지 크기 ${measuredSize}이(가) 설정된 알림 임계값 ${notifySize}을(를) 초과했습니다. {HERE}", + "moduleCheckRemoteSize.noticeNotConfigured": "원격 스토리지 크기 알림이 설정되어 있지 않습니다. {HERE}", "moduleCheckRemoteSize.option2GB": "2GB (표준)", "moduleCheckRemoteSize.option800MB": "800MB (Cloudant, fly.io)", "moduleCheckRemoteSize.optionAskMeLater": "나중에 물어보기", @@ -269,6 +286,7 @@ "moduleCheckRemoteSize.optionIncreaseLimit": "${newMax}MB로 증가", "moduleCheckRemoteSize.optionNoWarn": "아니요, 경고하지 마세요", "moduleCheckRemoteSize.optionRebuildAll": "지금 모든 것 재구축", + "moduleCheckRemoteSize.optionReview": "옵션 검토", "moduleCheckRemoteSize.titleDatabaseSizeLimitExceeded": "원격 스토리지 크기가 제한을 초과했습니다", "moduleCheckRemoteSize.titleDatabaseSizeNotify": "데이터베이스 크기 알림 설정", "moduleInputUIObsidian.defaultTitleConfirmation": "확인", @@ -284,17 +302,29 @@ "moduleLiveSyncMain.logSafetyScanFailed": "모듈에서 추가 안전 검사가 실패했습니다", "moduleLiveSyncMain.logUnloadingPlugin": "플러그인 언로딩 중...", "moduleLiveSyncMain.logVersionUpdate": "LiveSync가 업데이트되었습니다. 호환성 문제가 있는 업데이트의 경우 모든 자동 동기화가 일시적으로 비활성화되었습니다. 활성화하기 전에 모든 기기가 최신 상태인지 확인하세요.", - "moduleLiveSyncMain.msgScramEnabled": "Self-hosted LiveSync가 일부 이벤트를 무시하도록 설정되어 있습니다. 이 설정이 맞습니까?\n\n| 유형 | 상태 | 설명 |\n|:---:|:---:|---|\n| 스토리지 이벤트 | ${fileWatchingStatus} | 모든 수정 사항이 무시됩니다 |\n| 데이터베이스 이벤트 | ${parseReplicationStatus} | 모든 동기화 변경이 지연됩니다 |\n\n이벤트 감지를 다시 활성화하고 Obsidian을 재시작하시겠습니까?\n\n> [!DETAILS]-\n> 이러한 설정은 플러그인이 재구성 또는 데이터 가져오기 중에 자동으로 설정한 것입니다. 프로세스가 비정상적으로 종료되면 이 상태가 의도치 않게 유지될 수 있습니다.\n> 상태가 확실하지 않다면 이 과정을 다시 실행해 보세요. 재시작 전에 반드시 볼트를 백업해 주세요.", + "moduleLiveSyncMain.msgScramEnabled": "Self-hosted LiveSync가 일부 이벤트를 무시하도록 설정되어 있습니다. 이 설정이 맞습니까?\n\n| 유형 | 상태 | 설명 |\n|:---:|:---:|---|\n| 스토리지 이벤트 | ${fileWatchingStatus} | 모든 수정 사항이 무시됩니다 |\n| 데이터베이스 이벤트 | ${parseReplicationStatus} | 모든 동기화 변경이 지연됩니다 |\n\n이벤트 감지를 다시 활성화하고 Obsidian을 재시작하시겠습니까?\n\n> [!DETAILS]-\n> 이 플래그는 플러그인이 재구축하거나 가져오는 동안 설정한 것입니다. 처리가 비정상적으로 종료되면 의도치 않게 남아 있을 수 있습니다.\n> 확실하지 않다면 해당 처리를 다시 실행해 보세요. 반드시 보관함을 백업해 두시기 바랍니다.\n", "moduleLiveSyncMain.optionKeepLiveSyncDisabled": "LiveSync 비활성화 유지", "moduleLiveSyncMain.optionResumeAndRestart": "재개 후 Obsidian 재시작", - "moduleLiveSyncMain.titleScramEnabled": "Scram 활성화됨", + "moduleLiveSyncMain.titleScramEnabled": "긴급 정지 활성화됨", "moduleLocalDatabase.logWaitingForReady": "준비 대기 중...", "moduleLog.showLog": "로그 표시", "moduleMigration.docUri": "https://github.com/vrtmrz/obsidian-livesync/blob/main/README.md#how-to-use", + "moduleMigration.fix0256.buttons.checkItLater": "나중에 확인", + "moduleMigration.fix0256.buttons.DismissForever": "이미 해결했으니 다시 묻지 않기", + "moduleMigration.fix0256.buttons.fix": "수정", + "moduleMigration.fix0256.message": "최근 버그(v0.25.6)로 인해 일부 파일이 동기화 데이터베이스에 올바르게 저장되지 않았을 수 있습니다.\n파일을 검사한 결과 수정이 필요한 파일을 발견했습니다.\n\n**수정할 수 있는 파일:**\n\n${files}\n\n이 파일들은 스토리지에 크기가 일치하는 원본이 있어 복구할 수 있을 것으로 보입니다.\n이를 이용해 데이터베이스를 고칠 수 있으니, 아래 \"수정\" 버튼을 눌러 주세요.\n\n${messageUnrecoverable}\n\n다시 실행하려면 Hatch에서 실행할 수 있습니다.\n", + "moduleMigration.fix0256.messageUnrecoverable": "**이 기기에서는 수정할 수 없는 파일:**\n\n${filesNotRecoverable}\n\n이 파일들은 메타데이터가 일치하지 않아 이 기기에서는 수정할 수 없습니다(대부분 어느 쪽이 올바른지 판단할 수 없습니다).\n복원하려면 다른 기기에서 이 기능으로 확인해 보시거나, 백업에서 직접 복원해 주세요.\n", + "moduleMigration.fix0256.title": "손상된 파일이 감지되었습니다", + "moduleMigration.insecureChunkExist.buttons.fetch": "원격을 이미 재구축했습니다. 원격에서 가져오기", + "moduleMigration.insecureChunkExist.buttons.later": "나중에 하기", + "moduleMigration.insecureChunkExist.buttons.rebuild": "모두 재구축", + "moduleMigration.insecureChunkExist.laterMessage": "가능한 한 빨리 조치하시기를 강력히 권장합니다!", + "moduleMigration.insecureChunkExist.message": "일부 청크가 데이터베이스에 안전하게 저장되지 않았으며 암호화되어 있지 않습니다.\n**이 문제를 해결하려면 데이터베이스를 재구축해 주세요.**\n\n원격 데이터베이스에 SSL이 설정되어 있지 않거나 보안이 취약한 자격 증명을 사용하고 있다면, **민감한 데이터가 노출될 위험이 있습니다.**\n\n참고: 모든 기기의 Self-hosted LiveSync를 v0.25.6 이상으로 업그레이드하고, 보관함을 반드시 백업해 주세요.\n참고 2: 모두 재구축과 가져오기는 시간과 트래픽을 다소 소모하므로, 사용량이 적은 시간대에 안정적인 네트워크 환경에서 진행해 주세요.\n", + "moduleMigration.insecureChunkExist.title": "안전하지 않은 청크가 발견되었습니다!", "moduleMigration.logBulkSendCorrupted": "청크 일괄 전송이 활성화되었지만, 이 기능에 문제가 있었습니다. 불편을 드려 죄송합니다. 자동으로 비활성화되었습니다.", "moduleMigration.logFetchRemoteTweakFailed": "원격 조정 값을 가져오는데 실패했습니다", "moduleMigration.logLocalDatabaseNotReady": "문제가 발생했습니다! 로컬 데이터베이스가 준비되지 않았습니다", - "moduleMigration.logMigratedSameBehaviour": "이전과 같은 방식으로 동작하도록 db:${current}로 데이터 구조 전환이 완료되었습니다", + "moduleMigration.logMigratedSameBehaviour": "이전과 동일하게 동작하도록 db:${current}(으)로 마이그레이션했습니다", "moduleMigration.logMigrationFailed": "${old}에서 ${current}로의 데이터 구조 전환이 실패했거나 중단되었습니다", "moduleMigration.logRedflag2CreationFail": "redflag2 생성에 실패했습니다", "moduleMigration.logRemoteTweakUnavailable": "원격 조정 값을 가져올 수 없습니다", @@ -302,7 +332,7 @@ "moduleMigration.msgFetchRemoteAgain": "이미 알고 계시겠지만, Self-hosted LiveSync의 기본 동작 방식과 데이터베이스 구조가 변경되었습니다.\n\n다행히도 여러분의 노력 덕분에 원격 데이터베이스는 이미 성공적으로 데이터 구조 전환이 완료된 것으로 보입니다. 축하드립니다!\n\n하지만 아직 일부 추가 작업이 필요합니다. 이 기기의 설정이 원격 데이터베이스와 호환되지 않으므로, 원격 데이터를 다시 가져와야 합니다. 지금 원격 데이터베이스를 다시 가져오시겠습니까?\n\n___참고: 설정이 변경되고 데이터베이스를 다시 불러오기 전까지는 동기화가 불가능합니다.___\n___참고2: 청크는 변경이 불가능한 구조이므로, 메타데이터와 차이점만 가져올 수 있습니다.___", "moduleMigration.msgInitialSetup": "이 기기는 **아직 초기 설정이 완료되지 않았습니다**. 지금부터 설정 과정을 안내해 드리겠습니다.\n\n모든 대화 내용은 클립보드에 복사할 수 있습니다. 나중에 참고하려면 Obsidian 노트에 붙여넣거나 번역 도구를 활용해 번역하셔도 됩니다.\n\n먼저, **Setup URI**를 가지고 계신가요?\n\n참고: Setup URI가 무엇인지 잘 모르시겠다면 [문서](${URI_DOC})를 참고해 주세요.", "moduleMigration.msgRecommendSetupUri": "Setup URI를 생성해 사용하는 것을 강력히 권장합니다.\nSetup URI가 무엇인지 잘 모르시겠다면 [문서](${URI_DOC})를 참고해 주세요. 중요한 내용이니 꼭 확인하시기 바랍니다.\n\n직접 수동 설정을 진행하시겠습니까?", - "moduleMigration.msgSinceV02321": "v0.23.21부터 Self-hosted LiveSync의 기본 동작 방식과 데이터베이스 구조가 변경되었습니다. 주요 변경사항은 다음과 같습니다:\n\n1. **파일명 대소문자 구분 처리**\n 이제 파일명은 대소문자를 구분하지 않고 처리됩니다. 이는 파일명 구분을 제대로 지원하지 않는 Linux 및 iOS를 제외한 대부분의 플랫폼에서 유리한 변화입니다.\n (Linux나 iOS에서는 대소문자만 다른 파일이 존재할 경우 경고가 표시됩니다)\n\n2. **청크 리비전 관리 방식 개선**\n 청크는 변경 불가능한(immutable) 구조로 고정되며, 이를 통해 리비전 처리가 안정화되고 파일 저장 성능이 향상됩니다.\n\n___단, 위 기능을 활성화하려면 원격 및 로컬 데이터베이스를 모두 재구성해야 합니다. 이 과정은 수 분이 소요되므로 여유가 있을 때 실행하시는 것을 권장합니다.___\n\n- 기존 방식대로 유지하려면 `${KEEP}`을 선택해 이 과정을 건너뛸 수 있습니다.\n- 시간이 부족하다면 `${DISMISS}`를 눌러주시면 나중에 다시 안내드리겠습니다.\n- 이미 다른 기기에서 데이터베이스를 재구성하셨다면 `${DISMISS}`를 선택한 뒤 다시 동기화해 보세요. 차이점이 감지되면 다시 안내드리겠습니다.", + "moduleMigration.msgSinceV02321": "v0.23.21부터 Self-hosted LiveSync의 기본 동작 방식과 데이터베이스 구조가 변경되었습니다. 변경 내용은 다음과 같습니다:\n\n1. **파일명의 대소문자 구분**\n 이제 파일명을 대소문자 구분 없이 처리합니다. 파일명의 대소문자를 제대로 관리하지 못하는 Linux와 iOS를 제외한 대부분의 플랫폼에서 유리한 변경입니다.\n (해당 플랫폼에서는 이름이 같고 대소문자만 다른 파일에 대해 경고가 표시됩니다)\n\n2. **청크의 리비전 처리**\n 청크는 변경 불가능하므로 리비전을 고정할 수 있습니다. 이 변경으로 파일 저장 성능이 향상됩니다.\n\n___다만 이 변경 중 어느 하나라도 적용하려면 원격과 로컬 데이터베이스를 모두 재구축해야 합니다. 이 과정은 몇 분이 걸리므로 시간이 충분할 때 진행하시기를 권장합니다.___\n\n- 기존 동작을 유지하려면 `${KEEP}`을 선택해 이 과정을 건너뛸 수 있습니다.\n- 시간이 충분하지 않다면 `${DISMISS}`를 선택해 주세요. 나중에 다시 여쭤보겠습니다.\n- 다른 기기에서 이미 데이터베이스를 재구축했다면 `${DISMISS}`를 선택한 뒤 다시 동기화해 보세요. 차이가 감지되면 다시 안내해 드립니다.", "moduleMigration.optionAdjustRemote": "원격에 맞추기", "moduleMigration.optionDecideLater": "나중에 결정하기", "moduleMigration.optionEnableBoth": "둘 다 활성화", @@ -325,7 +355,7 @@ "Move remotely deleted files to the trash, instead of deleting.": "원격에서 삭제된 파일을 삭제하는 대신 휴지통으로 이동합니다.", "Network warning style": "네트워크 경고 표시 방식", "New Remote": "새 원격", - "No connected device information found. Cancelling Garbage Collection.": "연결된 기기 정보를 찾을 수 없습니다. Garbage Collection을 취소합니다.", + "No connected device information found. Cancelling Garbage Collection.": "연결된 기기 정보를 찾을 수 없습니다. 가비지 컬렉션을 취소합니다.", "No limit configured": "제한이 설정되지 않음", "No, please take me back": "아니요, 이전으로 돌아가겠습니다", "Node ID": "노드 ID", @@ -337,14 +367,14 @@ "Notify customized": "사용자 설정 알림", "Notify when other device has newly customized.": "다른 기기에서 새로운 사용자 설정이 있을 때 알림을 받습니다.", "Notify when the estimated remote storage size exceeds on start up": "시작 시 예상 원격 스토리지 크기가 초과되면 알림", - "Number of batches to process at a time. Defaults to 40. Minimum is 2. This along with batch size controls how many docs are kept in memory at a time.": "한 번에 처리할 일괄 처리 수입니다. 기본값은 40입니다. 최소값은 2입니다. 이는 일괄 크기와 함께 메모리에 보관되는 문서 수를 제어합니다.", + "Number of batches to process at a time. Defaults to 40. Minimum is 2. This along with batch size controls how many docs are kept in memory at a time.": "한 번에 처리할 배치 개수입니다. 기본값은 40이고 최소값은 2입니다. 배치 크기와 함께 한 번에 메모리에 보관되는 문서 수를 결정합니다.", "Number of changes to sync at a time. Defaults to 50. Minimum is 2.": "한 번에 동기화할 변경 사항의 수입니다. 기본값은 50입니다. 최소값은 2입니다.", "Obsidian version": "Obsidian 버전", "obsidianLiveSyncSettingTab.btnApply": "적용", "obsidianLiveSyncSettingTab.btnCheck": "확인", "obsidianLiveSyncSettingTab.btnCopy": "복사", "obsidianLiveSyncSettingTab.btnDisable": "비활성화", - "obsidianLiveSyncSettingTab.btnDiscard": "삭제", + "obsidianLiveSyncSettingTab.btnDiscard": "폐기", "obsidianLiveSyncSettingTab.btnEnable": "활성화", "obsidianLiveSyncSettingTab.btnFix": "수정", "obsidianLiveSyncSettingTab.btnGotItAndUpdated": "알겠습니다. 업데이트했습니다.", @@ -368,6 +398,7 @@ "obsidianLiveSyncSettingTab.errCorsNotAllowingCredentials": "❗ CORS에서 자격 증명을 허용하지 않습니다", "obsidianLiveSyncSettingTab.errCorsOrigins": "❗ cors.origins가 잘못되었습니다", "obsidianLiveSyncSettingTab.errEnableCors": "❗ httpd.enable_cors가 잘못되었습니다", + "obsidianLiveSyncSettingTab.errEnableCorsChttpd": "❗ chttpd.enable_cors가 잘못되었습니다", "obsidianLiveSyncSettingTab.errMaxDocumentSize": "❗ couchdb.max_document_size가 낮습니다)", "obsidianLiveSyncSettingTab.errMaxRequestSize": "❗ chttpd.max_http_request_size가 낮습니다)", "obsidianLiveSyncSettingTab.errMissingWwwAuth": "❗ httpd.WWW-Authenticate가 누락되었습니다", @@ -391,7 +422,7 @@ "obsidianLiveSyncSettingTab.logConfiguredLiveSync": "구성된 동기화 모드: LiveSync", "obsidianLiveSyncSettingTab.logConfiguredPeriodic": "구성된 동기화 모드: 주기적", "obsidianLiveSyncSettingTab.logCouchDbConfigFail": "CouchDB 구성: ${title} 실패", - "obsidianLiveSyncSettingTab.logCouchDbConfigSet": "CouchDB 구성: ${title} -> ${key}를 ${value}로 설정", + "obsidianLiveSyncSettingTab.logCouchDbConfigSet": "CouchDB 구성: ${title} -> ${key}을(를) ${value}(으)로 설정", "obsidianLiveSyncSettingTab.logCouchDbConfigUpdated": "CouchDB 구성: ${title} 성공적으로 업데이트됨", "obsidianLiveSyncSettingTab.logDatabaseConnected": "데이터베이스 연결됨", "obsidianLiveSyncSettingTab.logEncryptionNoPassphrase": "패스프레이즈 없이는 암호화를 활성화할 수 없습니다", @@ -402,17 +433,19 @@ "obsidianLiveSyncSettingTab.logPassphraseNotCompatible": "오류: 패스프레이즈가 원격 서버와 호환되지 않습니다! 다시 확인해 주세요!", "obsidianLiveSyncSettingTab.logRebuildNote": "동기화가 비활성화되었습니다. 원하는 경우 가져오기 후 다시 활성화하세요.", "obsidianLiveSyncSettingTab.logSelectAnyPreset": "프리셋을 선택하세요.", + "obsidianLiveSyncSettingTab.logServerConfigurationCheck": "--서버 구성 확인--", "obsidianLiveSyncSettingTab.msgAreYouSureProceed": "정말로 진행하시겠습니까?", "obsidianLiveSyncSettingTab.msgChangesNeedToBeApplied": "변경사항을 적용해야 합니다!", "obsidianLiveSyncSettingTab.msgConfigCheck": "--구성 확인--", "obsidianLiveSyncSettingTab.msgConfigCheckFailed": "구성 확인에 실패했습니다. 그래도 계속하시겠습니까?", "obsidianLiveSyncSettingTab.msgConnectionCheck": "--연결 확인--", "obsidianLiveSyncSettingTab.msgConnectionProxyNote": "구성 확인 후에도 연결 확인에 문제가 있는 경우, 리버스 프록시 구성을 확인해 주세요.", - "obsidianLiveSyncSettingTab.msgCurrentOrigin": "현재 원점: {origin}", + "obsidianLiveSyncSettingTab.msgCurrentOrigin": "현재 출처: ${origin}", "obsidianLiveSyncSettingTab.msgDiscardConfirmation": "정말로 기존 설정과 데이터베이스를 삭제하시겠습니까?", "obsidianLiveSyncSettingTab.msgDone": "--완료--", "obsidianLiveSyncSettingTab.msgEnableCors": "httpd.enable_cors 설정", - "obsidianLiveSyncSettingTab.msgEnableEncryptionRecommendation": "종단간 암호화와 경로 난독화를 활성화하는 것을 권장합니다. 정말로 암호화 없이 계속하시겠습니까?", + "obsidianLiveSyncSettingTab.msgEnableCorsChttpd": "chttpd.enable_cors 설정", + "obsidianLiveSyncSettingTab.msgEnableEncryptionRecommendation": "종단 간 암호화와 경로 난독화를 활성화하는 것을 권장합니다. 정말로 암호화 없이 계속하시겠습니까?", "obsidianLiveSyncSettingTab.msgFetchConfigFromRemote": "원격 서버에서 구성을 가져오시겠습니까?", "obsidianLiveSyncSettingTab.msgGenerateSetupURI": "모든 작업이 완료되었습니다! 다른 기기를 설정하기 위해 Setup URI를 생성하시겠습니까?", "obsidianLiveSyncSettingTab.msgIfConfigNotPersistent": "서버 설정이 영구적으로 저장되지 않는 환경(예: Docker에서 실행 중)에서는 이곳의 값들이 변경될 수 있습니다. 연결이 가능해지면 서버의 local.ini 파일에서 설정을 수동으로 업데이트해 주세요.", @@ -421,9 +454,9 @@ "obsidianLiveSyncSettingTab.msgNonHTTPSInfo": "비 HTTPS URI로 구성되었습니다. 모바일 기기에서는 작동하지 않을 수 있으니 주의하세요.", "obsidianLiveSyncSettingTab.msgNonHTTPSWarning": "비 HTTPS URI에 연결할 수 없습니다. 구성을 업데이트하고 다시 시도해 주세요.", "obsidianLiveSyncSettingTab.msgNotice": "---공지사항---", - "obsidianLiveSyncSettingTab.msgObjectStorageWarning": "⚠️ 주의: 이 기능은 아직 개발 중(WIP)입니다. 다음 사항을 유의해 주세요:\n- 추가 전용 구조(append-only)로 동작합니다. 저장 용량을 줄이려면 데이터 재구성이 필요합니다.\n- 기능이 다소 불안정할 수 있습니다.\n- 최초 동기화 시, 전체 히스토리가 원격 서버에서 전송됩니다. 데이터 용량 제한 및 느린 속도에 유의해 주세요.\n- 실시간 동기화는 변경된 부분만 처리됩니다.\n\n문제가 발생했거나 개선 아이디어가 있으시면 GitHub에 이슈를 등록해 주세요.\n기여에 깊이 감사드립니다.", - "obsidianLiveSyncSettingTab.msgOriginCheck": "원점 확인: {org}", - "obsidianLiveSyncSettingTab.msgRebuildRequired": "변경사항을 적용하려면 데이터베이스를 재구축해야 합니다. 아래 중 한 가지 방법을 선택해 주세요.\n\n
\n범례\n\n| 기호 | 의미 |\n|: ------ :| ------- |\n| ⇔ | 최신 상태 |\n| ⇄ | 동기화 균형 유지 |\n| ⇐,⇒ | 덮어쓰기 방식의 전송 |\n| ⇠,⇢ | 상대편에서 가져와 덮어쓰기 |\n\n
\n\n## ${OPTION_REBUILD_BOTH}\n개요: 📄 ⇒¹ 💻 ⇒² 🛰️ ⇢ⁿ 💻 ⇄ⁿ⁺¹ 📄\n이 기기의 기존 파일을 기반으로 로컬과 원격 데이터베이스를 모두 재구축합니다.\n이 과정에서 다른 기기는 일시적으로 접근이 제한되며, 가져오기 작업을 별도로 수행해야 합니다.\n\n## ${OPTION_FETCH}\n개요: 📄 ⇄² 💻 ⇐¹ 🛰️ ⇔ 💻 ⇔ 📄\n로컬 데이터베이스를 초기화한 후, 원격 데이터베이스에서 데이터를 가져와 재구축합니다.\n이는 원격 측에서 데이터베이스를 먼저 재구축한 경우에도 해당됩니다.\n\n## ${OPTION_ONLY_SETTING}\n설정만 저장합니다. **⚠️ 주의: 이 방법은 데이터 손상을 일으킬 수 있습니다.** 일반적으로는 전체 데이터베이스 재구축이 필요합니다.", + "obsidianLiveSyncSettingTab.msgObjectStorageWarning": "경고: 이 기능은 아직 개발 중이므로 다음 사항을 유의해 주세요:\n- 추가 전용 구조로 동작합니다. 저장 용량을 줄이려면 재구축이 필요합니다.\n- 다소 불안정합니다.\n- 최초 동기화 시 모든 기록이 원격에서 전송됩니다. 데이터 사용량 제한과 느린 속도에 유의해 주세요.\n- 실시간 동기화는 변경분만 처리합니다.\n\n문제가 발생했거나 이 기능에 대한 아이디어가 있다면 GitHub에 이슈를 등록해 주세요.\n큰 관심에 깊이 감사드립니다.", + "obsidianLiveSyncSettingTab.msgOriginCheck": "출처 확인: ${org}", + "obsidianLiveSyncSettingTab.msgRebuildRequired": "변경 사항을 적용하려면 데이터베이스를 재구축해야 합니다. 변경 사항을 적용할 방법을 선택해 주세요.\n\n
\n범례\n\n| 기호 | 의미 |\n|: ------ :| ------- |\n| ⇔ | 최신 상태 |\n| ⇄ | 양쪽을 맞추는 동기화 |\n| ⇐,⇒ | 덮어쓰기 전송 |\n| ⇠,⇢ | 반대편에서 덮어쓰기 전송 |\n\n
\n\n## ${OPTION_REBUILD_BOTH}\n한눈에 보기: 📄 ⇒¹ 💻 ⇒² 🛰️ ⇢ⁿ 💻 ⇄ⁿ⁺¹ 📄\n이 기기의 기존 파일을 사용해 로컬과 원격 데이터베이스를 모두 재구축합니다.\n이 경우 다른 기기는 잠기며, 가져오기를 수행해야 합니다.\n## ${OPTION_FETCH}\n한눈에 보기: 📄 ⇄² 💻 ⇐¹ 🛰️ ⇔ 💻 ⇔ 📄\n로컬 데이터베이스를 초기화한 뒤, 원격 데이터베이스에서 가져온 데이터로 재구축합니다.\n원격 데이터베이스를 이미 재구축한 경우도 여기에 해당합니다.\n## ${OPTION_ONLY_SETTING}\n설정만 저장합니다. **주의: 데이터가 손상될 수 있습니다.** 일반적으로는 데이터베이스 재구축이 필요합니다.", "obsidianLiveSyncSettingTab.msgSelectAndApplyPreset": "마법사를 완료하려면 프리셋 항목을 선택하고 적용해 주세요.", "obsidianLiveSyncSettingTab.msgSetCorsCredentials": "cors.credentials 설정", "obsidianLiveSyncSettingTab.msgSetCorsOrigins": "cors.origins 설정", @@ -449,9 +482,10 @@ "obsidianLiveSyncSettingTab.okAdminPrivileges": "✔ 관리자 권한이 있습니다.", "obsidianLiveSyncSettingTab.okCorsCredentials": "✔ cors.credentials가 정상입니다.", "obsidianLiveSyncSettingTab.okCorsCredentialsForOrigin": "CORS 자격 증명 정상", - "obsidianLiveSyncSettingTab.okCorsOriginMatched": "✔ CORS 원점 정상", + "obsidianLiveSyncSettingTab.okCorsOriginMatched": "✔ CORS 출처 정상", "obsidianLiveSyncSettingTab.okCorsOrigins": "✔ cors.origins가 정상입니다.", "obsidianLiveSyncSettingTab.okEnableCors": "✔ httpd.enable_cors가 정상입니다.", + "obsidianLiveSyncSettingTab.okEnableCorsChttpd": "✔ chttpd.enable_cors가 정상입니다.", "obsidianLiveSyncSettingTab.okMaxDocumentSize": "✔ couchdb.max_document_size가 정상입니다.", "obsidianLiveSyncSettingTab.okMaxRequestSize": "✔ chttpd.max_http_request_size가 정상입니다.", "obsidianLiveSyncSettingTab.okRequireValidUser": "✔ chttpd.require_valid_user가 정상입니다.", @@ -463,8 +497,8 @@ "obsidianLiveSyncSettingTab.optionDisableAllAutomatic": "모든 자동 비활성화", "obsidianLiveSyncSettingTab.optionFetchFromRemote": "원격에서 가져오기", "obsidianLiveSyncSettingTab.optionHere": "여기", - "obsidianLiveSyncSettingTab.optionLiveSync": "LiveSync 동기화", - "obsidianLiveSyncSettingTab.optionMinioS3R2": "Minio,S3,R2", + "obsidianLiveSyncSettingTab.optionLiveSync": "LiveSync", + "obsidianLiveSyncSettingTab.optionMinioS3R2": "MinIO, S3, R2", "obsidianLiveSyncSettingTab.optionOkReadEverything": "네, 모든 것을 읽었습니다.", "obsidianLiveSyncSettingTab.optionOnEvents": "이벤트 시", "obsidianLiveSyncSettingTab.optionPeriodicAndEvents": "주기적 및 이벤트 시", @@ -476,10 +510,12 @@ "obsidianLiveSyncSettingTab.panelPrivacyEncryption": "개인정보 보호 및 암호화", "obsidianLiveSyncSettingTab.panelRemoteConfiguration": "원격 구성", "obsidianLiveSyncSettingTab.panelSetup": "설정", - "obsidianLiveSyncSettingTab.titleAppearance": "외관", + "obsidianLiveSyncSettingTab.serverVersion": "서버 정보: ${info}", + "obsidianLiveSyncSettingTab.titleActiveRemoteServer": "활성 원격 서버", + "obsidianLiveSyncSettingTab.titleAppearance": "모양", "obsidianLiveSyncSettingTab.titleConflictResolution": "충돌 해결", "obsidianLiveSyncSettingTab.titleCongratulations": "축하합니다!", - "obsidianLiveSyncSettingTab.titleCouchDB": "CouchDB 서버", + "obsidianLiveSyncSettingTab.titleCouchDB": "CouchDB", "obsidianLiveSyncSettingTab.titleDeletionPropagation": "삭제 전파", "obsidianLiveSyncSettingTab.titleEncryptionNotEnabled": "암호화가 활성화되지 않음", "obsidianLiveSyncSettingTab.titleEncryptionPassphraseInvalid": "암호화 패스프레이즈 유효하지 않음", @@ -496,14 +532,14 @@ "obsidianLiveSyncSettingTab.titleRebuildRequired": "재구축 필요", "obsidianLiveSyncSettingTab.titleRemoteConfigCheckFailed": "원격 구성 확인 실패", "obsidianLiveSyncSettingTab.titleRemoteServer": "원격 서버", - "obsidianLiveSyncSettingTab.titleReset": "리셋", + "obsidianLiveSyncSettingTab.titleReset": "재설정", "obsidianLiveSyncSettingTab.titleSetupOtherDevices": "다른 기기 설정", "obsidianLiveSyncSettingTab.titleSynchronizationMethod": "동기화 방법", "obsidianLiveSyncSettingTab.titleSynchronizationPreset": "동기화 프리셋", "obsidianLiveSyncSettingTab.titleSyncSettings": "동기화 설정", - "obsidianLiveSyncSettingTab.titleSyncSettingsViaMarkdown": "마크다운을 통한 동기화 설정", + "obsidianLiveSyncSettingTab.titleSyncSettingsViaMarkdown": "마크다운을 통한 설정 동기화", "obsidianLiveSyncSettingTab.titleUpdateThinning": "업데이트 솎아내기", - "obsidianLiveSyncSettingTab.warnCorsOriginUnmatched": "⚠ CORS 원점이 일치하지 않습니다 {from}->{to}", + "obsidianLiveSyncSettingTab.warnCorsOriginUnmatched": "⚠ CORS 출처가 일치하지 않습니다 ${from}->${to}", "obsidianLiveSyncSettingTab.warnNoAdmin": "⚠ 관리자 권한이 없습니다.", "Ok": "확인", "Old Algorithm": "이전 알고리즘", @@ -513,7 +549,7 @@ "Overwrite": "덮어쓰기", "Overwrite patterns": "덮어쓰기 패턴", "Overwrite remote": "원격 덮어쓰기", - "Overwrite remote with local DB and passphrase.": "로컬 DB와 암호문구로 원격을 덮어씁니다.", + "Overwrite remote with local DB and passphrase.": "로컬 DB와 패스프레이즈로 원격을 덮어씁니다.", "Overwrite Server Data with This Device's Files": "이 기기의 파일로 서버 데이터를 덮어쓰기", "P2P.AskPassphraseForDecrypt": "원격 피어가 구성을 공유했습니다. 구성을 복호화하려면 패스프레이즈를 입력해 주세요.", "P2P.AskPassphraseForShare": "원격 피어가 이 기기의 구성을 요청했습니다. 구성을 공유하려면 패스프레이즈를 입력해 주세요. 이 대화상자를 취소하여 요청을 무시할 수 있습니다.", @@ -521,9 +557,9 @@ "P2P.FailedToOpen": "시그널링 서버에 P2P 연결을 열 수 없습니다.", "P2P.NoAutoSyncPeers": "자동 동기화 피어를 찾을 수 없습니다. %{long_p2p_sync} 창에서 피어를 설정해 주세요.", "P2P.NoKnownPeers": "피어가 감지되지 않았습니다. 다른 피어의 접속을 기다리고 있습니다...", - "P2P.Note.description": "이 복제기는 피어 투 피어(P2P) 연결을 통해 다른 기기들과 볼트를 동기화할 수 있도록 합니다. 클라우드 서비스를 거치지 않고도 기기간 동기화를 구현할 수 있습니다.\n\n이 복제기는 Trystero를 기반으로 하며, 기기 간 연결을 설정하기 위해 시그널링 서버를 사용합니다. 시그널링 서버는 단순히 연결 정보를 교환하는 용도로만 사용되며, 사용자 데이터를 저장하거나 접근하지 않습니다 (또는 그래야만 합니다).\n\n시그널링 서버는 누구나 운영할 수 있으며, 이는 단순한 Nostr 릴레이입니다. 편의성과 복제기의 작동 확인을 위해 `vrtmrz`가 자체적으로 시그널링 서버 인스턴스를 운영 중입니다. 사용자는 `vrtmrz`가 제공하는 실험용 서버를 사용할 수도 있고, 별도로 자신만의 서버를 설정할 수도 있습니다.\n\n참고로, 시그널링 서버는 사용자 데이터를 저장하지 않더라도 일부 기기의 연결 정보는 볼 수 있습니다. 이 점을 유의해 주세요. 특히 타인이 운영하는 서버를 사용할 경우 주의가 필요합니다.", - "P2P.Note.important_note": "피어 투 피어(P2P) 복제기의 실험적 구현입니다.", - "P2P.Note.important_note_sub": "이 기능은 아직 실험 단계에 있습니다. 이 기능이 예상대로 작동하지 않을 수 있음을 알아주세요. 또한 버그, 보안 문제 및 기타 문제가 있을 수 있습니다. 이 기능을 사용할 때는 본인의 책임 하에 사용하세요. 이 기능의 개발에 기여해 주세요.", + "P2P.Note.description": " 이 복제기는 피어 투 피어 연결을 이용해 다른 기기와 보관함을 동기화할 수 있게 해 줍니다.\n클라우드 서비스를 사용하지 않고도 다른 기기와 보관함을 동기화할 수 있습니다.\n이 복제기는 Trystero를 기반으로 합니다. 기기 간 연결을 맺기 위해 시그널링 서버도 사용합니다. 시그널링 서버는 기기 사이의 연결 정보를 교환하는 데 쓰이며, 사용자의 데이터는 알지도 저장하지도 않습니다(또는 그래야 합니다).\n\n시그널링 서버는 누구나 운영할 수 있습니다. 단순한 Nostr 릴레이일 뿐입니다. 편의를 위해, 그리고 복제기의 동작을 확인할 수 있도록 vrtmrz가 시그널링 서버 인스턴스를 하나 운영하고 있습니다. vrtmrz가 제공하는 실험용 서버를 사용해도 되고, 다른 서버를 사용해도 됩니다.\n\n참고로, 시그널링 서버가 데이터를 저장하지 않더라도 일부 기기의 연결 정보는 볼 수 있습니다. 이 점을 유의해 주세요. 또한 다른 사람이 제공하는 서버를 사용할 때는 주의하시기 바랍니다.", + "P2P.Note.important_note": "피어 투 피어 복제기입니다.", + "P2P.Note.important_note_sub": "이 기능은 아직 실험 단계입니다. 사용하기 전에 반드시 데이터를 백업해 주세요. 그리고 이 기능의 개발에 기여해 주신다면 매우 감사하겠습니다.", "P2P.Note.Summary": "이 기능은 무엇인가요? (설명과 참고사항이 적혀있습니다. 한 번 읽어보세요!)", "P2P.NotEnabled": "%{title_p2p_sync}가 활성화되지 않았습니다. 새로운 연결을 열 수 없습니다.", "P2P.P2PReplication": "%{P2P} 복제", @@ -533,21 +569,21 @@ "P2P.SyncAlreadyRunning": "P2P 동기화가 이미 실행 중입니다.", "P2P.SyncCompleted": "P2P 동기화가 완료되었습니다.", "P2P.SyncStartedWith": "${name}과의 P2P 동기화가 시작되었습니다.", - "paneMaintenance.markDeviceResolvedAfterBackup": "백업 후 장치를 해결됨으로 표시", - "paneMaintenance.remoteLockedAndDeviceNotAccepted": "원격 데이터베이스가 잠겨 있으며 이 장치는 아직 승인되지 않았습니다.", - "paneMaintenance.remoteLockedResolvedDevice": "원격 데이터베이스가 잠겨 있지만 이 장치는 이미 승인되었습니다.", + "paneMaintenance.markDeviceResolvedAfterBackup": "백업 후 이 기기를 해결됨으로 표시", + "paneMaintenance.remoteLockedAndDeviceNotAccepted": "원격 데이터베이스가 잠겨 있으며 이 기기는 아직 승인되지 않았습니다.", + "paneMaintenance.remoteLockedResolvedDevice": "원격 데이터베이스가 잠겨 있지만 이 기기는 이미 승인되었습니다.", "paneMaintenance.unlockDatabaseReady": "데이터베이스 잠금 해제", "Passphrase": "패스프레이즈", "Passphrase of sensitive configuration items": "민감한 구성 항목의 패스프레이즈", "password": "비밀번호", "Password": "비밀번호", "Paste a connection string": "연결 문자열 붙여넣기", - "Paste the Setup URI generated from one of your active devices.": "현재 사용 중인 장치 중 하나에서 생성한 설정 URI를 붙여 넣으세요。", + "Paste the Setup URI generated from one of your active devices.": "사용 중인 기기 중 하나에서 생성한 Setup URI를 붙여 넣으세요.", "Path Obfuscation": "경로 난독화", "Patterns to match files for overwriting instead of merging": "병합 대신 덮어쓸 파일을 판별하는 패턴", "Patterns to match files for syncing": "동기화할 파일을 판별하는 패턴", "Peer-to-Peer only": "Peer-to-Peer 전용", - "Peer-to-Peer Synchronisation": "피어 투 피어 동기화", + "Peer-to-Peer Synchronisation": "피어 투 피어(P2P) 동기화", "Per-file-saved customization sync": "파일별 저장 사용자 설정 동기화", "Perform": "실행", "Perform cleanup": "정리 실행", @@ -555,35 +591,42 @@ "Perform Garbage Collection to remove unused chunks and reduce database size.": "사용하지 않는 청크를 제거하고 데이터베이스 크기를 줄이기 위해 가비지 컬렉션을 실행합니다.", "Periodic Sync interval": "주기적 동기화 간격", "Pick a file to resolve conflict": "충돌을 해결할 파일 선택", - "Please disable 'Read chunks online' in settings to use Garbage Collection.": "Garbage Collection을 사용하려면 설정에서 \"Read chunks online\"을 비활성화해 주세요.", - "Please enable 'Compute revisions for chunks' in settings to use Garbage Collection.": "Garbage Collection을 사용하려면 설정에서 \"Compute revisions for chunks\"를 활성화해 주세요.", + "Pick a file to show history": "기록을 표시할 파일 선택", + "Please disable 'Read chunks online' in settings to use Garbage Collection.": "가비지 컬렉션을 사용하려면 설정에서 'Read chunks online'을 비활성화해 주세요.", + "Please enable 'Compute revisions for chunks' in settings to use Garbage Collection.": "가비지 컬렉션을 사용하려면 설정에서 'Compute revisions for chunks'를 활성화해 주세요.", "Please select 'Cancel' explicitly to cancel this operation.": "이 작업을 취소하려면 반드시 \"취소\"를 명시적으로 선택해 주세요.", - "Please select a method to import the settings from another device.": "다른 장치에서 설정을 가져올 방법을 선택해 주세요。", + "Please select a method to import the settings from another device.": "다른 기기에서 설정을 가져올 방법을 선택해 주세요.", "Please select an option to proceed": "계속하려면 항목을 선택해 주세요", - "Please select the type of server to which you are connecting.": "연결할 서버 유형을 선택해 주세요。", - "Please set device name to identify this device. This name should be unique among your devices. While not configured, we cannot enable this feature.": "이 장치를 식별할 장치 이름을 설정해 주세요. 이 이름은 장치 간에 고유해야 합니다. 설정되기 전까지는 이 기능을 활성화할 수 없습니다.", - "Please set this device name": "이 장치 이름을 설정해 주세요", + "Please select the type of server to which you are connecting.": "연결할 서버 유형을 선택해 주세요.", + "Please set device name to identify this device. This name should be unique among your devices. While not configured, we cannot enable this feature.": "이 기기를 식별할 기기 이름을 설정해 주세요. 이 이름은 기기 간에 고유해야 합니다. 설정하기 전까지는 이 기능을 활성화할 수 없습니다.", + "Please set this device name": "이 기기의 이름을 설정해 주세요", "Plug-in version": "플러그인 버전", "Prepare the 'report' to create an issue": "이슈 생성을 위한 '보고서' 준비", "Presets": "프리셋", - "Proceed Garbage Collection": "Garbage Collection 계속", - "Proceed with Setup URI": "설정 URI로 계속", - "Proceeding with Garbage Collection, ignoring missing nodes.": "누락된 노드를 무시하고 Garbage Collection을 계속 진행합니다.", - "Proceeding with Garbage Collection.": "Garbage Collection을 진행합니다.", + "Proceed Garbage Collection": "가비지 컬렉션 계속", + "Proceed with Setup URI": "Setup URI로 계속", + "Proceeding with Garbage Collection, ignoring missing nodes.": "누락된 노드를 무시하고 가비지 컬렉션을 계속 진행합니다.", + "Proceeding with Garbage Collection.": "가비지 컬렉션을 진행합니다.", "Process small files in the foreground": "포그라운드에서 작은 파일 처리", "Progress": "진행 상태", + "Property Encryption": "속성 암호화", "PureJS fallback (Fast, W/O WebAssembly)": "PureJS 대체 방식 (빠름, WebAssembly 없음)", "Purge all download/upload cache.": "모든 다운로드/업로드 캐시를 제거합니다.", "Purge all journal counter": "모든 저널 카운터 삭제", "Rebuild local and remote database with local files.": "로컬 파일로 로컬 및 원격 데이터베이스를 다시 구축합니다.", "Rebuilding Operations (Remote Only)": "재구축 작업 (원격 전용)", + "Recovery and Repair": "복구 및 수리", "Recreate all": "모두 다시 생성", "Recreate missing chunks for all files": "모든 파일의 누락된 청크 다시 생성", - "RedFlag.Fetch.Method.Desc": "어떻게 가져오시겠습니까?\n- %{RedFlag.Fetch.Method.FetchSafer}. (권장)\n **낮은 트래픽**, **높은 CPU**, **낮은 위험**\n- %{RedFlag.Fetch.Method.FetchSmoother}.\n **낮은 트래픽**, **보통 CPU**, **낮음에서 보통 위험**\n- %{RedFlag.Fetch.Method.FetchTraditional}.\n **높은 트래픽**, **낮은 CPU**, **낮음에서 보통 위험**\n\n>[!INFO]- 세부 사항\n> ## %{RedFlag.Fetch.Method.FetchSafer}. (권장)\n> **낮은 트래픽**, **높은 CPU**, **낮은 위험**\n> 이 옵션은 원격 소스에서 데이터를 가져오기 전에 기존 로컬 파일을 사용하여 로컬 데이터베이스를 먼저 생성합니다.\n> 로컬과 원격 모두에 일치하는 파일이 있으면 둘 사이의 차이점만 전송됩니다.\n> 하지만 두 위치 모두에 있는 파일은 초기에 충돌 파일로 처리됩니다. 실제로 충돌하지 않는다면 자동으로 해결되지만 이 과정은 시간이 걸릴 수 있습니다.\n> 이는 일반적으로 가장 안전한 방법으로 데이터 손실 위험을 최소화합니다.\n> ## %{RedFlag.Fetch.Method.FetchSmoother}.\n> **낮은 트래픽**, **보통 CPU**, **낮음에서 보통 위험** (작업에 따라)\n> 이 옵션은 먼저 로컬 파일에서 데이터베이스용 청크를 생성한 다음 데이터를 가져옵니다. 따라서 로컬에 없는 청크만 전송됩니다. 하지만 모든 메타데이터는 원격 소스에서 가져옵니다.\n> 그런 다음 로컬 파일이 시작 시 이 메타데이터와 비교됩니다. 더 새로운 것으로 간주되는 콘텐츠가 오래된 것을 덮어씁니다(수정 시간 기준). 이 결과는 원격 데이터베이스에 다시 동기화됩니다.\n> 로컬 파일이 실제로 최신 타임스탬프라면 일반적으로 안전합니다. 하지만 파일이 더 새로운 타임스탬프를 가지고 있지만 더 오래된 콘텐츠를 가지고 있다면(초기 `welcome.md`처럼) 문제가 발생할 수 있습니다.\n> 이는 \"%{RedFlag.Fetch.Method.FetchSafer}\"보다 CPU를 덜 사용하고 더 빠르지만 주의 깊게 사용하지 않으면 데이터 손실로 이어질 수 있습니다.\n> ## %{RedFlag.Fetch.Method.FetchTraditional}.\n> **높은 트래픽**, **낮은 CPU**, **낮음에서 보통 위험** (작업에 따라)\n> 모든 것이 원격에서 가져와집니다.\n> %{RedFlag.Fetch.Method.FetchSmoother}와 유사하지만 모든 청크가 원격 소스에서 가져와집니다.\n> 이는 가장 전통적인 가져오기 방법으로 일반적으로 가장 많은 네트워크 트래픽과 시간을 소모합니다. 또한 '%{RedFlag.Fetch.Method.FetchSmoother}' 옵션과 유사하게 원격 파일을 덮어쓸 위험이 있습니다.\n> 하지만 가장 오래되고 가장 직접적인 접근 방식이기 때문에 종종 가장 안정적인 방법으로 간주됩니다.", + "RedFlag.Fetch.Method.Desc": "어떻게 가져오시겠습니까?\n- %{RedFlag.Fetch.Method.FetchSafer}.\n **낮은 트래픽**, **높은 CPU**, **낮은 위험**\n 다음의 경우에 권장합니다.\n - 파일이 일관되지 않을 가능성이 있음\n - 파일이 그리 많지 않음\n- %{RedFlag.Fetch.Method.FetchSmoother}.\n **낮은 트래픽**, **보통 CPU**, **낮음~보통 위험**\n 다음의 경우에 권장합니다.\n - 파일이 대체로 일관됨\n - 파일이 많음\n- %{RedFlag.Fetch.Method.FetchTraditional}.\n **높은 트래픽**, **낮은 CPU**, **낮음~보통 위험**\n\n>[!INFO]- 자세히\n> ## %{RedFlag.Fetch.Method.FetchSafer}.\n> **낮은 트래픽**, **높은 CPU**, **낮은 위험**\n> 원격에서 데이터를 가져오기 전에 기존 로컬 파일로 로컬 데이터베이스를 먼저 만듭니다.\n> 로컬과 원격 양쪽에 일치하는 파일이 있으면 둘 사이의 차이만 전송됩니다.\n> 다만 양쪽에 모두 있는 파일은 처음에 충돌 파일로 처리됩니다. 실제로 충돌하지 않는다면 자동으로 해결되지만, 이 과정에 시간이 걸릴 수 있습니다.\n> 일반적으로 가장 안전한 방법이며 데이터 손실 위험이 가장 낮습니다.\n> ## %{RedFlag.Fetch.Method.FetchSmoother}.\n> **낮은 트래픽**, **보통 CPU**, **낮음~보통 위험** (작업에 따라 다름)\n> 먼저 로컬 파일로 데이터베이스용 청크를 만든 다음 데이터를 가져옵니다. 따라서 로컬에 없는 청크만 전송됩니다. 다만 메타데이터는 모두 원격에서 가져옵니다.\n> 그다음 시작 시점에 로컬 파일을 이 메타데이터와 비교합니다. 수정 시각을 기준으로 더 새롭다고 판단된 내용이 오래된 쪽을 덮어씁니다. 그 결과는 다시 원격 데이터베이스로 동기화됩니다.\n> 로컬 파일이 실제로 가장 최신 타임스탬프를 가지고 있다면 대체로 안전합니다. 하지만 타임스탬프는 더 새롭지만 내용은 더 오래된 파일(처음 만들어지는 `welcome.md` 같은)이 있으면 문제가 생길 수 있습니다.\n> \"%{RedFlag.Fetch.Method.FetchSafer}\"보다 CPU를 적게 쓰고 더 빠르지만, 주의해서 사용하지 않으면 데이터가 손실될 수 있습니다.\n> ## %{RedFlag.Fetch.Method.FetchTraditional}.\n> **높은 트래픽**, **낮은 CPU**, **낮음~보통 위험** (작업에 따라 다름)\n> 모든 것을 원격에서 가져옵니다.\n> %{RedFlag.Fetch.Method.FetchSmoother}와 비슷하지만, 모든 청크를 원격에서 가져옵니다.\n> 가장 전통적인 가져오기 방식으로, 보통 네트워크 트래픽과 시간을 가장 많이 소모합니다. 또한 '%{RedFlag.Fetch.Method.FetchSmoother}' 옵션과 마찬가지로 원격 파일을 덮어쓸 위험이 있습니다.\n> 다만 가장 오래되고 단순한 방식이기 때문에 가장 안정적인 방법으로 여겨지는 경우가 많습니다.", "RedFlag.Fetch.Method.FetchSafer": "가져오기 전에 로컬 데이터베이스를 한 번 생성", "RedFlag.Fetch.Method.FetchSmoother": "가져오기 전에 로컬 파일 청크 생성", "RedFlag.Fetch.Method.FetchTraditional": "원격에서 모든 것 가져오기", "RedFlag.Fetch.Method.Title": "어떻게 가져오시겠습니까?", + "RedFlag.FetchRemoteConfig.Buttons.Cancel": "아니요, 로컬 설정을 사용합니다", + "RedFlag.FetchRemoteConfig.Buttons.Fetch": "예, 원격 설정을 가져와 적용합니다", + "RedFlag.FetchRemoteConfig.Message": "원격에 저장된 환경 설정을 가져와 이 기기에 적용하시겠습니까?", + "RedFlag.FetchRemoteConfig.Title": "원격 구성 가져오기", "Reduces storage space by discarding all non-latest revisions. This requires the same amount of free space on the remote server and the local client.": "최신 버전이 아닌 모든 리비전을 제거하여 저장 공간을 줄입니다. 이 작업을 수행하려면 원격 서버와 로컬 클라이언트에 동일한 양의 여유 공간이 필요합니다.", "Reducing the frequency with which on-disk changes are reflected into the DB": "디스크 변경 사항이 데이터베이스에 반영되는 빈도를 줄입니다", "Region": "지역", @@ -596,7 +639,7 @@ "Remote Type": "원격 유형", "Rename": "이름 바꾸기", "Replicator.Dialogue.Locked.Action.Dismiss": "재확인을 위해 취소", - "Replicator.Dialogue.Locked.Action.Fetch": "원격 데이터베이스에서 모든 것을 다시 가져오기", + "Replicator.Dialogue.Locked.Action.Fetch": "이 기기의 동기화 재설정", "Replicator.Dialogue.Locked.Action.Unlock": "원격 데이터베이스 잠금 해제", "Replicator.Dialogue.Locked.Message": "원격 데이터베이스가 잠겨 있습니다. 이는 일부 터미널에서 데이터베이스를 재구축했기 때문입니다.\n따라서 현재 기기는 데이터베이스 손상을 방지하기 위해 연결을 일시적으로 보류해야 합니다.\n\n선택할 수 있는 세 가지 방법이 있습니다:\n\n- %{Replicator.Dialogue.Locked.Action.Fetch}\n 가장 권장되고 신뢰할 수 있는 방법입니다. 로컬 데이터베이스를 초기화한 뒤, 원격 데이터베이스의 전체 데이터를 다시 가져옵니다. 대부분의 경우 안전하게 수행할 수 있으나, 시간이 다소 걸리며 안정적인 네트워크 환경에서 진행해야 합니다.\n- %{Replicator.Dialogue.Locked.Action.Unlock}\n 이 방법은 다른 동기화 방식으로 이미 완전하고 안정적으로 동기화된 경우에만 사용할 수 있습니다. 단순히 파일이 같다는 의미가 아니므로, 확신이 없다면 사용을 피하는 것이 좋습니다.\n- %{Replicator.Dialogue.Locked.Action.Dismiss}\n 이번 작업을 취소하고, 다음 요청 시 다시 안내받습니다.\n", "Replicator.Dialogue.Locked.Message.Fetch": "모든 것 가져오기가 예약되었습니다. 이를 수행하기 위해 플러그인이 재시작됩니다.", @@ -606,7 +649,7 @@ "Replicator.Message.InitialiseFatalError": "사용 가능한 복제기가 없습니다. 치명적인 오류입니다.", "Replicator.Message.Pending": "일부 파일 이벤트가 대기 중입니다. 복제가 취소되었습니다.", "Replicator.Message.SomeModuleFailed": "일부 모듈 실패로 복제가 취소되었습니다", - "Replicator.Message.VersionUpFlash": "설정을 열고 메시지를 확인해 주세요. 복제가 취소되었습니다.", + "Replicator.Message.VersionUpFlash": "업데이트가 감지되었습니다. 설정 대화 상자를 열어 변경 로그를 확인해 주세요. 복제가 취소되었습니다.", "Requires restart of Obsidian": "Obsidian 재시작 필요", "Requires restart of Obsidian.": "Obsidian 재시작이 필요합니다.", "Rerun Onboarding Wizard": "온보딩 마법사 다시 실행", @@ -623,13 +666,14 @@ "Reset received": "수신 기록 재설정", "Reset sent history": "송신 기록 재설정", "Reset Synchronisation information": "동기화 정보 재설정", - "Reset Synchronisation on This Device": "이 장치의 동기화 상태 재설정", + "Reset Synchronisation on This Device": "이 기기의 동기화 재설정", "Reset the remote storage size threshold and check the remote storage size again.": "원격 저장소 크기 임계값을 초기화하고 원격 저장소 크기를 다시 확인합니다.", "Resolve All": "모두 해결", "Resolve all conflicted files": "충돌한 모든 파일 해결", "Resolve All conflicted files by the newer one": "충돌한 모든 파일을 최신 버전으로 해결", "Resolve all conflicted files by the newer one. Caution: This will overwrite the older one, and cannot resurrect the overwritten one.": "충돌한 모든 파일을 더 최신 버전으로 해결합니다. 주의: 이전 버전은 덮어써지며 복원할 수 없습니다.", "Restart Now": "지금 재시작", + "Restarting Obsidian is strongly recommended. Until restart, some changes may not take effect, and display may be inconsistent. Are you sure to restart now?": "Obsidian을 재시작하는 것을 강력히 권장합니다. 재시작하기 전까지는 일부 변경 사항이 적용되지 않거나 화면이 일관되지 않게 표시될 수 있습니다. 지금 재시작하시겠습니까?", "Restore or reconstruct local database from remote.": "원격에서 로컬 데이터베이스를 복원하거나 재구축합니다.", "Run Doctor": "진단 실행", "S3/MinIO/R2 Object Storage": "S3/MinIO/R2 객체 스토리지", @@ -642,12 +686,12 @@ "Scan customization every 1 minute.": "1분마다 사용자 설정을 검색합니다.", "Scan customization periodically": "주기적으로 사용자 설정 검색", "Scan for Broken files": "손상된 파일 검사", - "Scan for hidden files before replication": "복제 전 숨겨진 파일 검색", - "Scan hidden files periodically": "주기적으로 숨겨진 파일 검색", - "Scan the QR code displayed on an active device using this device's camera.": "이 장치의 카메라로 활성 장치에 표시된 QR 코드를 스캔하세요。", + "Scan for hidden files before replication": "복제 전 숨김 파일 검사", + "Scan hidden files periodically": "주기적으로 숨김 파일 검사", + "Scan the QR code displayed on an active device using this device's camera.": "이 기기의 카메라로 사용 중인 기기에 표시된 QR 코드를 스캔하세요.", "Schedule and Restart": "예약 후 재시작", - "Scram Switches": "긴급 전환 스위치", - "Scram!": "긴급 조치", + "Scram Switches": "긴급 정지 스위치", + "Scram!": "긴급 정지", "Seconds, 0 to disable": "초 단위, 0으로 설정하면 비활성화", "Seconds. Saving to the local database will be delayed until this value after we stop typing or saving.": "초 단위입니다. 타이핑이나 저장을 중단한 후 이 시간동안 로컬 데이터베이스 저장이 지연됩니다.", "Secret Key": "시크릿 키", @@ -655,7 +699,7 @@ "Send": "보내기", "Send chunks": "청크 보내기", "Server URI": "서버 URI", - "Setting.GenerateKeyPair.Desc": "키 페어를 생성했습니다!\n\n참고: 이 키 페어는 다시 표시되지 않습니다. 안전한 곳에 저장해 주세요. 분실하면 새 키 페어를 생성해야 합니다.\n참고 2: 공개 키는 spki 형식이고, 개인 키는 pkcs8 형식입니다. 편의상 공개 키의 줄 바꿈은 `\\n`으로 변환됩니다.\n참고 3: 공개 키는 원격 데이터베이스에서 구성되어야 하고, 개인 키는 로컬 기기에서 구성되어야 합니다.\n\n>[!FOR YOUR EYES ONLY]-\n>
\n>\n> ### 공개 키\n> ```\n${public_key}\n> ```\n>\n> ### 개인 키\n> ```\n${private_key}\n> ```\n>\n>
\n\n>[!Both for copying]-\n>\n>
\n>\n> ```\n${public_key}\n${private_key}\n> ```\n>\n>
\n\n\n", + "Setting.GenerateKeyPair.Desc": "키 페어를 생성했습니다!\n\n참고: 이 키 페어는 다시 표시되지 않습니다. 안전한 곳에 저장해 주세요. 분실하면 새 키 페어를 생성해야 합니다.\n참고 2: 공개 키는 spki 형식이고, 개인 키는 pkcs8 형식입니다. 편의를 위해 공개 키의 줄 바꿈은 `\\n`으로 변환됩니다.\n참고 3: 공개 키는 원격 데이터베이스에, 개인 키는 로컬 기기에 설정해야 합니다.\n\n>[!FOR YOUR EYES ONLY]-\n>
\n>\n> ### 공개 키\n> ```\n${public_key}\n> ```\n>\n> ### 개인 키\n> ```\n${private_key}\n> ```\n>\n>
\n\n>[!Both for copying]-\n>\n>
\n>\n> ```\n${public_key}\n${private_key}\n> ```\n>\n>
\n\n", "Setting.GenerateKeyPair.Title": "새 키 페어가 생성되었습니다!", "Setting.TroubleShooting": "문제 해결", "Setting.TroubleShooting.Doctor": "설정 진단 마법사", @@ -664,28 +708,44 @@ "Setting.TroubleShooting.ScanBrokenFiles.Desc": "데이터베이스에 올바르게 저장되지 않은 파일을 검사합니다.", "SettingTab.Message.AskRebuild": "변경 사항을 적용하려면 원격 데이터베이스에서 가져와야 합니다. 계속 진행하시겠습니까?", "Setup URI dialog cancelled.": "Setup URI 대화 상자가 취소되었습니다.", + "Setup.Apply.Buttons.ApplyAndFetch": "적용 후 가져오기", + "Setup.Apply.Buttons.ApplyAndMerge": "적용 후 병합", + "Setup.Apply.Buttons.ApplyAndRebuild": "적용 후 재구축", + "Setup.Apply.Buttons.Cancel": "폐기하고 취소", + "Setup.Apply.Buttons.OnlyApply": "적용만 하기", + "Setup.Apply.Message": "새 구성이 준비되었습니다. 이제 적용해 보겠습니다.\n적용 방법은 여러 가지가 있습니다:\n\n- 적용 후 가져오기\n 이 기기를 새 클라이언트로 구성합니다. 적용한 뒤 원격 서버에서 동기화합니다.\n- 적용 후 병합\n 이미 파일이 있는 기기에서 구성합니다. 로컬 파일을 처리한 뒤 차이만 전송합니다. 충돌이 발생할 수 있습니다.\n- 적용 후 재구축\n 로컬 파일로 원격을 재구축합니다. 보통 서버가 손상되었거나 처음부터 다시 시작하려는 경우에 사용합니다.\n 다른 기기는 잠기며 다시 가져오기를 수행해야 합니다.\n- 적용만 하기\n 적용만 합니다. 재구축이 필요한 경우 충돌이 발생할 수 있습니다.", + "Setup.Apply.Title": "${method}에서 가져온 새 구성 적용", + "Setup.Apply.WarningRebuildRecommended": "참고: 설정을 조정한 결과 재구축이 필요한 것으로 판단되었습니다. 적용만 하는 것은 권장하지 않습니다.", + "Setup.Doctor.Buttons.No": "아니요, URI에 담긴 설정을 그대로 사용합니다", + "Setup.Doctor.Buttons.Yes": "예, 설정 진단 마법사를 실행합니다", + "Setup.Doctor.Message": "Self-hosted LiveSync는 오랜 기간에 걸쳐 발전해 왔고, 그동안 권장 설정도 일부 바뀌었습니다.\n\n지금 설정 단계가 이를 점검하기에 아주 좋은 시점입니다.\n\n가져온 설정이 최신 기준에 비추어 최적인지 확인하도록 설정 진단 마법사를 실행하시겠습니까?", + "Setup.Doctor.Title": "설정 진단 마법사를 실행할까요?", + "Setup.FetchRemoteConf.Buttons.Fetch": "예, 구성을 가져옵니다", + "Setup.FetchRemoteConf.Buttons.Skip": "아니요, URI에 담긴 설정을 사용합니다", + "Setup.FetchRemoteConf.Message": "다른 기기와 이미 한 번이라도 동기화했다면, 원격 데이터베이스에 동기화된 기기 사이에 적합한 구성 값이 저장되어 있습니다. 플러그인은 더 견고한 구성을 위해 이 값을 가져오려고 합니다.\n\n다만 한 가지 확인이 필요합니다. 지금 네트워크에 안전하게 접근해 설정을 가져올 수 있는 상황인가요?\n\n참고: 원격 데이터베이스가 SSL 인증서로 보호되어 있고 네트워크가 안전하다면, 대부분의 경우 그대로 진행해도 괜찮습니다.", + "Setup.FetchRemoteConf.Title": "원격 데이터베이스에서 구성을 가져올까요?", "Setup.QRCode": "설정을 전송하기 위한 QR 코드를 생성했습니다. 휴대폰이나 다른 기기로 QR 코드를 스캔해 주세요.\n참고: QR 코드는 암호화되지 않았으므로 열 때 주의하세요.\n\n>[!FOR YOUR EYES ONLY]-\n>
${qr_image}
", "Setup.RemoteE2EE.AdvancedTitle": "고급", "Setup.RemoteE2EE.AlgorithmWarning": "암호화 알고리즘을 변경하면 다른 알고리즘으로 암호화된 기존 데이터에 접근할 수 없게 됩니다. 모든 기기에서 동일한 알고리즘을 사용하도록 설정해 데이터 접근성을 유지하세요.", "Setup.RemoteE2EE.ButtonCancel": "취소", "Setup.RemoteE2EE.ButtonProceed": "진행", - "Setup.RemoteE2EE.DefaultAlgorithmDesc": "대부분의 경우 기본 알고리즘(${algorithm})을 그대로 사용하는 것이 좋습니다. 이 설정은 기존 Vault가 다른 형식으로 암호화되어 있는 경우에만 필요합니다.", - "Setup.RemoteE2EE.Guidance": "엔드투엔드 암호화 설정을 구성해 주세요.", - "Setup.RemoteE2EE.LabelEncrypt": "엔드투엔드 암호화", + "Setup.RemoteE2EE.DefaultAlgorithmDesc": "대부분의 경우 기본 알고리즘(${algorithm})을 그대로 사용하는 것이 좋습니다. 이 설정은 기존 보관함이 다른 형식으로 암호화되어 있는 경우에만 필요합니다.", + "Setup.RemoteE2EE.Guidance": "종단 간 암호화 설정을 구성해 주세요.", + "Setup.RemoteE2EE.LabelEncrypt": "종단 간 암호화", "Setup.RemoteE2EE.LabelEncryptionAlgorithm": "암호화 알고리즘", "Setup.RemoteE2EE.LabelObfuscateProperties": "속성 난독화", "Setup.RemoteE2EE.MultiDestinationWarning": "여러 동기화 대상에 연결하는 경우에도 이 설정은 동일해야 합니다.", "Setup.RemoteE2EE.ObfuscatePropertiesDesc": "속성(예: 파일 경로, 크기, 생성일 및 수정일)을 난독화하면 원격 서버에서 파일과 폴더의 구조 및 이름을 식별하기 어렵게 만들어 보안을 한층 강화할 수 있습니다. 이는 개인 정보를 보호하고 권한 없는 사용자가 데이터에 관한 정보를 추론하기 어렵게 만듭니다.", - "Setup.RemoteE2EE.PassphraseValidationLine1": "엔드투엔드 암호화 패스프레이즈는 실제 동기화가 시작되기 전까지 검증되지 않는다는 점에 유의하세요. 이것은 데이터를 보호하기 위한 보안 조치입니다.", + "Setup.RemoteE2EE.PassphraseValidationLine1": "종단 간 암호화 패스프레이즈는 실제 동기화가 시작되기 전까지 검증되지 않는다는 점에 유의하세요. 데이터를 보호하기 위한 보안 조치입니다.", "Setup.RemoteE2EE.PassphraseValidationLine2": "따라서 서버 정보를 수동으로 구성할 때는 각별히 주의해 주세요. 잘못된 패스프레이즈를 입력하면 서버의 데이터가 손상됩니다. 이는 의도된 동작이니 반드시 이해하고 진행해 주세요.", "Setup.RemoteE2EE.PlaceholderPassphrase": "패스프레이즈를 입력하세요", - "Setup.RemoteE2EE.StronglyRecommendedLine1": "엔드투엔드 암호화를 활성화하면 데이터가 원격 서버로 전송되기 전에 이 기기에서 암호화됩니다. 즉, 누군가 서버에 접근하더라도 패스프레이즈 없이는 데이터를 읽을 수 없습니다. 다른 기기에서 데이터를 복호화할 때도 필요하므로 패스프레이즈를 반드시 기억해 두세요.", + "Setup.RemoteE2EE.StronglyRecommendedLine1": "종단 간 암호화를 활성화하면 데이터가 원격 서버로 전송되기 전에 이 기기에서 암호화됩니다. 즉, 누군가 서버에 접근하더라도 패스프레이즈 없이는 데이터를 읽을 수 없습니다. 다른 기기에서 데이터를 복호화할 때도 필요하므로 패스프레이즈를 반드시 기억해 두세요.", "Setup.RemoteE2EE.StronglyRecommendedLine2": "또한 Peer-to-Peer 동기화를 사용 중이더라도, 나중에 다른 방식으로 전환하여 원격 서버에 연결하면 이 설정이 그대로 사용됩니다.", "Setup.RemoteE2EE.StronglyRecommendedTitle": "강력 권장", - "Setup.RemoteE2EE.Title": "엔드투엔드 암호화", + "Setup.RemoteE2EE.Title": "종단 간 암호화", "Setup.ScanQRCode.ButtonClose": "이 대화 상자 닫기", "Setup.ScanQRCode.Guidance": "기존 기기에서 설정을 가져오려면 아래 단계를 따라 주세요.", - "Setup.ScanQRCode.Step1": "이 기기에서는 이 Vault를 계속 열어 두세요.", + "Setup.ScanQRCode.Step1": "이 기기에서는 이 보관함을 계속 열어 두세요.", "Setup.ScanQRCode.Step2": "원본 기기에서 Obsidian을 엽니다.", "Setup.ScanQRCode.Step3": "원본 기기에서 명령 팔레트를 열고 \"설정을 QR 코드로 표시\" 명령을 실행합니다.", "Setup.ScanQRCode.Step4": "이 기기에서 카메라 앱으로 전환하거나 QR 코드 스캐너를 사용해 표시된 QR 코드를 스캔하세요.", @@ -695,13 +755,13 @@ "Setup.UseSetupURI.ButtonCancel": "취소", "Setup.UseSetupURI.ButtonProceed": "설정 테스트 후 계속", "Setup.UseSetupURI.ErrorFailedToParse": "Setup URI를 해석하지 못했습니다. URI와 패스프레이즈를 확인해 주세요.", - "Setup.UseSetupURI.ErrorPassphraseRequired": "Vault 패스프레이즈를 입력해 주세요.", - "Setup.UseSetupURI.GuidanceLine1": "서버 설치 중 또는 다른 기기에서 생성된 Setup URI와 Vault 패스프레이즈를 입력해 주세요.", + "Setup.UseSetupURI.ErrorPassphraseRequired": "보관함 패스프레이즈를 입력해 주세요.", + "Setup.UseSetupURI.GuidanceLine1": "서버 설치 중에 또는 다른 기기에서 생성한 Setup URI와 보관함 패스프레이즈를 입력해 주세요.", "Setup.UseSetupURI.GuidanceLine2": "명령 팔레트에서 \"설정을 새 Setup URI로 복사\" 명령을 실행하면 새 Setup URI를 생성할 수 있습니다.", "Setup.UseSetupURI.InvalidInfo": "Setup URI가 올바르지 않습니다. 확인한 뒤 다시 시도해 주세요.", - "Setup.UseSetupURI.LabelPassphrase": "Vault 패스프레이즈", + "Setup.UseSetupURI.LabelPassphrase": "보관함 패스프레이즈", "Setup.UseSetupURI.LabelSetupURI": "Setup URI", - "Setup.UseSetupURI.PlaceholderPassphrase": "Vault 패스프레이즈를 입력하세요", + "Setup.UseSetupURI.PlaceholderPassphrase": "보관함 패스프레이즈를 입력하세요", "Setup.UseSetupURI.Title": "Setup URI 입력", "Setup.UseSetupURI.ValidInfo": "Setup URI가 유효하며 사용할 준비가 되었습니다.", "Should we keep folders that don't have any files inside?": "내부에 파일이 없는 폴더를 유지하시겠습니까?", @@ -709,17 +769,20 @@ "Should we prompt you about conflicting files when a file is opened?": "파일을 열 때 충돌하는 파일에 대해 알림을 표시하시겠습니까?", "Should we prompt you for every single merge, even if we can safely merge automatcially?": "안전하게 자동 병합할 수 있는 경우에도 모든 병합에 대해 알림을 받으시겠습니까?", "Show full banner": "전체 배너 표시", + "Show history": "기록 표시", + "Show icon only": "아이콘만 표시", "Show only notifications": "알림만 표시", "Show status as icons only": "아이콘으로만 상태 표시", "Show status icon instead of file warnings banner": "파일 경고 배너 대신 상태 아이콘 표시", "Show status inside the editor": "편집기 내부에 상태 표시", - "Show status on the status bar": "상태 바에 상태 표시", + "Show status on the status bar": "상태 표시줄에 상태 표시", "Show verbose log. Please enable if you report an issue.": "자세한 로그를 표시합니다. 문제를 신고하는 경우 활성화해 주세요.", "Some devices have differing progress values (max: ${maxProgress}, min: ${minProgress}).\nThis may indicate that some devices have not completed synchronisation, which could lead to conflicts. Strongly recommend confirming that all devices are synchronised before proceeding.": "일부 기기의 진행 값이 다릅니다(최대: ${maxProgress}, 최소: ${minProgress}).\n이는 일부 기기가 동기화를 완료하지 않았음을 의미할 수 있으며, 충돌로 이어질 수 있습니다. 계속 진행하기 전에 모든 기기가 동기화되었는지 반드시 확인하는 것을 강력히 권장합니다.", "Starts synchronisation when a file is saved.": "파일이 저장될 때 동기화를 시작합니다.", "Stop reflecting database changes to storage files.": "데이터베이스 변경 사항을 스토리지 파일에 반영하는 것을 중단합니다.", "Stop watching for file changes.": "파일 변경 사항 감시를 중단합니다.", - "Suppress notification of hidden files change": "숨겨진 파일 변경 알림 억제", + "Storage -> Database": "스토리지 -> 데이터베이스", + "Suppress notification of hidden files change": "숨김 파일 변경 알림 억제", "Suspend database reflecting": "데이터베이스 반영 일시 중단", "Suspend file watching": "파일 감시 일시 중단", "Switch to IDB": "IDB로 전환", @@ -731,7 +794,7 @@ "Sync on File Open": "파일 열기 시 동기화", "Sync on Save": "저장 시 동기화", "Sync on Startup": "시작 시 동기화", - "Synchronisation utilising journal files. You must have set up an S3/MinIO/R2 compatible object storage.": "저널 파일을 활용하는 동기화 방식입니다. S3/MinIO/R2 호환 객체 스토리지를 미리 구성해야 합니다。", + "Synchronisation utilising journal files. You must have set up an S3/MinIO/R2 compatible object storage.": "저널 파일을 활용하는 동기화 방식입니다. S3/MinIO/R2 호환 객체 스토리지를 미리 구성해 두어야 합니다.", "Synchronising files": "동기화할 파일", "Syncing": "동기화", "Target patterns": "대상 패턴", @@ -739,17 +802,20 @@ "The delay for consecutive on-demand fetches": "연속 청크 요청 간 대기 시간", "The following accepted nodes are missing its node information:\n- ${missingNodes}\n\nThis indicates that they have not been connected for some time or have been left on an older version.\nIt is preferable to update all devices if possible. If you have any devices that are no longer in use, you can clear all accepted nodes by locking the remote once.": "다음 승인된 노드에는 노드 정보가 없습니다:\n- ${missingNodes}\n\n이는 해당 노드가 한동안 연결되지 않았거나 이전 버전에 머물러 있음을 의미합니다.\n가능하다면 먼저 모든 기기를 업데이트하는 것이 좋습니다. 더 이상 사용하지 않는 기기가 있다면 원격을 한 번 잠가 승인된 노드를 모두 정리할 수 있습니다.", "The Hash algorithm for chunk IDs": "청크 ID용 해시 알고리즘", - "The maximum duration for which chunks can be incubated within the document. Chunks exceeding this period will graduate to independent chunks.": "변경 기록이 문서에 함께 보관될 수 있는 최대 시간입니다. 초과 시 문서에서 분리되어 개별로 저장됩니다.", - "The maximum number of chunks that can be incubated within the document. Chunks exceeding this number will immediately graduate to independent chunks.": "문서 안에 임시로 보관할 수 있는 변경 기록의 최대 개수입니다. 이 수를 초과하면 즉시 독립된 청크로 분리되어 저장됩니다.", - "The maximum total size of chunks that can be incubated within the document. Chunks exceeding this size will immediately graduate to independent chunks.": "문서 안에 임시로 보관할 수 있는 변경 기록의 전체 크기 제한입니다. 초과 시 자동으로 분리됩니다.", + "The IndexedDB adapter often offers superior performance in certain scenarios, but it has been found to cause memory leaks when used with LiveSync mode. When using LiveSync mode, please use IDB adapter instead.": "IndexedDB 어댑터는 특정 상황에서 더 나은 성능을 보이는 경우가 많지만, LiveSync 모드에서 사용하면 메모리 누수를 일으키는 것으로 확인되었습니다. LiveSync 모드를 사용할 때는 IDB 어댑터를 사용해 주세요.", + "The maximum duration for which chunks can be incubated within the document. Chunks exceeding this period will graduate to independent chunks.": "청크를 문서 안에 임시 보관할 수 있는 최대 기간입니다. 이 기간을 넘긴 청크는 독립된 청크로 분리됩니다.", + "The maximum number of chunks that can be incubated within the document. Chunks exceeding this number will immediately graduate to independent chunks.": "문서 안에 임시 보관할 수 있는 청크의 최대 개수입니다. 이 개수를 넘긴 청크는 즉시 독립된 청크로 분리됩니다.", + "The maximum total size of chunks that can be incubated within the document. Chunks exceeding this size will immediately graduate to independent chunks.": "문서 안에 임시 보관할 수 있는 청크의 최대 총 크기입니다. 이 크기를 넘긴 청크는 즉시 독립된 청크로 분리됩니다.", "The minimum interval for automatic synchronisation on event.": "이벤트 발생 시 자동 동기화의 최소 간격입니다.", - "This feature enables direct synchronisation between devices. No server is required, but both devices must be online at the same time for synchronisation to occur, and some features may be limited. Internet connection is only required to signalling (detecting peers) and not for data transfer.": "이 기능은 장치 간 직접 동기화를 제공합니다. 서버는 필요 없지만 동기화가 이루어지려면 두 장치가 동시에 온라인 상태여야 하며 일부 기능은 제한될 수 있습니다. 인터넷 연결은 시그널링(피어 감지)에만 필요하며 데이터 전송 자체에는 필요하지 않습니다。", - "This is an advanced option for users who do not have a URI or who wish to configure detailed settings.": "URI가 없거나 세부 설정을 직접 구성하려는 사용자를 위한 고급 옵션입니다。", - "This is the most suitable synchronisation method for the design. All functions are available. You must have set up a CouchDB instance.": "이 설계에 가장 적합한 동기화 방식입니다. 모든 기능을 사용할 수 있습니다. CouchDB 인스턴스를 미리 구성해야 합니다。", + "This feature enables direct synchronisation between devices. No server is required, but both devices must be online at the same time for synchronisation to occur, and some features may be limited. Internet connection is only required to signalling (detecting peers) and not for data transfer.": "기기 간에 직접 동기화하는 기능입니다. 서버는 필요 없지만 동기화가 이루어지려면 두 기기가 동시에 온라인 상태여야 하며, 일부 기능은 제한될 수 있습니다. 인터넷 연결은 시그널링(피어 탐지)에만 필요하고 데이터 전송에는 필요하지 않습니다.", + "This is an advanced option for users who do not have a URI or who wish to configure detailed settings.": "URI가 없거나 세부 설정을 직접 구성하려는 사용자를 위한 고급 옵션입니다.", + "This is the most suitable synchronisation method for the design. All functions are available. You must have set up a CouchDB instance.": "이 설계에 가장 적합한 동기화 방식입니다. 모든 기능을 사용할 수 있습니다. CouchDB 인스턴스를 미리 구성해 두어야 합니다.", "This passphrase will not be copied to another device. It will be set to `Default` until you configure it again.": "이 패스프레이즈는 다른 기기로 복사되지 않습니다. 다시 구성할 때까지 `기본값`으로 설정됩니다.", "This will recreate chunks for all files. If there were missing chunks, this may fix the errors.": "모든 파일의 청크를 다시 생성합니다. 누락된 청크가 있었다면 이 작업으로 오류가 해결될 수 있습니다.", "Transfer Tweak": "전송 조정", + "TweakMismatchResolve.Action.DisableAutoAcceptCompatible": "자동 수용 비활성화", "TweakMismatchResolve.Action.Dismiss": "무시", + "TweakMismatchResolve.Action.EnableAutoAcceptCompatible": "자동 수용 활성화", "TweakMismatchResolve.Action.UseConfigured": "구성된 설정 사용", "TweakMismatchResolve.Action.UseMine": "원격 데이터베이스 설정 업데이트", "TweakMismatchResolve.Action.UseMineAcceptIncompatible": "원격 데이터베이스 설정 업데이트하지만 그대로 유지", @@ -757,8 +823,11 @@ "TweakMismatchResolve.Action.UseRemote": "이 기기에 설정 적용", "TweakMismatchResolve.Action.UseRemoteAcceptIncompatible": "이 기기에 설정 적용하지만 호환성 문제 무시", "TweakMismatchResolve.Action.UseRemoteWithRebuild": "이 기기에 설정 적용하고 다시 가져오기", + "TweakMismatchResolve.Message.AutoAcceptCompatibleUndefined": "\n기기마다 설정이 다른 것으로 보입니다. 이제 호환되는 변경 사항은 자동으로 적용할 수 있습니다.\n이 `자동 수용` 설정을 활성화하시겠습니까?", "TweakMismatchResolve.Message.Main": "\n원격 데이터베이스의 설정은 다음과 같습니다. 이 값들은 이 기기와 최소 한 번 동기화된 다른 기기에서 구성된 것입니다.\n\n이 설정을 사용하려면 %{TweakMismatchResolve.Action.UseConfigured}를 선택해 주세요.\n이 기기의 설정을 유지하려면 %{TweakMismatchResolve.Action.Dismiss}를 선택해 주세요.\n\n${table}\n\n>[!TIP]\n> 모든 설정을 동기화하려면 이 기능으로 최소 구성을 적용한 후 `마크다운을 통한 설정 동기화`를 사용해 주세요.\n\n${additionalMessage}", "TweakMismatchResolve.Message.MainTweakResolving": "구성이 원격 서버의 것과 일치하지 않습니다.\n\n다음 구성이 일치해야 합니다:\n\n${table}\n\n결정을 알려주세요.\n\n${additionalMessage}", + "TweakMismatchResolve.Message.mineUpdated": "이 기기의 구성이 조정되었습니다.", + "TweakMismatchResolve.Message.remoteUpdated": "원격에 저장된 구성이 업데이트되었습니다.", "TweakMismatchResolve.Message.UseRemote.WarningRebuildRecommended": "\n>[!NOTICE]\n> 일부 변경사항은 호환 가능하지만 추가 스토리지 및 전송량을 소모할 수 있습니다. 재구축을 권장합니다. 하지만 현재 재구축을 수행하지 않더라도 향후 유지보수에서 구현될 수 있습니다.\n> ***시간적 여유가 있고 안정적인 네트워크에 연결된 상태에서 적용해 주세요!***", "TweakMismatchResolve.Message.UseRemote.WarningRebuildRequired": "\n>[!WARNING]\n> 일부 원격 구성이 이 기기의 로컬 데이터베이스와 호환되지 않습니다. 로컬 데이터베이스 재구축이 필요합니다.\n> ***시간적 여유가 있고 안정적인 네트워크에 연결된 상태에서 적용해 주세요!***", "TweakMismatchResolve.Message.WarningIncompatibleRebuildRecommended": "\n>[!NOTICE]\n> 로컬 데이터베이스와 원격 데이터베이스가 호환되지 않도록 만드는 값들이 다른 것을 감지했습니다.\n> 일부 변경사항은 호환 가능하지만 추가 스토리지 및 전송량을 소모할 수 있습니다. 재구축을 권장합니다. 하지만 현재 재구축을 수행하지 않더라도 향후 유지보수에서 구현될 수 있습니다.\n> 재구축을 원한다면 몇 분 이상 소요됩니다. **지금 수행해도 안전한지 확인해 주세요.**", @@ -766,11 +835,278 @@ "TweakMismatchResolve.Table": "| 값 이름 | 이 기기 | 원격 |\n|: --- |: ---- :|: ---- :|\n${rows}\n\n", "TweakMismatchResolve.Table.Row": "| ${name} | ${self} | ${remote} |", "TweakMismatchResolve.Title": "구성 불일치 감지", + "TweakMismatchResolve.Title.AutoAcceptCompatible": "자동 수용 사용 가능", "TweakMismatchResolve.Title.TweakResolving": "구성 불일치 감지", "TweakMismatchResolve.Title.UseRemoteConfig": "원격 구성 사용", + "Ui.Common.Signal.Caution": "주의", + "Ui.Common.Signal.Danger": "위험", + "Ui.Common.Signal.Notice": "알림", + "Ui.Common.Signal.Warning": "경고", + "Ui.Settings.Advanced.LocalDatabaseTweak": "로컬 데이터베이스 조정", + "Ui.Settings.Advanced.MemoryCache": "메모리 캐시", + "Ui.Settings.Advanced.TransferTweak": "전송 조정", + "Ui.Settings.Common.Analyse": "분석", + "Ui.Settings.Common.Back": "뒤로", + "Ui.Settings.Common.Check": "확인", + "Ui.Settings.Common.Configure": "설정", + "Ui.Settings.Common.Continue": "계속", + "Ui.Settings.Common.Delete": "삭제", + "Ui.Settings.Common.Fetch": "가져오기", + "Ui.Settings.Common.Lock": "잠금", + "Ui.Settings.Common.Merge": "병합", + "Ui.Settings.Common.Open": "열기", + "Ui.Settings.Common.Overwrite": "덮어쓰기", + "Ui.Settings.Common.Perform": "실행", + "Ui.Settings.Common.ResetAll": "모두 재설정", + "Ui.Settings.Common.ResolveAll": "모두 해결", + "Ui.Settings.Common.Scan": "검사", + "Ui.Settings.Common.Send": "보내기", + "Ui.Settings.Common.Use": "사용", + "Ui.Settings.Common.VerifyAll": "모두 검증", + "Ui.Settings.CustomizationSync.OpenDesc": "대화상자 열기", + "Ui.Settings.CustomizationSync.Panel": "사용자 설정 동기화", + "Ui.Settings.CustomizationSync.WarnChangeDeviceName": "이 기능이 활성화되어 있는 동안에는 기기 이름을 변경할 수 없습니다. 기기 이름을 변경하려면 이 기능을 비활성화하세요.", + "Ui.Settings.CustomizationSync.WarnSetDeviceName": "이 기기를 식별할 기기 이름을 설정해 주세요. 이 이름은 기기 간에 고유해야 합니다. 설정하기 전까지는 이 기능을 활성화할 수 없습니다.", + "Ui.Settings.Hatch.AnalyseDatabaseUsage": "데이터베이스 사용량 분석", + "Ui.Settings.Hatch.AnalyseDatabaseUsageDesc": "데이터베이스 사용량을 분석하고 직접 진단할 수 있도록 TSV 보고서를 생성합니다. 생성된 보고서는 원하는 스프레드시트에 붙여 넣어 확인할 수 있습니다.", + "Ui.Settings.Hatch.BackToNonConfigured": "미구성 상태로 되돌리기", + "Ui.Settings.Hatch.ConvertNonObfuscated": "경로 난독화되지 않은 파일 검사 및 변환", + "Ui.Settings.Hatch.ConvertNonObfuscatedDesc": "경로 난독화 없이 저장된 파일이 있는지 로컬 데이터베이스를 확인하고, 필요하면 변환합니다.", + "Ui.Settings.Hatch.CopyIssueReport": "보고서를 클립보드에 복사", + "Ui.Settings.Hatch.DatabaseLabel": "데이터베이스: ${details}", + "Ui.Settings.Hatch.DatabaseToStorage": "데이터베이스 -> 스토리지", + "Ui.Settings.Hatch.DeleteCustomizationSyncData": "모든 사용자 설정 동기화 데이터 삭제", + "Ui.Settings.Hatch.GeneratedReport": "생성된 보고서", + "Ui.Settings.Hatch.Missing": "누락됨", + "Ui.Settings.Hatch.ModifiedSize": "수정: ${modified}, 크기: ${size}", + "Ui.Settings.Hatch.ModifiedSizeActual": "수정: ${modified}, 크기: ${size} (실제 크기: ${actualSize})", + "Ui.Settings.Hatch.PrepareIssueReport": "이슈 생성을 위한 '보고서' 준비", + "Ui.Settings.Hatch.RecoveryAndRepair": "복구 및 수리", + "Ui.Settings.Hatch.RecreateAll": "모두 다시 생성", + "Ui.Settings.Hatch.RecreateMissingChunks": "모든 파일의 누락된 청크 다시 생성", + "Ui.Settings.Hatch.RecreateMissingChunksDesc": "모든 파일의 청크를 다시 생성합니다. 누락된 청크가 있었다면 이 작업으로 오류가 해결될 수 있습니다.", + "Ui.Settings.Hatch.ResetPanel": "재설정", + "Ui.Settings.Hatch.ResetRemoteUsage": "알림 임계값을 초기화하고 원격 데이터베이스 사용량 확인", + "Ui.Settings.Hatch.ResetRemoteUsageDesc": "원격 저장소 크기 임계값을 초기화하고 원격 저장소 크기를 다시 확인합니다.", + "Ui.Settings.Hatch.ResolveAllConflictedFiles": "충돌한 모든 파일을 최신 버전으로 해결", + "Ui.Settings.Hatch.ResolveAllConflictedFilesDesc": "충돌한 모든 파일을 더 최신 버전으로 해결합니다. 주의: 이전 버전은 덮어써지며 복원할 수 없습니다.", + "Ui.Settings.Hatch.RunDoctor": "진단 실행", + "Ui.Settings.Hatch.ScanBrokenFiles": "손상된 파일 검사", + "Ui.Settings.Hatch.ScramSwitches": "긴급 정지 스위치", + "Ui.Settings.Hatch.ShowHistory": "기록 표시", + "Ui.Settings.Hatch.StorageLabel": "스토리지: ${details}", + "Ui.Settings.Hatch.StorageToDatabase": "스토리지 -> 데이터베이스", + "Ui.Settings.Hatch.VerifyAndRepairAllFiles": "모든 파일 검증 및 복구", + "Ui.Settings.Hatch.VerifyAndRepairAllFilesDesc": "로컬 데이터베이스와 스토리지의 파일 내용을 비교합니다. 일치하지 않으면 어느 쪽을 유지할지 묻습니다.", + "Ui.Settings.Maintenance.Cleanup": "정리 실행", + "Ui.Settings.Maintenance.CleanupDesc": "최신 버전이 아닌 모든 리비전을 제거하여 저장 공간을 줄입니다. 이 작업을 수행하려면 원격 서버와 로컬 클라이언트에 동일한 양의 여유 공간이 필요합니다.", + "Ui.Settings.Maintenance.DeleteLocalDatabase": "Self-hosted LiveSync를 초기화하거나 제거하기 위해 로컬 데이터베이스를 삭제", + "Ui.Settings.Maintenance.EmergencyRestart": "긴급 재시작", + "Ui.Settings.Maintenance.EmergencyRestartDesc": "모든 동기화를 비활성화하고 재시작합니다.", + "Ui.Settings.Maintenance.FreshStartWipe": "초기화 후 새로 시작", + "Ui.Settings.Maintenance.FreshStartWipeDesc": "원격 서버의 모든 데이터를 삭제합니다.", + "Ui.Settings.Maintenance.GarbageCollection": "가비지 컬렉션 V3 (Beta)", + "Ui.Settings.Maintenance.GarbageCollectionAction": "가비지 컬렉션 실행", + "Ui.Settings.Maintenance.GarbageCollectionDesc": "사용하지 않는 청크를 제거하고 데이터베이스 크기를 줄이기 위해 가비지 컬렉션을 실행합니다.", + "Ui.Settings.Maintenance.LockServer": "서버 잠금", + "Ui.Settings.Maintenance.LockServerDesc": "다른 기기와 동기화되지 않도록 원격 서버를 잠급니다.", + "Ui.Settings.Maintenance.OverwriteRemote": "원격 덮어쓰기", + "Ui.Settings.Maintenance.OverwriteRemoteDesc": "로컬 DB와 패스프레이즈로 원격을 덮어씁니다.", + "Ui.Settings.Maintenance.OverwriteServerData": "이 기기의 파일로 서버 데이터를 덮어쓰기", + "Ui.Settings.Maintenance.OverwriteServerDataDesc": "이 기기의 파일로 로컬과 원격 데이터베이스를 재구축합니다.", + "Ui.Settings.Maintenance.PurgeAllJournalCounter": "모든 저널 카운터 삭제", + "Ui.Settings.Maintenance.PurgeAllJournalCounterDesc": "모든 다운로드 및 업로드 캐시를 제거합니다.", + "Ui.Settings.Maintenance.RebuildingOperations": "재구축 작업 (원격 전용)", + "Ui.Settings.Maintenance.Resend": "다시 보내기", + "Ui.Settings.Maintenance.ResendDesc": "모든 청크를 원격으로 다시 보냅니다.", + "Ui.Settings.Maintenance.Reset": "재설정", + "Ui.Settings.Maintenance.ResetAllJournalCounter": "모든 저널 카운터 재설정", + "Ui.Settings.Maintenance.ResetAllJournalCounterDesc": "모든 저널 기록을 초기화합니다. 다음 동기화 때 모든 항목을 다시 주고받습니다.", + "Ui.Settings.Maintenance.ResetJournalReceived": "저널 수신 기록 재설정", + "Ui.Settings.Maintenance.ResetJournalReceivedDesc": "저널 수신 기록을 초기화합니다. 다음 동기화 때 이 기기가 보낸 항목을 제외한 모든 항목을 다시 내려받습니다.", + "Ui.Settings.Maintenance.ResetJournalSent": "저널 송신 기록 재설정", + "Ui.Settings.Maintenance.ResetJournalSentDesc": "저널 송신 기록을 초기화합니다. 다음 동기화 때 이 기기가 받은 항목을 제외한 모든 항목을 다시 보냅니다.", + "Ui.Settings.Maintenance.ResetLocalSyncInfo": "동기화 정보 재설정", + "Ui.Settings.Maintenance.ResetLocalSyncInfoDesc": "원격에서 로컬 데이터베이스를 복원하거나 재구축합니다.", + "Ui.Settings.Maintenance.ResetReceived": "수신 기록 재설정", + "Ui.Settings.Maintenance.ResetSentHistory": "송신 기록 재설정", + "Ui.Settings.Maintenance.ResetThisDevice": "이 기기의 동기화 재설정", + "Ui.Settings.Maintenance.ScheduleAndRestart": "예약 후 재시작", + "Ui.Settings.Maintenance.Scram": "긴급 정지", + "Ui.Settings.Maintenance.SendChunks": "청크 보내기", + "Ui.Settings.Maintenance.Syncing": "동기화", + "Ui.Settings.Maintenance.WarningLockedReadyAction": "준비되었습니다. 데이터베이스 잠금 해제", + "Ui.Settings.Maintenance.WarningLockedReadyText": "의도치 않은 보관함 손상을 막기 위해 원격 데이터베이스가 동기화 잠금 상태입니다. (이 기기는 '해결됨'으로 표시되어 있습니다.) 모든 기기가 '해결됨'으로 표시되면 데이터베이스 잠금을 해제하세요. 이 경고는 복제를 통해 기기가 해결되었음이 확인될 때까지 계속 표시됩니다.", + "Ui.Settings.Maintenance.WarningLockedResolveAction": "백업했습니다. 이 기기를 해결됨으로 표시", + "Ui.Settings.Maintenance.WarningLockedResolveText": "이 기기가 '해결됨'으로 표시되어 있지 않아, 보관함 손상을 막기 위해 원격 데이터베이스가 동기화 잠금 상태입니다. 보관함을 백업하고 로컬 데이터베이스를 재설정한 뒤 '이 기기를 해결됨으로 표시'를 선택해 주세요. 이 경고는 복제를 통해 기기가 해결되었음이 확인될 때까지 계속 표시됩니다.", + "Ui.Settings.Maintenance.WriteRedFlagAndRestart": "표시 후 재시작", + "Ui.Settings.Patches.CompatibilityConflict": "호환성 (충돌 동작)", + "Ui.Settings.Patches.CompatibilityDatabase": "호환성 (데이터베이스 구조)", + "Ui.Settings.Patches.CompatibilityInternalApi": "호환성 (내부 API 사용)", + "Ui.Settings.Patches.CompatibilityMetadata": "호환성 (메타데이터)", + "Ui.Settings.Patches.CompatibilityRemote": "호환성 (원격 데이터베이스)", + "Ui.Settings.Patches.CompatibilityTrouble": "호환성 (문제 대응)", + "Ui.Settings.Patches.CurrentAdapter": "현재 어댑터: ${adapter}", + "Ui.Settings.Patches.DatabaseAdapter": "데이터베이스 어댑터", + "Ui.Settings.Patches.DatabaseAdapterDesc": "사용할 데이터베이스 어댑터를 선택합니다.", + "Ui.Settings.Patches.EdgeCaseBehaviour": "특수 상황 처리 (동작)", + "Ui.Settings.Patches.EdgeCaseDatabase": "특수 상황 처리 (데이터베이스)", + "Ui.Settings.Patches.EdgeCaseProcessing": "특수 상황 처리 (처리)", + "Ui.Settings.Patches.IndexedDbWarning": "IndexedDB 어댑터는 특정 상황에서 더 나은 성능을 보이는 경우가 많지만, LiveSync 모드에서 사용하면 메모리 누수를 일으키는 것으로 확인되었습니다. LiveSync 모드를 사용할 때는 IDB 어댑터를 사용해 주세요.", + "Ui.Settings.Patches.MigratingToIdb": "모든 데이터를 IDB로 마이그레이션하는 중...", + "Ui.Settings.Patches.MigratingToIndexedDb": "모든 데이터를 IndexedDB로 마이그레이션하는 중...", + "Ui.Settings.Patches.MigrationIdbCompleted": "IDB로 마이그레이션이 완료되었습니다. 새 구성을 적용하기 위해 Obsidian이 곧 재시작됩니다.", + "Ui.Settings.Patches.MigrationIdbCompletedFollowUp": "IDB로 마이그레이션이 완료되었습니다. 어댑터를 전환하고 Obsidian을 재시작해 주세요.", + "Ui.Settings.Patches.MigrationIndexedDbCompleted": "IndexedDB로 마이그레이션이 완료되었습니다. 새 구성을 적용하기 위해 Obsidian이 곧 재시작됩니다.", + "Ui.Settings.Patches.MigrationIndexedDbCompletedFollowUp": "IndexedDB로 마이그레이션이 완료되었습니다. 어댑터를 전환하고 Obsidian을 재시작해 주세요.", + "Ui.Settings.Patches.MigrationWarning": "이 설정을 변경하려면 기존 데이터를 마이그레이션하고(시간이 다소 걸릴 수 있습니다) Obsidian을 재시작해야 합니다. 진행하기 전에 반드시 데이터를 백업해 주세요.", + "Ui.Settings.Patches.OperationToIdb": "IDB로", + "Ui.Settings.Patches.OperationToIndexedDb": "IndexedDB로", + "Ui.Settings.Patches.Remediation": "복구 조치", + "Ui.Settings.Patches.RemediationChanged": "복구 설정이 변경됨", + "Ui.Settings.Patches.RemediationNoLimit": "제한이 설정되지 않음", + "Ui.Settings.Patches.RemediationRestarting": "복구 조치 설정이 변경되었습니다. Obsidian을 재시작하는 중...", + "Ui.Settings.Patches.RemediationRestartLater": "나중에", + "Ui.Settings.Patches.RemediationRestartMessage": "Obsidian을 재시작하는 것을 강력히 권장합니다. 재시작하기 전까지는 일부 변경 사항이 적용되지 않거나 화면이 일관되지 않게 표시될 수 있습니다. 지금 재시작하시겠습니까?", + "Ui.Settings.Patches.RemediationRestartNow": "지금 재시작", + "Ui.Settings.Patches.RemediationSuffixChanged": "접미사가 변경되었습니다. 데이터베이스를 다시 여는 중...", + "Ui.Settings.Patches.RemediationWithValue": "제한: ${date} (${timestamp})", + "Ui.Settings.Patches.RemoteDatabaseSunset": "원격 데이터베이스 조정 (폐기 예정)", + "Ui.Settings.Patches.SwitchToIDB": "IDB로 전환", + "Ui.Settings.Patches.SwitchToIndexedDb": "IndexedDB로 전환", + "Ui.Settings.PowerUsers.ConfigurationEncryption": "구성 암호화", + "Ui.Settings.PowerUsers.ConnectionTweak": "CouchDB 연결 조정", + "Ui.Settings.PowerUsers.ConnectionTweakDesc": "IBM Cloudant를 사용하다가 페이로드 크기 제한에 도달했다면, 배치 크기와 배치 개수 제한을 더 낮은 값으로 줄여 주세요.", + "Ui.Settings.PowerUsers.Default": "기본값", + "Ui.Settings.PowerUsers.Developer": "개발자", + "Ui.Settings.PowerUsers.EncryptSensitiveConfig": "민감한 구성 항목 암호화", + "Ui.Settings.PowerUsers.PromptPassphraseEveryLaunch": "시작할 때마다 패스프레이즈 묻기", + "Ui.Settings.PowerUsers.UseCustomPassphrase": "사용자 지정 패스프레이즈 사용", + "Ui.Settings.Remote.Activate": "활성화", + "Ui.Settings.Remote.ActiveSuffix": " (활성)", + "Ui.Settings.Remote.AddConnection": "연결 추가", + "Ui.Settings.Remote.AddRemoteDefaultName": "새 원격", + "Ui.Settings.Remote.ConfigureAndChangeRemote": "원격 구성 및 변경", + "Ui.Settings.Remote.ConfigureE2EE": "E2EE 구성", + "Ui.Settings.Remote.ConfigureRemote": "원격 구성", + "Ui.Settings.Remote.DeleteRemoteConfirm": "'${name}' 원격 구성을 삭제할까요?", + "Ui.Settings.Remote.DeleteRemoteTitle": "원격 구성 삭제", + "Ui.Settings.Remote.DisplayName": "표시 이름", + "Ui.Settings.Remote.DuplicateRemote": "원격 구성 복사", + "Ui.Settings.Remote.DuplicateRemoteSuffix": "${name} (사본)", + "Ui.Settings.Remote.E2EEConfiguration": "E2EE 구성", + "Ui.Settings.Remote.Export": "내보내기", + "Ui.Settings.Remote.FetchRemoteSettings": "원격 설정 가져오기", + "Ui.Settings.Remote.ImportConnection": "연결 가져오기", + "Ui.Settings.Remote.ImportConnectionPrompt": "연결 문자열 붙여넣기", + "Ui.Settings.Remote.ImportedCouchDb": "가져온 CouchDB", + "Ui.Settings.Remote.ImportedRemote": "원격", + "Ui.Settings.Remote.MoreActions": "추가 작업", + "Ui.Settings.Remote.PeerToPeerPanel": "피어 투 피어(P2P) 동기화", + "Ui.Settings.Remote.RemoteConfigurationPrefix": "원격 구성", + "Ui.Settings.Remote.RemoteDatabases": "원격 데이터베이스", + "Ui.Settings.Remote.RemoteName": "원격 이름", + "Ui.Settings.Remote.RemoteNameCouchDb": "CouchDB ${host}", + "Ui.Settings.Remote.RemoteNameP2P": "P2P ${room}", + "Ui.Settings.Remote.RemoteNameS3": "S3 ${bucket}", + "Ui.Settings.Remote.Rename": "이름 바꾸기", + "Ui.Settings.Selector.AddDefaultPatterns": "기본 패턴 추가", + "Ui.Settings.Selector.CrossPlatform": "크로스 플랫폼", + "Ui.Settings.Selector.Default": "기본값", + "Ui.Settings.Selector.HiddenFiles": "숨김 파일", + "Ui.Settings.Selector.IgnorePatterns": "무시 패턴", + "Ui.Settings.Selector.NonSynchronisingFiles": "동기화하지 않는 파일", + "Ui.Settings.Selector.NonSynchronisingFilesDesc": "(정규식) 설정하면 이 패턴과 일치하는 로컬 및 원격 파일 변경은 모두 건너뜁니다.", + "Ui.Settings.Selector.NormalFiles": "일반 파일", + "Ui.Settings.Selector.OverwritePatterns": "덮어쓰기 패턴", + "Ui.Settings.Selector.OverwritePatternsDesc": "병합 대신 덮어쓸 파일을 판별하는 패턴", + "Ui.Settings.Selector.SynchronisingFiles": "동기화할 파일", + "Ui.Settings.Selector.SynchronisingFilesDesc": "(정규식) 비워 두면 모든 파일을 동기화합니다. 정규식 필터를 지정하면 동기화할 파일을 제한할 수 있습니다.", + "Ui.Settings.Selector.TargetPatterns": "대상 패턴", + "Ui.Settings.Selector.TargetPatternsDesc": "동기화할 파일을 판별하는 패턴", + "Ui.Settings.Setup.RerunWizardButton": "마법사 다시 실행", + "Ui.Settings.Setup.RerunWizardDesc": "온보딩 마법사를 다시 실행하여 Self-hosted LiveSync를 다시 설정합니다.", + "Ui.Settings.Setup.RerunWizardName": "온보딩 마법사 다시 실행", + "Ui.Settings.SyncSettings.Fetch": "가져오기", + "Ui.Settings.SyncSettings.Merge": "병합", + "Ui.Settings.SyncSettings.Overwrite": "덮어쓰기", + "Ui.SetupWizard.Common.Back": "아니요, 이전으로 돌아가겠습니다", + "Ui.SetupWizard.Common.Cancel": "취소", + "Ui.SetupWizard.Common.ProceedSelectOption": "계속하려면 항목을 선택해 주세요", + "Ui.SetupWizard.Intro.ExistingOption": "기존 동기화 구성에 기기를 추가합니다", + "Ui.SetupWizard.Intro.ExistingOptionDesc": "다른 컴퓨터나 스마트폰에서 이미 동기화를 사용 중이라면 선택하세요. 이 기기를 기존 구성에 연결할 때 사용합니다.", + "Ui.SetupWizard.Intro.Guidance": "동기화 설정을 간단히 마칠 수 있도록 몇 가지 질문으로 안내해 드리겠습니다.", + "Ui.SetupWizard.Intro.NewOption": "처음으로 설정합니다", + "Ui.SetupWizard.Intro.NewOptionDesc": "이 기기를 첫 번째 동기화 기기로 설정한다면 선택하세요.", + "Ui.SetupWizard.Intro.ProceedExisting": "예, 이 기기를 기존 동기화 구성에 추가하겠습니다", + "Ui.SetupWizard.Intro.ProceedNew": "예, 새 동기화를 설정하겠습니다", + "Ui.SetupWizard.Intro.Question": "먼저 현재 상황에 가장 잘 맞는 항목을 선택해 주세요.", + "Ui.SetupWizard.Intro.Title": "Self-hosted LiveSync에 오신 것을 환영합니다", + "Ui.SetupWizard.Invitation.Start": "설정 시작", + "Ui.SetupWizard.OutroAskUserMode.CompatibleOption": "원격이 이미 설정되어 있고, 구성도 호환됩니다(또는 이번 작업으로 호환되었습니다).", + "Ui.SetupWizard.OutroAskUserMode.CompatibleOptionDesc": "확신이 없다면 이 옵션을 선택하는 것은 위험합니다. 서버 구성이 이 기기와 호환된다고 가정하기 때문에, 그렇지 않을 경우 데이터가 손실될 수 있습니다. 결과를 충분히 이해한 뒤에 선택해 주세요.", + "Ui.SetupWizard.OutroAskUserMode.ExistingOption": "원격 서버가 이미 설정되어 있습니다. 이 기기를 참여시키려고 합니다.", + "Ui.SetupWizard.OutroAskUserMode.ExistingOptionDesc": "이 옵션을 선택하면 이 기기가 기존 서버에 참여합니다. 서버에 있는 기존 동기화 데이터를 이 기기로 가져와야 합니다.", + "Ui.SetupWizard.OutroAskUserMode.Guidance": "서버 연결이 정상적으로 구성되었습니다. 다음 단계로, 로컬 데이터베이스 즉 동기화 정보를 재구축해야 합니다.", + "Ui.SetupWizard.OutroAskUserMode.NewOption": "서버를 처음 설정합니다 / 기존 서버를 초기화하려고 합니다.", + "Ui.SetupWizard.OutroAskUserMode.NewOptionDesc": "이 옵션을 선택하면 이 기기의 현재 데이터로 서버를 초기화합니다. 서버에 있던 기존 데이터는 완전히 덮어써집니다.", + "Ui.SetupWizard.OutroAskUserMode.ProceedApplySettings": "설정 적용", + "Ui.SetupWizard.OutroAskUserMode.ProceedNext": "다음 단계로 진행합니다.", + "Ui.SetupWizard.OutroAskUserMode.Question": "현재 상황을 선택해 주세요.", + "Ui.SetupWizard.OutroAskUserMode.Title": "거의 완료: 선택이 필요합니다", + "Ui.SetupWizard.OutroNewP2PUser.GuidanceNotice": "P2P에는 덮어쓸 중앙 서버 사본이 없습니다. 이 단계는 이 기기만 준비하며, 다른 기기가 초기 데이터를 가져올 때는 이 기기를 온라인 상태로 유지해 주세요.", + "Ui.SetupWizard.OutroNewP2PUser.GuidancePrimary": "Peer-to-Peer 연결이 정상적으로 구성되었습니다. 다음 단계로, 이 보관함의 현재 파일을 사용해 로컬 LiveSync 데이터베이스를 만듭니다.", + "Ui.SetupWizard.OutroNewP2PUser.Important": "유의해 주세요", + "Ui.SetupWizard.OutroNewP2PUser.Proceed": "재시작하고 이 기기 준비", + "Ui.SetupWizard.OutroNewP2PUser.Question": "재시작하고 로컬 초기화 확인 단계로 넘어가려면 아래 버튼을 선택해 주세요.", + "Ui.SetupWizard.OutroNewP2PUser.Title": "설정 완료: 이 P2P 기기 준비", + "Ui.SetupWizard.OutroNewUser.GuidancePrimary": "서버 연결이 정상적으로 구성되었습니다. 다음 단계로, 이 기기의 현재 데이터를 사용해 서버의 동기화 데이터를 만듭니다.", + "Ui.SetupWizard.OutroNewUser.GuidanceWarning": "재시작하면 이 기기의 데이터가 원본으로서 서버에 업로드됩니다. 현재 서버에 있는 데이터는 의도치 않은 것이라도 완전히 덮어써지므로 유의해 주세요.", + "Ui.SetupWizard.OutroNewUser.Important": "중요", + "Ui.SetupWizard.OutroNewUser.Proceed": "재시작하고 서버 초기화", + "Ui.SetupWizard.OutroNewUser.Question": "재시작하고 마지막 확인 단계로 넘어가려면 아래 버튼을 선택해 주세요.", + "Ui.SetupWizard.OutroNewUser.Title": "설정 완료: 서버 초기화 준비", + "Ui.SetupWizard.RebuildEverythingP2P.ConfirmLocalReset": "이 작업이 이 기기의 로컬 동기화 데이터베이스만 초기화한다는 것을 이해했습니다.", + "Ui.SetupWizard.RebuildEverythingP2P.ConfirmLocalResetNote": "현재 이 보관함에 있는 파일을 사용해 재구축합니다.", + "Ui.SetupWizard.RebuildEverythingP2P.ConfirmTitle": "⚠️ 다음 내용을 확인해 주세요", + "Ui.SetupWizard.RebuildEverythingP2P.Guidance": "이 절차는 이 기기의 로컬 LiveSync 데이터베이스를 삭제하고, 이 보관함의 현재 파일로 재구축합니다. 다른 기기의 데이터는 삭제하거나 덮어쓰지 않습니다.", + "Ui.SetupWizard.RebuildEverythingP2P.Note": "초기화 후에도 다른 기기가 이 기기에서 보관함을 가져올 수 있도록 이 기기를 온라인 상태로 유지해 주세요.", + "Ui.SetupWizard.RebuildEverythingP2P.Proceed": "이해했습니다, 이 기기 준비", + "Ui.SetupWizard.RebuildEverythingP2P.Title": "최종 확인: P2P를 위한 이 기기 준비", + "Ui.SetupWizard.SelectExisting.Guidance": "이 기기를 기존 동기화 구성에 추가합니다.", + "Ui.SetupWizard.SelectExisting.ManualOption": "서버 정보를 수동으로 입력", + "Ui.SetupWizard.SelectExisting.ManualOptionDesc": "다른 기기와 동일한 서버 정보를 다시 직접 입력합니다. 숙련된 사용자 전용입니다.", + "Ui.SetupWizard.SelectExisting.ProceedManual": "서버 정보를 알고 있으니 직접 입력하겠습니다", + "Ui.SetupWizard.SelectExisting.ProceedQr": "이 기기의 카메라로 사용 중인 기기에 표시된 QR 코드를 스캔하세요.", + "Ui.SetupWizard.SelectExisting.ProceedSetupUri": "Setup URI로 계속", + "Ui.SetupWizard.SelectExisting.QrOption": "QR 코드 스캔(모바일 권장)", + "Ui.SetupWizard.SelectExisting.QrOptionDesc": "이 기기의 카메라로 사용 중인 기기에 표시된 QR 코드를 스캔하세요.", + "Ui.SetupWizard.SelectExisting.Question": "다른 기기에서 설정을 가져올 방법을 선택해 주세요.", + "Ui.SetupWizard.SelectExisting.SetupUriOption": "Setup URI 사용(권장)", + "Ui.SetupWizard.SelectExisting.SetupUriOptionDesc": "사용 중인 기기 중 하나에서 생성한 Setup URI를 붙여 넣으세요.", + "Ui.SetupWizard.SelectExisting.Title": "기기 설정 방법", + "Ui.SetupWizard.SelectNew.Guidance": "이제 서버 구성을 진행하겠습니다.", + "Ui.SetupWizard.SelectNew.ManualOption": "서버 정보를 수동으로 입력", + "Ui.SetupWizard.SelectNew.ManualOptionDesc": "Setup URI가 없거나 세부 설정을 직접 구성하려는 사용자를 위한 고급 옵션입니다.", + "Ui.SetupWizard.SelectNew.ProceedManual": "서버 정보를 알고 있으니 직접 입력하겠습니다", + "Ui.SetupWizard.SelectNew.ProceedSetupUri": "Setup URI로 계속", + "Ui.SetupWizard.SelectNew.Question": "서버 연결을 어떻게 구성하시겠습니까?", + "Ui.SetupWizard.SelectNew.SetupUriOption": "Setup URI 사용(권장)", + "Ui.SetupWizard.SelectNew.SetupUriOptionDesc": "Setup URI는 서버 주소와 인증 정보를 담은 하나의 문자열입니다. 서버 설치 스크립트가 URI를 생성했다면, 간단하고 안전하게 구성할 수 있는 방법입니다.", + "Ui.SetupWizard.SelectNew.Title": "연결 방법", + "Ui.SetupWizard.SetupRemote.BucketOption": "S3/MinIO/R2 객체 스토리지", + "Ui.SetupWizard.SetupRemote.BucketOptionDesc": "저널 파일을 사용하는 동기화 방식입니다. S3/MinIO/R2 호환 객체 스토리지 서비스를 미리 구성해 두어야 합니다.", + "Ui.SetupWizard.SetupRemote.CouchDbOptionDesc": "현재 설계에 가장 적합한 동기화 방식입니다. 모든 기능을 사용할 수 있습니다. CouchDB 인스턴스를 미리 구성해 두어야 합니다.", + "Ui.SetupWizard.SetupRemote.Guidance": "연결할 서버 유형을 선택해 주세요.", + "Ui.SetupWizard.SetupRemote.P2POption": "Peer-to-Peer 전용", + "Ui.SetupWizard.SetupRemote.P2POptionDesc": "기기 간에 직접 동기화하는 방식입니다. 서버는 필요 없지만 두 기기가 동시에 온라인 상태여야 하며, 일부 기능은 제한될 수 있습니다. 인터넷 연결은 시그널링에만 필요하고 데이터 전송에는 필요하지 않습니다.", + "Ui.SetupWizard.SetupRemote.ProceedBucket": "S3/MinIO/R2 설정으로 계속", + "Ui.SetupWizard.SetupRemote.ProceedCouchDb": "CouchDB 설정으로 계속", + "Ui.SetupWizard.SetupRemote.ProceedP2P": "Peer-to-Peer 전용 설정으로 계속", + "Ui.SetupWizard.SetupRemote.Title": "서버 정보 입력", "Unique name between all synchronized devices. To edit this setting, please disable customization sync once.": "모든 동기화된 기기 간 고유 이름입니다. 이 설정을 편집하려면 사용자 설정 동기화를 한 번 비활성화해 주세요.", - "Use a custom passphrase": "사용자 지정 암호문구 사용", - "Use a Setup URI (Recommended)": "설정 URI 사용(권장)", + "Use a custom passphrase": "사용자 지정 패스프레이즈 사용", + "Use a Setup URI (Recommended)": "Setup URI 사용(권장)", "Use Custom HTTP Handler": "커스텀 HTTP 핸들러 사용", "Use dynamic iteration count": "동적 반복 횟수 사용", "Use Segmented-splitter": "의미 기반 분할 사용", @@ -783,16 +1119,16 @@ "Verify all": "모두 검증", "Verify and repair all files": "모든 파일 검증 및 복구", "Warning! This will have a serious impact on performance. And the logs will not be synchronised under the default name. Please be careful with logs; they often contain your confidential information.": "경고! 이는 성능에 심각한 영향을 미칩니다. 로그는 기본 이름으로 동기화되지 않습니다. 로그에는 종종 기밀 정보가 포함되어 있으므로 주의해 주세요.", - "We cannot change the device name while this feature is enabled. Please disable this feature to change the device name.": "이 기능이 활성화되어 있는 동안에는 장치 이름을 변경할 수 없습니다. 장치 이름을 변경하려면 이 기능을 비활성화하세요.", - "We will now guide you through a few questions to simplify the synchronisation setup.": "동기화 설정을 더 쉽게 진행할 수 있도록 몇 가지 질문으로 안내해 드리겠습니다。", - "We will now proceed with the server configuration.": "이제 서버 구성을 진행하겠습니다。", + "We cannot change the device name while this feature is enabled. Please disable this feature to change the device name.": "이 기능이 활성화되어 있는 동안에는 기기 이름을 변경할 수 없습니다. 기기 이름을 변경하려면 이 기능을 비활성화하세요.", + "We will now guide you through a few questions to simplify the synchronisation setup.": "동기화 설정을 간단히 마칠 수 있도록 몇 가지 질문으로 안내해 드리겠습니다.", + "We will now proceed with the server configuration.": "이제 서버 구성을 진행하겠습니다.", "Welcome to Self-hosted LiveSync": "Self-hosted LiveSync에 오신 것을 환영합니다", "When you save a file in the editor, start a sync automatically": "편집기에서 파일을 저장할 때 자동으로 동기화를 시작합니다", "Write credentials in the file": "파일에 자격 증명 저장", "Write logs into the file": "파일에 로그 기록", "xxhash32 (Fast but less collision resistance)": "xxhash32 (빠르지만 충돌 저항성은 낮음)", "xxhash64 (Fastest)": "xxhash64 (가장 빠름)", - "Yes, I want to add this device to my existing synchronisation": "예, 이 장치를 기존 동기화에 추가하겠습니다", + "Yes, I want to add this device to my existing synchronisation": "예, 이 기기를 기존 동기화 구성에 추가하겠습니다", "Yes, I want to set up a new synchronisation": "예, 새 동기화를 설정하겠습니다", - "You are adding this device to an existing synchronisation setup.": "이 장치를 기존 동기화 구성에 추가하려고 합니다。" + "You are adding this device to an existing synchronisation setup.": "이 기기를 기존 동기화 구성에 추가합니다." } diff --git a/src/common/messagesYAML/en.yaml b/src/common/messagesYAML/en.yaml index 14a91892..844842c5 100644 --- a/src/common/messagesYAML/en.yaml +++ b/src/common/messagesYAML/en.yaml @@ -2435,4 +2435,3 @@ You should perform this operation only in exceptional circumstances, such as whe when the server data is completely corrupted, when changes on all other devices are no longer needed, or when the database size has become unusually large in comparison to the Vault size. - diff --git a/src/common/messagesYAML/es.yaml b/src/common/messagesYAML/es.yaml index cfdae590..6b79fddc 100644 --- a/src/common/messagesYAML/es.yaml +++ b/src/common/messagesYAML/es.yaml @@ -31,6 +31,9 @@ "↓: Overwrite Local": "↓: Sobrescribir local" "⇅: Use newer": "⇅: Usar el más nuevo" +1 week: +1 semana +"> [!INFO]- The connected devices have been detected as follows:\n${devices}": |- + > [!INFO]- Se han detectado los siguientes dispositivos conectados: + ${devices} ⚠️ Important Notice: ⚠️ Aviso importante ⚠️ Please Confirm the Following: ⚠️ Confirma lo siguiente ✔ SELECT: ✔ SELECCIONAR @@ -51,6 +54,7 @@ Access Key: Clave de acceso Access Key ID: ID de clave de acceso Action: Acción Activate: Activar +Active Remote Configuration: Configuración remota activa Add default patterns: Añadir patrones predeterminados Add new connection: Añadir conexión AddOn Module (ConfigSync) has not been loaded. This is very unexpected situation. Please report this issue.: @@ -73,6 +77,10 @@ After that, synchronise to a brand new vault on each other device with the new r Después, sincroniza con un vault totalmente nuevo en cada uno de los demás dispositivos, uno por uno, usando el nuevo remoto. All checks passed successfully!: ¡Todas las comprobaciones se han superado correctamente! +All devices have the same progress value (${progress}). Your devices seem to be synchronised. And be able to proceed with Garbage Collection.: + Todos los dispositivos tienen el mismo valor de progreso (${progress}). Parece + que están sincronizados, por lo que se puede continuar con la recolección de + basura. All the same or non-existent: Todo igual o inexistente Allow in session: Permitir en esta sesión Allow permanently: Permitir permanentemente @@ -81,6 +89,12 @@ Also, please note that if you are using Peer-to-Peer synchronization, this confi cuando en el futuro cambies a otros métodos y te conectes a un servidor remoto. Always prompt merge conflicts: Siempre preguntar en conflictos +Analyse: Analizar +Analyse database usage: Analizar el uso de la base de datos +Analyse database usage and generate a TSV report for diagnosis yourself. You can paste the generated report with any spreadsheet you like.: + Analiza el uso de la base de datos y genera un informe TSV para que puedas + diagnosticarlo tú mismo. Puedes pegar el informe generado en la hoja de + cálculo que prefieras. Apply All Selected: Aplicar todo lo seleccionado Apply Latest Change if Conflicting: Aplicar último cambio en conflictos Apply preset configuration: Aplicar configuración predefinida @@ -104,10 +118,16 @@ Broadcasting?: ¿Difusión? Bucket Name: Nombre del bucket by resetting the remote, you will be informed on other devices.: al restablecer el remoto, se te avisará en los demás dispositivos. Cancel: Cancelar +Cancel Garbage Collection: Cancelar la recolección de basura Changing the encryption algorithm will prevent access to any data previously encrypted with a different algorithm. Ensure that all your devices are configured to use the same algorithm to maintain access to your data.: Cambiar el algoritmo de cifrado impedirá acceder a los datos cifrados previamente con otro algoritmo. Asegúrate de que todos tus dispositivos usen el mismo algoritmo para no perder el acceso a tus datos. +Changing this setting requires migrating existing data (a bit time may be taken) and restarting Obsidian. Please make sure to back up your data before proceeding.: + Cambiar este ajuste requiere migrar los datos existentes (puede tardar un + poco) y reiniciar Obsidian. Asegúrate de hacer una copia de seguridad de tus + datos antes de continuar. +Check: Comprobar Check and convert non-path-obfuscated files: Comprobar y convertir archivos sin ofuscación de ruta Check for documents that have not been converted to path-obfuscated IDs and convert them if necessary.: Comprueba los documentos que aún no se hayan convertido a identificadores con @@ -123,6 +143,10 @@ cmdConfigSync: Comma separated `.gitignore, .dockerignore`: "Separados por comas: `.gitignore, .dockerignore`" Command: Comando Communicating: Comunicando +Compaction in progress on remote database...: Compactación en curso en la base de datos remota... +Compaction on remote database completed successfully.: La compactación de la base de datos remota se ha completado correctamente. +Compaction on remote database failed.: La compactación de la base de datos remota ha fallado. +Compaction on remote database timed out.: La compactación de la base de datos remota ha superado el tiempo de espera. Compare file: Comparar archivo Compare the content of files between on local database and storage. If not matched, you will be asked which one you want to keep.: Compara el contenido de los archivos entre la base de datos local y el @@ -133,6 +157,7 @@ Compatibility (Internal API Usage): Compatibilidad (uso de la API interna) Compatibility (Metadata): Compatibilidad (metadatos) Compatibility (Remote Database): Compatibilidad (base de datos remota) Compatibility (Trouble addressed): Compatibilidad (problemas corregidos) +Compute revisions for chunks: Calcular revisiones para los chunks Compute revisions for chunks (Previous behaviour): Calcular revisiones para chunks (comportamiento anterior) Configuration: Configuración Configuration Encryption: Cifrado de configuración @@ -147,6 +172,7 @@ Connection Settings: Ajustes de conexión "Connection:": "Conexión:" Continue anyway: Continuar de todos modos Copy: Copiar +Copy Report to clipboard: Copiar el informe al portapapeles CouchDB Configuration: Configuración de CouchDB CouchDB Connection Tweak: Ajustes de conexión de CouchDB Create P2P remote: Crear remoto P2P @@ -157,6 +183,7 @@ Customization Sync: Sincronización de personalización Customization Sync (Beta3): Sincronización de personalización (Beta3) Data Compression: Compresión de datos Data to Copy: Datos a copiar +Database -> Storage: Base de datos -> Almacenamiento Database Adapter: Adaptador de base de datos Database Name: Nombre de la base de datos Database suffix: Sufijo de base de datos @@ -184,6 +211,7 @@ Deselect all: Deseleccionar todo desktop: equipo de escritorio Detected Peers: Pares detectados Developer: Desarrollador +Device: Dispositivo device name: nombre del dispositivo Device name: Nombre del dispositivo Device name to identify the device. Please use shorter one for the stable peer detection, i.e., "iphone-16" or "macbook-2021".: @@ -192,6 +220,23 @@ Device name to identify the device. Please use shorter one for the stable peer d Device Peer ID: ID de par del dispositivo "Devices:": "Dispositivos:" Diagnostic RTCPeerConnection is enabled: El RTCPeerConnection de diagnóstico está habilitado +dialog: + yourLanguageAvailable: + _value: >- + Self-hosted LiveSync tenía traducciones para tu idioma, así que se ha + activado el ajuste %{Display language}. + + + Nota: no todos los mensajes están traducidos. ¡Esperamos tus + contribuciones! + + Nota 2: si abres una incidencia, **vuelve antes a %{lang-def}** y luego + haz las capturas de pantalla y recoge los mensajes y registros. Puedes + hacerlo desde el diálogo de ajustes. + + ¡Que lo disfrutes! + Title: " ¡Hay traducción disponible!" + btnRevertToDefault: Mantener %{lang-def} Diff: Diferencias Different: Distinto Disables all synchronization and restart.: Desactiva toda la sincronización y reinicia la aplicación. @@ -206,6 +251,67 @@ Do not check configuration mismatch before replication: No verificar incompatibi Do not keep metadata of deleted files.: No conservar metadatos de archivos borrados Do not split chunks in the background: No dividir chunks en segundo plano Do not use internal API: No usar API interna +Doctor: + Button: + DismissThisVersion: No, y no volver a preguntar hasta la próxima versión + Fix: Corregirlo + FixButNoRebuild: Corregirlo, pero sin reconstruir + No: No + Skip: Dejarlo como está + Yes: Sí + Dialogue: + Main: |- + ¡Hola! El Doctor de configuración se ha activado por ${activateReason}. + Por desgracia, se han detectado algunos ajustes como posibles problemas. + Tranquilo: los resolveremos uno a uno. + + Para que lo sepas de antemano, te preguntaremos por los siguientes puntos. + + ${issues} + + ¿Empezamos? + MainFix: |- + + ## ${name} + + | Actual | Ideal | + |:---:|:---:| + | ${current} | ${ideal} | + + **Nivel de recomendación:** ${level} + + ### ¿Por qué se ha detectado? + + ${reason} + + ${note} + + ¿Ajustarlo al valor ideal? + Title: Doctor de configuración de Self-hosted LiveSync + TitleAlmostDone: ¡Casi hemos terminado! + TitleFix: Corregir el problema ${current}/${total} + Level: + Must: Obligatorio + Necessary: Necesario + Optional: Opcional + Recommended: Recomendado + Message: + NoIssues: ¡No se ha detectado ningún problema! + RebuildLocalRequired: ¡Atención! Hay que reconstruir la base de datos local para aplicar esto. + RebuildRequired: ¡Atención! Hay que reconstruir para aplicar esto. + SomeSkipped: Hemos dejado algunos problemas sin resolver. ¿Quieres que te lo + pregunte de nuevo en el próximo inicio? + RULES: + E2EE_V02500: + REASON: "El cifrado de extremo a extremo es ahora más robusto y más rápido. + Además, una nueva revisión del código reveló que el E2EE anterior estaba + comprometido, por lo que conviene aplicarlo cuanto antes. Lamentamos de + veras las molestias. Este ajuste no es compatible con versiones + anteriores: todos los dispositivos sincronizados deben actualizarse a la + v0.25.0 o superior. No es necesario reconstruir (los datos se + convertirán al nuevo formato durante la transferencia), pero se + recomienda hacerlo siempre que sea posible." +Document History: Historial del documento Duplicate: Duplicar Duplicate remote: Duplicar remoto E2EE Configuration: Configuración de E2EE @@ -258,11 +364,17 @@ Enter your username: Introduce tu usuario "Error during testAndFixSettings: ${reason}": "Error durante testAndFixSettings: ${reason}" Experimental Settings: Ajustes experimentales Export: Exportar +Failed to connect to remote for compaction.: No se pudo conectar al remoto para la compactación. +Failed to connect to remote for compaction. ${reason}: No se pudo conectar al remoto para la compactación. ${reason} "Failed to connect to the server: ${reason}": "No se pudo conectar al servidor: ${reason}" Failed to connect to the server. Please check your settings.: No se pudo conectar al servidor. Revisa tus ajustes. "Failed to connect to the signalling relay: ${reason}": "No se pudo conectar al relé de señalización: ${reason}" Failed to create replicator instance.: No se pudo crear la instancia del replicador. Failed to parse Setup-URI.: No se pudo interpretar el Setup-URI. +Failed to start one-shot replication before Garbage Collection. Garbage Collection Cancelled.: + No se pudo iniciar la replicación puntual previa a la recolección de basura. + Recolección de basura cancelada. +Failed to start replication after Garbage Collection.: No se pudo iniciar la replicación después de la recolección de basura. "Failed:": "Fallidas:" Fetch: Obtener Fetch chunks on demand: Obtener chunks bajo demanda @@ -272,6 +384,7 @@ FETCHING: OBTENIENDO Fetching status...: Obteniendo el estado... File integrity: Integridad de archivos File to resolve conflict: Archivo para resolver el conflicto +File to view History: Archivo cuyo historial se va a ver Filename: Nombre de archivo "Final Confirmation: Overwrite Server Data with This Device's Files": "Confirmación final: sobrescribir los datos del servidor con los archivos de @@ -288,7 +401,19 @@ Fresh Start Wipe: Borrado para reinicio completo Furthermore, if conflicts are already present in the server data, they will be synchronised to this device as they are, and you will need to resolve them locally.: Además, si ya hay conflictos en los datos del servidor, se sincronizarán tal cual a este dispositivo y tendrás que resolverlos localmente. +Garbage Collection cancelled by user.: Recolección de basura cancelada por el usuario. +"Garbage Collection completed. Deleted chunks: ${deletedChunks} / ${totalChunks}. Time taken: ${seconds} seconds.": + "Recolección de basura completada. Chunks eliminados: ${deletedChunks} / + ${totalChunks}. Tiempo empleado: ${seconds} segundos." +Garbage Collection Confirmation: Confirmación de la recolección de basura Garbage Collection V3 (Beta): Recolección de basura V3 (Beta) +"Garbage Collection: Found ${unusedChunks} unused chunks to delete.": + "Recolección de basura: se han encontrado ${unusedChunks} chunks sin usar para + eliminar." +"Garbage Collection: Scanned ${scanned} / ~${docCount}": "Recolección de basura: analizados ${scanned} / ~${docCount}" +"Garbage Collection: Scanning completed. Total chunks: ${totalChunks}, Used chunks: ${usedChunks}": + "Recolección de basura: análisis completado. Chunks totales: ${totalChunks}, + chunks en uso: ${usedChunks}" Gathering information...: Recopilando información... Generate Random ID: Generar un ID aleatorio Group ID: ID de grupo @@ -298,8 +423,10 @@ Hidden file synchronization have been temporarily disabled. Please enable them a La sincronización de archivos ocultos se ha desactivado temporalmente. Vuelve a activarla después de la obtención si la necesitas. Hidden Files: Archivos ocultos +Hide completely: Ocultar por completo Hide not applicable items: Ocultar elementos no aplicables Higher (${local} > ${remote}): Superior (${local} > ${remote}) +Highlight diff: Resaltar las diferencias How to display network errors when the sync server is unreachable.: Cómo mostrar los errores de red cuando el servidor de sincronización no está disponible. @@ -362,6 +489,9 @@ If you have unsynchronised changes in your Vault on this device, they will likel Si tienes cambios sin sincronizar en el Vault de este dispositivo, es probable que divergan de las versiones del servidor tras el restablecimiento. Esto puede provocar un gran número de conflictos de archivos. +If you reached the payload size limit when using IBM Cloudant, please decrease batch size and batch limit to a lower value.: + Si alcanzas el límite de tamaño de carga al usar IBM Cloudant, reduce el + tamaño de lote y el límite de lote. If you understand the risks and still wish to proceed, select so.: Si entiendes los riesgos y aun así quieres continuar, indícalo. If you want to store the data in a specific folder within the bucket, you can specify a folder prefix here. Otherwise, leave it blank to store data at the root of the bucket.: Si quieres guardar los datos en una carpeta concreta del bucket, indica aquí @@ -371,6 +501,7 @@ If you want to use `LiveSync`, you should broadcast changes. All `watching` peer Si quieres usar `LiveSync`, debes difundir los cambios. Todos los pares que estén `observando` y lo detecten iniciarán la replicación para obtenerlos. Ignore: Ignorar +Ignore and Proceed: Ignorar y continuar Ignore files: Archivos a ignorar Ignore patterns: Patrones de exclusión Import connection: Importar conexión @@ -389,6 +520,14 @@ Initial Action: Acción inicial Initialise all journal history, On the next sync, every item will be received and sent.: Restablece todo el historial del diario. En la próxima sincronización se recibirán y enviarán todos los elementos. +Initialise journal received history. On the next sync, every item except this device sent will be downloaded again.: + Inicializa el historial de recepción del diario. En la próxima sincronización + se volverán a descargar todos los elementos salvo los enviados por este + dispositivo. +Initialise journal sent history. On the next sync, every item except this device received will be sent again.: + Inicializa el historial de envío del diario. En la próxima sincronización se + volverán a enviar todos los elementos salvo los recibidos por este + dispositivo. Interval (sec): Intervalo (segundos) INVERTED: INVERTIDO "Issue detection log:": "Registro de detección de problemas:" @@ -407,11 +546,23 @@ JWT Expiration Duration (minutes): Duración de caducidad del JWT (minutos) JWT Key: Clave JWT JWT Key ID (kid): ID de clave JWT (kid) JWT Subject (sub): Sujeto JWT (sub) +K: + P2P: "%{Peer} a %{Peer}" + Peer: par + ScanCustomization: Buscar personalizaciones + exp: Experimental + long_p2p_sync: "%{title_p2p_sync}" + short_p2p_sync: Sincronización P2P + title_p2p_sync: Sincronización punto a punto Keep empty folder: Mantener carpetas vacías +lang_def: Predeterminado lang-de: Alemán +lang-def: "%{lang_def}" lang-es: Español lang-fr: Français +lang-he: Hebreo lang-ja: Japonés +lang-ko: Coreano lang-ru: Ruso lang-zh: Chino simplificado lang-zh-tw: Chino tradicional @@ -446,6 +597,8 @@ liveSyncReplicator: replicationInProgress: Replicación en curso retryLowerBatchSize: Reintentar con tamaño de lote más bajo:${batch_size}/${batches_limit} unlockRemoteDb: Desbloquear base de datos remota para prevenir corrupción de datos + mismatchedTweakDetected: Se han detectado discrepancias en la configuración + entre dispositivos. Ejecutar una replicación manual intentará resolverlo. liveSyncSetting: errorNoSuchSettingItem: "No existe el ajuste: ${key}" originalValue: "Original: ${value}" @@ -479,6 +632,7 @@ Memory cache size (by total characters): Tamaño caché memoria (por caracteres) Memory cache size (by total items): Tamaño caché memoria (por ítems) Merge: Fusionar Minimum delay for batch database updating: Retraso mínimo para actualización por lotes +Minimum interval for syncing: Intervalo mínimo de sincronización Mixed: Mixto moduleCheckRemoteSize: logCheckingStorageSizes: Comprobando tamaños de almacenamiento @@ -539,6 +693,11 @@ moduleCheckRemoteSize: optionRebuildAll: Reconstruir todo ahora titleDatabaseSizeLimitExceeded: El tamaño del almacenamiento remoto superó el límite titleDatabaseSizeNotify: Configuración de notificación de tamaño de base de datos + noticeExceeded: El tamaño del almacenamiento remoto es de ${measuredSize}, por + encima del umbral de aviso configurado de ${notifySize}. {HERE} + noticeNotConfigured: Los avisos sobre el tamaño del almacenamiento remoto no + están configurados. {HERE} + optionReview: Revisar las opciones moduleInputUIObsidian: defaultTitleConfirmation: Confirmación defaultTitleSelect: Seleccionar @@ -683,18 +842,98 @@ moduleMigration: optionKeepPreviousBehaviour: Mantener comportamiento anterior optionManualSetup: Configurarlo todo manualmente optionNoAskAgain: No, por favor pregúntame de nuevo + fix0256: + buttons: + DismissForever: Ya lo he corregido, no volver a preguntar + checkItLater: Comprobarlo más tarde + fix: Corregir + message: > + Debido a un error reciente (en la v0.25.6), puede que algunos archivos no + se hayan guardado correctamente en la base de datos de sincronización. + + Hemos analizado tus archivos y hemos encontrado algunos que hay que + corregir. + + + **Archivos que se pueden corregir:** + + + ${files} + + + Estos archivos tienen en el almacenamiento un original cuyo tamaño + coincide, por lo que es probable que se puedan recuperar. + + Podemos usarlos para corregir la base de datos: pulsa el botón «Corregir» + de abajo. + + + ${messageUnrecoverable} + + + Si quieres volver a ejecutarlo, puedes hacerlo desde Hatch. + messageUnrecoverable: > + **Archivos que no se pueden corregir en este dispositivo:** + + + ${filesNotRecoverable} + + + Estos archivos tienen metadatos inconsistentes y no se pueden corregir en + este dispositivo (por lo general no podemos determinar cuál es el + correcto). + + Para restaurarlos, comprueba tus otros dispositivos (también con esta + función) o restáuralos manualmente desde una copia de seguridad. + title: Se han detectado archivos dañados + insecureChunkExist: + buttons: + fetch: Ya he reconstruido el remoto. Obtener desde el remoto + later: Lo haré más tarde + rebuild: Reconstruir todo + laterMessage: ¡Te recomendamos encarecidamente solucionarlo cuanto antes! + message: > + Algunos chunks no se almacenan de forma segura y no están cifrados en las + bases de datos. + + **Reconstruye la base de datos para solucionarlo**. + + + Si tu base de datos remota no está configurada con SSL o usa credenciales + poco seguras, **corres el riesgo de exponer datos sensibles**. + + + Nota: actualiza Self-hosted LiveSync a la v0.25.6 o superior en todos tus + dispositivos y haz una copia de seguridad fiable de tu vault. + + Nota 2: reconstruir todo y obtener los datos consume algo de tiempo y de + tráfico; hazlo en horas de poco uso y con una conexión de red estable. + title: ¡Se han encontrado chunks no seguros! + optionNoSetupUri: No, no tengo + optionRemindNextLaunch: Recordármelo en el próximo inicio + optionSetupViaP2P: Usar %{short_p2p_sync} para configurarlo + optionSetupWizard: Llévame al asistente de configuración + optionYesFetchAgain: Sí, obtener de nuevo + titleCaseSensitivity: Distinción de mayúsculas y minúsculas + titleRecommendSetupUri: Recomendación de usar un Setup URI + titleWelcome: Bienvenido a Self-hosted LiveSync "Mostly Complete: Decision Required": "Casi terminado: se requiere una decisión" My remote server is already set up. I want to join this device.: Mi servidor remoto ya está configurado. Quiero añadir este dispositivo. Name: Nombre NEW: NUEVO Newer (${diff}): Más nuevo (${diff}) No checks have been performed yet.: Todavía no se ha realizado ninguna comprobación. +No connected device information found. Cancelling Garbage Collection.: + No se ha encontrado información de dispositivos conectados. Se cancela la + recolección de basura. No Connection: Sin conexión No devices available. Waiting for other devices to connect...: No hay dispositivos disponibles. Esperando a que se conecten otros dispositivos... No Items.: Sin elementos. NO PREVIEW: SIN VISTA PREVIA +Node ID: ID de nodo +Node Information Missing: Falta la información del nodo Not configured: Sin configurar Not now: Ahora no Note that the Group ID is not limited to the generated format; you can use any string as the Group ID.: @@ -710,6 +949,7 @@ Obfuscating properties (e.g., path of file, size, creation and modification date dificulta identificar la estructura y los nombres de tus archivos y carpetas en el servidor remoto. Esto ayuda a proteger tu privacidad y hace más difícil que usuarios no autorizados deduzcan información sobre tus datos. +Obsidian version: Versión de Obsidian Of course, we can back up the data before proceeding.: Por supuesto, se puede hacer una copia de seguridad de los datos antes de continuar. Off: Desactivado @@ -726,6 +966,53 @@ On this device, switch to the camera app or use a QR code scanner to scan the di Open connection: Abrir conexión Open P2P Setup...: Abrir la configuración P2P... Other files: Otros archivos +P2P: + AskPassphraseForDecrypt: El par remoto ha compartido la configuración. Introduce + la frase de contraseña para descifrarla. + AskPassphraseForShare: El par remoto ha solicitado la configuración de este + dispositivo. Introduce la frase de contraseña para compartirla. Puedes + ignorar la solicitud cancelando este diálogo. + DisabledButNeed: "%{title_p2p_sync} está desactivada. ¿Seguro que quieres activarla?" + FailedToOpen: No se pudo abrir la conexión P2P con el servidor de señalización. + NoAutoSyncPeers: No se han encontrado pares de sincronización automática. + Configúralos en el panel de %{long_p2p_sync}. + NoKnownPeers: No se ha detectado ningún par; esperando a que se conecten otros... + NotEnabled: "%{title_p2p_sync} no está activada. No se puede abrir una conexión nueva." + Note: + Summary: ¿Qué es esta función? (incluye notas importantes; léelas al menos una vez) + description: >2- + Este replicador permite sincronizar el vault con otros dispositivos + mediante una conexión punto a punto. Así se puede sincronizar con nuestros + otros dispositivos sin usar un servicio en la nube. + + El replicador se basa en Trystero. Usa además un servidor de señalización + para establecer la conexión entre dispositivos. Ese servidor sirve para + intercambiar la información de conexión y no conoce (ni debería almacenar) + ninguno de nuestros datos. + + + Cualquiera puede alojar el servidor de señalización: es simplemente un + relé Nostr. Por comodidad y para poder comprobar el comportamiento del + replicador, vrtmrz aloja una instancia. Puedes usar ese servidor + experimental o cualquier otro. + + + Por cierto, aunque el servidor de señalización no almacene nuestros datos, + sí puede ver la información de conexión de algunos de nuestros + dispositivos. Tenlo en cuenta y ten precaución al usar un servidor de + terceros. + important_note: Replicador punto a punto. + important_note_sub: Esta función sigue siendo muy experimental. Asegúrate de + tener una copia de seguridad de tus datos antes de usarla. Y nos alegraría + mucho que quisieras contribuir a su desarrollo. + P2PReplication: Replicación %{P2P} + PaneTitle: "%{long_p2p_sync}" + ReplicatorInstanceMissing: No se encuentra el replicador de sincronización P2P; + puede que no esté configurado o activado. + SeemsOffline: El par ${name} parece estar desconectado; se omite. + SyncAlreadyRunning: La sincronización P2P ya está en marcha. + SyncCompleted: Sincronización P2P completada. + SyncStartedWith: Se ha iniciado la sincronización P2P con ${name}. P2P Configuration: Configuración P2P P2P Status: Estado P2P Passphrase is required.: Se requiere la frase de contraseña. @@ -734,11 +1021,18 @@ Path: Ruta Peer to Peer Replicator: Replicador Punto a Punto Peers: Pares PERMANENT: PERMANENTE +Pick a file to show history: Elige un archivo para ver su historial Please be aware that the End-to-End Encryption passphrase is not validated until the synchronisation process actually commences. This is a security measure designed to protect your data.: Ten en cuenta que la frase de contraseña del cifrado de extremo a extremo no se valida hasta que comienza realmente la sincronización. Es una medida de seguridad para proteger tus datos. Please configure your end-to-end encryption settings.: Configura los ajustes de cifrado de extremo a extremo. +Please disable 'Read chunks online' in settings to use Garbage Collection.: + Desactiva «Leer chunks en línea» en los ajustes para poder usar la recolección + de basura. +Please enable 'Compute revisions for chunks' in settings to use Garbage Collection.: + Activa «Calcular revisiones para los chunks» en los ajustes para poder usar la + recolección de basura. Please enter the CouchDB server information below.: Introduce a continuación los datos del servidor CouchDB. Please enter the details required to connect to your S3/MinIO/R2 compatible object storage service.: Introduce los datos necesarios para conectarte a tu servicio de almacenamiento @@ -751,6 +1045,7 @@ Please follow the steps below to import settings from your existing device.: Sigue los pasos siguientes para importar los ajustes desde tu dispositivo actual. PLEASE NOTE: TEN EN CUENTA +Please select 'Cancel' explicitly to cancel this operation.: Selecciona «Cancelar» de forma explícita para cancelar esta operación. Please select an active P2P remote configuration to change P2P sync targets.: Selecciona una configuración remota P2P activa para cambiar los destinos de sincronización P2P. @@ -760,31 +1055,187 @@ Please select the button below to restart and proceed to the data fetching confi Please select the button below to restart and proceed to the final confirmation.: Pulsa el botón de abajo para reiniciar y pasar a la confirmación final. Please select your situation.: Selecciona tu situación. Please understand that this is intended behaviour.: Comprende que este es el comportamiento previsto. +Plug-in version: Versión del complemento Plugins: Complementos +Prepare the 'report' to create an issue: Preparar el «informe» para abrir una incidencia Prevent fetching configuration from server: Impedir la obtención de la configuración desde el servidor Proceed: Continuar +Proceed Garbage Collection: Continuar con la recolección de basura Proceed to the next step.: Continuar al paso siguiente. +Proceeding with Garbage Collection, ignoring missing nodes.: Se continúa con la recolección de basura, ignorando los nodos ausentes. +Proceeding with Garbage Collection.: Se continúa con la recolección de basura. +Progress: Progreso +Property Encryption: Cifrado de propiedades +Recovery and Repair: Recuperación y reparación +RedFlag: + Fetch: + Method: + Desc: >- + ¿Cómo quieres obtener los datos? + + - %{RedFlag.Fetch.Method.FetchSafer}. + **Poco tráfico**, **mucha CPU**, **riesgo bajo** + Recomendado si... + - Los archivos podrían ser inconsistentes + - No hay demasiados archivos + - %{RedFlag.Fetch.Method.FetchSmoother}. + **Poco tráfico**, **CPU moderada**, **riesgo bajo o moderado** + Recomendado si... + - Los archivos son probablemente consistentes + - Tienes muchos archivos + - %{RedFlag.Fetch.Method.FetchTraditional}. + **Mucho tráfico**, **poca CPU**, **riesgo bajo o moderado** + + >[!INFO]- Detalles + + > ## %{RedFlag.Fetch.Method.FetchSafer}. + + > **Poco tráfico**, **mucha CPU**, **riesgo bajo** + + > Esta opción crea primero una base de datos local a partir de los + archivos locales existentes antes de obtener los datos del remoto. + + > Si un archivo existe tanto en local como en remoto, solo se + transferirán las diferencias. + + > Sin embargo, los archivos presentes en ambos sitios se tratarán + inicialmente como archivos en conflicto. Se resolverán automáticamente + si en realidad no lo están, pero el proceso puede tardar. + + > En general es el método más seguro y el que menos riesgo de pérdida de + datos conlleva. + + > ## %{RedFlag.Fetch.Method.FetchSmoother}. + + > **Poco tráfico**, **CPU moderada**, **riesgo bajo o moderado** (según + la operación) + + > Esta opción crea primero los chunks de los archivos locales para la + base de datos y después obtiene los datos. Así solo se transfieren los + chunks que faltan en local. Aun así, todos los metadatos se toman del + remoto. + + > Al iniciar, los archivos locales se comparan con esos metadatos. El + contenido considerado más reciente sobrescribirá al más antiguo (según + la fecha de modificación) y el resultado se sincroniza de vuelta a la + base de datos remota. + + > Es seguro si los archivos locales son realmente los de fecha más + reciente, pero puede dar problemas si un archivo tiene una fecha más + nueva y un contenido más antiguo (como el `welcome.md` inicial). + + > Usa menos CPU y es más rápido que + «%{RedFlag.Fetch.Method.FetchSafer}», pero puede provocar pérdida de + datos si no se usa con cuidado. + + > ## %{RedFlag.Fetch.Method.FetchTraditional}. + + > **Mucho tráfico**, **poca CPU**, **riesgo bajo o moderado** (según la + operación) + + > Se obtiene todo del remoto. + + > Similar a %{RedFlag.Fetch.Method.FetchSmoother}, pero todos los chunks + se descargan del remoto. + + > Es la forma más tradicional de obtener los datos y normalmente la que + más tráfico y tiempo consume. Conlleva un riesgo de sobrescribir + archivos remotos parecido al de «%{RedFlag.Fetch.Method.FetchSmoother}». + + > Aun así, suele considerarse el método más estable, por ser el más + antiguo y directo. + FetchSafer: Crear una base de datos local antes de obtener los datos + FetchSmoother: Crear los chunks de los archivos locales antes de obtener los datos + FetchTraditional: Obtener todo del remoto + Title: ¿Cómo quieres obtener los datos? + FetchRemoteConfig: + Buttons: + Cancel: No, usar los ajustes locales + Fetch: Sí, obtener y aplicar los ajustes remotos + Message: ¿Quieres obtener y aplicar en este dispositivo los ajustes de + preferencias guardados en el remoto? + Title: Obtener la configuración remota +Reduces storage space by discarding all non-latest revisions. This requires the same amount of free space on the remote server and the local client.: + Reduce el espacio de almacenamiento descartando todas las revisiones que no + sean la última. Requiere la misma cantidad de espacio libre en el servidor + remoto y en el cliente local. Refresh: Actualizar Relay settings: Ajustes del relé Reload: Recargar Remote only: Solo remoto Replicate now: Replicar ahora -Replicating: Replicando -Replicating...: Replicando... +Replicating: + _value: Replicando + "": + "": + "": Replicando... +Replicator: + Dialogue: + Locked: + Action: + Dismiss: Cancelar para volver a confirmarlo + Fetch: Restablecer la sincronización en este dispositivo + Unlock: Desbloquear la base de datos remota + Message: + _value: > + La base de datos remota está bloqueada porque se ha reconstruido en + uno de los dispositivos. + + Por eso se pide a este dispositivo que no se conecte, para evitar + corromper la base de datos. + + + Hay tres opciones posibles: + + + - %{Replicator.Dialogue.Locked.Action.Fetch} + La más recomendable y fiable. Descarta la base de datos local y vuelve a tomar toda la información de sincronización del remoto. En la mayoría de los casos se puede hacer sin riesgo, aunque lleva algo de tiempo y conviene hacerlo con una red estable. + - %{Replicator.Dialogue.Locked.Action.Unlock} + Solo se puede usar si ya estamos sincronizados de forma fiable por otros métodos de replicación. Esto no significa simplemente tener los mismos archivos. Si no estás seguro, evítala. + - %{Replicator.Dialogue.Locked.Action.Dismiss} + Cancela la operación. Se volverá a preguntar en la próxima solicitud. + Fetch: Se ha programado la obtención completa. El complemento se reiniciará para + llevarla a cabo. + Unlocked: La base de datos remota se ha desbloqueado. Vuelve a intentar la + operación. + Title: Bloqueada + Message: + Cleaned: Se está limpiando la base de datos; la replicación se ha cancelado + InitialiseFatalError: No hay ningún replicador disponible; se trata de un error grave. + Pending: Hay eventos de archivo pendientes. La replicación se ha cancelado. + SomeModuleFailed: La replicación se ha cancelado por el fallo de algún módulo + VersionUpFlash: Se ha detectado una actualización. Abre el diálogo de ajustes y + consulta el registro de cambios. La replicación se ha cancelado. +Rerun Onboarding Wizard: Volver a ejecutar el asistente de configuración inicial +Rerun the onboarding wizard to set up Self-hosted LiveSync again.: + Vuelve a ejecutar el asistente de configuración inicial para configurar + Self-hosted LiveSync de nuevo. +Rerun Wizard: Volver a ejecutar el asistente Reset and Resume Synchronisation: Restablecer y reanudar la sincronización +Reset notification threshold and check the remote database usage: Restablecer el umbral de aviso y comprobar el uso de la base de datos remota +Reset the remote storage size threshold and check the remote storage size again.: + Restablece el umbral de tamaño del almacenamiento remoto y vuelve a comprobar + su tamaño. Restart and Fetch Data: Reiniciar y obtener los datos Restart and Initialise Server: Reiniciar e inicializar el servidor +Restarting Obsidian is strongly recommended. Until restart, some changes may not take effect, and display may be inconsistent. Are you sure to restart now?: + Se recomienda encarecidamente reiniciar Obsidian. Hasta que lo hagas, puede + que algunos cambios no surtan efecto y que la interfaz se muestre de forma + inconsistente. ¿Seguro que quieres reiniciar ahora? Rev: Rev Revert changes: Revertir cambios Revoke: Revocar Room ID: ID de sala "Room ID suffix:": "Sufijo del ID de sala:" +Run Doctor: Ejecutar el Doctor S3/MinIO/R2 Configuration: Configuración de S3/MinIO/R2 Same: Igual Same or local only: Igual o solo local Save and Apply: Guardar y aplicar Scan changes: Buscar cambios +Scan for Broken files: Buscar archivos dañados Scan QR Code: Escanear código QR +Scram Switches: Interruptores de emergencia Secret Access Key: Clave de acceso secreta Select active P2P remote: Seleccionar el remoto P2P activo Select All Shiny: Seleccionar todo lo nuevo @@ -800,6 +1251,10 @@ Selecting this option will result in this device joining the existing server. Yo Selective: Selectivo SENDING: ENVIANDO SESSION: SESIÓN +SettingTab: + Message: + AskRebuild: Tus cambios requieren obtener los datos de la base de datos remota. + ¿Quieres continuar? Setup: RemoteE2EE: Title: Cifrado de extremo a extremo @@ -807,87 +1262,143 @@ Setup: LabelEncrypt: Cifrado de extremo a extremo PlaceholderPassphrase: Introduce tu frase de contraseña StronglyRecommendedTitle: Muy recomendable - StronglyRecommendedLine1: Al habilitar el cifrado de extremo a extremo, tus datos se cifran en tu dispositivo antes de enviarse al servidor remoto. Esto significa que, incluso si alguien obtiene acceso al servidor, no podrá leer tus datos sin la frase de contraseña. Asegúrate de recordarla, ya que también será necesaria para descifrar tus datos en otros dispositivos. - StronglyRecommendedLine2: Además, ten en cuenta que si estás usando sincronización Peer-to-Peer, esta configuración se utilizará cuando más adelante cambies a otros métodos y te conectes a un servidor remoto. - MultiDestinationWarning: Este ajuste debe ser el mismo incluso cuando te conectes a varios destinos de sincronización. + StronglyRecommendedLine1: Al habilitar el cifrado de extremo a extremo, tus + datos se cifran en tu dispositivo antes de enviarse al servidor remoto. + Esto significa que, incluso si alguien obtiene acceso al servidor, no + podrá leer tus datos sin la frase de contraseña. Asegúrate de recordarla, + ya que también será necesaria para descifrar tus datos en otros + dispositivos. + StronglyRecommendedLine2: Además, ten en cuenta que si estás usando + sincronización Peer-to-Peer, esta configuración se utilizará cuando más + adelante cambies a otros métodos y te conectes a un servidor remoto. + MultiDestinationWarning: Este ajuste debe ser el mismo incluso cuando te + conectes a varios destinos de sincronización. LabelObfuscateProperties: Ofuscar propiedades - ObfuscatePropertiesDesc: Ofuscar propiedades (por ejemplo, la ruta del archivo, el tamaño y las fechas de creación y modificación) añade una capa adicional de seguridad al dificultar la identificación de la estructura y los nombres de tus archivos y carpetas en el servidor remoto. Esto ayuda a proteger tu privacidad y dificulta que usuarios no autorizados deduzcan información sobre tus datos. + ObfuscatePropertiesDesc: Ofuscar propiedades (por ejemplo, la ruta del archivo, + el tamaño y las fechas de creación y modificación) añade una capa + adicional de seguridad al dificultar la identificación de la estructura y + los nombres de tus archivos y carpetas en el servidor remoto. Esto ayuda a + proteger tu privacidad y dificulta que usuarios no autorizados deduzcan + información sobre tus datos. AdvancedTitle: Avanzado LabelEncryptionAlgorithm: Algoritmo de cifrado - DefaultAlgorithmDesc: En la mayoría de los casos, debes mantener el algoritmo predeterminado (${algorithm}). Este ajuste solo es necesario si ya tienes un Vault cifrado con un formato diferente. - AlgorithmWarning: Cambiar el algoritmo de cifrado impedirá el acceso a cualquier dato cifrado anteriormente con otro algoritmo. Asegúrate de que todos tus dispositivos estén configurados para usar el mismo algoritmo y así mantener el acceso a tus datos. - PassphraseValidationLine1: Ten en cuenta que la frase de contraseña del cifrado de extremo a extremo no se valida hasta que el proceso de sincronización comienza realmente. Esta es una medida de seguridad diseñada para proteger tus datos. - PassphraseValidationLine2: Por lo tanto, te pedimos que tengas muchísimo cuidado al configurar manualmente la información del servidor. Si introduces una frase de contraseña incorrecta, los datos del servidor se corromperán. Ten en cuenta que este comportamiento es intencionado. + DefaultAlgorithmDesc: En la mayoría de los casos, debes mantener el algoritmo + predeterminado (${algorithm}). Este ajuste solo es necesario si ya tienes + un Vault cifrado con un formato diferente. + AlgorithmWarning: Cambiar el algoritmo de cifrado impedirá el acceso a cualquier + dato cifrado anteriormente con otro algoritmo. Asegúrate de que todos tus + dispositivos estén configurados para usar el mismo algoritmo y así + mantener el acceso a tus datos. + PassphraseValidationLine1: Ten en cuenta que la frase de contraseña del cifrado + de extremo a extremo no se valida hasta que el proceso de sincronización + comienza realmente. Esta es una medida de seguridad diseñada para proteger + tus datos. + PassphraseValidationLine2: Por lo tanto, te pedimos que tengas muchísimo cuidado + al configurar manualmente la información del servidor. Si introduces una + frase de contraseña incorrecta, los datos del servidor se corromperán. Ten + en cuenta que este comportamiento es intencionado. ButtonProceed: Continuar ButtonCancel: Cancelar UseSetupURI: Title: Introducir URI de configuración - GuidanceLine1: Introduce la URI de configuración que se generó durante la instalación del servidor o en otro dispositivo, junto con la frase de contraseña del Vault. - GuidanceLine2: Ten en cuenta que puedes generar una nueva URI de configuración ejecutando el comando "Copiar ajustes como nueva URI de configuración" desde la paleta de comandos. + GuidanceLine1: Introduce la URI de configuración que se generó durante la + instalación del servidor o en otro dispositivo, junto con la frase de + contraseña del Vault. + GuidanceLine2: Ten en cuenta que puedes generar una nueva URI de configuración + ejecutando el comando "Copiar ajustes como nueva URI de configuración" + desde la paleta de comandos. LabelSetupURI: URI de configuración ValidInfo: La URI de configuración es válida y está lista para usarse. InvalidInfo: La URI de configuración no es válida. Revísala e inténtalo de nuevo. LabelPassphrase: Frase de contraseña del Vault PlaceholderPassphrase: Introduce la frase de contraseña del Vault ErrorPassphraseRequired: Introduce la frase de contraseña del Vault. - ErrorFailedToParse: No se pudo procesar la URI de configuración. Revisa la URI y la frase de contraseña. + ErrorFailedToParse: No se pudo procesar la URI de configuración. Revisa la URI y + la frase de contraseña. ButtonProceed: Probar ajustes y continuar ButtonCancel: Cancelar ScanQRCode: Title: Escanear código QR - Guidance: Sigue los pasos de abajo para importar los ajustes desde tu dispositivo actual. + Guidance: Sigue los pasos de abajo para importar los ajustes desde tu + dispositivo actual. Step1: En este dispositivo, mantén este Vault abierto. Step2: En el dispositivo de origen, abre Obsidian. - Step3: En el dispositivo de origen, ejecuta desde la paleta de comandos la orden "Mostrar ajustes como código QR". - Step4: En este dispositivo, cambia a la cámara o usa un escáner QR para escanear el código mostrado. + Step3: En el dispositivo de origen, ejecuta desde la paleta de comandos la orden + "Mostrar ajustes como código QR". + Step4: En este dispositivo, cambia a la cámara o usa un escáner QR para escanear + el código mostrado. ButtonClose: Cerrar este diálogo - "Please enable 'Compute revisions for chunks' in settings to use Garbage Collection.": Activa "Compute revisions for chunks" en los ajustes para usar la recolección de basura. - "Please disable 'Read chunks online' in settings to use Garbage Collection.": Desactiva "Read chunks online" en los ajustes para usar la recolección de basura. - "Setup URI dialog cancelled.": Se canceló el diálogo de Setup URI. - "Please select 'Cancel' explicitly to cancel this operation.": Selecciona explícitamente "Cancelar" para cancelar esta operación. - "Failed to connect to remote for compaction.": No se pudo conectar a la base de datos remota para la compactación. - "Failed to connect to remote for compaction. ${reason}": No se pudo conectar a la base de datos remota para la compactación. ${reason} - "Compaction in progress on remote database...": La compactación está en curso en la base de datos remota... - "Compaction on remote database timed out.": La compactación en la base de datos remota agotó el tiempo de espera. - "Compaction on remote database completed successfully.": La compactación en la base de datos remota se completó correctamente. - "Compaction on remote database failed.": La compactación en la base de datos remota falló. - "Failed to start one-shot replication before Garbage Collection. Garbage Collection Cancelled.": No se pudo iniciar la replicación de una sola vez antes de la recolección de basura. La recolección de basura se canceló. - "Cancel Garbage Collection": Cancelar la recolección de basura - "No connected device information found. Cancelling Garbage Collection.": No se encontró información de dispositivos conectados. Cancelando la recolección de basura. - "The following accepted nodes are missing its node information:\n- ${missingNodes}\n\nThis indicates that they have not been connected for some time or have been left on an older version.\nIt is preferable to update all devices if possible. If you have any devices that are no longer in use, you can clear all accepted nodes by locking the remote once.": |- + Please enable 'Compute revisions for chunks' in settings to use Garbage Collection.: + Activa "Compute revisions for chunks" en los ajustes para usar la + recolección de basura. + Please disable 'Read chunks online' in settings to use Garbage Collection.: + Desactiva "Read chunks online" en los ajustes para usar la recolección de + basura. + Setup URI dialog cancelled.: Se canceló el diálogo de Setup URI. + Please select 'Cancel' explicitly to cancel this operation.: Selecciona explícitamente "Cancelar" para cancelar esta operación. + Failed to connect to remote for compaction.: No se pudo conectar a la base de datos remota para la compactación. + Failed to connect to remote for compaction. ${reason}: No se pudo conectar a la base de datos remota para la compactación. ${reason} + Compaction in progress on remote database...: La compactación está en curso en la base de datos remota... + Compaction on remote database timed out.: La compactación en la base de datos remota agotó el tiempo de espera. + Compaction on remote database completed successfully.: La compactación en la base de datos remota se completó correctamente. + Compaction on remote database failed.: La compactación en la base de datos remota falló. + Failed to start one-shot replication before Garbage Collection. Garbage Collection Cancelled.: + No se pudo iniciar la replicación de una sola vez antes de la recolección de + basura. La recolección de basura se canceló. + Cancel Garbage Collection: Cancelar la recolección de basura + No connected device information found. Cancelling Garbage Collection.: + No se encontró información de dispositivos conectados. Cancelando la + recolección de basura. + "The following accepted nodes are missing its node information:\n- ${missingNodes}\n\nThis indicates that they have not been connected for some time or have been left on an older version.\nIt is preferable to update all devices if possible. If you have any devices that are no longer in use, you can clear all accepted nodes by locking the remote once.": >- Los siguientes nodos aceptados no tienen información del nodo: + - ${missingNodes} - Esto indica que no se han conectado desde hace algún tiempo o que se han quedado en una versión anterior. - Si es posible, es preferible actualizar todos los dispositivos. Si tienes dispositivos que ya no se usan, puedes borrar todos los nodos aceptados bloqueando el remoto una vez. - "Ignore and Proceed": Ignorar y continuar - "Node Information Missing": Falta información del nodo - "Garbage Collection cancelled by user.": El usuario canceló la recolección de basura. - "Proceeding with Garbage Collection, ignoring missing nodes.": Continuando con la recolección de basura e ignorando los nodos faltantes. - "Proceed Garbage Collection": Continuar con la recolección de basura + + Esto indica que no se han conectado desde hace algún tiempo o que se han + quedado en una versión anterior. + + Si es posible, es preferible actualizar todos los dispositivos. Si tienes + dispositivos que ya no se usan, puedes borrar todos los nodos aceptados + bloqueando el remoto una vez. + Ignore and Proceed: Ignorar y continuar + Node Information Missing: Falta información del nodo + Garbage Collection cancelled by user.: El usuario canceló la recolección de basura. + Proceeding with Garbage Collection, ignoring missing nodes.: Continuando con la recolección de basura e ignorando los nodos faltantes. + Proceed Garbage Collection: Continuar con la recolección de basura "> [!INFO]- The connected devices have been detected as follows:\n${devices}": |- > [!INFO]- Se detectaron los siguientes dispositivos conectados: ${devices} - "Device": Dispositivo - "Node ID": ID del nodo - "Obsidian version": Versión de Obsidian - "Plug-in version": Versión del complemento - "Progress": Progreso - "Some devices have differing progress values (max: ${maxProgress}, min: ${minProgress}).\nThis may indicate that some devices have not completed synchronisation, which could lead to conflicts. Strongly recommend confirming that all devices are synchronised before proceeding.": |- - Algunos dispositivos tienen valores de progreso diferentes (máx.: ${maxProgress}, mín.: ${minProgress}). - Esto puede indicar que algunos dispositivos no han completado la sincronización, lo que podría causar conflictos. Se recomienda encarecidamente confirmar que todos los dispositivos estén sincronizados antes de continuar. - "All devices have the same progress value (${progress}). Your devices seem to be synchronised. And be able to proceed with Garbage Collection.": Todos los dispositivos tienen el mismo valor de progreso (${progress}). Parece que tus dispositivos están sincronizados y se puede continuar con la recolección de basura. - "Garbage Collection Confirmation": Confirmación de recolección de basura - "Proceeding with Garbage Collection.": Continuando con la recolección de basura. - "Garbage Collection: Scanned ${scanned} / ~${docCount}": |- - Recolección de basura: escaneados ${scanned} / ~${docCount} - "Garbage Collection: Scanning completed. Total chunks: ${totalChunks}, Used chunks: ${usedChunks}": |- - Recolección de basura: escaneo completado. Chunks totales: ${totalChunks}, chunks usados: ${usedChunks} - "Garbage Collection: Found ${unusedChunks} unused chunks to delete.": |- - Recolección de basura: se encontraron ${unusedChunks} chunks no usados para eliminar. - "Garbage Collection completed. Deleted chunks: ${deletedChunks} / ${totalChunks}. Time taken: ${seconds} seconds.": |- - Recolección de basura completada. Chunks eliminados: ${deletedChunks} / ${totalChunks}. Tiempo empleado: ${seconds} segundos. - "Failed to start replication after Garbage Collection.": No se pudo iniciar la replicación después de la recolección de basura. + Device: Dispositivo + Node ID: ID del nodo + Obsidian version: Versión de Obsidian + Plug-in version: Versión del complemento + Progress: Progreso + "Some devices have differing progress values (max: ${maxProgress}, min: ${minProgress}).\nThis may indicate that some devices have not completed synchronisation, which could lead to conflicts. Strongly recommend confirming that all devices are synchronised before proceeding.": >- + Algunos dispositivos tienen valores de progreso diferentes (máx.: + ${maxProgress}, mín.: ${minProgress}). + + Esto puede indicar que algunos dispositivos no han completado la + sincronización, lo que podría causar conflictos. Se recomienda + encarecidamente confirmar que todos los dispositivos estén sincronizados + antes de continuar. + All devices have the same progress value (${progress}). Your devices seem to be synchronised. And be able to proceed with Garbage Collection.: + Todos los dispositivos tienen el mismo valor de progreso (${progress}). + Parece que tus dispositivos están sincronizados y se puede continuar con la + recolección de basura. + Garbage Collection Confirmation: Confirmación de recolección de basura + Proceeding with Garbage Collection.: Continuando con la recolección de basura. + "Garbage Collection: Scanned ${scanned} / ~${docCount}": "Recolección de basura: escaneados ${scanned} / ~${docCount}" + "Garbage Collection: Scanning completed. Total chunks: ${totalChunks}, Used chunks: ${usedChunks}": + "Recolección de basura: escaneo completado. Chunks totales: ${totalChunks}, + chunks usados: ${usedChunks}" + "Garbage Collection: Found ${unusedChunks} unused chunks to delete.": + "Recolección de basura: se encontraron ${unusedChunks} chunks no usados para + eliminar." + "Garbage Collection completed. Deleted chunks: ${deletedChunks} / ${totalChunks}. Time taken: ${seconds} seconds.": + "Recolección de basura completada. Chunks eliminados: ${deletedChunks} / + ${totalChunks}. Tiempo empleado: ${seconds} segundos." + Failed to start replication after Garbage Collection.: No se pudo iniciar la replicación después de la recolección de basura. optionNoSetupUri: No, no tengo optionRemindNextLaunch: Recordármelo en el próximo inicio optionSetupWizard: Llévame al asistente de configuración @@ -895,6 +1406,77 @@ Setup: titleCaseSensitivity: Sensibilidad a mayúsculas titleRecommendSetupUri: Recomendación de uso de URI de configuración titleWelcome: Bienvenido a Self-hosted LiveSync + Apply: + Buttons: + ApplyAndFetch: Aplicar y obtener + ApplyAndMerge: Aplicar y combinar + ApplyAndRebuild: Aplicar y reconstruir + Cancel: Descartar y cancelar + OnlyApply: Solo aplicar + Message: >- + La nueva configuración está lista. Vamos a aplicarla. + + Hay varias formas de hacerlo: + + + - Aplicar y obtener + Configura este dispositivo como cliente nuevo. Tras aplicarla, sincroniza desde el servidor remoto. + - Aplicar y combinar + Para un dispositivo que ya tiene los archivos. Procesa los archivos locales y transfiere las diferencias. Pueden surgir conflictos. + - Aplicar y reconstruir + Reconstruye el remoto a partir de los archivos locales. Se hace normalmente si el servidor se ha corrompido o si se quiere empezar de cero. + Los demás dispositivos quedarán bloqueados y tendrán que volver a obtener los datos. + - Solo aplicar + Solo aplica la configuración. Pueden surgir conflictos si hace falta reconstruir. + Title: Aplicar la nueva configuración de ${method} + WarningRebuildRecommended: "NOTA: tras ajustar la configuración se ha + determinado que hace falta reconstruir; no se recomienda «solo importar»." + Doctor: + Buttons: + No: No, usar los ajustes del URI tal cual + Yes: Sí, consultar al doctor + Message: >- + Self-hosted LiveSync tiene ya una historia larga y algunos ajustes + recomendados han cambiado. + + + La configuración inicial es un momento muy bueno para revisarlos. + + + ¿Quieres ejecutar el Doctor para comprobar si los ajustes importados son + los óptimos respecto al estado actual? + Title: ¿Quieres consultar al doctor? + FetchRemoteConf: + Buttons: + Fetch: Sí, obtener la configuración + Skip: No, usar los ajustes del URI + Message: >- + Si ya hemos sincronizado alguna vez con otro dispositivo, la base de datos + remota guarda los valores de configuración adecuados para los dispositivos + sincronizados. El complemento querría recuperarlos para lograr una + configuración más sólida. + + + Antes hay que asegurar una cosa: ¿estamos en una situación en la que se + puede acceder a la red de forma segura y recuperar los ajustes? + + + Nota: normalmente puedes hacerlo sin riesgo si tu base de datos remota se + sirve con un certificado SSL y tu red no está comprometida. + Title: ¿Obtener la configuración de la base de datos remota? + QRCode: >- + Hemos generado un código QR para transferir los ajustes. Escanéalo con tu + móvil u otro dispositivo. + + Nota: el código QR no está cifrado, así que ten cuidado al abrirlo. + + + >[!SOLO PARA TUS OJOS]- + + >
${qr_image}
+ ShowQRCode: + _value: Mostrar el código QR + Desc: Muestra un código QR para transferir los ajustes. moduleObsidianMenu: replicate: Replicar More actions: Más acciones @@ -1174,6 +1756,11 @@ obsidianLiveSyncSettingTab: titleUpdateThinning: Actualización de adelgazamiento warnCorsOriginUnmatched: "⚠ El origen de CORS no coincide: {from}->{to}" warnNoAdmin: ⚠ No tienes privilegios de administrador. + errEnableCorsChttpd: ❗ chttpd.enable_cors es incorrecto + msgEnableCorsChttpd: Establecer chttpd.enable_cors + okEnableCorsChttpd: ✔ chttpd.enable_cors es correcto. + serverVersion: "Información del servidor: ${info}" + titleActiveRemoteServer: Servidor remoto activo Ok: Aceptar Old Algorithm: Algoritmo antiguo Older fallback (Slow, W/O WebAssembly): Alternativa anterior (lenta, sin WebAssembly) @@ -1342,15 +1929,26 @@ Setting: > Title: ¡Se ha generado un nuevo par de claves! + TroubleShooting: + _value: Resolución de problemas + Doctor: + _value: Doctor de ajustes + Desc: Detecta ajustes no óptimos. (Igual que durante la migración) + ScanBrokenFiles: + _value: Buscar archivos dañados + Desc: Busca archivos que no se hayan guardado correctamente en la base de datos. "Setup Complete: Preparing to Fetch Synchronisation Data": "Configuración completada: preparando la obtención de los datos de sincronización" "Setup Complete: Preparing to Initialise Server": "Configuración completada: preparando la inicialización del servidor" +Setup URI dialog cancelled.: Se ha cancelado el diálogo del Setup URI. Setup-URI: Setup-URI Should we keep folders that don't have any files inside?: ¿Mantener carpetas vacías? Should we only check for conflicts when a file is opened?: ¿Solo comprobar conflictos al abrir archivo? Should we prompt you about conflicting files when a file is opened?: ¿Notificar sobre conflictos al abrir archivo? Should we prompt you for every single merge, even if we can safely merge automatcially?: ¿Preguntar en cada fusión aunque sea automática? Show full banner: Mostrar banner completo +Show history: Mostrar el historial +Show icon only: Mostrar solo el icono Show only notifications: Mostrar solo notificaciones Show status as icons only: Mostrar estado solo con íconos Show status icon instead of file warnings banner: Mostrar icono de estado en lugar del banner de advertencia de archivos @@ -1361,6 +1959,13 @@ Signaling Server Connection: Conexión al servidor de señalización Signalling Status: Estado de la señalización Skip and close: Omitir y cerrar Snippets: Fragmentos +"Some devices have differing progress values (max: ${maxProgress}, min: ${minProgress}).\nThis may indicate that some devices have not completed synchronisation, which could lead to conflicts. Strongly recommend confirming that all devices are synchronised before proceeding.": >- + Algunos dispositivos tienen valores de progreso distintos (máx.: + ${maxProgress}, mín.: ${minProgress}). + + Esto puede indicar que algunos no han terminado de sincronizar, lo que podría + provocar conflictos. Se recomienda encarecidamente confirmar que todos los + dispositivos están sincronizados antes de continuar. Start Broadcasting: Iniciar difusión Start change-broadcasting on Connect: Iniciar la difusión de cambios al conectar Start Sync & Close: Iniciar sincronización y cerrar @@ -1371,6 +1976,7 @@ Stop ⚡: Detener ⚡ Stop Broadcasting: Detener difusión Stop reflecting database changes to storage files.: Dejar de reflejar cambios de BD en archivos Stop watching for file changes.: Dejar de monitorear cambios en archivos +Storage -> Database: Almacenamiento -> Base de datos Strongly Recommended: Muy recomendado Suppress notification of hidden files change: Suprimir notificaciones de cambios en archivos ocultos Suspend database reflecting: Suspender reflejo de base de datos @@ -1387,8 +1993,11 @@ Sync on Save: Sincronizar al guardar Sync on Startup: Sincronizar al iniciar Sync once: Sincronizar una vez Synchronising files: Archivos sincronizados -Syncing: Sincronización -Syncing...: Sincronizando... +Syncing: + _value: Sincronización + "": + "": + "": Sincronizando... Target patterns: Patrones objetivo Test Settings and Continue: Probar los ajustes y continuar Testing only - Resolve file conflicts by syncing newer copies of the file, this can overwrite modified files. Be Warned.: @@ -1399,11 +2008,27 @@ The connection to the server has been configured successfully. As the next step, siguiente, The delay for consecutive on-demand fetches: Retraso entre obtenciones consecutivas The files in this Vault are almost identical to the server's.: Los archivos de este Vault son casi idénticos a los del servidor. +"The following accepted nodes are missing its node information:\n- ${missingNodes}\n\nThis indicates that they have not been connected for some time or have been left on an older version.\nIt is preferable to update all devices if possible. If you have any devices that are no longer in use, you can clear all accepted nodes by locking the remote once.": >- + A los siguientes nodos aceptados les falta su información de nodo: + + - ${missingNodes} + + + Esto indica que llevan tiempo sin conectarse o que se han quedado en una + versión antigua. + + Si es posible, conviene actualizar todos los dispositivos. Si tienes + dispositivos que ya no usas, puedes borrar todos los nodos aceptados + bloqueando el remoto una vez. The Group ID and passphrase are used to identify your group of devices. Make sure to use the same Group ID and passphrase on all devices you want to synchronise.: El ID de grupo y la frase de contraseña identifican tu grupo de dispositivos. Usa el mismo ID de grupo y la misma frase de contraseña en todos los dispositivos que quieras sincronizar. The Hash algorithm for chunk IDs: Algoritmo hash para IDs de chunks +The IndexedDB adapter often offers superior performance in certain scenarios, but it has been found to cause memory leaks when used with LiveSync mode. When using LiveSync mode, please use IDB adapter instead.: + El adaptador IndexedDB suele ofrecer mejor rendimiento en ciertos casos, pero + se ha comprobado que provoca fugas de memoria con el modo LiveSync. Si usas el + modo LiveSync, utiliza en su lugar el adaptador IDB. the latest synchronisation data will be downloaded from the server to this device.: se descargarán a este dispositivo los datos de sincronización más recientes del servidor. @@ -1415,6 +2040,7 @@ The maximum number of chunks that can be incubated within the document. Chunks e Número máximo de chunks que pueden incubarse en el documento. Excedentes se independizan The maximum total size of chunks that can be incubated within the document. Chunks exceeding this size will immediately graduate to independent chunks.: Tamaño total máximo de chunks incubados. Excedentes se independizan +The minimum interval for automatic synchronisation on event.: Intervalo mínimo para la sincronización automática al producirse un evento. The remote is already set up, and the configuration is compatible (or got compatible by this operation).: El remoto ya está configurado y la configuración es compatible (o pasa a serlo con esta operación). @@ -1468,6 +2094,502 @@ TURN server settings are only necessary if you are behind a strict NAT or firewa mayoría de los casos puedes dejar estos campos vacíos. TURN Server URLs (comma-separated): URL de servidores TURN (separadas por comas) TURN Username: Usuario de TURN +TweakMismatchResolve: + Action: + DisableAutoAcceptCompatible: Desactivar la aceptación automática + Dismiss: Descartar + EnableAutoAcceptCompatible: Activar la aceptación automática + UseConfigured: Usar los ajustes configurados + UseMine: Actualizar los ajustes de la base de datos remota + UseMineAcceptIncompatible: Actualizar los ajustes de la base de datos remota, pero dejarlo como está + UseMineWithRebuild: Actualizar los ajustes de la base de datos remota y reconstruir de nuevo + UseRemote: Aplicar los ajustes a este dispositivo + UseRemoteAcceptIncompatible: Aplicar los ajustes a este dispositivo e ignorar la incompatibilidad + UseRemoteWithRebuild: Aplicar los ajustes a este dispositivo y volver a obtener los datos + Message: + AutoAcceptCompatibleUndefined: >- + + Parece que los ajustes son distintos en cada dispositivo. Ahora se pueden + aplicar automáticamente los cambios compatibles a estas configuraciones. + + ¿Quieres activar la aceptación automática (`auto-accept`)? + Main: >- + + Los ajustes de la base de datos remota son los siguientes. Los han + configurado otros dispositivos que se han sincronizado con este al menos + una vez. + + + Si quieres usar estos ajustes, selecciona + %{TweakMismatchResolve.Action.UseConfigured}. + + Si prefieres conservar los de este dispositivo, selecciona + %{TweakMismatchResolve.Action.Dismiss}. + + + ${table} + + + >[!TIP] + + > Si quieres sincronizar todos los ajustes, usa «Sync settings via + markdown» después de aplicar la configuración mínima con esta función. + + + ${additionalMessage} + MainTweakResolving: |- + Tu configuración no coincide con la del servidor remoto. + + La siguiente configuración debería coincidir: + + ${table} + + Indícanos qué decides. + + ${additionalMessage} + UseRemote: + WarningRebuildRecommended: >- + + >[!NOTICE] + + > Algunos cambios son compatibles, pero pueden consumir almacenamiento y + transferencia de más. Se recomienda reconstruir. De momento puede que no + se reconstruya, pero podría hacerse en un mantenimiento futuro. + + > ***Asegúrate de tener tiempo y una red estable antes de aplicarlo.*** + WarningRebuildRequired: >- + + >[!WARNING] + + > Algunas configuraciones remotas no son compatibles con la base de + datos local de este dispositivo. Habrá que reconstruirla. + + > ***Asegúrate de tener tiempo y una red estable antes de aplicarlo.*** + WarningIncompatibleRebuildRecommended: >- + + >[!NOTICE] + + > Hemos detectado que algunos valores difieren de forma que hacen + incompatible la base de datos local con la remota. + + > Algunos cambios son compatibles, pero pueden consumir almacenamiento y + transferencia de más. Se recomienda reconstruir. De momento puede que no + se reconstruya, pero podría hacerse en un mantenimiento futuro. + + > Si decides reconstruir, tardará unos minutos o más. **Asegúrate de que + es seguro hacerlo ahora.** + WarningIncompatibleRebuildRequired: >- + + >[!WARNING] + + > Hemos detectado que algunos valores difieren de forma que hacen + incompatible la base de datos local con la remota. + + > Hay que reconstruir la local o la remota. Ambas cosas tardan unos + minutos o más. **Asegúrate de que es seguro hacerlo ahora.** + mineUpdated: Se ha ajustado la configuración del dispositivo. + remoteUpdated: Se ha actualizado la configuración almacenada en el remoto. + Table: + _value: |+ + | Nombre del valor | Este dispositivo | En el remoto | + |: --- |: ---- :|: ---- :| + ${rows} + + Row: "| ${name} | ${self} | ${remote} |" + Title: + _value: Se ha detectado una discrepancia de configuración + AutoAcceptCompatible: Aceptación automática disponible + TweakResolving: Se ha detectado una discrepancia de configuración + UseRemoteConfig: Usar la configuración remota +Ui: + Common: + Signal: + Caution: PRECAUCIÓN + Danger: PELIGRO + Notice: AVISO + Warning: ADVERTENCIA + Settings: + Advanced: + LocalDatabaseTweak: Ajuste fino de la base de datos local + MemoryCache: Caché en memoria + TransferTweak: Ajuste fino de la transferencia + Common: + Analyse: Analizar + Back: Volver + Check: Comprobar + Configure: Configurar + Continue: Continuar + Delete: Eliminar + Fetch: Obtener + Lock: Bloquear + Merge: Combinar + Open: Abrir + Overwrite: Sobrescribir + Perform: Ejecutar + ResetAll: Restablecer todo + ResolveAll: Resolver todo + Scan: Analizar + Send: Enviar + Use: Usar + VerifyAll: Verificar todo + CustomizationSync: + OpenDesc: Abre el diálogo + Panel: Sincronización de personalizaciones + WarnChangeDeviceName: No se puede cambiar el nombre del dispositivo mientras + esta función esté activada. Desactívala para poder cambiarlo. + WarnSetDeviceName: Establece un nombre para identificar este dispositivo. Debe + ser único entre tus dispositivos. Mientras no esté configurado, no se + puede activar esta función. + Hatch: + AnalyseDatabaseUsage: Analizar el uso de la base de datos + AnalyseDatabaseUsageDesc: Analiza el uso de la base de datos y genera un informe + TSV para que puedas diagnosticarlo tú mismo. Puedes pegar el informe + generado en la hoja de cálculo que prefieras. + BackToNonConfigured: Volver al estado sin configurar + ConvertNonObfuscated: Comprobar y convertir los archivos sin ruta ofuscada + ConvertNonObfuscatedDesc: Comprueba si la base de datos local contiene archivos + guardados sin ofuscación de ruta y los convierte si hace falta. + CopyIssueReport: Copiar el informe al portapapeles + DatabaseLabel: "Base de datos: ${details}" + DatabaseToStorage: Base de datos -> Almacenamiento + DeleteCustomizationSyncData: Eliminar todos los datos de la sincronización de personalizaciones + GeneratedReport: Informe generado + Missing: Falta + ModifiedSize: "Modificado: ${modified}, tamaño: ${size}" + ModifiedSizeActual: "Modificado: ${modified}, tamaño: ${size} (tamaño real: ${actualSize})" + PrepareIssueReport: Preparar el «informe» para abrir una incidencia + RecoveryAndRepair: Recuperación y reparación + RecreateAll: Recrear todo + RecreateMissingChunks: Recrear los chunks que faltan de todos los archivos + RecreateMissingChunksDesc: Recrea los chunks de todos los archivos. Si faltaban + chunks, esto puede corregir los errores. + ResetPanel: Restablecer + ResetRemoteUsage: Restablecer el umbral de aviso y comprobar el uso de la base + de datos remota + ResetRemoteUsageDesc: Restablece el umbral de tamaño del almacenamiento remoto y + vuelve a comprobar su tamaño. + ResolveAllConflictedFiles: Resolver todos los archivos en conflicto con el más reciente + ResolveAllConflictedFilesDesc: "Resuelve todos los archivos en conflicto + quedándose con el más reciente. Atención: esto sobrescribe el más + antiguo y no se puede recuperar." + RunDoctor: Ejecutar el Doctor + ScanBrokenFiles: Buscar archivos dañados + ScramSwitches: Interruptores de emergencia + ShowHistory: Mostrar el historial + StorageLabel: "Almacenamiento: ${details}" + StorageToDatabase: Almacenamiento -> Base de datos + VerifyAndRepairAllFiles: Verificar y reparar todos los archivos + VerifyAndRepairAllFilesDesc: Compara el contenido de los archivos entre la base + de datos local y el almacenamiento. Si no coinciden, se te preguntará + cuál conservar. + Maintenance: + Cleanup: Realizar limpieza + CleanupDesc: Reduce el espacio de almacenamiento descartando todas las + revisiones que no sean la última. Requiere la misma cantidad de espacio + libre en el servidor remoto y en el cliente local. + DeleteLocalDatabase: Eliminar la base de datos local para restablecer o + desinstalar Self-hosted LiveSync + EmergencyRestart: Reinicio de emergencia + EmergencyRestartDesc: Desactiva toda la sincronización y reinicia. + FreshStartWipe: Borrado para empezar de cero + FreshStartWipeDesc: Elimina todos los datos del servidor remoto. + GarbageCollection: Recolección de basura V3 (beta) + GarbageCollectionAction: Realizar la recolección de basura + GarbageCollectionDesc: Realiza una recolección de basura para eliminar los + chunks sin usar y reducir el tamaño de la base de datos. + LockServer: Bloquear el servidor + LockServerDesc: Bloquea el servidor remoto para impedir la sincronización con + otros dispositivos. + OverwriteRemote: Sobrescribir el remoto + OverwriteRemoteDesc: Sobrescribe el remoto con la base de datos local y la frase + de contraseña. + OverwriteServerData: Sobrescribir los datos del servidor con los archivos de este dispositivo + OverwriteServerDataDesc: Reconstruye la base de datos local y la remota con los + archivos de este dispositivo. + PurgeAllJournalCounter: Purgar todos los contadores del diario + PurgeAllJournalCounterDesc: Purga todas las cachés de descarga y de subida. + RebuildingOperations: Operaciones de reconstrucción (solo remoto) + Resend: Reenviar + ResendDesc: Reenvía todos los chunks al remoto. + Reset: Restablecer + ResetAllJournalCounter: Restablecer todos los contadores del diario + ResetAllJournalCounterDesc: Inicializa todo el historial del diario. En la + próxima sincronización se volverán a recibir y enviar todos los + elementos. + ResetJournalReceived: Restablecer el historial de recepción del diario + ResetJournalReceivedDesc: Inicializa el historial de recepción del diario. En la + próxima sincronización se volverán a descargar todos los elementos salvo + los enviados por este dispositivo. + ResetJournalSent: Restablecer el historial de envío del diario + ResetJournalSentDesc: Inicializa el historial de envío del diario. En la próxima + sincronización se volverán a enviar todos los elementos salvo los + recibidos por este dispositivo. + ResetLocalSyncInfo: Restablecer la información de sincronización + ResetLocalSyncInfoDesc: Restaura o reconstruye la base de datos local a partir del remoto. + ResetReceived: Restablecer lo recibido + ResetSentHistory: Restablecer el historial de envíos + ResetThisDevice: Restablecer la sincronización en este dispositivo + ScheduleAndRestart: Programar y reiniciar + Scram: ¡Parada de emergencia! + SendChunks: Enviar los chunks + Syncing: Sincronización + WarningLockedReadyAction: Estoy listo, desbloquear la base de datos + WarningLockedReadyText: Para evitar que el vault se corrompa, la base de datos + remota se ha bloqueado para la sincronización. (Este dispositivo está + marcado como «resuelto».) Cuando todos tus dispositivos estén marcados + como «resueltos», desbloquea la base de datos. Este aviso seguirá + apareciendo hasta que la replicación confirme que el dispositivo está + resuelto. + WarningLockedResolveAction: He hecho una copia de seguridad, marcar este dispositivo como resuelto + WarningLockedResolveText: La base de datos remota está bloqueada para la + sincronización a fin de evitar que el vault se corrompa, porque este + dispositivo no está marcado como «resuelto». Haz una copia de seguridad + de tu vault, restablece la base de datos local y selecciona «Marcar este + dispositivo como resuelto». Este aviso seguirá apareciendo hasta que la + replicación confirme que el dispositivo está resuelto. + WriteRedFlagAndRestart: Marcar y reiniciar + Patches: + CompatibilityConflict: Compatibilidad (comportamiento ante conflictos) + CompatibilityDatabase: Compatibilidad (estructura de la base de datos) + CompatibilityInternalApi: Compatibilidad (uso de la API interna) + CompatibilityMetadata: Compatibilidad (metadatos) + CompatibilityRemote: Compatibilidad (base de datos remota) + CompatibilityTrouble: Compatibilidad (problemas resueltos) + CurrentAdapter: "Adaptador actual: ${adapter}" + DatabaseAdapter: Adaptador de base de datos + DatabaseAdapterDesc: Selecciona el adaptador de base de datos que se va a usar. + EdgeCaseBehaviour: Casos límite (comportamiento) + EdgeCaseDatabase: Casos límite (base de datos) + EdgeCaseProcessing: Casos límite (procesamiento) + IndexedDbWarning: El adaptador IndexedDB suele ofrecer mejor rendimiento en + ciertos casos, pero se ha comprobado que provoca fugas de memoria con el + modo LiveSync. Si usas el modo LiveSync, utiliza en su lugar el + adaptador IDB. + MigratingToIdb: Migrando todos los datos a IDB... + MigratingToIndexedDb: Migrando todos los datos a IndexedDB... + MigrationIdbCompleted: Migración a IDB completada. Obsidian se reiniciará de + inmediato con la nueva configuración. + MigrationIdbCompletedFollowUp: Migración a IDB completada. Cambia el adaptador y reinicia Obsidian. + MigrationIndexedDbCompleted: Migración a IndexedDB completada. Obsidian se + reiniciará de inmediato con la nueva configuración. + MigrationIndexedDbCompletedFollowUp: Migración a IndexedDB completada. Cambia el + adaptador y reinicia Obsidian. + MigrationWarning: Cambiar este ajuste requiere migrar los datos existentes, lo + que puede tardar un rato, y reiniciar Obsidian. Asegúrate de hacer una + copia de seguridad de tus datos antes de continuar. + OperationToIdb: a IDB + OperationToIndexedDb: a IndexedDB + Remediation: Remediación + RemediationChanged: Se ha cambiado el ajuste de remediación + RemediationNoLimit: Sin límite configurado + RemediationRestartLater: Más tarde + RemediationRestartMessage: Se recomienda encarecidamente reiniciar Obsidian. + Hasta que lo hagas, puede que algunos cambios no surtan efecto y que la + interfaz se muestre de forma inconsistente. ¿Seguro que quieres + reiniciar ahora? + RemediationRestartNow: Reiniciar ahora + RemediationRestarting: Se ha cambiado el ajuste de remediación. Reiniciando Obsidian... + RemediationSuffixChanged: El sufijo ha cambiado. Reabriendo la base de datos... + RemediationWithValue: "Límite: ${date} (${timestamp})" + RemoteDatabaseSunset: Ajuste fino de la base de datos remota (en desuso) + SwitchToIDB: Cambiar a IDB + SwitchToIndexedDb: Cambiar a IndexedDB + PowerUsers: + ConfigurationEncryption: Cifrado de la configuración + ConnectionTweak: Ajuste fino de la conexión con CouchDB + ConnectionTweakDesc: Si alcanzas el límite de tamaño de carga al usar IBM + Cloudant, reduce el tamaño de lote y el límite de lote. + Default: Predeterminado + Developer: Desarrollo + EncryptSensitiveConfig: Cifrar los elementos sensibles de la configuración + PromptPassphraseEveryLaunch: Solicitar la frase de contraseña en cada inicio + UseCustomPassphrase: Usar una frase de contraseña personalizada + Remote: + Activate: Activar + ActiveSuffix: " (activo)" + AddConnection: Añadir conexión + AddRemoteDefaultName: Remoto nuevo + ConfigureAndChangeRemote: Configurar y cambiar el remoto + ConfigureE2EE: Configurar el E2EE + ConfigureRemote: Configurar el remoto + DeleteRemoteConfirm: ¿Eliminar la configuración remota «${name}»? + DeleteRemoteTitle: Eliminar la configuración remota + DisplayName: Nombre visible + DuplicateRemote: Duplicar el remoto + DuplicateRemoteSuffix: ${name} (copia) + E2EEConfiguration: Configuración del E2EE + Export: Exportar + FetchRemoteSettings: Obtener los ajustes remotos + ImportConnection: Importar conexión + ImportConnectionPrompt: Pega una cadena de conexión + ImportedCouchDb: CouchDB importado + ImportedRemote: Remoto + MoreActions: Más acciones + PeerToPeerPanel: Sincronización punto a punto + RemoteConfigurationPrefix: Configuración remota + RemoteDatabases: Bases de datos remotas + RemoteName: Nombre del remoto + RemoteNameCouchDb: CouchDB ${host} + RemoteNameP2P: P2P ${room} + RemoteNameS3: S3 ${bucket} + Rename: Cambiar el nombre + Selector: + AddDefaultPatterns: Añadir patrones predeterminados + CrossPlatform: Multiplataforma + Default: Predeterminado + HiddenFiles: Archivos ocultos + IgnorePatterns: Patrones de exclusión + NonSynchronisingFiles: Archivos que no se sincronizan + NonSynchronisingFilesDesc: (RegExp) Si se establece, se omitirá cualquier cambio + en archivos locales y remotos que coincida con este patrón. + NormalFiles: Archivos normales + OverwritePatterns: Patrones de sobrescritura + OverwritePatternsDesc: Patrones de los archivos que se sobrescriben en lugar de combinarse + SynchronisingFiles: Archivos que se sincronizan + SynchronisingFilesDesc: (RegExp) Déjalo vacío para sincronizar todos los + archivos. Define un filtro como expresión regular para limitar los + archivos sincronizados. + TargetPatterns: Patrones de inclusión + TargetPatternsDesc: Patrones de los archivos que se van a sincronizar + Setup: + RerunWizardButton: Volver a ejecutar el asistente + RerunWizardDesc: Vuelve a ejecutar el asistente de configuración inicial para + configurar Self-hosted LiveSync de nuevo. + RerunWizardName: Volver a ejecutar el asistente de configuración inicial + SyncSettings: + Fetch: Obtener + Merge: Combinar + Overwrite: Sobrescribir + SetupWizard: + Common: + Back: No, volver atrás + Cancel: Cancelar + ProceedSelectOption: Selecciona una opción para continuar + Intro: + ExistingOption: Estoy añadiendo un dispositivo a una configuración de + sincronización existente + ExistingOptionDesc: Elige esto si ya usas la sincronización en otro ordenador o + móvil. Usa esta opción para conectar este dispositivo a esa + configuración existente. + Guidance: Te guiaremos con unas cuantas preguntas para simplificar la + configuración de la sincronización. + NewOption: Lo estoy configurando por primera vez + NewOptionDesc: Elige esto si estás configurando este dispositivo como el primero + de la sincronización. + ProceedExisting: Sí, quiero añadir este dispositivo a mi sincronización existente + ProceedNew: Sí, quiero configurar una sincronización nueva + Question: Primero, selecciona la opción que mejor describa tu situación actual. + Title: Bienvenido a Self-hosted LiveSync + Invitation: + Start: Comenzar la configuración + OutroAskUserMode: + CompatibleOption: El remoto ya está configurado y la configuración es compatible + (o pasa a serlo con esta operación). + CompatibleOptionDesc: Si no estás seguro, elegir esta opción es arriesgado. Da + por supuesto que la configuración del servidor es compatible con este + dispositivo. Si no lo es, puede haber pérdida de datos. Asegúrate de + entender las consecuencias. + ExistingOption: Mi servidor remoto ya está configurado. Quiero añadir este dispositivo. + ExistingOptionDesc: Al elegir esta opción, este dispositivo se unirá al servidor + existente. Tendrás que obtener del servidor los datos de sincronización + ya existentes. + Guidance: La conexión con el servidor se ha configurado correctamente. Como paso + siguiente hay que reconstruir la base de datos local, es decir, la + información de sincronización. + NewOption: Estoy configurando un servidor nuevo por primera vez / quiero + restablecer mi servidor actual. + NewOptionDesc: Al elegir esta opción, el servidor se inicializará con los datos + actuales de este dispositivo. Cualquier dato existente en el servidor se + sobrescribirá por completo. + ProceedApplySettings: Aplicar los ajustes + ProceedNext: Continuar al paso siguiente. + Question: Selecciona tu situación. + Title: "Casi terminado: se requiere una decisión" + OutroNewP2PUser: + GuidanceNotice: En P2P no hay una copia en un servidor central que sobrescribir. + Este paso prepara solo este dispositivo; mantenlo conectado cuando otro + dispositivo obtenga sus datos iniciales. + GuidancePrimary: La conexión punto a punto se ha configurado correctamente. A + continuación, la base de datos local de LiveSync se construirá a partir + de los archivos actuales de este Vault. + Important: TEN EN CUENTA + Proceed: Reiniciar y preparar este dispositivo + Question: Pulsa el botón de abajo para reiniciar y pasar a la confirmación de la + inicialización local. + Title: "Configuración completada: preparando este dispositivo P2P" + OutroNewUser: + GuidancePrimary: La conexión con el servidor se ha configurado correctamente. + Como paso siguiente, los datos de sincronización del servidor se + construirán a partir de los datos actuales de este dispositivo. + GuidanceWarning: Tras reiniciar, los datos de este dispositivo se subirán al + servidor como copia maestra. Ten en cuenta que cualquier dato no deseado + que haya ahora en el servidor se sobrescribirá por completo. + Important: IMPORTANTE + Proceed: Reiniciar e inicializar el servidor + Question: Pulsa el botón de abajo para reiniciar y pasar a la confirmación final. + Title: "Configuración completada: preparando la inicialización del servidor" + RebuildEverythingP2P: + ConfirmLocalReset: Entiendo que esto restablece únicamente la base de datos de + sincronización local de este dispositivo. + ConfirmLocalResetNote: Se usarán los archivos que hay ahora en este Vault para reconstruirla. + ConfirmTitle: ⚠️ Confirma lo siguiente + Guidance: Este procedimiento descartará la base de datos local de LiveSync de + este dispositivo y la reconstruirá a partir de los archivos actuales de + este Vault. No elimina ni sobrescribe datos de otro dispositivo. + Note: Mantén este dispositivo conectado después de la inicialización para que + otro dispositivo pueda obtener el Vault desde él. + Proceed: Lo entiendo, preparar este dispositivo + Title: "Confirmación final: preparar este dispositivo para P2P" + SelectExisting: + Guidance: Estás añadiendo este dispositivo a una configuración de sincronización + existente. + ManualOption: Configurar un remoto manualmente + ManualOptionDesc: Vuelve a configurar manualmente el mismo remoto que en tus + otros dispositivos. Está pensado solo para usuarios avanzados. + ProceedManual: Continuar con la configuración manual + ProceedQr: Escanea con la cámara de este dispositivo el código QR mostrado en un + dispositivo activo. + ProceedSetupUri: Continuar con el Setup URI + QrOption: Escanear un código QR (recomendado en móvil) + QrOptionDesc: Escanea con la cámara de este dispositivo el código QR mostrado en + un dispositivo activo. + Question: Selecciona un método para importar los ajustes desde otro dispositivo. + SetupUriOption: Usar un Setup URI (recomendado) + SetupUriOptionDesc: Pega el Setup URI generado en uno de tus dispositivos activos. + Title: Método de configuración del dispositivo + SelectNew: + Guidance: Vamos a configurar la conexión de sincronización. + ManualOption: Configurar un remoto manualmente + ManualOptionDesc: Es una opción avanzada para quienes no tienen un Setup URI o + quieren ajustar la configuración en detalle. También puedes usarla para + la sincronización P2P en lugar de CouchDB o de un almacenamiento de + objetos compatible con S3. + ProceedManual: Continuar con la configuración manual + ProceedSetupUri: Continuar con el Setup URI + Question: ¿Cómo quieres configurar esta conexión de sincronización? + SetupUriOption: Usar un Setup URI (recomendado) + SetupUriOptionDesc: Un Setup URI es una única cadena que contiene los datos de + conexión y autenticación. Cuando un script de instalación te proporciona + uno, es la forma más sencilla y segura de configurarlo. + Title: Método de conexión + SetupRemote: + BucketOption: Almacenamiento de objetos compatible con S3 + BucketOptionDesc: Sincronización mediante archivos de diario. Necesitas tener ya + un servicio de almacenamiento de objetos compatible con S3, como Amazon + S3, MinIO o Cloudflare R2. + CouchDbOptionDesc: Es el método de sincronización más adecuado para el diseño + actual y ofrece todas las funciones. Necesitas tener ya una instancia de + CouchDB en marcha. + Guidance: Selecciona el tipo de remoto para esta configuración de sincronización. + P2POption: Punto a punto (P2P) + P2POptionDesc: Permite la sincronización directa entre dispositivos. No hace + falta servidor, pero ambos dispositivos deben estar conectados a la vez + y algunas funciones pueden estar limitadas. Solo se necesita internet + para la señalización, no para transferir los datos. + ProceedBucket: Continuar con la configuración del almacenamiento de objetos + ProceedCouchDb: Continuar con la configuración de CouchDB + ProceedP2P: Continuar con la configuración de P2P + Title: Elige un remoto de sincronización Unique name between all synchronized devices. To edit this setting, please disable customization sync once.: Nombre único entre dispositivos sincronizados. Para editarlo, desactive sincronización de personalización @@ -1516,49 +2638,77 @@ Write logs into the file: Escribir logs en archivo xxhash32 (Fast but less collision resistance): xxhash32 (rápido, pero con menor resistencia a colisiones) xxhash64 (Fastest): xxhash64 (el más rápido) "Welcome to Self-hosted LiveSync": "Bienvenido a Self-hosted LiveSync" -"We will now guide you through a few questions to simplify the synchronisation setup.": "Ahora le guiaremos con unas pocas preguntas para simplificar la configuración de la sincronización。" +"We will now guide you through a few questions to simplify the synchronisation setup.": + "Ahora le guiaremos con unas pocas preguntas para simplificar la configuración + de la sincronización。" "First, please select the option that best describes your current situation.": "Primero, seleccione la opción que describa mejor su situación actual。" "I am setting this up for the first time": "Estoy configurando esto por primera vez" -"(Select this if you are configuring this device as the first synchronisation device.) This option is suitable if you are new to LiveSync and want to set it up from scratch.": "(Seleccione esto si está configurando este dispositivo como el primer dispositivo de sincronización). Esta opción es adecuada si es nuevo en LiveSync y desea configurarlo desde cero。" -"I am adding a device to an existing synchronisation setup": "Estoy agregando un dispositivo a una configuración de sincronización existente" -"(Select this if you are already using synchronisation on another computer or smartphone.) This option is suitable if you are new to LiveSync and want to set it up from scratch.": "(Seleccione esto si ya utiliza la sincronización en otro ordenador o teléfono). Esta opción es adecuada si desea añadir este dispositivo a una configuración de LiveSync existente。" +"(Select this if you are configuring this device as the first synchronisation device.) This option is suitable if you are new to LiveSync and want to set it up from scratch.": + "(Seleccione esto si está configurando este dispositivo como el primer + dispositivo de sincronización). Esta opción es adecuada si es nuevo en + LiveSync y desea configurarlo desde cero。" +"I am adding a device to an existing synchronisation setup": + "Estoy agregando un dispositivo a una configuración de sincronización + existente" +"(Select this if you are already using synchronisation on another computer or smartphone.) This option is suitable if you are new to LiveSync and want to set it up from scratch.": + "(Seleccione esto si ya utiliza la sincronización en otro ordenador o + teléfono). Esta opción es adecuada si desea añadir este dispositivo a una + configuración de LiveSync existente。" "Yes, I want to set up a new synchronisation": "Sí, quiero configurar una nueva sincronización" "Yes, I want to add this device to my existing synchronisation": "Sí, quiero añadir este dispositivo a mi sincronización existente" "No, please take me back": "No, volver atrás" "Device Setup Method": "Método de configuración del dispositivo" -"You are adding this device to an existing synchronisation setup.": "Está añadiendo este dispositivo a una configuración de sincronización existente。" +"You are adding this device to an existing synchronisation setup.": + "Está añadiendo este dispositivo a una configuración de sincronización + existente。" "Please select a method to import the settings from another device.": "Seleccione un método para importar la configuración desde otro dispositivo。" "Use a Setup URI (Recommended)": "Usar un URI de configuración (recomendado)" "Paste the Setup URI generated from one of your active devices.": "Pegue el URI de configuración generado desde uno de sus dispositivos activos。" "Scan a QR Code (Recommended for mobile)": "Escanear un código QR (recomendado para móviles)" -"Scan the QR code displayed on an active device using this device's camera.": "Escanee con la cámara de este dispositivo el código QR mostrado en un dispositivo activo。" +"Scan the QR code displayed on an active device using this device's camera.": + "Escanee con la cámara de este dispositivo el código QR mostrado en un + dispositivo activo。" "Enter the server information manually": "Introducir manualmente la información del servidor" -"Configure the same server information as your other devices again, manually, very advanced users only.": "Configure manualmente la misma información del servidor que en sus otros dispositivos. Solo para usuarios muy avanzados。" +"Configure the same server information as your other devices again, manually, very advanced users only.": + "Configure manualmente la misma información del servidor que en sus otros + dispositivos. Solo para usuarios muy avanzados。" "Proceed with Setup URI": "Continuar con el URI de configuración" "I know my server details, let me enter them": "Conozco los datos de mi servidor; permítame introducirlos" "Please select an option to proceed": "Seleccione una opción para continuar" "Connection Method": "Método de conexión" "We will now proceed with the server configuration.": "Ahora continuaremos con la configuración del servidor。" "How would you like to configure the connection to your server?": "¿Cómo desea configurar la conexión con su servidor?" -"A Setup URI is a single string of text containing your server address and authentication details. Using a URI, if one was generated by your server installation script, provides a simple and secure configuration.": "Un URI de configuración es una única cadena de texto que contiene la dirección del servidor y los datos de autenticación. Si el script de instalación de su servidor generó un URI, usarlo proporciona una configuración sencilla y segura。" -"This is an advanced option for users who do not have a URI or who wish to configure detailed settings.": "Esta es una opción avanzada para usuarios que no disponen de un URI o que desean configurar parámetros detallados。" +"A Setup URI is a single string of text containing your server address and authentication details. Using a URI, if one was generated by your server installation script, provides a simple and secure configuration.": + "Un URI de configuración es una única cadena de texto que contiene la + dirección del servidor y los datos de autenticación. Si el script de + instalación de su servidor generó un URI, usarlo proporciona una configuración + sencilla y segura。" +"This is an advanced option for users who do not have a URI or who wish to configure detailed settings.": + "Esta es una opción avanzada para usuarios que no disponen de un URI o que + desean configurar parámetros detallados。" "Enter Server Information": "Introducir información del servidor" "Please select the type of server to which you are connecting.": "Seleccione el tipo de servidor al que se está conectando。" "Continue to CouchDB setup": "Continuar con la configuración de CouchDB" "Continue to S3/MinIO/R2 setup": "Continuar con la configuración de S3/MinIO/R2" "Continue to Peer-to-Peer only setup": "Continuar con la configuración solo Peer-to-Peer" -"This is the most suitable synchronisation method for the design. All functions are available. You must have set up a CouchDB instance.": "Este es el método de sincronización más adecuado para el diseño. Todas las funciones están disponibles. Debe tener configurada una instancia de CouchDB。" +"This is the most suitable synchronisation method for the design. All functions are available. You must have set up a CouchDB instance.": + "Este es el método de sincronización más adecuado para el diseño. Todas las + funciones están disponibles. Debe tener configurada una instancia de CouchDB。" "S3/MinIO/R2 Object Storage": "Almacenamiento de objetos S3/MinIO/R2" -"Synchronisation utilising journal files. You must have set up an S3/MinIO/R2 compatible object storage.": "Sincronización mediante archivos de registro. Debe haber configurado un almacenamiento de objetos compatible con S3/MinIO/R2。" +"Synchronisation utilising journal files. You must have set up an S3/MinIO/R2 compatible object storage.": + "Sincronización mediante archivos de registro. Debe haber configurado un + almacenamiento de objetos compatible con S3/MinIO/R2。" "Peer-to-Peer only": "Solo Peer-to-Peer" -"This feature enables direct synchronisation between devices. No server is required, but both devices must be online at the same time for synchronisation to occur, and some features may be limited. Internet connection is only required to signalling (detecting peers) and not for data transfer.": "Esta función permite la sincronización directa entre dispositivos. No requiere servidor, pero ambos dispositivos deben estar en línea al mismo tiempo para que la sincronización se produzca, y algunas funciones pueden ser limitadas. La conexión a Internet solo se necesita para la señalización (detección de pares), no para la transferencia de datos。" - +"This feature enables direct synchronisation between devices. No server is required, but both devices must be online at the same time for synchronisation to occur, and some features may be limited. Internet connection is only required to signalling (detecting peers) and not for data transfer.": + "Esta función permite la sincronización directa entre dispositivos. No + requiere servidor, pero ambos dispositivos deben estar en línea al mismo + tiempo para que la sincronización se produzca, y algunas funciones pueden ser + limitadas. La conexión a Internet solo se necesita para la señalización + (detección de pares), no para la transferencia de datos。" You can configure in the Obsidian Plugin Settings.: Puedes configurarlo en los ajustes del complemento de Obsidian. - You should create a new synchronisation destination and rebuild your data there.: Deberías crear un nuevo destino de sincronización y reconstruir allí tus datos. You should perform this operation only in exceptional circumstances, such as when the server data is completely corrupted, when changes on all other devices are no longer needed, or when the database size has become unusually large in comparison to the Vault size.: "Solo deberías realizar esta operación en circunstancias excepcionales: cuando los datos del servidor estén completamente corruptos, cuando ya no necesites los cambios de los demás dispositivos o cuando el tamaño de la base de datos sea inusualmente grande respecto al del Vault." - diff --git a/src/common/messagesYAML/ko.yaml b/src/common/messagesYAML/ko.yaml index 3167321f..1e9f8c0f 100644 --- a/src/common/messagesYAML/ko.yaml +++ b/src/common/messagesYAML/ko.yaml @@ -2,41 +2,54 @@ (BETA) Always overwrite with a newer file: (베타) 항상 새로운 파일로 덮어쓰기 (Beta) Use ignore files: (베타) 제외 규칙 파일 사용 (Days passed, 0 to disable automatic-deletion): (지난 일수, 0으로 설정하면 자동 삭제 비활성화) -(ex. Read chunks online) If this option is enabled, LiveSync reads chunks online directly instead of replicating them locally. Increasing Custom chunk size is recommended.: - "(예: 청크를 원격에서 읽음) 이 옵션을 활성화하면, LiveSync는 청크를 로컬에 복제하지 않고 원격에서 직접 읽습니다. 커스텀 청크 - 크기를 키우는 것을 권장합니다." +(ex. Read chunks online) If this option is enabled, LiveSync reads chunks online directly instead of replicating them locally. Increasing Custom chunk size is recommended.: "(예: 청크를 원격에서 읽음) 이 옵션을 활성화하면, LiveSync는 청크를 로컬에 복제하지 않고 원격에서 직접 읽습니다. 커스텀 청크 크기를 키우는 것을 권장합니다." (MB) If this is set, changes to local and remote files that are larger than this will be skipped. If the file becomes smaller again, a newer one will be used.: (MB) 이 값이 설정되면, 이보다 큰 로컬 및 원격 파일의 변경 사항은 건너뜁니다. 파일이 다시 작아지면 더 새로운 파일이 사용됩니다. -(Mega chars): (메가 문자) +(Mega chars): (백만 자 단위) (Not recommended) If set, credentials will be stored in the file.: (권장하지 않음) 설정한 경우 자격 증명이 파일에 저장됩니다. (Obsolete) Use an old adapter for compatibility: (사용 중단) 호환성을 위해 이전 어댑터 사용 (RegExp) Empty to sync all files. Set filter as a regular expression to limit synchronising files.: (정규식) 비워 두면 모든 파일을 동기화합니다. 정규식을 지정하면 동기화할 파일을 제한할 수 있습니다. (RegExp) If this is set, any changes to local and remote files that match this will be skipped.: (정규식) 설정하면 이 패턴과 일치하는 로컬 및 원격 파일 변경은 모두 건너뜁니다. +(Select this if you are already using synchronisation on another computer or smartphone.) This option is suitable if you are new to LiveSync and want to set it up from scratch.: (다른 컴퓨터나 스마트폰에서 이미 동기화를 사용 중이라면 선택하세요.) 이 기기를 기존 LiveSync 구성에 추가하려는 경우에 적합합니다. +(Select this if you are configuring this device as the first synchronisation device.) This option is suitable if you are new to LiveSync and want to set it up from scratch.: (이 기기를 첫 번째 동기화 기기로 설정한다면 선택하세요.) LiveSync를 처음 사용하며 처음부터 설정하려는 경우에 적합합니다. +"> [!INFO]- The connected devices have been detected as follows:\n${devices}": |- + > [!INFO]- 다음 연결된 기기가 감지되었습니다: + ${devices} +A Setup URI is a single string of text containing your server address and authentication details. Using a URI, if one was generated by your server installation script, provides a simple and secure configuration.: Setup URI는 서버 주소와 인증 정보를 담은 하나의 문자열입니다. 서버 설치 스크립트가 URI를 생성했다면, 이를 사용해 간단하고 안전하게 구성할 수 있습니다. Access Key: 액세스 키 Activate: 활성화 +Active Remote Configuration: 활성 원격 구성 Add default patterns: 기본 패턴 추가 Add new connection: 연결 추가 +All devices have the same progress value (${progress}). Your devices seem to be synchronised. And be able to proceed with Garbage Collection.: 모든 기기의 진행 값이 동일합니다(${progress}). 기기들이 동기화된 것으로 보이므로 가비지 컬렉션을 진행할 수 있습니다. Always prompt merge conflicts: 항상 병합 충돌 알림 +Analyse: 분석 +Analyse database usage: 데이터베이스 사용량 분석 +Analyse database usage and generate a TSV report for diagnosis yourself. You can paste the generated report with any spreadsheet you like.: 데이터베이스 사용량을 분석하고 직접 진단할 수 있도록 TSV 보고서를 생성합니다. 생성된 보고서는 원하는 스프레드시트에 붙여 넣어 확인할 수 있습니다. Apply Latest Change if Conflicting: 충돌 시 최신 변경 사항 적용 Apply preset configuration: 프리셋 구성 적용 -Ask a passphrase at every launch: 시작할 때마다 암호문구 묻기 +Ask a passphrase at every launch: 시작할 때마다 패스프레이즈 묻기 Automatically Sync all files when opening Obsidian.: Obsidian을 열 때 모든 파일을 자동으로 동기화합니다. Back: 뒤로 Back to non-configured: 미구성 상태로 되돌리기 Batch database update: 일괄 데이터베이스 업데이트 -Batch limit: 일괄 제한 -Batch size: 일괄 크기 -Batch size of on-demand fetching: 필요 시 가져올 청크 묶음 크기 -Before v0.17.16, we used an old adapter for the local database. Now the new adapter is preferred. However, it needs local database rebuilding. Please disable this toggle when you have enough time. If leave it enabled, also while fetching from the remote database, you will be asked to disable this.: - v0.17.16 이전에는 로컬 데이터베이스에 이전 어댑터를 사용했습니다. 이제는 새로운 어댑터를 권장합니다. 하지만 로컬 데이터베이스 - 재구축이 필요합니다. 충분한 시간이 있을 때 이 토글을 비활성화해 주세요. 활성화된 상태로 두면 원격 데이터베이스에서 가져올 때도 이를 - 비활성화하라는 메시지가 나타납니다. +Batch limit: 배치 개수 제한 +Batch size: 배치 크기 +Batch size of on-demand fetching: 필요 시 가져오기의 배치 크기 +Before v0.17.16, we used an old adapter for the local database. Now the new adapter is preferred. However, it needs local database rebuilding. Please disable this toggle when you have enough time. If leave it enabled, also while fetching from the remote database, you will be asked to disable this.: v0.17.16 이전에는 로컬 데이터베이스에 이전 어댑터를 사용했습니다. 이제는 새로운 어댑터를 권장합니다. 하지만 로컬 데이터베이스 재구축이 필요합니다. 충분한 시간이 있을 때 이 토글을 비활성화해 주세요. 활성화된 상태로 두면 원격 데이터베이스에서 가져올 때도 이를 비활성화하라는 메시지가 나타납니다. Bucket Name: 버킷 이름 Cancel: 취소 +Cancel Garbage Collection: 가비지 컬렉션 취소 +Changing this setting requires migrating existing data (a bit time may be taken) and restarting Obsidian. Please make sure to back up your data before proceeding.: 이 설정을 변경하려면 기존 데이터를 마이그레이션하고(시간이 다소 걸릴 수 있습니다) Obsidian을 재시작해야 합니다. 진행하기 전에 반드시 데이터를 백업해 주세요. +Check: 확인 Check and convert non-path-obfuscated files: 경로 난독화되지 않은 파일 검사 및 변환 Check for documents that have not been converted to path-obfuscated IDs and convert them if necessary.: 아직 경로 난독화 ID로 변환되지 않은 문서를 확인하고 필요하면 변환합니다. cmdConfigSync: showCustomizationSync: 사용자 설정 동기화 표시 Comma separated `.gitignore, .dockerignore`: 쉼표로 구분된 `.gitignore, .dockerignore` +Compaction in progress on remote database...: 원격 데이터베이스에서 압축 정리를 진행 중입니다... +Compaction on remote database completed successfully.: 원격 데이터베이스 압축 정리가 성공적으로 완료되었습니다. +Compaction on remote database failed.: 원격 데이터베이스 압축 정리에 실패했습니다. +Compaction on remote database timed out.: 원격 데이터베이스 압축 정리 시간이 초과되었습니다. Compare the content of files between on local database and storage. If not matched, you will be asked which one you want to keep.: 로컬 데이터베이스와 저장소 간의 파일 내용을 비교합니다. 일치하지 않으면 어떤 쪽을 유지할지 묻게 됩니다. Compatibility (Conflict Behaviour): 호환성 (충돌 동작) Compatibility (Database structure): 호환성 (데이터베이스 구조) @@ -50,13 +63,20 @@ Configure: 설정 Configure And Change Remote: 원격 구성 및 변경 Configure E2EE: E2EE 구성 Configure Remote: 원격 구성 +Configure the same server information as your other devices again, manually, very advanced users only.: 다른 기기와 동일한 서버 정보를 다시 직접 입력합니다. 숙련된 사용자 전용입니다. +Connection Method: 연결 방법 +Continue to CouchDB setup: CouchDB 설정으로 계속 +Continue to Peer-to-Peer only setup: Peer-to-Peer 전용 설정으로 계속 +Continue to S3/MinIO/R2 setup: S3/MinIO/R2 설정으로 계속 Copy: 복사 +Copy Report to clipboard: 보고서를 클립보드에 복사 CouchDB Connection Tweak: CouchDB 연결 조정 Cross-platform: 크로스 플랫폼 "Current adapter: {adapter}": "현재 어댑터: {adapter}" -Customization Sync: 사용자 지정 동기화 -Customization Sync (Beta3): 사용자 지정 동기화 (Beta3) +Customization Sync: 사용자 설정 동기화 +Customization Sync (Beta3): 사용자 설정 동기화 (Beta3) Data Compression: 데이터 압축 +Database -> Storage: 데이터베이스 -> 스토리지 Database Adapter: 데이터베이스 어댑터 Database Name: 데이터베이스 이름 Database suffix: 데이터베이스 접미사 @@ -64,7 +84,7 @@ Default: 기본값 Delay conflict resolution of inactive files: 비활성 파일의 충돌 해결 지연 Delay merge conflict prompt for inactive files.: 비활성 파일의 병합 충돌 프롬프트 지연. Delete: 삭제 -Delete all customization sync data: 모든 사용자 정의 동기화 데이터 삭제 +Delete all customization sync data: 모든 사용자 설정 동기화 데이터 삭제 Delete all data on the remote server.: 원격 서버의 모든 데이터를 삭제합니다. Delete local database to reset or uninstall Self-hosted LiveSync: Self-hosted LiveSync를 초기화하거나 제거하기 위해 로컬 데이터베이스를 삭제 Delete old metadata of deleted files on start-up: 시작 시 삭제된 파일의 오래된 메타데이터 삭제 @@ -72,19 +92,17 @@ Delete Remote Configuration: 원격 구성 삭제 Delete remote configuration '{name}'?: "'{name}' 원격 구성을 삭제할까요?" desktop: 데스크톱 Developer: 개발자 +Device: 기기 Device name: 기기 이름 +Device Setup Method: 기기 설정 방법 dialog: yourLanguageAvailable: - _value: >- - Self-hosted LiveSync에서 귀하의 언어로 번역을 제공하므로 %{Display language} 설정이 활성화되었습니다. + _value: |- + Self-hosted LiveSync가 사용 중인 언어의 번역을 제공하므로 %{Display Language} 설정이 활성화되었습니다. - - 참고: 모든 메시지가 번역되지는 않습니다. 귀하의 기여를 기다리고 있습니다! - - 참고 2: 이슈를 생성하는 경우 **%{lang-def}로 되돌린 후** 스크린샷, 메시지, 로그를 가져와 주세요. 이는 설정 대화 - 상자에서 할 수 있습니다. - - 간편하게 사용하실 수 있었으면 좋겠습니다! + 참고: 모든 메시지가 번역되어 있지는 않습니다. 여러분의 기여를 기다리고 있습니다! + 참고 2: 이슈를 등록할 때는 **%{lang-def} 로 되돌린 뒤** 스크린샷과 메시지, 로그를 첨부해 주세요. 설정 대화 상자에서 되돌릴 수 있습니다. + 편하게 사용하실 수 있기를 바랍니다! btnRevertToDefault: "%{lang-def} 유지" Title: " 번역을 사용할 수 있습니다!" Disables all synchronization and restart.: 모든 동기화를 비활성화하고 재시작합니다. @@ -105,32 +123,38 @@ Doctor: Yes: 예 Dialogue: Main: |- - 안녕하세요! ${activateReason} 로 인해 구성 진단 마법사가 활성화되었습니다! - 그리고 일부 구성이 잠재적인 문제로 감지되었습니다. - 안심하세요. 하나씩 해결해 봅시다. + 안녕하세요! ${activateReason}(으)로 인해 구성 진단 마법사가 실행되었습니다! + 아쉽게도 일부 구성에서 잠재적인 문제가 감지되었습니다. + 걱정하지 마세요. 하나씩 함께 해결해 보겠습니다. - 대상 항목은 다음과 같습니다. + 미리 알려드리자면, 다음 항목들에 대해 여쭤보겠습니다. ${issues} - 시작하시겠습니까? + 시작할까요? MainFix: |- - **구성 이름:** `${name}` - **현재 값:** `${current}`, **이상적인 값:** `${ideal}` - **권장 수준:** ${level} - **왜 이것이 감지되었나요?** - ${reason} + ## ${name} + + | 현재 값 | 이상적인 값 | + |:---:|:---:| + | ${current} | ${ideal} | + + **권장 수준:** ${level} + + ### 왜 이것이 감지되었나요? + + ${reason} ${note} - 이상적인 값으로 수정하시겠습니까? + 이상적인 값으로 수정할까요? Title: Self-hosted LiveSync 구성 진단 마법사 TitleAlmostDone: 거의 완료되었습니다! TitleFix: 문제 해결 ${current}/${total} Level: Must: 필수 - Necessary: 필수 + Necessary: 필요 Optional: 선택사항 Recommended: 권장 Message: @@ -138,8 +162,12 @@ Doctor: RebuildLocalRequired: 주의! 이를 적용하려면 로컬 데이터베이스 재구축이 필요합니다! RebuildRequired: 주의! 이를 적용하려면 재구축이 필요합니다! SomeSkipped: 일부 문제를 그대로 두었습니다. 다음 시작 시 다시 질문할까요? -Duplicate: 복제 -Duplicate remote: 원격 구성 복제 + RULES: + E2EE_V02500: + REASON: 종단 간 암호화가 더 견고하고 빨라졌습니다. 또한 다시 진행한 코드 검토에서 이전 E2EE에 취약점이 있는 것으로 확인되었기 때문에, 가능한 한 빨리 적용해 주시기 바랍니다. 불편을 드려 대단히 죄송합니다. 그리고 이 설정은 이전 버전과 호환되지 않습니다. 동기화 중인 모든 기기를 v0.25.0 이상으로 업데이트해야 합니다. 재구축은 필요하지 않으며 새로 전송되는 항목부터 새 형식으로 변환됩니다. 다만 가능하다면 재구축하시기를 권장합니다. +Document History: 문서 기록 +Duplicate: 복사본 만들기 +Duplicate remote: 원격 구성 복사 E2EE Configuration: E2EE 구성 Edge case addressing (Behaviour): 특수 상황 처리 (동작) Edge case addressing (Database): 특수 상황 처리 (데이터베이스) @@ -154,47 +182,65 @@ Enable this if your Object Storage doesn't support CORS: 객체 스토리지가 Enable this option to automatically apply the most recent change to documents even when it conflicts: 이 옵션을 활성화하면 충돌이 있어도 문서에 가장 최근 변경 사항을 자동으로 적용합니다 Encrypt contents on the remote database. If you use the plugin's synchronization feature, enabling this is recommended.: 원격 데이터베이스의 내용을 암호화합니다. 플러그인의 동기화 기능을 사용하는 경우 활성화를 권장합니다. Encrypting sensitive configuration items: 민감한 구성 항목 암호화 -Encryption phassphrase. If changed, you should overwrite the server's database with the new (encrypted) files.: 패스프레이즈는 암호화에 사용되는 긴 암호 문구입니다. 변경한 경우, 암호화된 새 파일로 서버의 데이터베이스를 덮어써야 합니다. -End-to-End Encryption: 종단간 암호화 +Encryption phassphrase. If changed, you should overwrite the server's database with the new (encrypted) files.: 암호화에 사용할 패스프레이즈입니다. 변경한 경우, 새로 암호화된 파일로 서버의 데이터베이스를 덮어써야 합니다. +End-to-End Encryption: 종단 간 암호화 Endpoint URL: 엔드포인트 URL -Enhance chunk size: 청크 크기 향상 +Enhance chunk size: 청크 크기 확대 +Enter Server Information: 서버 정보 입력 +Enter the server information manually: 서버 정보를 수동으로 입력 Export: 내보내기 +Failed to connect to remote for compaction.: 압축 정리를 위해 원격 데이터베이스에 연결하지 못했습니다. +Failed to connect to remote for compaction. ${reason}: 압축 정리를 위해 원격 데이터베이스에 연결하지 못했습니다. ${reason} +Failed to start one-shot replication before Garbage Collection. Garbage Collection Cancelled.: 가비지 컬렉션 전에 일회성 복제를 시작하지 못했습니다. 가비지 컬렉션을 취소합니다. +Failed to start replication after Garbage Collection.: 가비지 컬렉션 후 복제를 시작하지 못했습니다. Fetch: 가져오기 Fetch chunks on demand: 필요 시 청크 원격 가져오기 Fetch database with previous behaviour: 이전 동작으로 데이터베이스 가져오기 Fetch remote settings: 원격 설정 가져오기 File to resolve conflict: 충돌을 해결할 파일 +File to view History: 기록을 볼 파일 Filename: 파일명 +First, please select the option that best describes your current situation.: 먼저 현재 상황에 가장 잘 맞는 항목을 선택해 주세요. Flag and restart: 표시 후 재시작 Forces the file to be synced when opened.: 파일을 열 때 강제로 동기화합니다. -Fresh Start Wipe: 새로 시작 지우기 +Fresh Start Wipe: 초기화 후 새로 시작 +Garbage Collection cancelled by user.: 사용자가 가비지 컬렉션을 취소했습니다. +"Garbage Collection completed. Deleted chunks: ${deletedChunks} / ${totalChunks}. Time taken: ${seconds} seconds.": "가비지 컬렉션이 완료되었습니다. 삭제된 청크: ${deletedChunks} / ${totalChunks}. 소요 시간: ${seconds}초." +Garbage Collection Confirmation: 가비지 컬렉션 확인 Garbage Collection V3 (Beta): 가비지 컬렉션 V3 (Beta) +"Garbage Collection: Found ${unusedChunks} unused chunks to delete.": "가비지 컬렉션: 삭제할 미사용 청크 ${unusedChunks}개를 찾았습니다." +"Garbage Collection: Scanned ${scanned} / ~${docCount}": "가비지 컬렉션: ${scanned} / ~${docCount} 검사함" +"Garbage Collection: Scanning completed. Total chunks: ${totalChunks}, Used chunks: ${usedChunks}": "가비지 컬렉션: 검사 완료. 전체 청크 수: ${totalChunks}, 사용 중인 청크 수: ${usedChunks}" Handle files as Case-Sensitive: 파일을 대소문자 구분으로 처리 Hidden Files: 숨김 파일 +Hide completely: 완전히 숨기기 +Highlight diff: 차이 강조 How to display network errors when the sync server is unreachable.: 동기화 서버에 연결할 수 없을 때 네트워크 오류를 어떻게 표시할지 설정합니다. +How would you like to configure the connection to your server?: 서버 연결을 어떻게 구성하시겠습니까? +I am adding a device to an existing synchronisation setup: 기존 동기화 구성에 기기를 추가합니다 +I am setting this up for the first time: 처음으로 설정합니다 +I know my server details, let me enter them: 서버 정보를 알고 있으니 직접 입력하겠습니다 If disabled(toggled), chunks will be split on the UI thread (Previous behaviour).: 비활성화(토글)되면 청크는 UI 스레드에서 분할됩니다 (이전 동작). -If enabled per-filed efficient customization sync will be used. We need a small migration when enabling this. And all devices should be updated to v0.23.18. Once we enabled this, we lost a compatibility with old versions.: - 활성화하면 파일별 효율적인 사용자 설정 동기화가 사용됩니다. 이를 활성화할 때 소규모 데이터 구조 전환이 필요합니다. 모든 기기를 - v0.23.18로 업데이트해야 합니다. 이를 활성화하면 이전 버전과의 호환성이 사라집니다. +If enabled per-filed efficient customization sync will be used. We need a small migration when enabling this. And all devices should be updated to v0.23.18. Once we enabled this, we lost a compatibility with old versions.: 활성화하면 파일별 효율적인 사용자 설정 동기화가 사용됩니다. 이를 활성화할 때 소규모 데이터 구조 전환이 필요합니다. 모든 기기를 v0.23.18로 업데이트해야 합니다. 이를 활성화하면 이전 버전과의 호환성이 사라집니다. If enabled, chunks will be split into no more than 100 items. However, dedupe is slightly weaker.: 활성화하면 청크는 최대 100개 항목으로 분할됩니다. 하지만 중복 제거 기능이 약간 약해집니다. -If enabled, newly created chunks are temporarily kept within the document, and graduated to become independent chunks once stabilised.: 활성화하면 새로 생성된 변경 기록(청크)은 문서 안에 임시로 보관되며, 일정 조건을 만족하면 자동으로 문서 밖으로 분리되어 저장됩니다. +If enabled, newly created chunks are temporarily kept within the document, and graduated to become independent chunks once stabilised.: 활성화하면 새로 생성된 청크가 문서 안에 임시로 보관되며, 안정화된 뒤에 독립된 청크로 분리됩니다. If enabled, the ⛔ icon will be shown inside the status instead of the file warnings banner. No details will be shown.: 활성화하면 파일 경고 배너 대신 상태 영역에 ⛔ 아이콘만 표시됩니다. 자세한 내용은 표시되지 않습니다. If enabled, the file under 1kb will be processed in the UI thread.: 활성화하면 1kb 미만의 파일은 UI 스레드에서 처리됩니다. -If enabled, the notification of hidden files change will be suppressed.: 활성화하면 숨겨진 파일 변경 알림이 억제됩니다. +If enabled, the notification of hidden files change will be suppressed.: 활성화하면 숨김 파일 변경 알림이 표시되지 않습니다. If this enabled, all chunks will be stored with the revision made from its content. (Previous behaviour): 이 옵션이 활성화되면 모든 청크는 콘텐츠에서 생성된 리비전과 함께 저장됩니다. (이전 동작) If this enabled, All files are handled as case-Sensitive (Previous behaviour).: 이 옵션이 활성화되면 모든 파일이 대소문자를 구분하여 처리됩니다 (이전 동작). If this enabled, chunks will be split into semantically meaningful segments. Not all platforms support this feature.: 이 옵션을 활성화하면 청크가 문단이나 의미 단위로 나뉘어 저장됩니다. 단, 이 기능은 일부 플랫폼에서는 지원되지 않을 수 있습니다. -If this is set, changes to local files which are matched by the ignore files will be skipped. Remote changes are determined using local ignore files.: - 이 옵션을 활성화하면, 제외 규칙 파일에 일치하는 로컬 파일의 변경 사항은 건너뜁니다. 원격 변경 여부 또한 로컬의 제외 규칙 파일에 따라 - 판단됩니다. -If this option is enabled, PouchDB will hold the connection open for 60 seconds, and if no change arrives in that time, close and reopen the socket, instead of holding it open indefinitely. Useful when a proxy limits request duration but can increase resource usage.: - 이 옵션이 활성화되면 PouchDB는 연결을 더이상 무한히 열어두지 않고 60초 동안 유지합니다. 그 시간 내에 변경 사항이 없으면 소켓을 - 닫고 다시 엽니다. 프록시가 요청 지속 시간을 제한할 때 유용하지만 리소스 사용량이 증가할 수 있습니다. +If this is set, changes to local files which are matched by the ignore files will be skipped. Remote changes are determined using local ignore files.: 이 옵션을 활성화하면, 제외 규칙 파일에 일치하는 로컬 파일의 변경 사항은 건너뜁니다. 원격 변경 여부 또한 로컬의 제외 규칙 파일에 따라 판단됩니다. +If this option is enabled, PouchDB will hold the connection open for 60 seconds, and if no change arrives in that time, close and reopen the socket, instead of holding it open indefinitely. Useful when a proxy limits request duration but can increase resource usage.: 이 옵션이 활성화되면 PouchDB는 연결을 더이상 무한히 열어두지 않고 60초 동안 유지합니다. 그 시간 내에 변경 사항이 없으면 소켓을 닫고 다시 엽니다. 프록시가 요청 지속 시간을 제한할 때 유용하지만 리소스 사용량이 증가할 수 있습니다. +If you reached the payload size limit when using IBM Cloudant, please decrease batch size and batch limit to a lower value.: IBM Cloudant를 사용하다가 페이로드 크기 제한에 도달했다면, 배치 크기와 배치 개수 제한을 더 낮은 값으로 줄여 주세요. +Ignore and Proceed: 무시하고 계속 Ignore files: 제외 규칙 파일 Ignore patterns: 무시 패턴 Import connection: 연결 가져오기 -Incubate Chunks in Document: 문서 내 변경 기록 임시 보관 +Incubate Chunks in Document: 문서 내 청크 임시 보관 Initialise all journal history, On the next sync, every item will be received and sent.: 모든 저널 기록을 초기화합니다. 다음 동기화 때 모든 항목을 다시 받고 다시 보냅니다. +Initialise journal received history. On the next sync, every item except this device sent will be downloaded again.: 저널 수신 기록을 초기화합니다. 다음 동기화 때 이 기기가 보낸 항목을 제외한 모든 항목을 다시 내려받습니다. +Initialise journal sent history. On the next sync, every item except this device received will be sent again.: 저널 송신 기록을 초기화합니다. 다음 동기화 때 이 기기가 받은 항목을 제외한 모든 항목을 다시 보냅니다. Interval (sec): 간격 (초) K: exp: 실험 기능 @@ -202,14 +248,15 @@ K: P2P: "%{Peer}-to-%{Peer}" Peer: 피어 ScanCustomization: 사용자 설정 검색 - short_p2p_sync: P2P 동기화 (%{exp}) + short_p2p_sync: P2P 동기화 title_p2p_sync: 피어 투 피어(P2P) 동기화 Keep empty folder: 빈 폴더 유지 -lang_def: Default +lang_def: 기본값 lang-de: Deutsche lang-def: "%{lang_def}" lang-es: Español lang-fr: Français +lang-he: עברית lang-ja: 日本語 lang-ko: 한국어 lang-ru: Русский @@ -217,7 +264,7 @@ lang-zh: 简体中文 lang-zh-tw: 繁體中文 Later: 나중에 "Limit: {datetime} ({timestamp})": "제한: {datetime} ({timestamp})" -LiveSync could not handle multiple vaults which have same name without different prefix, This should be automatically configured.: LiveSync는 서로 다른 접두사 없이 동일한 이름을 가진 여러 볼트를 처리할 수 없습니다. 이는 자동으로 구성되어야 합니다. +LiveSync could not handle multiple vaults which have same name without different prefix, This should be automatically configured.: LiveSync는 접두사로 구분되지 않은 동일한 이름의 보관함을 여러 개 처리할 수 없습니다. 이 값은 자동으로 구성되어야 합니다. liveSyncReplicator: beforeLiveSync: LiveSync 전에 OneShot을 먼저 시작합니다... cantReplicateLowerValue: 더 낮은 값으로 복제할 수 없습니다. @@ -226,12 +273,13 @@ liveSyncReplicator: ${uri}에 연결할 수 없습니다: ${name} (${db}) couldNotConnectToRemoteDb: "원격 데이터베이스에 연결할 수 없습니다: ${d}" - couldNotConnectToServer: 서버에 연결할 수 없습니다. + couldNotConnectToServer: 원격에 대한 연결이 차단되었거나 실패했습니다. couldNotConnectToURI: "${uri}에 연결할 수 없습니다: ${dbRet}" couldNotMarkResolveRemoteDb: 원격 데이터베이스를 해결됨으로 표시할 수 없습니다. liveSyncBegin: LiveSync 시작... lockRemoteDb: 데이터 손상을 방지하기 위해 원격 데이터베이스를 잠급니다 markDeviceResolved: 이 기기를 '해결됨'으로 표시합니다. + mismatchedTweakDetected: 기기 간 구성에서 일부 불일치가 감지되었습니다. 수동으로 복제를 실행하면 이 문제를 해결하려고 시도합니다. oneShotSyncBegin: OneShot 동기화 시작... (${syncMode}) remoteDbCorrupted: 원격 데이터베이스가 더 최신이거나 손상되었습니다. 최신 버전의 self-hosted-livesync가 설치되어 있는지 확인하세요 remoteDbCreatedOrConnected: 원격 데이터베이스가 생성되거나 연결되었습니다 @@ -240,7 +288,7 @@ liveSyncReplicator: remoteDbMarkedResolved: 원격 데이터베이스가 해결됨으로 표시되었습니다. replicationClosed: 복제가 종료되었습니다 replicationInProgress: 복제가 이미 진행 중입니다 - retryLowerBatchSize: "더 낮은 일괄 크기로 재시도: ${batch_size}/${batches_limit}" + retryLowerBatchSize: "더 작은 배치 크기로 재시도: ${batch_size}/${batches_limit}" unlockRemoteDb: 데이터 손상을 방지하기 위해 원격 데이터베이스를 잠금 해제합니다 liveSyncSetting: errorNoSuchSettingItem: "해당 설정 항목이 없습니다: ${key}" @@ -255,54 +303,58 @@ Lock the remote server to prevent synchronization with other devices.: 다른 logPane: autoScroll: 자동 스크롤 logWindowOpened: 로그 창이 열렸습니다 - pause: 일시 중단 + pause: 일시 정지 title: Self-hosted LiveSync 로그 wrap: 줄 바꿈 Maximum delay for batch database updating: 일괄 데이터베이스 업데이트 최대 지연 Maximum file size: 최대 파일 크기 -Maximum Incubating Chunk Size: 임시 보관 변경 기록의 최대 크기 -Maximum Incubating Chunks: 임시 보관 중인 변경 기록 최대 수 -Maximum Incubation Period: 변경 기록 임시 보관 최대 시간 +Maximum Incubating Chunk Size: 임시 보관 청크의 최대 크기 +Maximum Incubating Chunks: 임시 보관 청크의 최대 개수 +Maximum Incubation Period: 청크 임시 보관 최대 기간 MB (0 to disable).: MB (0으로 설정하면 비활성화). Memory cache: 메모리 캐시 Memory cache size (by total characters): 메모리 캐시 크기 (총 문자 수) Memory cache size (by total items): 메모리 캐시 크기 (총 항목 수) Merge: 병합 Minimum delay for batch database updating: 일괄 데이터베이스 업데이트 최소 지연 +Minimum interval for syncing: 동기화 최소 간격 moduleCheckRemoteSize: logCheckingStorageSizes: 스토리지 크기 확인 중 logCurrentStorageSize: "원격 스토리지 크기: ${measuredSize}" - logExceededWarning: "원격 스토리지 크기: ${measuredSize}가 ${notifySize}를 초과했습니다" + logExceededWarning: "원격 스토리지 크기: ${measuredSize}이(가) ${notifySize}을(를) 초과했습니다" logThresholdEnlarged: 임계값이 ${size}MB로 증가되었습니다 msgConfirmRebuild: 시간이 꽤 오래 걸릴 수 있습니다. 정말 지금 모든 것을 재구축하시겠습니까? - msgDatabaseGrowing: |- - **데이터베이스 용량이 점점 커지고 있습니다!** 하지만 걱정하지 마세요. 아직 원격 스토리지 공간이 완전히 부족해진 건 아닙니다. + msgDatabaseGrowing: | + **데이터베이스 용량이 점점 커지고 있습니다!** 하지만 걱정하지 마세요. 지금 대응할 수 있습니다. 원격 스토리지 공간이 부족해지기까지 남은 시간입니다. | 측정된 크기 | 설정된 한도 | | --- | --- | | ${estimatedSize} | ${maxSize} | > [!MORE]- - > 오랜 기간 사용했다면 참조되지 않는 청크, 즉 '쓰레기 데이터'가 쌓였을 수 있습니다. 이 경우 전체 재구성을 권장합니다. 용량이 훨씬 줄어들 수 있습니다. + > 오랜 기간 사용했다면 참조되지 않는 청크, 즉 쓰레기 데이터가 데이터베이스에 쌓였을 수 있습니다. 이 경우 전체 재구축을 권장합니다. 용량이 훨씬 줄어들 것입니다. > - > 단순히 볼트 자체 용량이 커지고 있는 것이라면, 먼저 파일을 정리한 후 전체를 재구성하는 것이 좋습니다. Self-hosted LiveSync는 처리 속도를 위해 삭제해도 실제 데이터를 바로 지우지 않습니다. 이 내용은 [기술 문서](https://github.com/vrtmrz/obsidian-livesync/blob/main/docs/tech_info.md)에 간략히 정리되어 있습니다. + > 단순히 보관함 용량이 커지고 있는 것이라면, 파일을 정리한 뒤에 전체를 재구축하는 것이 좋습니다. Self-hosted LiveSync는 처리 속도를 위해 파일을 삭제해도 실제 데이터를 바로 지우지 않습니다. 이 내용은 [기술 문서](https://github.com/vrtmrz/obsidian-livesync/blob/main/docs/tech_info.md)에 간략히 정리되어 있습니다. + > + > 용량 증가가 괜찮다면 알림 한도를 100MB 단위로 높일 수 있습니다. 직접 서버를 운영하는 경우에 적합한 방법입니다. 다만 가끔은 전체를 재구축해 주는 것이 좋습니다. > - > 용량 증가가 괜찮다면 알림 임계치를 100MB 단위로 높일 수 있습니다. 직접 서버를 운영하는 경우에 적합한 방법입니다. 다만, 가끔은 전체 재구성을 해주는 것이 바람직합니다. > [!WARNING] - > 전체 재구성을 실행할 경우, 모든 기기가 반드시 동기화되어 있어야 합니다. 플러그인이 최대한 병합하려고 시도하긴 하지만 완전하지 않을 수 있습니다. + > 전체 재구축을 실행할 때는 모든 기기가 동기화되어 있는지 확인해 주세요. 플러그인이 최대한 병합하려고 시도하기는 합니다. msgSetDBCapacity: | **원격 스토리지 공간이 부족해지기 전에 미리 조치할 수 있도록** 데이터베이스 용량 경고를 설정할 수 있습니다. 이 기능을 활성화하시겠습니까? > [!MORE]- - > - 0: 스토리지 용량에 대한 경고 없음 - > 자체 서버를 사용하는 등 여유 공간이 충분한 경우에 권장됩니다. 스토리지 용량을 직접 확인하고 수동으로 재구성할 수 있습니다. - > - 800: 원격 스토리지 용량이 800MB를 초과하면 경고 - > 1GB 제한이 있는 fly.io나 IBM Cloudant 사용 시 권장됩니다. - > - 2000: 원격 스토리지 용량이 2GB를 초과하면 경고 + > - 0: 스토리지 용량을 경고하지 않습니다. + > 직접 서버를 운영하는 등 원격 스토리지에 여유 공간이 충분한 경우에 권장합니다. 스토리지 용량을 직접 확인하고 수동으로 재구축할 수 있습니다. + > - 800: 원격 스토리지 용량이 800MB를 초과하면 경고합니다. + > 1GB 제한이 있는 fly.io나 IBM Cloudant를 사용하는 경우에 권장합니다. + > - 2000: 원격 스토리지 용량이 2GB를 초과하면 경고합니다. - 설정한 용량 한도에 도달하면, 단계적으로 경고 한도를 늘릴지 여부를 묻게 됩니다. + 한도에 도달하면 한도를 단계적으로 늘릴지 여쭤보겠습니다. + noticeExceeded: 원격 스토리지 크기 ${measuredSize}이(가) 설정된 알림 임계값 ${notifySize}을(를) 초과했습니다. {HERE} + noticeNotConfigured: 원격 스토리지 크기 알림이 설정되어 있지 않습니다. {HERE} option2GB: 2GB (표준) option800MB: 800MB (Cloudant, fly.io) optionAskMeLater: 나중에 물어보기 @@ -310,6 +362,7 @@ moduleCheckRemoteSize: optionIncreaseLimit: ${newMax}MB로 증가 optionNoWarn: 아니요, 경고하지 마세요 optionRebuildAll: 지금 모든 것 재구축 + optionReview: 옵션 검토 titleDatabaseSizeLimitExceeded: 원격 스토리지 크기가 제한을 초과했습니다 titleDatabaseSizeNotify: 데이터베이스 크기 알림 설정 moduleInputUIObsidian: @@ -326,100 +379,116 @@ moduleLiveSyncMain: logSafetyScanCompleted: 추가 안전 검사가 완료되었습니다 logSafetyScanFailed: 모듈에서 추가 안전 검사가 실패했습니다 logUnloadingPlugin: 플러그인 언로딩 중... - logVersionUpdate: LiveSync가 업데이트되었습니다. 호환성 문제가 있는 업데이트의 경우 모든 자동 동기화가 일시적으로 - 비활성화되었습니다. 활성화하기 전에 모든 기기가 최신 상태인지 확인하세요. - msgScramEnabled: >- + logVersionUpdate: LiveSync가 업데이트되었습니다. 호환성 문제가 있는 업데이트의 경우 모든 자동 동기화가 일시적으로 비활성화되었습니다. 활성화하기 전에 모든 기기가 최신 상태인지 확인하세요. + msgScramEnabled: | Self-hosted LiveSync가 일부 이벤트를 무시하도록 설정되어 있습니다. 이 설정이 맞습니까? - | 유형 | 상태 | 설명 | - |:---:|:---:|---| - | 스토리지 이벤트 | ${fileWatchingStatus} | 모든 수정 사항이 무시됩니다 | - | 데이터베이스 이벤트 | ${parseReplicationStatus} | 모든 동기화 변경이 지연됩니다 | - 이벤트 감지를 다시 활성화하고 Obsidian을 재시작하시겠습니까? - > [!DETAILS]- - - > 이러한 설정은 플러그인이 재구성 또는 데이터 가져오기 중에 자동으로 설정한 것입니다. 프로세스가 비정상적으로 종료되면 이 상태가 - 의도치 않게 유지될 수 있습니다. - - > 상태가 확실하지 않다면 이 과정을 다시 실행해 보세요. 재시작 전에 반드시 볼트를 백업해 주세요. + > 이 플래그는 플러그인이 재구축하거나 가져오는 동안 설정한 것입니다. 처리가 비정상적으로 종료되면 의도치 않게 남아 있을 수 있습니다. + > 확실하지 않다면 해당 처리를 다시 실행해 보세요. 반드시 보관함을 백업해 두시기 바랍니다. optionKeepLiveSyncDisabled: LiveSync 비활성화 유지 optionResumeAndRestart: 재개 후 Obsidian 재시작 - titleScramEnabled: Scram 활성화됨 + titleScramEnabled: 긴급 정지 활성화됨 moduleLocalDatabase: logWaitingForReady: 준비 대기 중... moduleLog: showLog: 로그 표시 moduleMigration: docUri: https://github.com/vrtmrz/obsidian-livesync/blob/main/README.md#how-to-use + fix0256: + buttons: + checkItLater: 나중에 확인 + DismissForever: 이미 해결했으니 다시 묻지 않기 + fix: 수정 + message: | + 최근 버그(v0.25.6)로 인해 일부 파일이 동기화 데이터베이스에 올바르게 저장되지 않았을 수 있습니다. + 파일을 검사한 결과 수정이 필요한 파일을 발견했습니다. + + **수정할 수 있는 파일:** + + ${files} + + 이 파일들은 스토리지에 크기가 일치하는 원본이 있어 복구할 수 있을 것으로 보입니다. + 이를 이용해 데이터베이스를 고칠 수 있으니, 아래 "수정" 버튼을 눌러 주세요. + + ${messageUnrecoverable} + + 다시 실행하려면 Hatch에서 실행할 수 있습니다. + messageUnrecoverable: | + **이 기기에서는 수정할 수 없는 파일:** + + ${filesNotRecoverable} + + 이 파일들은 메타데이터가 일치하지 않아 이 기기에서는 수정할 수 없습니다(대부분 어느 쪽이 올바른지 판단할 수 없습니다). + 복원하려면 다른 기기에서 이 기능으로 확인해 보시거나, 백업에서 직접 복원해 주세요. + title: 손상된 파일이 감지되었습니다 + insecureChunkExist: + buttons: + fetch: 원격을 이미 재구축했습니다. 원격에서 가져오기 + later: 나중에 하기 + rebuild: 모두 재구축 + laterMessage: 가능한 한 빨리 조치하시기를 강력히 권장합니다! + message: | + 일부 청크가 데이터베이스에 안전하게 저장되지 않았으며 암호화되어 있지 않습니다. + **이 문제를 해결하려면 데이터베이스를 재구축해 주세요.** + + 원격 데이터베이스에 SSL이 설정되어 있지 않거나 보안이 취약한 자격 증명을 사용하고 있다면, **민감한 데이터가 노출될 위험이 있습니다.** + + 참고: 모든 기기의 Self-hosted LiveSync를 v0.25.6 이상으로 업그레이드하고, 보관함을 반드시 백업해 주세요. + 참고 2: 모두 재구축과 가져오기는 시간과 트래픽을 다소 소모하므로, 사용량이 적은 시간대에 안정적인 네트워크 환경에서 진행해 주세요. + title: 안전하지 않은 청크가 발견되었습니다! logBulkSendCorrupted: 청크 일괄 전송이 활성화되었지만, 이 기능에 문제가 있었습니다. 불편을 드려 죄송합니다. 자동으로 비활성화되었습니다. logFetchRemoteTweakFailed: 원격 조정 값을 가져오는데 실패했습니다 logLocalDatabaseNotReady: 문제가 발생했습니다! 로컬 데이터베이스가 준비되지 않았습니다 - logMigratedSameBehaviour: 이전과 같은 방식으로 동작하도록 db:${current}로 데이터 구조 전환이 완료되었습니다 + logMigratedSameBehaviour: 이전과 동일하게 동작하도록 db:${current}(으)로 마이그레이션했습니다 logMigrationFailed: ${old}에서 ${current}로의 데이터 구조 전환이 실패했거나 중단되었습니다 logRedflag2CreationFail: redflag2 생성에 실패했습니다 logRemoteTweakUnavailable: 원격 조정 값을 가져올 수 없습니다 logSetupCancelled: 설정이 취소되었습니다. Self-hosted LiveSync가 설정을 기다리고 있습니다! - msgFetchRemoteAgain: >- + msgFetchRemoteAgain: |- 이미 알고 계시겠지만, Self-hosted LiveSync의 기본 동작 방식과 데이터베이스 구조가 변경되었습니다. - 다행히도 여러분의 노력 덕분에 원격 데이터베이스는 이미 성공적으로 데이터 구조 전환이 완료된 것으로 보입니다. 축하드립니다! - - 하지만 아직 일부 추가 작업이 필요합니다. 이 기기의 설정이 원격 데이터베이스와 호환되지 않으므로, 원격 데이터를 다시 가져와야 합니다. - 지금 원격 데이터베이스를 다시 가져오시겠습니까? - + 하지만 아직 일부 추가 작업이 필요합니다. 이 기기의 설정이 원격 데이터베이스와 호환되지 않으므로, 원격 데이터를 다시 가져와야 합니다. 지금 원격 데이터베이스를 다시 가져오시겠습니까? ___참고: 설정이 변경되고 데이터베이스를 다시 불러오기 전까지는 동기화가 불가능합니다.___ - ___참고2: 청크는 변경이 불가능한 구조이므로, 메타데이터와 차이점만 가져올 수 있습니다.___ - msgInitialSetup: >- + msgInitialSetup: |- 이 기기는 **아직 초기 설정이 완료되지 않았습니다**. 지금부터 설정 과정을 안내해 드리겠습니다. - - 모든 대화 내용은 클립보드에 복사할 수 있습니다. 나중에 참고하려면 Obsidian 노트에 붙여넣거나 번역 도구를 활용해 번역하셔도 - 됩니다. - + 모든 대화 내용은 클립보드에 복사할 수 있습니다. 나중에 참고하려면 Obsidian 노트에 붙여넣거나 번역 도구를 활용해 번역하셔도 됩니다. 먼저, **Setup URI**를 가지고 계신가요? - 참고: Setup URI가 무엇인지 잘 모르시겠다면 [문서](${URI_DOC})를 참고해 주세요. msgRecommendSetupUri: |- Setup URI를 생성해 사용하는 것을 강력히 권장합니다. Setup URI가 무엇인지 잘 모르시겠다면 [문서](${URI_DOC})를 참고해 주세요. 중요한 내용이니 꼭 확인하시기 바랍니다. 직접 수동 설정을 진행하시겠습니까? - msgSinceV02321: >- - v0.23.21부터 Self-hosted LiveSync의 기본 동작 방식과 데이터베이스 구조가 변경되었습니다. 주요 변경사항은 다음과 - 같습니다: + msgSinceV02321: |- + v0.23.21부터 Self-hosted LiveSync의 기본 동작 방식과 데이터베이스 구조가 변경되었습니다. 변경 내용은 다음과 같습니다: + 1. **파일명의 대소문자 구분** + 이제 파일명을 대소문자 구분 없이 처리합니다. 파일명의 대소문자를 제대로 관리하지 못하는 Linux와 iOS를 제외한 대부분의 플랫폼에서 유리한 변경입니다. + (해당 플랫폼에서는 이름이 같고 대소문자만 다른 파일에 대해 경고가 표시됩니다) - 1. **파일명 대소문자 구분 처리** - 이제 파일명은 대소문자를 구분하지 않고 처리됩니다. 이는 파일명 구분을 제대로 지원하지 않는 Linux 및 iOS를 제외한 대부분의 플랫폼에서 유리한 변화입니다. - (Linux나 iOS에서는 대소문자만 다른 파일이 존재할 경우 경고가 표시됩니다) + 2. **청크의 리비전 처리** + 청크는 변경 불가능하므로 리비전을 고정할 수 있습니다. 이 변경으로 파일 저장 성능이 향상됩니다. - 2. **청크 리비전 관리 방식 개선** - 청크는 변경 불가능한(immutable) 구조로 고정되며, 이를 통해 리비전 처리가 안정화되고 파일 저장 성능이 향상됩니다. + ___다만 이 변경 중 어느 하나라도 적용하려면 원격과 로컬 데이터베이스를 모두 재구축해야 합니다. 이 과정은 몇 분이 걸리므로 시간이 충분할 때 진행하시기를 권장합니다.___ - ___단, 위 기능을 활성화하려면 원격 및 로컬 데이터베이스를 모두 재구성해야 합니다. 이 과정은 수 분이 소요되므로 여유가 있을 때 - 실행하시는 것을 권장합니다.___ - - - - 기존 방식대로 유지하려면 `${KEEP}`을 선택해 이 과정을 건너뛸 수 있습니다. - - - 시간이 부족하다면 `${DISMISS}`를 눌러주시면 나중에 다시 안내드리겠습니다. - - - 이미 다른 기기에서 데이터베이스를 재구성하셨다면 `${DISMISS}`를 선택한 뒤 다시 동기화해 보세요. 차이점이 감지되면 다시 - 안내드리겠습니다. + - 기존 동작을 유지하려면 `${KEEP}`을 선택해 이 과정을 건너뛸 수 있습니다. + - 시간이 충분하지 않다면 `${DISMISS}`를 선택해 주세요. 나중에 다시 여쭤보겠습니다. + - 다른 기기에서 이미 데이터베이스를 재구축했다면 `${DISMISS}`를 선택한 뒤 다시 동기화해 보세요. 차이가 감지되면 다시 안내해 드립니다. optionAdjustRemote: 원격에 맞추기 optionDecideLater: 나중에 결정하기 optionEnableBoth: 둘 다 활성화 @@ -443,7 +512,11 @@ More actions: 추가 작업 Move remotely deleted files to the trash, instead of deleting.: 원격에서 삭제된 파일을 삭제하는 대신 휴지통으로 이동합니다. Network warning style: 네트워크 경고 표시 방식 New Remote: 새 원격 +No connected device information found. Cancelling Garbage Collection.: 연결된 기기 정보를 찾을 수 없습니다. 가비지 컬렉션을 취소합니다. No limit configured: 제한이 설정되지 않음 +No, please take me back: 아니요, 이전으로 돌아가겠습니다 +Node ID: 노드 ID +Node Information Missing: 노드 정보 누락 Non-Synchronising files: 동기화하지 않는 파일 Normal Files: 일반 파일 Not all messages have been translated. And, please revert to "Default" when reporting errors.: 모든 메시지가 번역되지 않았습니다. 오류 신고 시 "기본값"으로 되돌려 주세요. @@ -451,14 +524,15 @@ Notify all setting files: 모든 설정 파일 알림 Notify customized: 사용자 설정 알림 Notify when other device has newly customized.: 다른 기기에서 새로운 사용자 설정이 있을 때 알림을 받습니다. Notify when the estimated remote storage size exceeds on start up: 시작 시 예상 원격 스토리지 크기가 초과되면 알림 -Number of batches to process at a time. Defaults to 40. Minimum is 2. This along with batch size controls how many docs are kept in memory at a time.: 한 번에 처리할 일괄 처리 수입니다. 기본값은 40입니다. 최소값은 2입니다. 이는 일괄 크기와 함께 메모리에 보관되는 문서 수를 제어합니다. +Number of batches to process at a time. Defaults to 40. Minimum is 2. This along with batch size controls how many docs are kept in memory at a time.: 한 번에 처리할 배치 개수입니다. 기본값은 40이고 최소값은 2입니다. 배치 크기와 함께 한 번에 메모리에 보관되는 문서 수를 결정합니다. Number of changes to sync at a time. Defaults to 50. Minimum is 2.: 한 번에 동기화할 변경 사항의 수입니다. 기본값은 50입니다. 최소값은 2입니다. +Obsidian version: Obsidian 버전 obsidianLiveSyncSettingTab: btnApply: 적용 btnCheck: 확인 btnCopy: 복사 btnDisable: 비활성화 - btnDiscard: 삭제 + btnDiscard: 폐기 btnEnable: 활성화 btnFix: 수정 btnGotItAndUpdated: 알겠습니다. 업데이트했습니다. @@ -482,6 +556,7 @@ obsidianLiveSyncSettingTab: errCorsNotAllowingCredentials: ❗ CORS에서 자격 증명을 허용하지 않습니다 errCorsOrigins: ❗ cors.origins가 잘못되었습니다 errEnableCors: ❗ httpd.enable_cors가 잘못되었습니다 + errEnableCorsChttpd: ❗ chttpd.enable_cors가 잘못되었습니다 errMaxDocumentSize: ❗ couchdb.max_document_size가 낮습니다) errMaxRequestSize: ❗ chttpd.max_http_request_size가 낮습니다) errMissingWwwAuth: ❗ httpd.WWW-Authenticate가 누락되었습니다 @@ -507,7 +582,7 @@ obsidianLiveSyncSettingTab: logConfiguredLiveSync: "구성된 동기화 모드: LiveSync" logConfiguredPeriodic: "구성된 동기화 모드: 주기적" logCouchDbConfigFail: "CouchDB 구성: ${title} 실패" - logCouchDbConfigSet: "CouchDB 구성: ${title} -> ${key}를 ${value}로 설정" + logCouchDbConfigSet: "CouchDB 구성: ${title} -> ${key}을(를) ${value}(으)로 설정" logCouchDbConfigUpdated: "CouchDB 구성: ${title} 성공적으로 업데이트됨" logDatabaseConnected: 데이터베이스 연결됨 logEncryptionNoPassphrase: 패스프레이즈 없이는 암호화를 활성화할 수 없습니다 @@ -518,38 +593,39 @@ obsidianLiveSyncSettingTab: logPassphraseNotCompatible: "오류: 패스프레이즈가 원격 서버와 호환되지 않습니다! 다시 확인해 주세요!" logRebuildNote: 동기화가 비활성화되었습니다. 원하는 경우 가져오기 후 다시 활성화하세요. logSelectAnyPreset: 프리셋을 선택하세요. + logServerConfigurationCheck: --서버 구성 확인-- msgAreYouSureProceed: 정말로 진행하시겠습니까? msgChangesNeedToBeApplied: 변경사항을 적용해야 합니다! msgConfigCheck: --구성 확인-- msgConfigCheckFailed: 구성 확인에 실패했습니다. 그래도 계속하시겠습니까? msgConnectionCheck: --연결 확인-- msgConnectionProxyNote: 구성 확인 후에도 연결 확인에 문제가 있는 경우, 리버스 프록시 구성을 확인해 주세요. - msgCurrentOrigin: "현재 원점: {origin}" + msgCurrentOrigin: "현재 출처: ${origin}" msgDiscardConfirmation: 정말로 기존 설정과 데이터베이스를 삭제하시겠습니까? msgDone: --완료-- msgEnableCors: httpd.enable_cors 설정 - msgEnableEncryptionRecommendation: 종단간 암호화와 경로 난독화를 활성화하는 것을 권장합니다. 정말로 암호화 없이 계속하시겠습니까? + msgEnableCorsChttpd: chttpd.enable_cors 설정 + msgEnableEncryptionRecommendation: 종단 간 암호화와 경로 난독화를 활성화하는 것을 권장합니다. 정말로 암호화 없이 계속하시겠습니까? msgFetchConfigFromRemote: 원격 서버에서 구성을 가져오시겠습니까? msgGenerateSetupURI: 모든 작업이 완료되었습니다! 다른 기기를 설정하기 위해 Setup URI를 생성하시겠습니까? - msgIfConfigNotPersistent: "서버 설정이 영구적으로 저장되지 않는 환경(예: Docker에서 실행 중)에서는 이곳의 값들이 - 변경될 수 있습니다. 연결이 가능해지면 서버의 local.ini 파일에서 설정을 수동으로 업데이트해 주세요." + msgIfConfigNotPersistent: "서버 설정이 영구적으로 저장되지 않는 환경(예: Docker에서 실행 중)에서는 이곳의 값들이 변경될 수 있습니다. 연결이 가능해지면 서버의 local.ini 파일에서 설정을 수동으로 업데이트해 주세요." msgInvalidPassphrase: 암호화 패스프레이즈가 유효하지 않을 수 있습니다. 정말로 계속하시겠습니까? msgNewVersionNote: 업그레이드 알림으로 여기에 오셨나요? 버전 기록을 검토해 주세요. 만족하신다면 버튼을 클릭하세요. 새로운 업데이트 시 다시 안내됩니다. msgNonHTTPSInfo: 비 HTTPS URI로 구성되었습니다. 모바일 기기에서는 작동하지 않을 수 있으니 주의하세요. msgNonHTTPSWarning: 비 HTTPS URI에 연결할 수 없습니다. 구성을 업데이트하고 다시 시도해 주세요. msgNotice: ---공지사항--- msgObjectStorageWarning: |- - ⚠️ 주의: 이 기능은 아직 개발 중(WIP)입니다. 다음 사항을 유의해 주세요: - - 추가 전용 구조(append-only)로 동작합니다. 저장 용량을 줄이려면 데이터 재구성이 필요합니다. - - 기능이 다소 불안정할 수 있습니다. - - 최초 동기화 시, 전체 히스토리가 원격 서버에서 전송됩니다. 데이터 용량 제한 및 느린 속도에 유의해 주세요. - - 실시간 동기화는 변경된 부분만 처리됩니다. + 경고: 이 기능은 아직 개발 중이므로 다음 사항을 유의해 주세요: + - 추가 전용 구조로 동작합니다. 저장 용량을 줄이려면 재구축이 필요합니다. + - 다소 불안정합니다. + - 최초 동기화 시 모든 기록이 원격에서 전송됩니다. 데이터 사용량 제한과 느린 속도에 유의해 주세요. + - 실시간 동기화는 변경분만 처리합니다. - 문제가 발생했거나 개선 아이디어가 있으시면 GitHub에 이슈를 등록해 주세요. - 기여에 깊이 감사드립니다. - msgOriginCheck: "원점 확인: {org}" + 문제가 발생했거나 이 기능에 대한 아이디어가 있다면 GitHub에 이슈를 등록해 주세요. + 큰 관심에 깊이 감사드립니다. + msgOriginCheck: "출처 확인: ${org}" msgRebuildRequired: |- - 변경사항을 적용하려면 데이터베이스를 재구축해야 합니다. 아래 중 한 가지 방법을 선택해 주세요. + 변경 사항을 적용하려면 데이터베이스를 재구축해야 합니다. 변경 사항을 적용할 방법을 선택해 주세요.
범례 @@ -557,24 +633,22 @@ obsidianLiveSyncSettingTab: | 기호 | 의미 | |: ------ :| ------- | | ⇔ | 최신 상태 | - | ⇄ | 동기화 균형 유지 | - | ⇐,⇒ | 덮어쓰기 방식의 전송 | - | ⇠,⇢ | 상대편에서 가져와 덮어쓰기 | + | ⇄ | 양쪽을 맞추는 동기화 | + | ⇐,⇒ | 덮어쓰기 전송 | + | ⇠,⇢ | 반대편에서 덮어쓰기 전송 |
## ${OPTION_REBUILD_BOTH} - 개요: 📄 ⇒¹ 💻 ⇒² 🛰️ ⇢ⁿ 💻 ⇄ⁿ⁺¹ 📄 - 이 기기의 기존 파일을 기반으로 로컬과 원격 데이터베이스를 모두 재구축합니다. - 이 과정에서 다른 기기는 일시적으로 접근이 제한되며, 가져오기 작업을 별도로 수행해야 합니다. - + 한눈에 보기: 📄 ⇒¹ 💻 ⇒² 🛰️ ⇢ⁿ 💻 ⇄ⁿ⁺¹ 📄 + 이 기기의 기존 파일을 사용해 로컬과 원격 데이터베이스를 모두 재구축합니다. + 이 경우 다른 기기는 잠기며, 가져오기를 수행해야 합니다. ## ${OPTION_FETCH} - 개요: 📄 ⇄² 💻 ⇐¹ 🛰️ ⇔ 💻 ⇔ 📄 - 로컬 데이터베이스를 초기화한 후, 원격 데이터베이스에서 데이터를 가져와 재구축합니다. - 이는 원격 측에서 데이터베이스를 먼저 재구축한 경우에도 해당됩니다. - + 한눈에 보기: 📄 ⇄² 💻 ⇐¹ 🛰️ ⇔ 💻 ⇔ 📄 + 로컬 데이터베이스를 초기화한 뒤, 원격 데이터베이스에서 가져온 데이터로 재구축합니다. + 원격 데이터베이스를 이미 재구축한 경우도 여기에 해당합니다. ## ${OPTION_ONLY_SETTING} - 설정만 저장합니다. **⚠️ 주의: 이 방법은 데이터 손상을 일으킬 수 있습니다.** 일반적으로는 전체 데이터베이스 재구축이 필요합니다. + 설정만 저장합니다. **주의: 데이터가 손상될 수 있습니다.** 일반적으로는 데이터베이스 재구축이 필요합니다. msgSelectAndApplyPreset: 마법사를 완료하려면 프리셋 항목을 선택하고 적용해 주세요. msgSetCorsCredentials: cors.credentials 설정 msgSetCorsOrigins: cors.origins 설정 @@ -582,8 +656,7 @@ obsidianLiveSyncSettingTab: msgSetMaxRequestSize: chttpd.max_http_request_size 설정 msgSetRequireValidUser: chttpd.require_valid_user = true로 설정 msgSetRequireValidUserAuth: chttpd_auth.require_valid_user = true로 설정 - msgSettingModified: '"${setting}" 설정이 다른 기기에서 수정되었습니다. 설정을 다시 로드하려면 {HERE}를 - 클릭하세요. 변경사항을 무시하려면 다른 곳을 클릭하세요.' + msgSettingModified: '"${setting}" 설정이 다른 기기에서 수정되었습니다. 설정을 다시 로드하려면 {HERE}를 클릭하세요. 변경사항을 무시하려면 다른 곳을 클릭하세요.' msgSettingsUnchangeableDuringSync: 동기화 중에는 이 설정들을 변경할 수 없습니다. 잠금을 해제하려면 "동기화 설정"에서 모든 동기화를 비활성화해 주세요. msgSetWwwAuth: httpd.WWW-Authenticate 설정 nameApplySettings: 설정 적용 @@ -601,9 +674,10 @@ obsidianLiveSyncSettingTab: okAdminPrivileges: ✔ 관리자 권한이 있습니다. okCorsCredentials: ✔ cors.credentials가 정상입니다. okCorsCredentialsForOrigin: CORS 자격 증명 정상 - okCorsOriginMatched: ✔ CORS 원점 정상 + okCorsOriginMatched: ✔ CORS 출처 정상 okCorsOrigins: ✔ cors.origins가 정상입니다. okEnableCors: ✔ httpd.enable_cors가 정상입니다. + okEnableCorsChttpd: ✔ chttpd.enable_cors가 정상입니다. okMaxDocumentSize: ✔ couchdb.max_document_size가 정상입니다. okMaxRequestSize: ✔ chttpd.max_http_request_size가 정상입니다. okRequireValidUser: ✔ chttpd.require_valid_user가 정상입니다. @@ -615,8 +689,8 @@ obsidianLiveSyncSettingTab: optionDisableAllAutomatic: 모든 자동 비활성화 optionFetchFromRemote: 원격에서 가져오기 optionHere: 여기 - optionLiveSync: LiveSync 동기화 - optionMinioS3R2: Minio,S3,R2 + optionLiveSync: LiveSync + optionMinioS3R2: MinIO, S3, R2 optionOkReadEverything: 네, 모든 것을 읽었습니다. optionOnEvents: 이벤트 시 optionPeriodicAndEvents: 주기적 및 이벤트 시 @@ -628,10 +702,12 @@ obsidianLiveSyncSettingTab: panelPrivacyEncryption: 개인정보 보호 및 암호화 panelRemoteConfiguration: 원격 구성 panelSetup: 설정 - titleAppearance: 외관 + serverVersion: "서버 정보: ${info}" + titleActiveRemoteServer: 활성 원격 서버 + titleAppearance: 모양 titleConflictResolution: 충돌 해결 titleCongratulations: 축하합니다! - titleCouchDB: CouchDB 서버 + titleCouchDB: CouchDB titleDeletionPropagation: 삭제 전파 titleEncryptionNotEnabled: 암호화가 활성화되지 않음 titleEncryptionPassphraseInvalid: 암호화 패스프레이즈 유효하지 않음 @@ -648,14 +724,14 @@ obsidianLiveSyncSettingTab: titleRebuildRequired: 재구축 필요 titleRemoteConfigCheckFailed: 원격 구성 확인 실패 titleRemoteServer: 원격 서버 - titleReset: 리셋 + titleReset: 재설정 titleSetupOtherDevices: 다른 기기 설정 titleSynchronizationMethod: 동기화 방법 titleSynchronizationPreset: 동기화 프리셋 titleSyncSettings: 동기화 설정 - titleSyncSettingsViaMarkdown: 마크다운을 통한 동기화 설정 + titleSyncSettingsViaMarkdown: 마크다운을 통한 설정 동기화 titleUpdateThinning: 업데이트 솎아내기 - warnCorsOriginUnmatched: ⚠ CORS 원점이 일치하지 않습니다 {from}->{to} + warnCorsOriginUnmatched: ⚠ CORS 출처가 일치하지 않습니다 ${from}->${to} warnNoAdmin: ⚠ 관리자 권한이 없습니다. Ok: 확인 Old Algorithm: 이전 알고리즘 @@ -665,36 +741,26 @@ Open the dialog: 대화상자 열기 Overwrite: 덮어쓰기 Overwrite patterns: 덮어쓰기 패턴 Overwrite remote: 원격 덮어쓰기 -Overwrite remote with local DB and passphrase.: 로컬 DB와 암호문구로 원격을 덮어씁니다. +Overwrite remote with local DB and passphrase.: 로컬 DB와 패스프레이즈로 원격을 덮어씁니다. Overwrite Server Data with This Device's Files: 이 기기의 파일로 서버 데이터를 덮어쓰기 P2P: AskPassphraseForDecrypt: 원격 피어가 구성을 공유했습니다. 구성을 복호화하려면 패스프레이즈를 입력해 주세요. - AskPassphraseForShare: 원격 피어가 이 기기의 구성을 요청했습니다. 구성을 공유하려면 패스프레이즈를 입력해 주세요. 이 - 대화상자를 취소하여 요청을 무시할 수 있습니다. + AskPassphraseForShare: 원격 피어가 이 기기의 구성을 요청했습니다. 구성을 공유하려면 패스프레이즈를 입력해 주세요. 이 대화상자를 취소하여 요청을 무시할 수 있습니다. DisabledButNeed: "%{title_p2p_sync}가 비활성화되어 있습니다. 정말로 활성화하시겠습니까?" FailedToOpen: 시그널링 서버에 P2P 연결을 열 수 없습니다. NoAutoSyncPeers: 자동 동기화 피어를 찾을 수 없습니다. %{long_p2p_sync} 창에서 피어를 설정해 주세요. NoKnownPeers: 피어가 감지되지 않았습니다. 다른 피어의 접속을 기다리고 있습니다... Note: - description: >- - 이 복제기는 피어 투 피어(P2P) 연결을 통해 다른 기기들과 볼트를 동기화할 수 있도록 합니다. 클라우드 서비스를 거치지 않고도 - 기기간 동기화를 구현할 수 있습니다. + description: |2- + 이 복제기는 피어 투 피어 연결을 이용해 다른 기기와 보관함을 동기화할 수 있게 해 줍니다. + 클라우드 서비스를 사용하지 않고도 다른 기기와 보관함을 동기화할 수 있습니다. + 이 복제기는 Trystero를 기반으로 합니다. 기기 간 연결을 맺기 위해 시그널링 서버도 사용합니다. 시그널링 서버는 기기 사이의 연결 정보를 교환하는 데 쓰이며, 사용자의 데이터는 알지도 저장하지도 않습니다(또는 그래야 합니다). + 시그널링 서버는 누구나 운영할 수 있습니다. 단순한 Nostr 릴레이일 뿐입니다. 편의를 위해, 그리고 복제기의 동작을 확인할 수 있도록 vrtmrz가 시그널링 서버 인스턴스를 하나 운영하고 있습니다. vrtmrz가 제공하는 실험용 서버를 사용해도 되고, 다른 서버를 사용해도 됩니다. - 이 복제기는 Trystero를 기반으로 하며, 기기 간 연결을 설정하기 위해 시그널링 서버를 사용합니다. 시그널링 서버는 단순히 연결 - 정보를 교환하는 용도로만 사용되며, 사용자 데이터를 저장하거나 접근하지 않습니다 (또는 그래야만 합니다). - - - 시그널링 서버는 누구나 운영할 수 있으며, 이는 단순한 Nostr 릴레이입니다. 편의성과 복제기의 작동 확인을 위해 `vrtmrz`가 - 자체적으로 시그널링 서버 인스턴스를 운영 중입니다. 사용자는 `vrtmrz`가 제공하는 실험용 서버를 사용할 수도 있고, 별도로 - 자신만의 서버를 설정할 수도 있습니다. - - - 참고로, 시그널링 서버는 사용자 데이터를 저장하지 않더라도 일부 기기의 연결 정보는 볼 수 있습니다. 이 점을 유의해 주세요. 특히 - 타인이 운영하는 서버를 사용할 경우 주의가 필요합니다. - important_note: 피어 투 피어(P2P) 복제기의 실험적 구현입니다. - important_note_sub: 이 기능은 아직 실험 단계에 있습니다. 이 기능이 예상대로 작동하지 않을 수 있음을 알아주세요. 또한 버그, - 보안 문제 및 기타 문제가 있을 수 있습니다. 이 기능을 사용할 때는 본인의 책임 하에 사용하세요. 이 기능의 개발에 기여해 주세요. + 참고로, 시그널링 서버가 데이터를 저장하지 않더라도 일부 기기의 연결 정보는 볼 수 있습니다. 이 점을 유의해 주세요. 또한 다른 사람이 제공하는 서버를 사용할 때는 주의하시기 바랍니다. + important_note: 피어 투 피어 복제기입니다. + important_note_sub: 이 기능은 아직 실험 단계입니다. 사용하기 전에 반드시 데이터를 백업해 주세요. 그리고 이 기능의 개발에 기여해 주신다면 매우 감사하겠습니다. Summary: 이 기능은 무엇인가요? (설명과 참고사항이 적혀있습니다. 한 번 읽어보세요!) NotEnabled: "%{title_p2p_sync}가 활성화되지 않았습니다. 새로운 연결을 열 수 없습니다." P2PReplication: "%{P2P} 복제" @@ -705,19 +771,21 @@ P2P: SyncCompleted: P2P 동기화가 완료되었습니다. SyncStartedWith: ${name}과의 P2P 동기화가 시작되었습니다. paneMaintenance: - markDeviceResolvedAfterBackup: 백업 후 장치를 해결됨으로 표시 - remoteLockedAndDeviceNotAccepted: 원격 데이터베이스가 잠겨 있으며 이 장치는 아직 승인되지 않았습니다. - remoteLockedResolvedDevice: 원격 데이터베이스가 잠겨 있지만 이 장치는 이미 승인되었습니다. + markDeviceResolvedAfterBackup: 백업 후 이 기기를 해결됨으로 표시 + remoteLockedAndDeviceNotAccepted: 원격 데이터베이스가 잠겨 있으며 이 기기는 아직 승인되지 않았습니다. + remoteLockedResolvedDevice: 원격 데이터베이스가 잠겨 있지만 이 기기는 이미 승인되었습니다. unlockDatabaseReady: 데이터베이스 잠금 해제 Passphrase: 패스프레이즈 Passphrase of sensitive configuration items: 민감한 구성 항목의 패스프레이즈 password: 비밀번호 Password: 비밀번호 Paste a connection string: 연결 문자열 붙여넣기 +Paste the Setup URI generated from one of your active devices.: 사용 중인 기기 중 하나에서 생성한 Setup URI를 붙여 넣으세요. Path Obfuscation: 경로 난독화 Patterns to match files for overwriting instead of merging: 병합 대신 덮어쓸 파일을 판별하는 패턴 Patterns to match files for syncing: 동기화할 파일을 판별하는 패턴 -Peer-to-Peer Synchronisation: 피어 투 피어 동기화 +Peer-to-Peer only: Peer-to-Peer 전용 +Peer-to-Peer Synchronisation: 피어 투 피어(P2P) 동기화 Per-file-saved customization sync: 파일별 저장 사용자 설정 동기화 Perform: 실행 Perform cleanup: 정리 실행 @@ -725,77 +793,81 @@ Perform Garbage Collection: 가비지 컬렉션 실행 Perform Garbage Collection to remove unused chunks and reduce database size.: 사용하지 않는 청크를 제거하고 데이터베이스 크기를 줄이기 위해 가비지 컬렉션을 실행합니다. Periodic Sync interval: 주기적 동기화 간격 Pick a file to resolve conflict: 충돌을 해결할 파일 선택 -Please set device name to identify this device. This name should be unique among your devices. While not configured, we cannot enable this feature.: 이 장치를 식별할 장치 이름을 설정해 주세요. 이 이름은 장치 간에 고유해야 합니다. 설정되기 전까지는 이 기능을 활성화할 수 없습니다. -Please set this device name: 이 장치 이름을 설정해 주세요 +Pick a file to show history: 기록을 표시할 파일 선택 +Please disable 'Read chunks online' in settings to use Garbage Collection.: 가비지 컬렉션을 사용하려면 설정에서 'Read chunks online'을 비활성화해 주세요. +Please enable 'Compute revisions for chunks' in settings to use Garbage Collection.: 가비지 컬렉션을 사용하려면 설정에서 'Compute revisions for chunks'를 활성화해 주세요. +Please select 'Cancel' explicitly to cancel this operation.: 이 작업을 취소하려면 반드시 "취소"를 명시적으로 선택해 주세요. +Please select a method to import the settings from another device.: 다른 기기에서 설정을 가져올 방법을 선택해 주세요. +Please select an option to proceed: 계속하려면 항목을 선택해 주세요 +Please select the type of server to which you are connecting.: 연결할 서버 유형을 선택해 주세요. +Please set device name to identify this device. This name should be unique among your devices. While not configured, we cannot enable this feature.: 이 기기를 식별할 기기 이름을 설정해 주세요. 이 이름은 기기 간에 고유해야 합니다. 설정하기 전까지는 이 기능을 활성화할 수 없습니다. +Please set this device name: 이 기기의 이름을 설정해 주세요 +Plug-in version: 플러그인 버전 +Prepare the 'report' to create an issue: 이슈 생성을 위한 '보고서' 준비 Presets: 프리셋 +Proceed Garbage Collection: 가비지 컬렉션 계속 +Proceed with Setup URI: Setup URI로 계속 +Proceeding with Garbage Collection, ignoring missing nodes.: 누락된 노드를 무시하고 가비지 컬렉션을 계속 진행합니다. +Proceeding with Garbage Collection.: 가비지 컬렉션을 진행합니다. Process small files in the foreground: 포그라운드에서 작은 파일 처리 +Progress: 진행 상태 +Property Encryption: 속성 암호화 PureJS fallback (Fast, W/O WebAssembly): PureJS 대체 방식 (빠름, WebAssembly 없음) Purge all download/upload cache.: 모든 다운로드/업로드 캐시를 제거합니다. Purge all journal counter: 모든 저널 카운터 삭제 Rebuild local and remote database with local files.: 로컬 파일로 로컬 및 원격 데이터베이스를 다시 구축합니다. Rebuilding Operations (Remote Only): 재구축 작업 (원격 전용) +Recovery and Repair: 복구 및 수리 Recreate all: 모두 다시 생성 Recreate missing chunks for all files: 모든 파일의 누락된 청크 다시 생성 RedFlag: Fetch: Method: - Desc: >- + Desc: |- 어떻게 가져오시겠습니까? - - - %{RedFlag.Fetch.Method.FetchSafer}. (권장) + - %{RedFlag.Fetch.Method.FetchSafer}. **낮은 트래픽**, **높은 CPU**, **낮은 위험** + 다음의 경우에 권장합니다. + - 파일이 일관되지 않을 가능성이 있음 + - 파일이 그리 많지 않음 - %{RedFlag.Fetch.Method.FetchSmoother}. - **낮은 트래픽**, **보통 CPU**, **낮음에서 보통 위험** + **낮은 트래픽**, **보통 CPU**, **낮음~보통 위험** + 다음의 경우에 권장합니다. + - 파일이 대체로 일관됨 + - 파일이 많음 - %{RedFlag.Fetch.Method.FetchTraditional}. - **높은 트래픽**, **낮은 CPU**, **낮음에서 보통 위험** - - >[!INFO]- 세부 사항 - - > ## %{RedFlag.Fetch.Method.FetchSafer}. (권장) + **높은 트래픽**, **낮은 CPU**, **낮음~보통 위험** + >[!INFO]- 자세히 + > ## %{RedFlag.Fetch.Method.FetchSafer}. > **낮은 트래픽**, **높은 CPU**, **낮은 위험** - - > 이 옵션은 원격 소스에서 데이터를 가져오기 전에 기존 로컬 파일을 사용하여 로컬 데이터베이스를 먼저 생성합니다. - - > 로컬과 원격 모두에 일치하는 파일이 있으면 둘 사이의 차이점만 전송됩니다. - - > 하지만 두 위치 모두에 있는 파일은 초기에 충돌 파일로 처리됩니다. 실제로 충돌하지 않는다면 자동으로 해결되지만 이 과정은 - 시간이 걸릴 수 있습니다. - - > 이는 일반적으로 가장 안전한 방법으로 데이터 손실 위험을 최소화합니다. - + > 원격에서 데이터를 가져오기 전에 기존 로컬 파일로 로컬 데이터베이스를 먼저 만듭니다. + > 로컬과 원격 양쪽에 일치하는 파일이 있으면 둘 사이의 차이만 전송됩니다. + > 다만 양쪽에 모두 있는 파일은 처음에 충돌 파일로 처리됩니다. 실제로 충돌하지 않는다면 자동으로 해결되지만, 이 과정에 시간이 걸릴 수 있습니다. + > 일반적으로 가장 안전한 방법이며 데이터 손실 위험이 가장 낮습니다. > ## %{RedFlag.Fetch.Method.FetchSmoother}. - - > **낮은 트래픽**, **보통 CPU**, **낮음에서 보통 위험** (작업에 따라) - - > 이 옵션은 먼저 로컬 파일에서 데이터베이스용 청크를 생성한 다음 데이터를 가져옵니다. 따라서 로컬에 없는 청크만 전송됩니다. - 하지만 모든 메타데이터는 원격 소스에서 가져옵니다. - - > 그런 다음 로컬 파일이 시작 시 이 메타데이터와 비교됩니다. 더 새로운 것으로 간주되는 콘텐츠가 오래된 것을 덮어씁니다(수정 - 시간 기준). 이 결과는 원격 데이터베이스에 다시 동기화됩니다. - - > 로컬 파일이 실제로 최신 타임스탬프라면 일반적으로 안전합니다. 하지만 파일이 더 새로운 타임스탬프를 가지고 있지만 더 오래된 - 콘텐츠를 가지고 있다면(초기 `welcome.md`처럼) 문제가 발생할 수 있습니다. - - > 이는 "%{RedFlag.Fetch.Method.FetchSafer}"보다 CPU를 덜 사용하고 더 빠르지만 주의 깊게 - 사용하지 않으면 데이터 손실로 이어질 수 있습니다. - + > **낮은 트래픽**, **보통 CPU**, **낮음~보통 위험** (작업에 따라 다름) + > 먼저 로컬 파일로 데이터베이스용 청크를 만든 다음 데이터를 가져옵니다. 따라서 로컬에 없는 청크만 전송됩니다. 다만 메타데이터는 모두 원격에서 가져옵니다. + > 그다음 시작 시점에 로컬 파일을 이 메타데이터와 비교합니다. 수정 시각을 기준으로 더 새롭다고 판단된 내용이 오래된 쪽을 덮어씁니다. 그 결과는 다시 원격 데이터베이스로 동기화됩니다. + > 로컬 파일이 실제로 가장 최신 타임스탬프를 가지고 있다면 대체로 안전합니다. 하지만 타임스탬프는 더 새롭지만 내용은 더 오래된 파일(처음 만들어지는 `welcome.md` 같은)이 있으면 문제가 생길 수 있습니다. + > "%{RedFlag.Fetch.Method.FetchSafer}"보다 CPU를 적게 쓰고 더 빠르지만, 주의해서 사용하지 않으면 데이터가 손실될 수 있습니다. > ## %{RedFlag.Fetch.Method.FetchTraditional}. - - > **높은 트래픽**, **낮은 CPU**, **낮음에서 보통 위험** (작업에 따라) - - > 모든 것이 원격에서 가져와집니다. - - > %{RedFlag.Fetch.Method.FetchSmoother}와 유사하지만 모든 청크가 원격 소스에서 가져와집니다. - - > 이는 가장 전통적인 가져오기 방법으로 일반적으로 가장 많은 네트워크 트래픽과 시간을 소모합니다. 또한 - '%{RedFlag.Fetch.Method.FetchSmoother}' 옵션과 유사하게 원격 파일을 덮어쓸 위험이 있습니다. - - > 하지만 가장 오래되고 가장 직접적인 접근 방식이기 때문에 종종 가장 안정적인 방법으로 간주됩니다. + > **높은 트래픽**, **낮은 CPU**, **낮음~보통 위험** (작업에 따라 다름) + > 모든 것을 원격에서 가져옵니다. + > %{RedFlag.Fetch.Method.FetchSmoother}와 비슷하지만, 모든 청크를 원격에서 가져옵니다. + > 가장 전통적인 가져오기 방식으로, 보통 네트워크 트래픽과 시간을 가장 많이 소모합니다. 또한 '%{RedFlag.Fetch.Method.FetchSmoother}' 옵션과 마찬가지로 원격 파일을 덮어쓸 위험이 있습니다. + > 다만 가장 오래되고 단순한 방식이기 때문에 가장 안정적인 방법으로 여겨지는 경우가 많습니다. FetchSafer: 가져오기 전에 로컬 데이터베이스를 한 번 생성 FetchSmoother: 가져오기 전에 로컬 파일 청크 생성 FetchTraditional: 원격에서 모든 것 가져오기 Title: 어떻게 가져오시겠습니까? + FetchRemoteConfig: + Buttons: + Cancel: 아니요, 로컬 설정을 사용합니다 + Fetch: 예, 원격 설정을 가져와 적용합니다 + Message: 원격에 저장된 환경 설정을 가져와 이 기기에 적용하시겠습니까? + Title: 원격 구성 가져오기 +Reduces storage space by discarding all non-latest revisions. This requires the same amount of free space on the remote server and the local client.: 최신 버전이 아닌 모든 리비전을 제거하여 저장 공간을 줄입니다. 이 작업을 수행하려면 원격 서버와 로컬 클라이언트에 동일한 양의 여유 공간이 필요합니다. Reducing the frequency with which on-disk changes are reflected into the DB: 디스크 변경 사항이 데이터베이스에 반영되는 빈도를 줄입니다 Region: 지역 Remediation: 복구 조치 @@ -811,18 +883,15 @@ Replicator: Locked: Action: Dismiss: 재확인을 위해 취소 - Fetch: 원격 데이터베이스에서 모든 것을 다시 가져오기 + Fetch: 이 기기의 동기화 재설정 Unlock: 원격 데이터베이스 잠금 해제 Message: - _value: > + _value: | 원격 데이터베이스가 잠겨 있습니다. 이는 일부 터미널에서 데이터베이스를 재구축했기 때문입니다. - 따라서 현재 기기는 데이터베이스 손상을 방지하기 위해 연결을 일시적으로 보류해야 합니다. - 선택할 수 있는 세 가지 방법이 있습니다: - - %{Replicator.Dialogue.Locked.Action.Fetch} 가장 권장되고 신뢰할 수 있는 방법입니다. 로컬 데이터베이스를 초기화한 뒤, 원격 데이터베이스의 전체 데이터를 다시 가져옵니다. 대부분의 경우 안전하게 수행할 수 있으나, 시간이 다소 걸리며 안정적인 네트워크 환경에서 진행해야 합니다. - %{Replicator.Dialogue.Locked.Action.Unlock} @@ -837,9 +906,12 @@ Replicator: InitialiseFatalError: 사용 가능한 복제기가 없습니다. 치명적인 오류입니다. Pending: 일부 파일 이벤트가 대기 중입니다. 복제가 취소되었습니다. SomeModuleFailed: 일부 모듈 실패로 복제가 취소되었습니다 - VersionUpFlash: 설정을 열고 메시지를 확인해 주세요. 복제가 취소되었습니다. + VersionUpFlash: 업데이트가 감지되었습니다. 설정 대화 상자를 열어 변경 로그를 확인해 주세요. 복제가 취소되었습니다. Requires restart of Obsidian: Obsidian 재시작 필요 Requires restart of Obsidian.: Obsidian 재시작이 필요합니다. +Rerun Onboarding Wizard: 온보딩 마법사 다시 실행 +Rerun the onboarding wizard to set up Self-hosted LiveSync again.: 온보딩 마법사를 다시 실행하여 Self-hosted LiveSync를 다시 설정합니다. +Rerun Wizard: 마법사 다시 실행 Resend: 다시 보내기 Resend all chunks to the remote.: 모든 청크를 원격으로 다시 보냅니다. Reset: 재설정 @@ -847,27 +919,36 @@ Reset all: 모두 재설정 Reset all journal counter: 모든 저널 카운터 재설정 Reset journal received history: 저널 수신 기록 재설정 Reset journal sent history: 저널 송신 기록 재설정 +Reset notification threshold and check the remote database usage: 알림 임계값을 초기화하고 원격 데이터베이스 사용량 확인 Reset received: 수신 기록 재설정 Reset sent history: 송신 기록 재설정 Reset Synchronisation information: 동기화 정보 재설정 -Reset Synchronisation on This Device: 이 장치의 동기화 상태 재설정 +Reset Synchronisation on This Device: 이 기기의 동기화 재설정 +Reset the remote storage size threshold and check the remote storage size again.: 원격 저장소 크기 임계값을 초기화하고 원격 저장소 크기를 다시 확인합니다. Resolve All: 모두 해결 Resolve all conflicted files: 충돌한 모든 파일 해결 Resolve All conflicted files by the newer one: 충돌한 모든 파일을 최신 버전으로 해결 "Resolve all conflicted files by the newer one. Caution: This will overwrite the older one, and cannot resurrect the overwritten one.": "충돌한 모든 파일을 더 최신 버전으로 해결합니다. 주의: 이전 버전은 덮어써지며 복원할 수 없습니다." Restart Now: 지금 재시작 +Restarting Obsidian is strongly recommended. Until restart, some changes may not take effect, and display may be inconsistent. Are you sure to restart now?: Obsidian을 재시작하는 것을 강력히 권장합니다. 재시작하기 전까지는 일부 변경 사항이 적용되지 않거나 화면이 일관되지 않게 표시될 수 있습니다. 지금 재시작하시겠습니까? Restore or reconstruct local database from remote.: 원격에서 로컬 데이터베이스를 복원하거나 재구축합니다. +Run Doctor: 진단 실행 +S3/MinIO/R2 Object Storage: S3/MinIO/R2 객체 스토리지 Save settings to a markdown file. You will be notified when new settings arrive. You can set different files by the platform.: 설정을 마크다운 파일에 저장합니다. 새로운 설정이 도착하면 알림을 받게 됩니다. 플랫폼별로 다른 파일을 설정할 수 있습니다. Saving will be performed forcefully after this number of seconds.: 이 시간(초) 후에 강제로 저장이 수행됩니다. +Scan a QR Code (Recommended for mobile): QR 코드 스캔(모바일 권장) Scan changes on customization sync: 사용자 설정 동기화 시 변경 사항 검색 Scan customization automatically: 사용자 설정 자동 검색 Scan customization before replicating.: 복제하기 전에 사용자 설정을 검색합니다. Scan customization every 1 minute.: 1분마다 사용자 설정을 검색합니다. Scan customization periodically: 주기적으로 사용자 설정 검색 -Scan for hidden files before replication: 복제 전 숨겨진 파일 검색 -Scan hidden files periodically: 주기적으로 숨겨진 파일 검색 +Scan for Broken files: 손상된 파일 검사 +Scan for hidden files before replication: 복제 전 숨김 파일 검사 +Scan hidden files periodically: 주기적으로 숨김 파일 검사 +Scan the QR code displayed on an active device using this device's camera.: 이 기기의 카메라로 사용 중인 기기에 표시된 QR 코드를 스캔하세요. Schedule and Restart: 예약 후 재시작 -Scram!: 긴급 조치 +Scram Switches: 긴급 정지 스위치 +Scram!: 긴급 정지 Seconds, 0 to disable: 초 단위, 0으로 설정하면 비활성화 Seconds. Saving to the local database will be delayed until this value after we stop typing or saving.: 초 단위입니다. 타이핑이나 저장을 중단한 후 이 시간동안 로컬 데이터베이스 저장이 지연됩니다. Secret Key: 시크릿 키 @@ -881,8 +962,8 @@ Setting: 키 페어를 생성했습니다! 참고: 이 키 페어는 다시 표시되지 않습니다. 안전한 곳에 저장해 주세요. 분실하면 새 키 페어를 생성해야 합니다. - 참고 2: 공개 키는 spki 형식이고, 개인 키는 pkcs8 형식입니다. 편의상 공개 키의 줄 바꿈은 `\n`으로 변환됩니다. - 참고 3: 공개 키는 원격 데이터베이스에서 구성되어야 하고, 개인 키는 로컬 기기에서 구성되어야 합니다. + 참고 2: 공개 키는 spki 형식이고, 개인 키는 pkcs8 형식입니다. 편의를 위해 공개 키의 줄 바꿈은 `\n`으로 변환됩니다. + 참고 3: 공개 키는 원격 데이터베이스에, 개인 키는 로컬 기기에 설정해야 합니다. >[!FOR YOUR EYES ONLY]- >
@@ -910,7 +991,6 @@ Setting: > >
- Title: 새 키 페어가 생성되었습니다! TroubleShooting: _value: 문제 해결 @@ -923,119 +1003,122 @@ Setting: SettingTab: Message: AskRebuild: 변경 사항을 적용하려면 원격 데이터베이스에서 가져와야 합니다. 계속 진행하시겠습니까? +Setup URI dialog cancelled.: Setup URI 대화 상자가 취소되었습니다. Setup: + Apply: + Buttons: + ApplyAndFetch: 적용 후 가져오기 + ApplyAndMerge: 적용 후 병합 + ApplyAndRebuild: 적용 후 재구축 + Cancel: 폐기하고 취소 + OnlyApply: 적용만 하기 + Message: |- + 새 구성이 준비되었습니다. 이제 적용해 보겠습니다. + 적용 방법은 여러 가지가 있습니다: + + - 적용 후 가져오기 + 이 기기를 새 클라이언트로 구성합니다. 적용한 뒤 원격 서버에서 동기화합니다. + - 적용 후 병합 + 이미 파일이 있는 기기에서 구성합니다. 로컬 파일을 처리한 뒤 차이만 전송합니다. 충돌이 발생할 수 있습니다. + - 적용 후 재구축 + 로컬 파일로 원격을 재구축합니다. 보통 서버가 손상되었거나 처음부터 다시 시작하려는 경우에 사용합니다. + 다른 기기는 잠기며 다시 가져오기를 수행해야 합니다. + - 적용만 하기 + 적용만 합니다. 재구축이 필요한 경우 충돌이 발생할 수 있습니다. + Title: ${method}에서 가져온 새 구성 적용 + WarningRebuildRecommended: "참고: 설정을 조정한 결과 재구축이 필요한 것으로 판단되었습니다. 적용만 하는 것은 권장하지 않습니다." + Doctor: + Buttons: + No: 아니요, URI에 담긴 설정을 그대로 사용합니다 + Yes: 예, 설정 진단 마법사를 실행합니다 + Message: |- + Self-hosted LiveSync는 오랜 기간에 걸쳐 발전해 왔고, 그동안 권장 설정도 일부 바뀌었습니다. + + 지금 설정 단계가 이를 점검하기에 아주 좋은 시점입니다. + + 가져온 설정이 최신 기준에 비추어 최적인지 확인하도록 설정 진단 마법사를 실행하시겠습니까? + Title: 설정 진단 마법사를 실행할까요? + FetchRemoteConf: + Buttons: + Fetch: 예, 구성을 가져옵니다 + Skip: 아니요, URI에 담긴 설정을 사용합니다 + Message: |- + 다른 기기와 이미 한 번이라도 동기화했다면, 원격 데이터베이스에 동기화된 기기 사이에 적합한 구성 값이 저장되어 있습니다. 플러그인은 더 견고한 구성을 위해 이 값을 가져오려고 합니다. + + 다만 한 가지 확인이 필요합니다. 지금 네트워크에 안전하게 접근해 설정을 가져올 수 있는 상황인가요? + + 참고: 원격 데이터베이스가 SSL 인증서로 보호되어 있고 네트워크가 안전하다면, 대부분의 경우 그대로 진행해도 괜찮습니다. + Title: 원격 데이터베이스에서 구성을 가져올까요? QRCode: |- 설정을 전송하기 위한 QR 코드를 생성했습니다. 휴대폰이나 다른 기기로 QR 코드를 스캔해 주세요. 참고: QR 코드는 암호화되지 않았으므로 열 때 주의하세요. >[!FOR YOUR EYES ONLY]- >
${qr_image}
- ShowQRCode: - _value: QR 코드 표시 - Desc: 설정을 전송하기 위한 QR 코드를 표시합니다. RemoteE2EE: - Title: 엔드투엔드 암호화 - Guidance: 엔드투엔드 암호화 설정을 구성해 주세요. - LabelEncrypt: 엔드투엔드 암호화 - PlaceholderPassphrase: 패스프레이즈를 입력하세요 - StronglyRecommendedTitle: 강력 권장 - StronglyRecommendedLine1: 엔드투엔드 암호화를 활성화하면 데이터가 원격 서버로 전송되기 전에 이 기기에서 암호화됩니다. 즉, 누군가 서버에 접근하더라도 패스프레이즈 없이는 데이터를 읽을 수 없습니다. 다른 기기에서 데이터를 복호화할 때도 필요하므로 패스프레이즈를 반드시 기억해 두세요. - StronglyRecommendedLine2: 또한 Peer-to-Peer 동기화를 사용 중이더라도, 나중에 다른 방식으로 전환하여 원격 서버에 연결하면 이 설정이 그대로 사용됩니다. - MultiDestinationWarning: 여러 동기화 대상에 연결하는 경우에도 이 설정은 동일해야 합니다. - LabelObfuscateProperties: 속성 난독화 - ObfuscatePropertiesDesc: >- - 속성(예: 파일 경로, 크기, 생성일 및 수정일)을 난독화하면 원격 서버에서 파일과 폴더의 구조 및 이름을 식별하기 어렵게 만들어 보안을 한층 강화할 수 있습니다. 이는 개인 정보를 보호하고 권한 없는 사용자가 데이터에 관한 정보를 추론하기 어렵게 만듭니다. AdvancedTitle: 고급 - LabelEncryptionAlgorithm: 암호화 알고리즘 - DefaultAlgorithmDesc: 대부분의 경우 기본 알고리즘(${algorithm})을 그대로 사용하는 것이 좋습니다. 이 설정은 기존 Vault가 다른 형식으로 암호화되어 있는 경우에만 필요합니다. AlgorithmWarning: 암호화 알고리즘을 변경하면 다른 알고리즘으로 암호화된 기존 데이터에 접근할 수 없게 됩니다. 모든 기기에서 동일한 알고리즘을 사용하도록 설정해 데이터 접근성을 유지하세요. - PassphraseValidationLine1: 엔드투엔드 암호화 패스프레이즈는 실제 동기화가 시작되기 전까지 검증되지 않는다는 점에 유의하세요. 이것은 데이터를 보호하기 위한 보안 조치입니다. - PassphraseValidationLine2: 따라서 서버 정보를 수동으로 구성할 때는 각별히 주의해 주세요. 잘못된 패스프레이즈를 입력하면 서버의 데이터가 손상됩니다. 이는 의도된 동작이니 반드시 이해하고 진행해 주세요. + ButtonCancel: 취소 ButtonProceed: 진행 - ButtonCancel: 취소 - UseSetupURI: - Title: Setup URI 입력 - GuidanceLine1: 서버 설치 중 또는 다른 기기에서 생성된 Setup URI와 Vault 패스프레이즈를 입력해 주세요. - GuidanceLine2: 명령 팔레트에서 "설정을 새 Setup URI로 복사" 명령을 실행하면 새 Setup URI를 생성할 수 있습니다. - LabelSetupURI: Setup URI - ValidInfo: Setup URI가 유효하며 사용할 준비가 되었습니다. - InvalidInfo: Setup URI가 올바르지 않습니다. 확인한 뒤 다시 시도해 주세요. - LabelPassphrase: Vault 패스프레이즈 - PlaceholderPassphrase: Vault 패스프레이즈를 입력하세요 - ErrorPassphraseRequired: Vault 패스프레이즈를 입력해 주세요. - ErrorFailedToParse: Setup URI를 해석하지 못했습니다. URI와 패스프레이즈를 확인해 주세요. - ButtonProceed: 설정 테스트 후 계속 - ButtonCancel: 취소 + DefaultAlgorithmDesc: 대부분의 경우 기본 알고리즘(${algorithm})을 그대로 사용하는 것이 좋습니다. 이 설정은 기존 보관함이 다른 형식으로 암호화되어 있는 경우에만 필요합니다. + Guidance: 종단 간 암호화 설정을 구성해 주세요. + LabelEncrypt: 종단 간 암호화 + LabelEncryptionAlgorithm: 암호화 알고리즘 + LabelObfuscateProperties: 속성 난독화 + MultiDestinationWarning: 여러 동기화 대상에 연결하는 경우에도 이 설정은 동일해야 합니다. + ObfuscatePropertiesDesc: "속성(예: 파일 경로, 크기, 생성일 및 수정일)을 난독화하면 원격 서버에서 파일과 폴더의 구조 및 이름을 식별하기 어렵게 만들어 보안을 한층 강화할 수 있습니다. 이는 개인 정보를 보호하고 권한 없는 사용자가 데이터에 관한 정보를 추론하기 어렵게 만듭니다." + PassphraseValidationLine1: 종단 간 암호화 패스프레이즈는 실제 동기화가 시작되기 전까지 검증되지 않는다는 점에 유의하세요. 데이터를 보호하기 위한 보안 조치입니다. + PassphraseValidationLine2: 따라서 서버 정보를 수동으로 구성할 때는 각별히 주의해 주세요. 잘못된 패스프레이즈를 입력하면 서버의 데이터가 손상됩니다. 이는 의도된 동작이니 반드시 이해하고 진행해 주세요. + PlaceholderPassphrase: 패스프레이즈를 입력하세요 + StronglyRecommendedLine1: 종단 간 암호화를 활성화하면 데이터가 원격 서버로 전송되기 전에 이 기기에서 암호화됩니다. 즉, 누군가 서버에 접근하더라도 패스프레이즈 없이는 데이터를 읽을 수 없습니다. 다른 기기에서 데이터를 복호화할 때도 필요하므로 패스프레이즈를 반드시 기억해 두세요. + StronglyRecommendedLine2: 또한 Peer-to-Peer 동기화를 사용 중이더라도, 나중에 다른 방식으로 전환하여 원격 서버에 연결하면 이 설정이 그대로 사용됩니다. + StronglyRecommendedTitle: 강력 권장 + Title: 종단 간 암호화 ScanQRCode: - Title: QR 코드 스캔 + ButtonClose: 이 대화 상자 닫기 Guidance: 기존 기기에서 설정을 가져오려면 아래 단계를 따라 주세요. - Step1: 이 기기에서는 이 Vault를 계속 열어 두세요. + Step1: 이 기기에서는 이 보관함을 계속 열어 두세요. Step2: 원본 기기에서 Obsidian을 엽니다. Step3: 원본 기기에서 명령 팔레트를 열고 "설정을 QR 코드로 표시" 명령을 실행합니다. Step4: 이 기기에서 카메라 앱으로 전환하거나 QR 코드 스캐너를 사용해 표시된 QR 코드를 스캔하세요. - ButtonClose: 이 대화 상자 닫기 -"Please enable 'Compute revisions for chunks' in settings to use Garbage Collection.": Garbage Collection을 사용하려면 설정에서 "Compute revisions for chunks"를 활성화해 주세요. -"Please disable 'Read chunks online' in settings to use Garbage Collection.": Garbage Collection을 사용하려면 설정에서 "Read chunks online"을 비활성화해 주세요. -"Setup URI dialog cancelled.": Setup URI 대화 상자가 취소되었습니다. -"Please select 'Cancel' explicitly to cancel this operation.": 이 작업을 취소하려면 반드시 "취소"를 명시적으로 선택해 주세요. -"Failed to connect to remote for compaction.": 압축을 위해 원격 데이터베이스에 연결하지 못했습니다. -"Failed to connect to remote for compaction. ${reason}": 압축을 위해 원격 데이터베이스에 연결하지 못했습니다. ${reason} -"Compaction in progress on remote database...": 원격 데이터베이스에서 압축을 진행 중입니다... -"Compaction on remote database timed out.": 원격 데이터베이스 압축 시간이 초과되었습니다. -"Compaction on remote database completed successfully.": 원격 데이터베이스 압축이 성공적으로 완료되었습니다. -"Compaction on remote database failed.": 원격 데이터베이스 압축에 실패했습니다. -"Failed to start one-shot replication before Garbage Collection. Garbage Collection Cancelled.": Garbage Collection 전에 일회성 복제를 시작하지 못했습니다. Garbage Collection을 취소합니다. -"Cancel Garbage Collection": Garbage Collection 취소 -"No connected device information found. Cancelling Garbage Collection.": 연결된 기기 정보를 찾을 수 없습니다. Garbage Collection을 취소합니다. -"The following accepted nodes are missing its node information:\n- ${missingNodes}\n\nThis indicates that they have not been connected for some time or have been left on an older version.\nIt is preferable to update all devices if possible. If you have any devices that are no longer in use, you can clear all accepted nodes by locking the remote once.": |- - 다음 승인된 노드에는 노드 정보가 없습니다: - - ${missingNodes} - - 이는 해당 노드가 한동안 연결되지 않았거나 이전 버전에 머물러 있음을 의미합니다. - 가능하다면 먼저 모든 기기를 업데이트하는 것이 좋습니다. 더 이상 사용하지 않는 기기가 있다면 원격을 한 번 잠가 승인된 노드를 모두 정리할 수 있습니다. -"Ignore and Proceed": 무시하고 계속 -"Node Information Missing": 노드 정보 누락 -"Garbage Collection cancelled by user.": 사용자가 Garbage Collection을 취소했습니다. -"Proceeding with Garbage Collection, ignoring missing nodes.": 누락된 노드를 무시하고 Garbage Collection을 계속 진행합니다. -"Proceed Garbage Collection": Garbage Collection 계속 -"> [!INFO]- The connected devices have been detected as follows:\n${devices}": |- - > [!INFO]- 다음 연결된 기기가 감지되었습니다: - ${devices} -"Device": 기기 -"Node ID": 노드 ID -"Obsidian version": Obsidian 버전 -"Plug-in version": 플러그인 버전 -"Progress": 진행 상태 -"Some devices have differing progress values (max: ${maxProgress}, min: ${minProgress}).\nThis may indicate that some devices have not completed synchronisation, which could lead to conflicts. Strongly recommend confirming that all devices are synchronised before proceeding.": |- - 일부 기기의 진행 값이 다릅니다(최대: ${maxProgress}, 최소: ${minProgress}). - 이는 일부 기기가 동기화를 완료하지 않았음을 의미할 수 있으며, 충돌로 이어질 수 있습니다. 계속 진행하기 전에 모든 기기가 동기화되었는지 반드시 확인하는 것을 강력히 권장합니다. -"All devices have the same progress value (${progress}). Your devices seem to be synchronised. And be able to proceed with Garbage Collection.": 모든 기기의 진행 값이 동일합니다(${progress}). 기기들이 동기화된 것으로 보이므로 Garbage Collection을 진행할 수 있습니다. -"Garbage Collection Confirmation": Garbage Collection 확인 -"Proceeding with Garbage Collection.": Garbage Collection을 진행합니다. -"Garbage Collection: Scanned ${scanned} / ~${docCount}": |- - Garbage Collection: ${scanned} / ~${docCount} 스캔됨 -"Garbage Collection: Scanning completed. Total chunks: ${totalChunks}, Used chunks: ${usedChunks}": |- - Garbage Collection: 스캔 완료. 전체 청크 수: ${totalChunks}, 사용 중인 청크 수: ${usedChunks} -"Garbage Collection: Found ${unusedChunks} unused chunks to delete.": |- - Garbage Collection: 삭제할 미사용 청크 ${unusedChunks}개를 찾았습니다. -"Garbage Collection completed. Deleted chunks: ${deletedChunks} / ${totalChunks}. Time taken: ${seconds} seconds.": |- - Garbage Collection이 완료되었습니다. 삭제된 청크: ${deletedChunks} / ${totalChunks}. 소요 시간: ${seconds}초. -"Failed to start replication after Garbage Collection.": Garbage Collection 후 복제를 시작하지 못했습니다. + Title: QR 코드 스캔 + ShowQRCode: + _value: QR 코드 표시 + Desc: 설정을 전송하기 위한 QR 코드를 표시합니다. + UseSetupURI: + ButtonCancel: 취소 + ButtonProceed: 설정 테스트 후 계속 + ErrorFailedToParse: Setup URI를 해석하지 못했습니다. URI와 패스프레이즈를 확인해 주세요. + ErrorPassphraseRequired: 보관함 패스프레이즈를 입력해 주세요. + GuidanceLine1: 서버 설치 중에 또는 다른 기기에서 생성한 Setup URI와 보관함 패스프레이즈를 입력해 주세요. + GuidanceLine2: 명령 팔레트에서 "설정을 새 Setup URI로 복사" 명령을 실행하면 새 Setup URI를 생성할 수 있습니다. + InvalidInfo: Setup URI가 올바르지 않습니다. 확인한 뒤 다시 시도해 주세요. + LabelPassphrase: 보관함 패스프레이즈 + LabelSetupURI: Setup URI + PlaceholderPassphrase: 보관함 패스프레이즈를 입력하세요 + Title: Setup URI 입력 + ValidInfo: Setup URI가 유효하며 사용할 준비가 되었습니다. Should we keep folders that don't have any files inside?: 내부에 파일이 없는 폴더를 유지하시겠습니까? Should we only check for conflicts when a file is opened?: 파일을 열 때만 충돌을 확인하시겠습니까? Should we prompt you about conflicting files when a file is opened?: 파일을 열 때 충돌하는 파일에 대해 알림을 표시하시겠습니까? Should we prompt you for every single merge, even if we can safely merge automatcially?: 안전하게 자동 병합할 수 있는 경우에도 모든 병합에 대해 알림을 받으시겠습니까? Show full banner: 전체 배너 표시 +Show history: 기록 표시 +Show icon only: 아이콘만 표시 Show only notifications: 알림만 표시 Show status as icons only: 아이콘으로만 상태 표시 Show status icon instead of file warnings banner: 파일 경고 배너 대신 상태 아이콘 표시 Show status inside the editor: 편집기 내부에 상태 표시 -Show status on the status bar: 상태 바에 상태 표시 +Show status on the status bar: 상태 표시줄에 상태 표시 Show verbose log. Please enable if you report an issue.: 자세한 로그를 표시합니다. 문제를 신고하는 경우 활성화해 주세요. +"Some devices have differing progress values (max: ${maxProgress}, min: ${minProgress}).\nThis may indicate that some devices have not completed synchronisation, which could lead to conflicts. Strongly recommend confirming that all devices are synchronised before proceeding.": |- + 일부 기기의 진행 값이 다릅니다(최대: ${maxProgress}, 최소: ${minProgress}). + 이는 일부 기기가 동기화를 완료하지 않았음을 의미할 수 있으며, 충돌로 이어질 수 있습니다. 계속 진행하기 전에 모든 기기가 동기화되었는지 반드시 확인하는 것을 강력히 권장합니다. Starts synchronisation when a file is saved.: 파일이 저장될 때 동기화를 시작합니다. Stop reflecting database changes to storage files.: 데이터베이스 변경 사항을 스토리지 파일에 반영하는 것을 중단합니다. Stop watching for file changes.: 파일 변경 사항 감시를 중단합니다. -Suppress notification of hidden files change: 숨겨진 파일 변경 알림 억제 +Storage -> Database: 스토리지 -> 데이터베이스 +Suppress notification of hidden files change: 숨김 파일 변경 알림 억제 Suspend database reflecting: 데이터베이스 반영 일시 중단 Suspend file watching: 파일 감시 일시 중단 Switch to IDB: IDB로 전환 @@ -1047,21 +1130,35 @@ Sync on Editor Save: 편집기 저장 시 동기화 Sync on File Open: 파일 열기 시 동기화 Sync on Save: 저장 시 동기화 Sync on Startup: 시작 시 동기화 +Synchronisation utilising journal files. You must have set up an S3/MinIO/R2 compatible object storage.: 저널 파일을 활용하는 동기화 방식입니다. S3/MinIO/R2 호환 객체 스토리지를 미리 구성해 두어야 합니다. Synchronising files: 동기화할 파일 Syncing: 동기화 Target patterns: 대상 패턴 Testing only - Resolve file conflicts by syncing newer copies of the file, this can overwrite modified files. Be Warned.: 테스트 전용 - 파일의 새로운 사본을 동기화하여 파일 충돌을 해결하며, 수정된 파일을 덮어쓸 수 있습니다. 주의하세요. The delay for consecutive on-demand fetches: 연속 청크 요청 간 대기 시간 +"The following accepted nodes are missing its node information:\n- ${missingNodes}\n\nThis indicates that they have not been connected for some time or have been left on an older version.\nIt is preferable to update all devices if possible. If you have any devices that are no longer in use, you can clear all accepted nodes by locking the remote once.": |- + 다음 승인된 노드에는 노드 정보가 없습니다: + - ${missingNodes} + + 이는 해당 노드가 한동안 연결되지 않았거나 이전 버전에 머물러 있음을 의미합니다. + 가능하다면 먼저 모든 기기를 업데이트하는 것이 좋습니다. 더 이상 사용하지 않는 기기가 있다면 원격을 한 번 잠가 승인된 노드를 모두 정리할 수 있습니다. The Hash algorithm for chunk IDs: 청크 ID용 해시 알고리즘 -The maximum duration for which chunks can be incubated within the document. Chunks exceeding this period will graduate to independent chunks.: 변경 기록이 문서에 함께 보관될 수 있는 최대 시간입니다. 초과 시 문서에서 분리되어 개별로 저장됩니다. -The maximum number of chunks that can be incubated within the document. Chunks exceeding this number will immediately graduate to independent chunks.: 문서 안에 임시로 보관할 수 있는 변경 기록의 최대 개수입니다. 이 수를 초과하면 즉시 독립된 청크로 분리되어 저장됩니다. -The maximum total size of chunks that can be incubated within the document. Chunks exceeding this size will immediately graduate to independent chunks.: 문서 안에 임시로 보관할 수 있는 변경 기록의 전체 크기 제한입니다. 초과 시 자동으로 분리됩니다. +The IndexedDB adapter often offers superior performance in certain scenarios, but it has been found to cause memory leaks when used with LiveSync mode. When using LiveSync mode, please use IDB adapter instead.: IndexedDB 어댑터는 특정 상황에서 더 나은 성능을 보이는 경우가 많지만, LiveSync 모드에서 사용하면 메모리 누수를 일으키는 것으로 확인되었습니다. LiveSync 모드를 사용할 때는 IDB 어댑터를 사용해 주세요. +The maximum duration for which chunks can be incubated within the document. Chunks exceeding this period will graduate to independent chunks.: 청크를 문서 안에 임시 보관할 수 있는 최대 기간입니다. 이 기간을 넘긴 청크는 독립된 청크로 분리됩니다. +The maximum number of chunks that can be incubated within the document. Chunks exceeding this number will immediately graduate to independent chunks.: 문서 안에 임시 보관할 수 있는 청크의 최대 개수입니다. 이 개수를 넘긴 청크는 즉시 독립된 청크로 분리됩니다. +The maximum total size of chunks that can be incubated within the document. Chunks exceeding this size will immediately graduate to independent chunks.: 문서 안에 임시 보관할 수 있는 청크의 최대 총 크기입니다. 이 크기를 넘긴 청크는 즉시 독립된 청크로 분리됩니다. +The minimum interval for automatic synchronisation on event.: 이벤트 발생 시 자동 동기화의 최소 간격입니다. +This feature enables direct synchronisation between devices. No server is required, but both devices must be online at the same time for synchronisation to occur, and some features may be limited. Internet connection is only required to signalling (detecting peers) and not for data transfer.: 기기 간에 직접 동기화하는 기능입니다. 서버는 필요 없지만 동기화가 이루어지려면 두 기기가 동시에 온라인 상태여야 하며, 일부 기능은 제한될 수 있습니다. 인터넷 연결은 시그널링(피어 탐지)에만 필요하고 데이터 전송에는 필요하지 않습니다. +This is an advanced option for users who do not have a URI or who wish to configure detailed settings.: URI가 없거나 세부 설정을 직접 구성하려는 사용자를 위한 고급 옵션입니다. +This is the most suitable synchronisation method for the design. All functions are available. You must have set up a CouchDB instance.: 이 설계에 가장 적합한 동기화 방식입니다. 모든 기능을 사용할 수 있습니다. CouchDB 인스턴스를 미리 구성해 두어야 합니다. This passphrase will not be copied to another device. It will be set to `Default` until you configure it again.: 이 패스프레이즈는 다른 기기로 복사되지 않습니다. 다시 구성할 때까지 `기본값`으로 설정됩니다. This will recreate chunks for all files. If there were missing chunks, this may fix the errors.: 모든 파일의 청크를 다시 생성합니다. 누락된 청크가 있었다면 이 작업으로 오류가 해결될 수 있습니다. Transfer Tweak: 전송 조정 TweakMismatchResolve: Action: + DisableAutoAcceptCompatible: 자동 수용 비활성화 Dismiss: 무시 + EnableAutoAcceptCompatible: 자동 수용 활성화 UseConfigured: 구성된 설정 사용 UseMine: 원격 데이터베이스 설정 업데이트 UseMineAcceptIncompatible: 원격 데이터베이스 설정 업데이트하지만 그대로 유지 @@ -1070,6 +1167,10 @@ TweakMismatchResolve: UseRemoteAcceptIncompatible: 이 기기에 설정 적용하지만 호환성 문제 무시 UseRemoteWithRebuild: 이 기기에 설정 적용하고 다시 가져오기 Message: + AutoAcceptCompatibleUndefined: |- + + 기기마다 설정이 다른 것으로 보입니다. 이제 호환되는 변경 사항은 자동으로 적용할 수 있습니다. + 이 `자동 수용` 설정을 활성화하시겠습니까? Main: |- 원격 데이터베이스의 설정은 다음과 같습니다. 이 값들은 이 기기와 최소 한 번 동기화된 다른 기기에서 구성된 것입니다. @@ -1093,29 +1194,24 @@ TweakMismatchResolve: 결정을 알려주세요. ${additionalMessage} + mineUpdated: 이 기기의 구성이 조정되었습니다. + remoteUpdated: 원격에 저장된 구성이 업데이트되었습니다. UseRemote: - WarningRebuildRecommended: >- + WarningRebuildRecommended: |- >[!NOTICE] - - > 일부 변경사항은 호환 가능하지만 추가 스토리지 및 전송량을 소모할 수 있습니다. 재구축을 권장합니다. 하지만 현재 재구축을 - 수행하지 않더라도 향후 유지보수에서 구현될 수 있습니다. - + > 일부 변경사항은 호환 가능하지만 추가 스토리지 및 전송량을 소모할 수 있습니다. 재구축을 권장합니다. 하지만 현재 재구축을 수행하지 않더라도 향후 유지보수에서 구현될 수 있습니다. > ***시간적 여유가 있고 안정적인 네트워크에 연결된 상태에서 적용해 주세요!*** WarningRebuildRequired: |- >[!WARNING] > 일부 원격 구성이 이 기기의 로컬 데이터베이스와 호환되지 않습니다. 로컬 데이터베이스 재구축이 필요합니다. > ***시간적 여유가 있고 안정적인 네트워크에 연결된 상태에서 적용해 주세요!*** - WarningIncompatibleRebuildRecommended: >- + WarningIncompatibleRebuildRecommended: |- >[!NOTICE] - > 로컬 데이터베이스와 원격 데이터베이스가 호환되지 않도록 만드는 값들이 다른 것을 감지했습니다. - - > 일부 변경사항은 호환 가능하지만 추가 스토리지 및 전송량을 소모할 수 있습니다. 재구축을 권장합니다. 하지만 현재 재구축을 - 수행하지 않더라도 향후 유지보수에서 구현될 수 있습니다. - + > 일부 변경사항은 호환 가능하지만 추가 스토리지 및 전송량을 소모할 수 있습니다. 재구축을 권장합니다. 하지만 현재 재구축을 수행하지 않더라도 향후 유지보수에서 구현될 수 있습니다. > 재구축을 원한다면 몇 분 이상 소요됩니다. **지금 수행해도 안전한지 확인해 주세요.** WarningIncompatibleRebuildRequired: |- @@ -1131,10 +1227,304 @@ TweakMismatchResolve: Row: "| ${name} | ${self} | ${remote} |" Title: _value: 구성 불일치 감지 + AutoAcceptCompatible: 자동 수용 사용 가능 TweakResolving: 구성 불일치 감지 UseRemoteConfig: 원격 구성 사용 +Ui: + Common: + Signal: + Caution: 주의 + Danger: 위험 + Notice: 알림 + Warning: 경고 + Settings: + Advanced: + LocalDatabaseTweak: 로컬 데이터베이스 조정 + MemoryCache: 메모리 캐시 + TransferTweak: 전송 조정 + Common: + Analyse: 분석 + Back: 뒤로 + Check: 확인 + Configure: 설정 + Continue: 계속 + Delete: 삭제 + Fetch: 가져오기 + Lock: 잠금 + Merge: 병합 + Open: 열기 + Overwrite: 덮어쓰기 + Perform: 실행 + ResetAll: 모두 재설정 + ResolveAll: 모두 해결 + Scan: 검사 + Send: 보내기 + Use: 사용 + VerifyAll: 모두 검증 + CustomizationSync: + OpenDesc: 대화상자 열기 + Panel: 사용자 설정 동기화 + WarnChangeDeviceName: 이 기능이 활성화되어 있는 동안에는 기기 이름을 변경할 수 없습니다. 기기 이름을 변경하려면 이 기능을 비활성화하세요. + WarnSetDeviceName: 이 기기를 식별할 기기 이름을 설정해 주세요. 이 이름은 기기 간에 고유해야 합니다. 설정하기 전까지는 이 기능을 활성화할 수 없습니다. + Hatch: + AnalyseDatabaseUsage: 데이터베이스 사용량 분석 + AnalyseDatabaseUsageDesc: 데이터베이스 사용량을 분석하고 직접 진단할 수 있도록 TSV 보고서를 생성합니다. 생성된 보고서는 원하는 스프레드시트에 붙여 넣어 확인할 수 있습니다. + BackToNonConfigured: 미구성 상태로 되돌리기 + ConvertNonObfuscated: 경로 난독화되지 않은 파일 검사 및 변환 + ConvertNonObfuscatedDesc: 경로 난독화 없이 저장된 파일이 있는지 로컬 데이터베이스를 확인하고, 필요하면 변환합니다. + CopyIssueReport: 보고서를 클립보드에 복사 + DatabaseLabel: "데이터베이스: ${details}" + DatabaseToStorage: 데이터베이스 -> 스토리지 + DeleteCustomizationSyncData: 모든 사용자 설정 동기화 데이터 삭제 + GeneratedReport: 생성된 보고서 + Missing: 누락됨 + ModifiedSize: "수정: ${modified}, 크기: ${size}" + ModifiedSizeActual: "수정: ${modified}, 크기: ${size} (실제 크기: ${actualSize})" + PrepareIssueReport: 이슈 생성을 위한 '보고서' 준비 + RecoveryAndRepair: 복구 및 수리 + RecreateAll: 모두 다시 생성 + RecreateMissingChunks: 모든 파일의 누락된 청크 다시 생성 + RecreateMissingChunksDesc: 모든 파일의 청크를 다시 생성합니다. 누락된 청크가 있었다면 이 작업으로 오류가 해결될 수 있습니다. + ResetPanel: 재설정 + ResetRemoteUsage: 알림 임계값을 초기화하고 원격 데이터베이스 사용량 확인 + ResetRemoteUsageDesc: 원격 저장소 크기 임계값을 초기화하고 원격 저장소 크기를 다시 확인합니다. + ResolveAllConflictedFiles: 충돌한 모든 파일을 최신 버전으로 해결 + ResolveAllConflictedFilesDesc: "충돌한 모든 파일을 더 최신 버전으로 해결합니다. 주의: 이전 버전은 덮어써지며 복원할 수 없습니다." + RunDoctor: 진단 실행 + ScanBrokenFiles: 손상된 파일 검사 + ScramSwitches: 긴급 정지 스위치 + ShowHistory: 기록 표시 + StorageLabel: "스토리지: ${details}" + StorageToDatabase: 스토리지 -> 데이터베이스 + VerifyAndRepairAllFiles: 모든 파일 검증 및 복구 + VerifyAndRepairAllFilesDesc: 로컬 데이터베이스와 스토리지의 파일 내용을 비교합니다. 일치하지 않으면 어느 쪽을 유지할지 묻습니다. + Maintenance: + Cleanup: 정리 실행 + CleanupDesc: 최신 버전이 아닌 모든 리비전을 제거하여 저장 공간을 줄입니다. 이 작업을 수행하려면 원격 서버와 로컬 클라이언트에 동일한 양의 여유 공간이 필요합니다. + DeleteLocalDatabase: Self-hosted LiveSync를 초기화하거나 제거하기 위해 로컬 데이터베이스를 삭제 + EmergencyRestart: 긴급 재시작 + EmergencyRestartDesc: 모든 동기화를 비활성화하고 재시작합니다. + FreshStartWipe: 초기화 후 새로 시작 + FreshStartWipeDesc: 원격 서버의 모든 데이터를 삭제합니다. + GarbageCollection: 가비지 컬렉션 V3 (Beta) + GarbageCollectionAction: 가비지 컬렉션 실행 + GarbageCollectionDesc: 사용하지 않는 청크를 제거하고 데이터베이스 크기를 줄이기 위해 가비지 컬렉션을 실행합니다. + LockServer: 서버 잠금 + LockServerDesc: 다른 기기와 동기화되지 않도록 원격 서버를 잠급니다. + OverwriteRemote: 원격 덮어쓰기 + OverwriteRemoteDesc: 로컬 DB와 패스프레이즈로 원격을 덮어씁니다. + OverwriteServerData: 이 기기의 파일로 서버 데이터를 덮어쓰기 + OverwriteServerDataDesc: 이 기기의 파일로 로컬과 원격 데이터베이스를 재구축합니다. + PurgeAllJournalCounter: 모든 저널 카운터 삭제 + PurgeAllJournalCounterDesc: 모든 다운로드 및 업로드 캐시를 제거합니다. + RebuildingOperations: 재구축 작업 (원격 전용) + Resend: 다시 보내기 + ResendDesc: 모든 청크를 원격으로 다시 보냅니다. + Reset: 재설정 + ResetAllJournalCounter: 모든 저널 카운터 재설정 + ResetAllJournalCounterDesc: 모든 저널 기록을 초기화합니다. 다음 동기화 때 모든 항목을 다시 주고받습니다. + ResetJournalReceived: 저널 수신 기록 재설정 + ResetJournalReceivedDesc: 저널 수신 기록을 초기화합니다. 다음 동기화 때 이 기기가 보낸 항목을 제외한 모든 항목을 다시 내려받습니다. + ResetJournalSent: 저널 송신 기록 재설정 + ResetJournalSentDesc: 저널 송신 기록을 초기화합니다. 다음 동기화 때 이 기기가 받은 항목을 제외한 모든 항목을 다시 보냅니다. + ResetLocalSyncInfo: 동기화 정보 재설정 + ResetLocalSyncInfoDesc: 원격에서 로컬 데이터베이스를 복원하거나 재구축합니다. + ResetReceived: 수신 기록 재설정 + ResetSentHistory: 송신 기록 재설정 + ResetThisDevice: 이 기기의 동기화 재설정 + ScheduleAndRestart: 예약 후 재시작 + Scram: 긴급 정지 + SendChunks: 청크 보내기 + Syncing: 동기화 + WarningLockedReadyAction: 준비되었습니다. 데이터베이스 잠금 해제 + WarningLockedReadyText: 의도치 않은 보관함 손상을 막기 위해 원격 데이터베이스가 동기화 잠금 상태입니다. (이 기기는 '해결됨'으로 표시되어 있습니다.) 모든 기기가 '해결됨'으로 표시되면 데이터베이스 잠금을 해제하세요. 이 경고는 복제를 통해 기기가 해결되었음이 확인될 때까지 계속 표시됩니다. + WarningLockedResolveAction: 백업했습니다. 이 기기를 해결됨으로 표시 + WarningLockedResolveText: 이 기기가 '해결됨'으로 표시되어 있지 않아, 보관함 손상을 막기 위해 원격 데이터베이스가 동기화 잠금 상태입니다. 보관함을 백업하고 로컬 데이터베이스를 재설정한 뒤 '이 기기를 해결됨으로 표시'를 선택해 주세요. 이 경고는 복제를 통해 기기가 해결되었음이 확인될 때까지 계속 표시됩니다. + WriteRedFlagAndRestart: 표시 후 재시작 + Patches: + CompatibilityConflict: 호환성 (충돌 동작) + CompatibilityDatabase: 호환성 (데이터베이스 구조) + CompatibilityInternalApi: 호환성 (내부 API 사용) + CompatibilityMetadata: 호환성 (메타데이터) + CompatibilityRemote: 호환성 (원격 데이터베이스) + CompatibilityTrouble: 호환성 (문제 대응) + CurrentAdapter: "현재 어댑터: ${adapter}" + DatabaseAdapter: 데이터베이스 어댑터 + DatabaseAdapterDesc: 사용할 데이터베이스 어댑터를 선택합니다. + EdgeCaseBehaviour: 특수 상황 처리 (동작) + EdgeCaseDatabase: 특수 상황 처리 (데이터베이스) + EdgeCaseProcessing: 특수 상황 처리 (처리) + IndexedDbWarning: IndexedDB 어댑터는 특정 상황에서 더 나은 성능을 보이는 경우가 많지만, LiveSync 모드에서 사용하면 메모리 누수를 일으키는 것으로 확인되었습니다. LiveSync 모드를 사용할 때는 IDB 어댑터를 사용해 주세요. + MigratingToIdb: 모든 데이터를 IDB로 마이그레이션하는 중... + MigratingToIndexedDb: 모든 데이터를 IndexedDB로 마이그레이션하는 중... + MigrationIdbCompleted: IDB로 마이그레이션이 완료되었습니다. 새 구성을 적용하기 위해 Obsidian이 곧 재시작됩니다. + MigrationIdbCompletedFollowUp: IDB로 마이그레이션이 완료되었습니다. 어댑터를 전환하고 Obsidian을 재시작해 주세요. + MigrationIndexedDbCompleted: IndexedDB로 마이그레이션이 완료되었습니다. 새 구성을 적용하기 위해 Obsidian이 곧 재시작됩니다. + MigrationIndexedDbCompletedFollowUp: IndexedDB로 마이그레이션이 완료되었습니다. 어댑터를 전환하고 Obsidian을 재시작해 주세요. + MigrationWarning: 이 설정을 변경하려면 기존 데이터를 마이그레이션하고(시간이 다소 걸릴 수 있습니다) Obsidian을 재시작해야 합니다. 진행하기 전에 반드시 데이터를 백업해 주세요. + OperationToIdb: IDB로 + OperationToIndexedDb: IndexedDB로 + Remediation: 복구 조치 + RemediationChanged: 복구 설정이 변경됨 + RemediationNoLimit: 제한이 설정되지 않음 + RemediationRestarting: 복구 조치 설정이 변경되었습니다. Obsidian을 재시작하는 중... + RemediationRestartLater: 나중에 + RemediationRestartMessage: Obsidian을 재시작하는 것을 강력히 권장합니다. 재시작하기 전까지는 일부 변경 사항이 적용되지 않거나 화면이 일관되지 않게 표시될 수 있습니다. 지금 재시작하시겠습니까? + RemediationRestartNow: 지금 재시작 + RemediationSuffixChanged: 접미사가 변경되었습니다. 데이터베이스를 다시 여는 중... + RemediationWithValue: "제한: ${date} (${timestamp})" + RemoteDatabaseSunset: 원격 데이터베이스 조정 (폐기 예정) + SwitchToIDB: IDB로 전환 + SwitchToIndexedDb: IndexedDB로 전환 + PowerUsers: + ConfigurationEncryption: 구성 암호화 + ConnectionTweak: CouchDB 연결 조정 + ConnectionTweakDesc: IBM Cloudant를 사용하다가 페이로드 크기 제한에 도달했다면, 배치 크기와 배치 개수 제한을 더 낮은 값으로 줄여 주세요. + Default: 기본값 + Developer: 개발자 + EncryptSensitiveConfig: 민감한 구성 항목 암호화 + PromptPassphraseEveryLaunch: 시작할 때마다 패스프레이즈 묻기 + UseCustomPassphrase: 사용자 지정 패스프레이즈 사용 + Remote: + Activate: 활성화 + ActiveSuffix: " (활성)" + AddConnection: 연결 추가 + AddRemoteDefaultName: 새 원격 + ConfigureAndChangeRemote: 원격 구성 및 변경 + ConfigureE2EE: E2EE 구성 + ConfigureRemote: 원격 구성 + DeleteRemoteConfirm: "'${name}' 원격 구성을 삭제할까요?" + DeleteRemoteTitle: 원격 구성 삭제 + DisplayName: 표시 이름 + DuplicateRemote: 원격 구성 복사 + DuplicateRemoteSuffix: ${name} (사본) + E2EEConfiguration: E2EE 구성 + Export: 내보내기 + FetchRemoteSettings: 원격 설정 가져오기 + ImportConnection: 연결 가져오기 + ImportConnectionPrompt: 연결 문자열 붙여넣기 + ImportedCouchDb: 가져온 CouchDB + ImportedRemote: 원격 + MoreActions: 추가 작업 + PeerToPeerPanel: 피어 투 피어(P2P) 동기화 + RemoteConfigurationPrefix: 원격 구성 + RemoteDatabases: 원격 데이터베이스 + RemoteName: 원격 이름 + RemoteNameCouchDb: CouchDB ${host} + RemoteNameP2P: P2P ${room} + RemoteNameS3: S3 ${bucket} + Rename: 이름 바꾸기 + Selector: + AddDefaultPatterns: 기본 패턴 추가 + CrossPlatform: 크로스 플랫폼 + Default: 기본값 + HiddenFiles: 숨김 파일 + IgnorePatterns: 무시 패턴 + NonSynchronisingFiles: 동기화하지 않는 파일 + NonSynchronisingFilesDesc: (정규식) 설정하면 이 패턴과 일치하는 로컬 및 원격 파일 변경은 모두 건너뜁니다. + NormalFiles: 일반 파일 + OverwritePatterns: 덮어쓰기 패턴 + OverwritePatternsDesc: 병합 대신 덮어쓸 파일을 판별하는 패턴 + SynchronisingFiles: 동기화할 파일 + SynchronisingFilesDesc: (정규식) 비워 두면 모든 파일을 동기화합니다. 정규식 필터를 지정하면 동기화할 파일을 제한할 수 있습니다. + TargetPatterns: 대상 패턴 + TargetPatternsDesc: 동기화할 파일을 판별하는 패턴 + Setup: + RerunWizardButton: 마법사 다시 실행 + RerunWizardDesc: 온보딩 마법사를 다시 실행하여 Self-hosted LiveSync를 다시 설정합니다. + RerunWizardName: 온보딩 마법사 다시 실행 + SyncSettings: + Fetch: 가져오기 + Merge: 병합 + Overwrite: 덮어쓰기 + SetupWizard: + Common: + Back: 아니요, 이전으로 돌아가겠습니다 + Cancel: 취소 + ProceedSelectOption: 계속하려면 항목을 선택해 주세요 + Intro: + ExistingOption: 기존 동기화 구성에 기기를 추가합니다 + ExistingOptionDesc: 다른 컴퓨터나 스마트폰에서 이미 동기화를 사용 중이라면 선택하세요. 이 기기를 기존 구성에 연결할 때 사용합니다. + Guidance: 동기화 설정을 간단히 마칠 수 있도록 몇 가지 질문으로 안내해 드리겠습니다. + NewOption: 처음으로 설정합니다 + NewOptionDesc: 이 기기를 첫 번째 동기화 기기로 설정한다면 선택하세요. + ProceedExisting: 예, 이 기기를 기존 동기화 구성에 추가하겠습니다 + ProceedNew: 예, 새 동기화를 설정하겠습니다 + Question: 먼저 현재 상황에 가장 잘 맞는 항목을 선택해 주세요. + Title: Self-hosted LiveSync에 오신 것을 환영합니다 + Invitation: + Start: 설정 시작 + OutroAskUserMode: + CompatibleOption: 원격이 이미 설정되어 있고, 구성도 호환됩니다(또는 이번 작업으로 호환되었습니다). + CompatibleOptionDesc: 확신이 없다면 이 옵션을 선택하는 것은 위험합니다. 서버 구성이 이 기기와 호환된다고 가정하기 때문에, 그렇지 않을 경우 데이터가 손실될 수 있습니다. 결과를 충분히 이해한 뒤에 선택해 주세요. + ExistingOption: 원격 서버가 이미 설정되어 있습니다. 이 기기를 참여시키려고 합니다. + ExistingOptionDesc: 이 옵션을 선택하면 이 기기가 기존 서버에 참여합니다. 서버에 있는 기존 동기화 데이터를 이 기기로 가져와야 합니다. + Guidance: 서버 연결이 정상적으로 구성되었습니다. 다음 단계로, 로컬 데이터베이스 즉 동기화 정보를 재구축해야 합니다. + NewOption: 서버를 처음 설정합니다 / 기존 서버를 초기화하려고 합니다. + NewOptionDesc: 이 옵션을 선택하면 이 기기의 현재 데이터로 서버를 초기화합니다. 서버에 있던 기존 데이터는 완전히 덮어써집니다. + ProceedApplySettings: 설정 적용 + ProceedNext: 다음 단계로 진행합니다. + Question: 현재 상황을 선택해 주세요. + Title: "거의 완료: 선택이 필요합니다" + OutroNewP2PUser: + GuidanceNotice: P2P에는 덮어쓸 중앙 서버 사본이 없습니다. 이 단계는 이 기기만 준비하며, 다른 기기가 초기 데이터를 가져올 때는 이 기기를 온라인 상태로 유지해 주세요. + GuidancePrimary: Peer-to-Peer 연결이 정상적으로 구성되었습니다. 다음 단계로, 이 보관함의 현재 파일을 사용해 로컬 LiveSync 데이터베이스를 만듭니다. + Important: 유의해 주세요 + Proceed: 재시작하고 이 기기 준비 + Question: 재시작하고 로컬 초기화 확인 단계로 넘어가려면 아래 버튼을 선택해 주세요. + Title: "설정 완료: 이 P2P 기기 준비" + OutroNewUser: + GuidancePrimary: 서버 연결이 정상적으로 구성되었습니다. 다음 단계로, 이 기기의 현재 데이터를 사용해 서버의 동기화 데이터를 만듭니다. + GuidanceWarning: 재시작하면 이 기기의 데이터가 원본으로서 서버에 업로드됩니다. 현재 서버에 있는 데이터는 의도치 않은 것이라도 완전히 덮어써지므로 유의해 주세요. + Important: 중요 + Proceed: 재시작하고 서버 초기화 + Question: 재시작하고 마지막 확인 단계로 넘어가려면 아래 버튼을 선택해 주세요. + Title: "설정 완료: 서버 초기화 준비" + RebuildEverythingP2P: + ConfirmLocalReset: 이 작업이 이 기기의 로컬 동기화 데이터베이스만 초기화한다는 것을 이해했습니다. + ConfirmLocalResetNote: 현재 이 보관함에 있는 파일을 사용해 재구축합니다. + ConfirmTitle: ⚠️ 다음 내용을 확인해 주세요 + Guidance: 이 절차는 이 기기의 로컬 LiveSync 데이터베이스를 삭제하고, 이 보관함의 현재 파일로 재구축합니다. 다른 기기의 데이터는 삭제하거나 덮어쓰지 않습니다. + Note: 초기화 후에도 다른 기기가 이 기기에서 보관함을 가져올 수 있도록 이 기기를 온라인 상태로 유지해 주세요. + Proceed: 이해했습니다, 이 기기 준비 + Title: "최종 확인: P2P를 위한 이 기기 준비" + SelectExisting: + Guidance: 이 기기를 기존 동기화 구성에 추가합니다. + ManualOption: 서버 정보를 수동으로 입력 + ManualOptionDesc: 다른 기기와 동일한 서버 정보를 다시 직접 입력합니다. 숙련된 사용자 전용입니다. + ProceedManual: 서버 정보를 알고 있으니 직접 입력하겠습니다 + ProceedQr: 이 기기의 카메라로 사용 중인 기기에 표시된 QR 코드를 스캔하세요. + ProceedSetupUri: Setup URI로 계속 + QrOption: QR 코드 스캔(모바일 권장) + QrOptionDesc: 이 기기의 카메라로 사용 중인 기기에 표시된 QR 코드를 스캔하세요. + Question: 다른 기기에서 설정을 가져올 방법을 선택해 주세요. + SetupUriOption: Setup URI 사용(권장) + SetupUriOptionDesc: 사용 중인 기기 중 하나에서 생성한 Setup URI를 붙여 넣으세요. + Title: 기기 설정 방법 + SelectNew: + Guidance: 이제 서버 구성을 진행하겠습니다. + ManualOption: 서버 정보를 수동으로 입력 + ManualOptionDesc: Setup URI가 없거나 세부 설정을 직접 구성하려는 사용자를 위한 고급 옵션입니다. + ProceedManual: 서버 정보를 알고 있으니 직접 입력하겠습니다 + ProceedSetupUri: Setup URI로 계속 + Question: 서버 연결을 어떻게 구성하시겠습니까? + SetupUriOption: Setup URI 사용(권장) + SetupUriOptionDesc: Setup URI는 서버 주소와 인증 정보를 담은 하나의 문자열입니다. 서버 설치 스크립트가 URI를 생성했다면, 간단하고 안전하게 구성할 수 있는 방법입니다. + Title: 연결 방법 + SetupRemote: + BucketOption: S3/MinIO/R2 객체 스토리지 + BucketOptionDesc: 저널 파일을 사용하는 동기화 방식입니다. S3/MinIO/R2 호환 객체 스토리지 서비스를 미리 구성해 두어야 합니다. + CouchDbOptionDesc: 현재 설계에 가장 적합한 동기화 방식입니다. 모든 기능을 사용할 수 있습니다. CouchDB 인스턴스를 미리 구성해 두어야 합니다. + Guidance: 연결할 서버 유형을 선택해 주세요. + P2POption: Peer-to-Peer 전용 + P2POptionDesc: 기기 간에 직접 동기화하는 방식입니다. 서버는 필요 없지만 두 기기가 동시에 온라인 상태여야 하며, 일부 기능은 제한될 수 있습니다. 인터넷 연결은 시그널링에만 필요하고 데이터 전송에는 필요하지 않습니다. + ProceedBucket: S3/MinIO/R2 설정으로 계속 + ProceedCouchDb: CouchDB 설정으로 계속 + ProceedP2P: Peer-to-Peer 전용 설정으로 계속 + Title: 서버 정보 입력 Unique name between all synchronized devices. To edit this setting, please disable customization sync once.: 모든 동기화된 기기 간 고유 이름입니다. 이 설정을 편집하려면 사용자 설정 동기화를 한 번 비활성화해 주세요. -Use a custom passphrase: 사용자 지정 암호문구 사용 +Use a custom passphrase: 사용자 지정 패스프레이즈 사용 +Use a Setup URI (Recommended): Setup URI 사용(권장) Use Custom HTTP Handler: 커스텀 HTTP 핸들러 사용 Use dynamic iteration count: 동적 반복 횟수 사용 Use Segmented-splitter: 의미 기반 분할 사용 @@ -1146,66 +1536,16 @@ Username: 사용자명 Verbose Log: 자세한 로그 Verify all: 모두 검증 Verify and repair all files: 모든 파일 검증 및 복구 -Warning! This will have a serious impact on performance. And the logs will not be synchronised under the default name. Please be careful with logs; they often contain your confidential information.: - 경고! 이는 성능에 심각한 영향을 미칩니다. 로그는 기본 이름으로 동기화되지 않습니다. 로그에는 종종 기밀 정보가 포함되어 있으므로 주의해 - 주세요. -We cannot change the device name while this feature is enabled. Please disable this feature to change the device name.: 이 기능이 활성화되어 있는 동안에는 장치 이름을 변경할 수 없습니다. 장치 이름을 변경하려면 이 기능을 비활성화하세요. +Warning! This will have a serious impact on performance. And the logs will not be synchronised under the default name. Please be careful with logs; they often contain your confidential information.: 경고! 이는 성능에 심각한 영향을 미칩니다. 로그는 기본 이름으로 동기화되지 않습니다. 로그에는 종종 기밀 정보가 포함되어 있으므로 주의해 주세요. +We cannot change the device name while this feature is enabled. Please disable this feature to change the device name.: 이 기능이 활성화되어 있는 동안에는 기기 이름을 변경할 수 없습니다. 기기 이름을 변경하려면 이 기능을 비활성화하세요. +We will now guide you through a few questions to simplify the synchronisation setup.: 동기화 설정을 간단히 마칠 수 있도록 몇 가지 질문으로 안내해 드리겠습니다. +We will now proceed with the server configuration.: 이제 서버 구성을 진행하겠습니다. +Welcome to Self-hosted LiveSync: Self-hosted LiveSync에 오신 것을 환영합니다 When you save a file in the editor, start a sync automatically: 편집기에서 파일을 저장할 때 자동으로 동기화를 시작합니다 Write credentials in the file: 파일에 자격 증명 저장 Write logs into the file: 파일에 로그 기록 xxhash32 (Fast but less collision resistance): xxhash32 (빠르지만 충돌 저항성은 낮음) xxhash64 (Fastest): xxhash64 (가장 빠름) -Reduces storage space by discarding all non-latest revisions. This requires the same amount of free space on the remote server and the local client.: - 최신 버전이 아닌 모든 리비전을 제거하여 저장 공간을 줄입니다. 이 작업을 수행하려면 원격 서버와 로컬 클라이언트에 동일한 양의 여유 공간이 필요합니다. -Rerun Onboarding Wizard: 온보딩 마법사 다시 실행 -Rerun the onboarding wizard to set up Self-hosted LiveSync again.: 온보딩 마법사를 다시 실행하여 Self-hosted LiveSync를 다시 설정합니다. -Rerun Wizard: 마법사 다시 실행 -Run Doctor: 진단 실행 -Scan for Broken files: 손상된 파일 검사 -Prepare the 'report' to create an issue: 이슈 생성을 위한 '보고서' 준비 -Copy Report to clipboard: 보고서를 클립보드에 복사 -Analyse database usage: 데이터베이스 사용량 분석 -Analyse database usage and generate a TSV report for diagnosis yourself. You can paste the generated report with any spreadsheet you like.: - 데이터베이스 사용량을 분석하고 직접 진단할 수 있도록 TSV 보고서를 생성합니다. 생성된 보고서는 원하는 스프레드시트에 붙여 넣어 확인할 수 있습니다. -Reset notification threshold and check the remote database usage: 알림 임계값을 초기화하고 원격 데이터베이스 사용량 확인 -Reset the remote storage size threshold and check the remote storage size again.: 원격 저장소 크기 임계값을 초기화하고 원격 저장소 크기를 다시 확인합니다. -Scram Switches: 긴급 전환 스위치 -Minimum interval for syncing: 동기화 최소 간격 -The minimum interval for automatic synchronisation on event.: 이벤트 발생 시 자동 동기화의 최소 간격입니다. -"Welcome to Self-hosted LiveSync": "Self-hosted LiveSync에 오신 것을 환영합니다" -"We will now guide you through a few questions to simplify the synchronisation setup.": "동기화 설정을 더 쉽게 진행할 수 있도록 몇 가지 질문으로 안내해 드리겠습니다。" -"First, please select the option that best describes your current situation.": "먼저 현재 상황에 가장 잘 맞는 항목을 선택해 주세요。" -"I am setting this up for the first time": "처음으로 설정합니다" -"(Select this if you are configuring this device as the first synchronisation device.) This option is suitable if you are new to LiveSync and want to set it up from scratch.": "(이 장치를 첫 번째 동기화 장치로 설정하는 경우 선택하세요.) LiveSync를 처음 사용하며 처음부터 설정하려는 경우에 적합합니다。" -"I am adding a device to an existing synchronisation setup": "기존 동기화 구성에 장치를 추가합니다" -"(Select this if you are already using synchronisation on another computer or smartphone.) This option is suitable if you are new to LiveSync and want to set it up from scratch.": "(다른 컴퓨터나 스마트폰에서 이미 동기화를 사용 중인 경우 선택하세요.) 이 장치를 기존 LiveSync 구성에 추가하려는 경우에 적합합니다。" -"Yes, I want to set up a new synchronisation": "예, 새 동기화를 설정하겠습니다" -"Yes, I want to add this device to my existing synchronisation": "예, 이 장치를 기존 동기화에 추가하겠습니다" -"No, please take me back": "아니요, 이전으로 돌아가겠습니다" -"Device Setup Method": "장치 설정 방법" -"You are adding this device to an existing synchronisation setup.": "이 장치를 기존 동기화 구성에 추가하려고 합니다。" -"Please select a method to import the settings from another device.": "다른 장치에서 설정을 가져올 방법을 선택해 주세요。" -"Use a Setup URI (Recommended)": "설정 URI 사용(권장)" -"Paste the Setup URI generated from one of your active devices.": "현재 사용 중인 장치 중 하나에서 생성한 설정 URI를 붙여 넣으세요。" -"Scan a QR Code (Recommended for mobile)": "QR 코드 스캔(모바일 권장)" -"Scan the QR code displayed on an active device using this device's camera.": "이 장치의 카메라로 활성 장치에 표시된 QR 코드를 스캔하세요。" -"Enter the server information manually": "서버 정보를 수동으로 입력" -"Configure the same server information as your other devices again, manually, very advanced users only.": "다른 장치와 동일한 서버 정보를 다시 수동으로 입력합니다. 고급 사용자 전용입니다。" -"Proceed with Setup URI": "설정 URI로 계속" -"I know my server details, let me enter them": "서버 정보를 알고 있으니 직접 입력하겠습니다" -"Please select an option to proceed": "계속하려면 항목을 선택해 주세요" -"Connection Method": "연결 방법" -"We will now proceed with the server configuration.": "이제 서버 구성을 진행하겠습니다。" -"How would you like to configure the connection to your server?": "서버 연결을 어떻게 구성하시겠습니까?" -"A Setup URI is a single string of text containing your server address and authentication details. Using a URI, if one was generated by your server installation script, provides a simple and secure configuration.": "설정 URI는 서버 주소와 인증 정보를 포함한 단일 문자열입니다. 서버 설치 스크립트가 URI를 생성했다면 이를 사용하면 간단하고 안전하게 구성할 수 있습니다。" -"This is an advanced option for users who do not have a URI or who wish to configure detailed settings.": "URI가 없거나 세부 설정을 직접 구성하려는 사용자를 위한 고급 옵션입니다。" -"Enter Server Information": "서버 정보 입력" -"Please select the type of server to which you are connecting.": "연결할 서버 유형을 선택해 주세요。" -"Continue to CouchDB setup": "CouchDB 설정으로 계속" -"Continue to S3/MinIO/R2 setup": "S3/MinIO/R2 설정으로 계속" -"Continue to Peer-to-Peer only setup": "Peer-to-Peer 전용 설정으로 계속" -"This is the most suitable synchronisation method for the design. All functions are available. You must have set up a CouchDB instance.": "이 설계에 가장 적합한 동기화 방식입니다. 모든 기능을 사용할 수 있습니다. CouchDB 인스턴스를 미리 구성해야 합니다。" -"S3/MinIO/R2 Object Storage": "S3/MinIO/R2 객체 스토리지" -"Synchronisation utilising journal files. You must have set up an S3/MinIO/R2 compatible object storage.": "저널 파일을 활용하는 동기화 방식입니다. S3/MinIO/R2 호환 객체 스토리지를 미리 구성해야 합니다。" -"Peer-to-Peer only": "Peer-to-Peer 전용" -"This feature enables direct synchronisation between devices. No server is required, but both devices must be online at the same time for synchronisation to occur, and some features may be limited. Internet connection is only required to signalling (detecting peers) and not for data transfer.": "이 기능은 장치 간 직접 동기화를 제공합니다. 서버는 필요 없지만 동기화가 이루어지려면 두 장치가 동시에 온라인 상태여야 하며 일부 기능은 제한될 수 있습니다. 인터넷 연결은 시그널링(피어 감지)에만 필요하며 데이터 전송 자체에는 필요하지 않습니다。" +Yes, I want to add this device to my existing synchronisation: 예, 이 기기를 기존 동기화 구성에 추가하겠습니다 +Yes, I want to set up a new synchronisation: 예, 새 동기화를 설정하겠습니다 +You are adding this device to an existing synchronisation setup.: 이 기기를 기존 동기화 구성에 추가합니다. diff --git a/src/modules/core/ReplicateResultProcessor.ts b/src/modules/core/ReplicateResultProcessor.ts index e86ad530..e6840439 100644 --- a/src/modules/core/ReplicateResultProcessor.ts +++ b/src/modules/core/ReplicateResultProcessor.ts @@ -24,9 +24,16 @@ import type { ReactiveSource } from "octagonal-wheels/dataobject/reactive_v2"; import type { LiveSyncBaseCore } from "@/LiveSyncBaseCore"; import { isNotFoundError } from "@vrtmrz/livesync-commonlib/compat/common/utils.doc"; import type PouchDB from "pouchdb-core"; +import { promiseWithResolvers, type PromiseWithResolvers } from "octagonal-wheels/promises"; const KV_KEY_REPLICATION_RESULT_PROCESSOR_SNAPSHOT = "replicationResultProcessorSnapshot"; const REPROCESS_BATCH_SIZE = 100; +type LocalApplicationActivityOwner = { + runBoundedLocalApplicationActivity( + task: () => T | PromiseLike, + options?: { label?: string } + ): Promise; +}; type ReplicateResultProcessorState = { queued: PouchDB.Core.ExistingDocument[]; processing: PouchDB.Core.ExistingDocument[]; @@ -67,9 +74,11 @@ export class ReplicateResultProcessor { public suspend() { this._suspended = true; + this.updateProcessingActivity(); } public resume() { this._suspended = false; + this.updateProcessingActivity(); fireAndForget(() => this.runProcessQueue()); } @@ -251,6 +260,40 @@ export class ReplicateResultProcessor { */ private _processingChanges: PouchDB.Core.ExistingDocument[] = []; + private _processingActivity?: Promise; + private _processingActivityDone?: PromiseWithResolvers; + + private updateProcessingActivity() { + if (this.isSuspended) { + this._processingActivityDone?.resolve(); + return; + } + const hasPendingDocuments = this._queuedChanges.length > 0 || this._processingChanges.length > 0; + if (!hasPendingDocuments) { + this._processingActivityDone?.resolve(); + return; + } + if (this._processingActivity) return; + + const activityDone = promiseWithResolvers(); + this._processingActivityDone = activityDone; + const activityOwner = this.services.replicator as typeof this.services.replicator & + Partial; + this._processingActivity = ( + activityOwner.runBoundedLocalApplicationActivity + ? activityOwner.runBoundedLocalApplicationActivity(() => activityDone.promise, { + label: "replicated-document-application", + }) + : activityDone.promise + ) + .catch((error) => this.logError(error)) + .finally(() => { + if (this._processingActivityDone === activityDone) this._processingActivityDone = undefined; + this._processingActivity = undefined; + this.updateProcessingActivity(); + }); + } + /** * Enqueue the given document change for processing. * @param doc Document change to enqueue @@ -278,6 +321,7 @@ export class ReplicateResultProcessor { } // Enqueue the change this._queuedChanges.push(doc); + this.updateProcessingActivity(); this.triggerTakeSnapshot(); this.triggerProcessQueue(); } @@ -385,7 +429,19 @@ export class ReplicateResultProcessor { } finally { // Remove from processing queue this._processingChanges = this._processingChanges.filter((e) => e !== change); - this.triggerTakeSnapshot(); + try { + if (this._queuedChanges.length === 0 && this._processingChanges.length === 0) { + try { + await this._takeSnapshot(); + } catch (error) { + this.logError(error); + } + } else { + this.triggerTakeSnapshot(); + } + } finally { + this.updateProcessingActivity(); + } } } diff --git a/src/modules/core/ReplicateResultProcessor.unit.spec.ts b/src/modules/core/ReplicateResultProcessor.unit.spec.ts index c55e85fc..61c7af61 100644 --- a/src/modules/core/ReplicateResultProcessor.unit.spec.ts +++ b/src/modules/core/ReplicateResultProcessor.unit.spec.ts @@ -1,8 +1,67 @@ +import { promiseWithResolvers } from "octagonal-wheels/promises"; +import { reactiveSource } from "octagonal-wheels/dataobject/reactive"; import { describe, expect, it, vi } from "vitest"; import type { EntryDoc } from "@vrtmrz/livesync-commonlib/compat/common/types"; import { ReplicateResultProcessor } from "./ReplicateResultProcessor"; -describe("ReplicateResultProcessor target-filter reprocessing", () => { +function note(id: string): PouchDB.Core.ExistingDocument { + return { + _id: id, + _rev: "1-test", + path: `${id}.md`, + ctime: 1, + mtime: 2, + size: 1, + children: [], + datatype: "plain", + type: "plain", + eden: {}, + } as unknown as PouchDB.Core.ExistingDocument; +} + +type SetupOptions = { + processSynchroniseResult?: (entry: unknown) => Promise; + setSnapshot?: (key: string, value: unknown) => Promise; +}; + +function setup(options: SetupOptions = {}) { + const processSynchroniseResult = vi.fn(options.processSynchroniseResult ?? (async () => undefined)); + const setSnapshot = vi.fn(options.setSnapshot ?? (async () => undefined)); + const runBoundedLocalApplicationActivity = vi.fn(async (task: () => Promise) => await task()); + const core = { + services: { + appLifecycle: { isReady: true, isSuspended: () => false }, + path: { getPath: (entry: { path: string }) => entry.path }, + replication: { + databaseQueueCount: reactiveSource(0), + storageApplyingCount: reactiveSource(0), + replicationResultCount: reactiveSource(0), + processVirtualDocument: vi.fn(async () => false), + processOptionalSynchroniseResult: vi.fn(async () => false), + processSynchroniseResult, + }, + replicator: { runBoundedLocalApplicationActivity }, + vault: { + isTargetFile: vi.fn(async () => true), + isFileSizeTooLarge: vi.fn(() => false), + isValidPath: vi.fn(() => true), + }, + }, + kvDB: { set: setSnapshot }, + localDatabase: { + getRaw: vi.fn(async (id: string) => ({ _id: id, _rev: "1-test" })), + getDBEntryFromMeta: vi.fn(async (entry: object) => ({ ...entry, data: "x" })), + }, + replicator: { closeReplication: vi.fn() }, + }; + const processor = new ReplicateResultProcessor({ + core, + settings: { maxMTimeForReflectEvents: 0, suspendParseReplicationResult: false }, + } as never); + return { processor, processSynchroniseResult, runBoundedLocalApplicationActivity }; +} + +describe("ReplicateResultProcessor", () => { it("scans normal-file metadata without loading chunk documents and requeues it", async () => { const documents = [ { _id: "first", _rev: "1-a", type: "plain", path: "first.md" }, @@ -22,4 +81,67 @@ describe("ReplicateResultProcessor target-filter reprocessing", () => { expect(enqueueAll).toHaveBeenCalledOnce(); expect(enqueueAll).toHaveBeenCalledWith(documents); }); + + it("keeps one local application activity until every replicated document has been applied", async () => { + const applying = promiseWithResolvers(); + let activityFinished = false; + const { processor, processSynchroniseResult, runBoundedLocalApplicationActivity } = setup({ + processSynchroniseResult: async () => applying.promise, + }); + runBoundedLocalApplicationActivity.mockImplementation(async (task: () => Promise) => { + await task(); + activityFinished = true; + }); + + processor.enqueueAll([note("one"), note("two")]); + + await vi.waitFor(() => expect(processSynchroniseResult).toHaveBeenCalledTimes(2)); + expect(runBoundedLocalApplicationActivity).toHaveBeenCalledTimes(1); + expect(runBoundedLocalApplicationActivity).toHaveBeenCalledWith(expect.any(Function), { + label: "replicated-document-application", + }); + expect(activityFinished).toBe(false); + + applying.resolve(); + + await vi.waitFor(() => expect(activityFinished).toBe(true)); + }); + + it("settles local application activity when the final recovery snapshot fails", async () => { + let activityFinished = false; + const { processor, runBoundedLocalApplicationActivity } = setup({ + setSnapshot: async () => Promise.reject(new Error("snapshot failed")), + }); + runBoundedLocalApplicationActivity.mockImplementation(async (task: () => Promise) => { + await task(); + activityFinished = true; + }); + + processor.enqueueAll([note("one")]); + + await vi.waitFor(() => expect(activityFinished).toBe(true)); + }); + + it("releases and reacquires local application activity around processing suspension", async () => { + const applying = promiseWithResolvers(); + let completedActivities = 0; + const { processor, processSynchroniseResult, runBoundedLocalApplicationActivity } = setup({ + processSynchroniseResult: async () => applying.promise, + }); + runBoundedLocalApplicationActivity.mockImplementation(async (task: () => Promise) => { + await task(); + completedActivities++; + }); + processor.enqueueAll([note("one")]); + await vi.waitFor(() => expect(processSynchroniseResult).toHaveBeenCalledOnce()); + + processor.suspend(); + await vi.waitFor(() => expect(completedActivities).toBe(1)); + + processor.resume(); + await vi.waitFor(() => expect(runBoundedLocalApplicationActivity).toHaveBeenCalledTimes(2)); + + applying.resolve(); + await vi.waitFor(() => expect(completedActivities).toBe(2)); + }); }); diff --git a/src/modules/essentialObsidian/ModuleObsidianEvents.ts b/src/modules/essentialObsidian/ModuleObsidianEvents.ts index 46ff9bf8..d266dd72 100644 --- a/src/modules/essentialObsidian/ModuleObsidianEvents.ts +++ b/src/modules/essentialObsidian/ModuleObsidianEvents.ts @@ -113,9 +113,20 @@ export class ModuleObsidianEvents extends AbstractObsidianModule { hasFocus = true; isLastHidden = false; - private boundedRemoteActivityEndHandler?: (value: { readonly value: number }) => unknown; + private boundedActivityEndHandler?: (value: { readonly value: number }) => unknown; private deferredBoundedLifecycle?: "suspend-if-hidden" | "restart-continuous-if-visible"; + private get boundedActivityCounts(): ReactiveSource[] { + const replicator = this.services.replicator as typeof this.services.replicator & { + boundedLocalApplicationActivityCount: ReactiveSource; + }; + return [replicator.boundedRemoteActivityCount, replicator.boundedLocalApplicationActivityCount]; + } + + private hasBoundedActivity() { + return this.boundedActivityCounts.some((count) => count.value > 0); + } + private keepReplicationActiveInBackground() { return ( this.settings.keepReplicationActiveInBackground && @@ -125,9 +136,8 @@ export class ModuleObsidianEvents extends AbstractObsidianModule { } private async applyDeferredBoundedActivityLifecycle() { - const count = this.services.replicator.boundedRemoteActivityCount; - if (count.value !== 0) { - this.deferLifecycleUntilBoundedRemoteActivityEnds(); + if (this.hasBoundedActivity()) { + this.deferLifecycleUntilBoundedActivityEnds(); return; } const deferredLifecycle = this.deferredBoundedLifecycle; @@ -149,17 +159,17 @@ export class ModuleObsidianEvents extends AbstractObsidianModule { } } - private deferLifecycleUntilBoundedRemoteActivityEnds() { - if (this.boundedRemoteActivityEndHandler) return; - const count = this.services.replicator.boundedRemoteActivityCount; - const handler = (value: { readonly value: number }) => { - if (value.value !== 0) return; - count.offChanged(handler); - this.boundedRemoteActivityEndHandler = undefined; + private deferLifecycleUntilBoundedActivityEnds() { + if (this.boundedActivityEndHandler) return; + const counts = this.boundedActivityCounts; + const handler = () => { + if (this.hasBoundedActivity()) return; + for (const count of counts) count.offChanged(handler); + this.boundedActivityEndHandler = undefined; fireAndForget(() => this.applyDeferredBoundedActivityLifecycle()); }; - this.boundedRemoteActivityEndHandler = handler; - count.onChanged(handler); + this.boundedActivityEndHandler = handler; + for (const count of counts) count.onChanged(handler); } setHasFocus(hasFocus: boolean) { @@ -188,12 +198,12 @@ export class ModuleObsidianEvents extends AbstractObsidianModule { if ( this.settings.isConfigured && this.services.appLifecycle.isReady() && - this.services.replicator.boundedRemoteActivityCount.value > 0 + this.hasBoundedActivity() ) { const isHidden = activeWindow.document.hidden; this.isLastHidden = isHidden; this.deferredBoundedLifecycle = isHidden ? "suspend-if-hidden" : undefined; - this.deferLifecycleUntilBoundedRemoteActivityEnds(); + this.deferLifecycleUntilBoundedActivityEnds(); } return; } @@ -210,8 +220,8 @@ export class ModuleObsidianEvents extends AbstractObsidianModule { return; } - const boundedRemoteActivityInProgress = this.services.replicator.boundedRemoteActivityCount.value > 0; - if (!isHidden && boundedRemoteActivityInProgress && this.deferredBoundedLifecycle === "suspend-if-hidden") { + const boundedActivityInProgress = this.hasBoundedActivity(); + if (!isHidden && boundedActivityInProgress && this.deferredBoundedLifecycle === "suspend-if-hidden") { this.isLastHidden = false; this.deferredBoundedLifecycle = undefined; return; @@ -228,18 +238,18 @@ export class ModuleObsidianEvents extends AbstractObsidianModule { const keepActiveInBackground = this.keepReplicationActiveInBackground(); if (isHidden) { - if (boundedRemoteActivityInProgress && !keepActiveInBackground) { + if (boundedActivityInProgress && !keepActiveInBackground) { this.deferredBoundedLifecycle = "suspend-if-hidden"; - this.deferLifecycleUntilBoundedRemoteActivityEnds(); + this.deferLifecycleUntilBoundedActivityEnds(); } else if (!keepActiveInBackground) { await this.services.appLifecycle.onSuspending(); } } else { // suspend all temporary. if (this.services.appLifecycle.isSuspended()) return; - if (boundedRemoteActivityInProgress && keepActiveInBackground && this.settings.liveSync) { + if (boundedActivityInProgress && keepActiveInBackground && this.settings.liveSync) { this.deferredBoundedLifecycle = "restart-continuous-if-visible"; - this.deferLifecycleUntilBoundedRemoteActivityEnds(); + this.deferLifecycleUntilBoundedActivityEnds(); return; } // Only the continuous (LiveSync) channel can go stalled-but-not-terminated: PouchDB diff --git a/src/modules/essentialObsidian/ModuleObsidianEvents.unit.spec.ts b/src/modules/essentialObsidian/ModuleObsidianEvents.unit.spec.ts index 48305577..64b92b2b 100644 --- a/src/modules/essentialObsidian/ModuleObsidianEvents.unit.spec.ts +++ b/src/modules/essentialObsidian/ModuleObsidianEvents.unit.spec.ts @@ -24,6 +24,7 @@ function setup(opts: SetupOptions) { }; const fileProcessing = { commitPendingFileEvents: vi.fn(async () => true) }; const boundedRemoteActivityCount = reactiveSource(0); + const boundedLocalApplicationActivityCount = reactiveSource(0); const core = { _services: { @@ -38,7 +39,7 @@ function setup(opts: SetupOptions) { setting: { saveSettingData: vi.fn(async () => undefined) }, appLifecycle, fileProcessing, - replicator: { boundedRemoteActivityCount }, + replicator: { boundedRemoteActivityCount, boundedLocalApplicationActivityCount }, }, settings: { ...DEFAULT_SETTINGS, @@ -56,7 +57,13 @@ function setup(opts: SetupOptions) { // The handler reads `activeWindow.document.hidden`. (globalThis as any).activeWindow = { document: { hidden: opts.hidden } }; - return { module, appLifecycle, fileProcessing, boundedRemoteActivityCount }; + return { + module, + appLifecycle, + fileProcessing, + boundedRemoteActivityCount, + boundedLocalApplicationActivityCount, + }; } describe("watchWindowVisibilityAsync — keepReplicationActiveInBackground", () => { @@ -109,6 +116,21 @@ describe("watchWindowVisibilityAsync — keepReplicationActiveInBackground", () await vi.waitFor(() => expect(appLifecycle.onSuspending).toHaveBeenCalledTimes(1)); }); + it("defers suspension while local document application is active", async () => { + const { module, appLifecycle, boundedLocalApplicationActivityCount } = setup({ + settings: { keepReplicationActiveInBackground: false, liveSync: false }, + hidden: true, + }); + boundedLocalApplicationActivityCount.value = 1; + + await module.watchWindowVisibilityAsync(); + + expect(appLifecycle.onSuspending).not.toHaveBeenCalled(); + + boundedLocalApplicationActivityCount.value = 0; + await vi.waitFor(() => expect(appLifecycle.onSuspending).toHaveBeenCalledTimes(1)); + }); + it("defers mobile suspension while bounded remote activity is running", async () => { const { module, appLifecycle, boundedRemoteActivityCount } = setup({ settings: { keepReplicationActiveInBackground: false, liveSync: false }, diff --git a/src/modules/features/DocumentHistory/DocumentHistoryModal.ts b/src/modules/features/DocumentHistory/DocumentHistoryModal.ts index 468a4ee5..3a173ebd 100644 --- a/src/modules/features/DocumentHistory/DocumentHistoryModal.ts +++ b/src/modules/features/DocumentHistory/DocumentHistoryModal.ts @@ -74,6 +74,11 @@ export class DocumentHistoryModal extends Modal { currentDeleted = false; initialRev?: string; + // Revision navigation state (◀/▶ beside the range slider) + revPrevBtn!: HTMLButtonElement; + revNextBtn!: HTMLButtonElement; + revNavIndicator!: HTMLSpanElement; + // Diff navigation state currentDiffIndex = -1; diffNavContainer!: HTMLDivElement; @@ -84,6 +89,8 @@ export class DocumentHistoryModal extends Modal { searchKeyword = ""; searchResults: { rev: string; index: number; matchType: "Content" | "Diff" }[] = []; currentSearchIndex = -1; + searchPrevBtn!: HTMLButtonElement; + searchNextBtn!: HTMLButtonElement; searchResultIndicator!: HTMLSpanElement; searchProgressIndicator!: HTMLSpanElement; searchTimeout: number | null = null; @@ -125,12 +132,14 @@ export class DocumentHistoryModal extends Modal { this.range.value = this.range.max; this.fileInfo.setText(`${this.file} / ${this.revs_info.length} revisions`); await this.loadRevs(initialRev); + this.updateRevisionNavUI(); } catch (ex) { if (isErrorOfMissingDoc(ex)) { this.range.max = "0"; this.range.value = ""; this.range.disabled = true; this.contentView.setText(`We don't have any history for this note.`); + this.updateRevisionNavUI(); } else { this.contentView.setText(`Error while loading file.`); Logger(ex, LOG_LEVEL_VERBOSE); @@ -148,6 +157,37 @@ export class DocumentHistoryModal extends Modal { const index = this.revs_info.length - 1 - (Number(this.range.value) || 0); const rev = this.revs_info[index]; await this.showExactRev(rev.rev); + this.updateRevisionNavUI(); + } + + navigateVersion(direction: "older" | "newer") { + const current = Number(this.range.value) || 0; + const max = Number(this.range.max) || 0; + + if (direction === "older" && current > 0) { + this.range.value = `${current - 1}`; + } else if (direction === "newer" && current < max) { + this.range.value = `${current + 1}`; + } else { + return; + } + + this.updateRevisionNavUI(); + void scheduleOnceIfDuplicated("loadRevs", () => this.loadRevs()); + } + + updateRevisionNavUI() { + if (!this.revNavIndicator) return; + + const total = this.revs_info.length; + const max = Number(this.range.max) || 0; + const current = Number(this.range.value) || 0; + + this.revNavIndicator.setText(total > 0 ? `Rev ${current + 1}/${total}` : "\u2014"); + + const disabled = !!this.range.disabled || total <= 1; + this.revPrevBtn.disabled = disabled || current <= 0; + this.revNextBtn.disabled = disabled || current >= max; } BlobURLs = new Map(); @@ -391,6 +431,7 @@ export class DocumentHistoryModal extends Modal { if (!keyword) { this.searchResultIndicator.setText(""); this.searchProgressIndicator.setText(""); + this.updateSearchUI(); return; } @@ -464,6 +505,10 @@ export class DocumentHistoryModal extends Modal { const current = this.currentSearchIndex >= 0 ? this.currentSearchIndex + 1 : 0; this.searchResultIndicator.setText(`${current}/${this.searchResults.length} matches`); } + + const hasResults = this.searchResults.length > 0; + this.searchPrevBtn.disabled = !hasResults; + this.searchNextBtn.disabled = !hasResults; } navigateSearch(direction: "prev" | "next") { @@ -515,12 +560,14 @@ export class DocumentHistoryModal extends Modal { }, 500); }); - searchRow.createEl("button", { text: "\u25B2" }, (e) => { + this.searchPrevBtn = searchRow.createEl("button", { text: "\u25B2" }, (e) => { e.title = "Previous match"; + e.disabled = true; e.addEventListener("click", () => this.navigateSearch("prev")); }); - searchRow.createEl("button", { text: "\u25BC" }, (e) => { + this.searchNextBtn = searchRow.createEl("button", { text: "\u25BC" }, (e) => { e.title = "Next match"; + e.disabled = true; e.addEventListener("click", () => this.navigateSearch("next")); }); @@ -530,18 +577,37 @@ export class DocumentHistoryModal extends Modal { this.searchProgressIndicator = searchRow.createSpan({ text: "" }); this.searchProgressIndicator.addClass("history-search-progress-indicator"); - const divView = contentEl.createDiv(""); - divView.addClass("op-flex"); + const revNavRow = contentEl.createDiv({ cls: "history-rev-nav-row" }); - divView.createEl("input", { type: "range" }, (e) => { + this.revPrevBtn = revNavRow.createEl("button", { text: "\u25C0" }, (e) => { + e.addClass("history-rev-nav-btn"); + e.title = "Older revision"; + e.disabled = true; + e.addEventListener("click", () => this.navigateVersion("older")); + }); + + revNavRow.createEl("input", { type: "range" }, (e) => { this.range = e; - e.addEventListener("change", (e) => { + e.addEventListener("change", () => { + this.updateRevisionNavUI(); void scheduleOnceIfDuplicated("loadRevs", () => this.loadRevs()); }); - e.addEventListener("input", (e) => { + e.addEventListener("input", () => { + this.updateRevisionNavUI(); void scheduleOnceIfDuplicated("loadRevs", () => this.loadRevs()); }); }); + + this.revNextBtn = revNavRow.createEl("button", { text: "\u25B6" }, (e) => { + e.addClass("history-rev-nav-btn"); + e.title = "Newer revision"; + e.disabled = true; + e.addEventListener("click", () => this.navigateVersion("newer")); + }); + + this.revNavIndicator = revNavRow.createSpan({ text: "\u2014" }, (e) => { + e.addClass("history-rev-indicator"); + }); const diffOptionsRow = contentEl.createDiv(""); diffOptionsRow.addClass("op-info"); diffOptionsRow.addClass("diff-options-row"); diff --git a/src/modules/services/ObsidianServices.ts b/src/modules/services/ObsidianServices.ts index 2873e014..9ea120d2 100644 --- a/src/modules/services/ObsidianServices.ts +++ b/src/modules/services/ObsidianServices.ts @@ -10,11 +10,32 @@ import { ConfigServiceBrowserCompat } from "@vrtmrz/livesync-commonlib/compat/se import type { ObsidianServiceContext } from "@/modules/services/ObsidianServiceContext"; import { KeyValueDBService } from "@vrtmrz/livesync-commonlib/compat/services/base/KeyValueDBService"; import { ControlService } from "@vrtmrz/livesync-commonlib/compat/services/base/ControlService"; +import { reactiveSource } from "octagonal-wheels/dataobject/reactive"; + +type ActivityOptions = { + label?: string; +}; export class ObsidianDatabaseEventService extends InjectableDatabaseEventService {} // InjectableReplicatorService -export class ObsidianReplicatorService extends InjectableReplicatorService {} +export class ObsidianReplicatorService extends InjectableReplicatorService { + readonly boundedLocalApplicationActivityCount = reactiveSource(0); + + async runBoundedLocalApplicationActivity( + task: () => T | PromiseLike, + options?: ActivityOptions + ): Promise { + this.boundedLocalApplicationActivityCount.value++; + try { + return this.dependencies.activityRunner + ? await this.dependencies.activityRunner.run(task, options) + : await task(); + } finally { + this.boundedLocalApplicationActivityCount.value--; + } + } +} // InjectableFileProcessingService export class ObsidianFileProcessingService extends InjectableFileProcessingService {} // InjectableReplicationService diff --git a/src/modules/services/ObsidianServices.unit.spec.ts b/src/modules/services/ObsidianServices.unit.spec.ts new file mode 100644 index 00000000..1e09755d --- /dev/null +++ b/src/modules/services/ObsidianServices.unit.spec.ts @@ -0,0 +1,35 @@ +import { promiseWithResolvers } from "octagonal-wheels/promises"; +import { describe, expect, it, vi } from "vitest"; +import { ObsidianReplicatorService } from "./ObsidianServices"; + +function handler() { + return { addHandler: vi.fn() }; +} + +describe("ObsidianReplicatorService", () => { + it("tracks local application activity without extending remote activity", async () => { + const activity = promiseWithResolvers(); + const service = new ObsidianReplicatorService({ events: {}, translate: String } as never, { + settingService: { onRealiseSetting: handler() }, + appLifecycleService: { onSuspending: handler(), getUnresolvedMessages: handler() }, + databaseEventService: { + onResetDatabase: handler(), + onDatabaseInitialisation: handler(), + onDatabaseInitialised: handler(), + onDatabaseHasReady: handler(), + }, + activityRunner: { run: vi.fn(async (task: () => Promise) => await task()) }, + } as never); + + const running = service.runBoundedLocalApplicationActivity(() => activity.promise); + + expect(service.boundedLocalApplicationActivityCount.value).toBe(1); + expect(service.boundedRemoteActivityCount.value).toBe(0); + + activity.resolve(); + await running; + + expect(service.boundedLocalApplicationActivityCount.value).toBe(0); + expect(service.boundedRemoteActivityCount.value).toBe(0); + }); +}); diff --git a/src/serviceModules/FileSystemAdapters/ObsidianVaultAdapter.ts b/src/serviceModules/FileSystemAdapters/ObsidianVaultAdapter.ts index fb5fff32..291fd290 100644 --- a/src/serviceModules/FileSystemAdapters/ObsidianVaultAdapter.ts +++ b/src/serviceModules/FileSystemAdapters/ObsidianVaultAdapter.ts @@ -10,7 +10,8 @@ export class ObsidianVaultAdapter implements IVaultAdapter { constructor(private app: App) {} async read(file: TFile): Promise { - return await this.app.vault.read(file); + // Vault.read strips a leading UTF-8 BOM, leaving the content size inconsistent with TFile.stat. + return await this.app.vault.adapter.read(file.path); } async cachedRead(file: TFile): Promise { diff --git a/src/serviceModules/FileSystemAdapters/ObsidianVaultAdapter.unit.spec.ts b/src/serviceModules/FileSystemAdapters/ObsidianVaultAdapter.unit.spec.ts new file mode 100644 index 00000000..5a307d52 --- /dev/null +++ b/src/serviceModules/FileSystemAdapters/ObsidianVaultAdapter.unit.spec.ts @@ -0,0 +1,37 @@ +import { describe, expect, it, vi } from "vitest"; +import type { App, TFile } from "obsidian"; +import { ObsidianVaultAdapter } from "./ObsidianVaultAdapter"; + +describe("ObsidianVaultAdapter.read", () => { + it("preserves a UTF-8 BOM so the content size matches the file stat", async () => { + const path = "Transcripts/字幕.md"; + const contentWithoutBom = "字幕の検証行です。\n"; + const contentWithBom = `\ufeff${contentWithoutBom}`; + const read = vi.fn().mockResolvedValue(contentWithoutBom); + const adapterRead = vi.fn().mockResolvedValue(contentWithBom); + const app = { + vault: { + read, + adapter: { + read: adapterRead, + }, + }, + } as unknown as App; + const file = { + path, + stat: { + ctime: 1, + mtime: 2, + size: new Blob([contentWithBom]).size, + }, + } as TFile; + const adapter = new ObsidianVaultAdapter(app); + + const result = await adapter.read(file); + + expect(new Blob([result]).size).toBe(file.stat.size); + expect(result.charCodeAt(0)).toBe(0xfeff); + expect(adapterRead).toHaveBeenCalledWith(path); + expect(read).not.toHaveBeenCalled(); + }); +}); diff --git a/styles.css b/styles.css index df392c58..d6efd96a 100644 --- a/styles.css +++ b/styles.css @@ -748,6 +748,51 @@ body.is-mobile .livesync-compatibility-review-notice { color: var(--text-muted); } +.history-search-row button:disabled { + opacity: 0.4; + cursor: not-allowed; +} + +.history-rev-nav-row { + display: flex; + align-items: center; + gap: 6px; + margin-bottom: 8px; +} + +.history-rev-nav-row input[type="range"] { + flex-grow: 1; + margin-bottom: 0; +} + +.history-rev-nav-btn { + flex-shrink: 0; + padding: 2px 10px; + font-size: 0.9em; + cursor: pointer; + border: 1px solid var(--background-modifier-border); + border-radius: 4px; + background-color: var(--background-secondary); + color: var(--text-normal); +} + +.history-rev-nav-btn:hover:not(:disabled) { + background-color: var(--background-modifier-hover); +} + +.history-rev-nav-btn:disabled { + opacity: 0.4; + cursor: not-allowed; +} + +.history-rev-indicator { + flex-shrink: 0; + font-size: 0.85em; + color: var(--text-muted); + min-width: 4.5em; + text-align: right; +} + .history-diff-options-row { justify-content: space-between; } diff --git a/test/e2e-obsidian/scripts/document-history-nav.ts b/test/e2e-obsidian/scripts/document-history-nav.ts new file mode 100644 index 00000000..9daf0752 --- /dev/null +++ b/test/e2e-obsidian/scripts/document-history-nav.ts @@ -0,0 +1,293 @@ +import { mkdir, writeFile } from "node:fs/promises"; +import { join } from "node:path"; +import { evalObsidianJson } from "../runner/cli.ts"; +import { discoverObsidianCli, requireObsidianBinary } from "../runner/environment.ts"; +import { createE2eObsidianDeviceLocalState, waitForLiveSyncCoreReady } from "../runner/liveSyncWorkflow.ts"; +import { startObsidianLiveSyncSession, type ObsidianLiveSyncSession } from "../runner/session.ts"; +import { withObsidianPage } from "../runner/ui.ts"; +import { createTemporaryVault } from "../runner/vault.ts"; + +process.env.E2E_OBSIDIAN_CLI_TIMEOUT_MS ??= "60000"; +process.env.E2E_OBSIDIAN_CORE_READY_TIMEOUT_MS ??= "60000"; +process.env.E2E_OBSIDIAN_LOCAL_DB_TIMEOUT_MS ??= "30000"; + +const notePath = "E2E/document-history-nav.md"; +const revisions = ["Version one alpha", "Version two beta keyword", "Version three gamma"]; + +type RevisionInfo = { + revCount: number; + id: string; +}; + +type OpenHistoryResult = { + opened: boolean; + modalTitle: string | null; +}; + +function assertEqual(actual: unknown, expected: unknown, message: string): void { + if (actual !== expected) { + throw new Error(`${message}\nExpected: ${String(expected)}\nActual: ${String(actual)}`); + } +} + +function assertTrue(value: boolean, message: string): void { + if (!value) { + throw new Error(message); + } +} + +async function dismissWelcomeWizard(port: number): Promise { + await withObsidianPage(port, async (page) => { + const cancel = page.getByText("No, please take me back"); + if (await cancel.isVisible({ timeout: 5000 }).catch(() => false)) { + await cancel.click(); + await page.waitForTimeout(500); + } + }); +} + +async function seedRevisions(cliBinary: string, env: NodeJS.ProcessEnv): Promise { + return await evalObsidianJson( + cliBinary, + [ + "(async()=>{", + `const path=${JSON.stringify(notePath)};`, + `const revisions=${JSON.stringify(revisions)};`, + "const core=app.plugins.plugins['obsidian-livesync'].core;", + "const sleep=(ms)=>new Promise((resolve)=>setTimeout(resolve,ms));", + "if(!(await app.vault.adapter.exists('E2E'))) await app.vault.createFolder('E2E');", + "const existing=app.vault.getAbstractFileByPath(path);", + "if(existing) await app.vault.delete(existing);", + "const id=await core.services.path.path2id(path);", + "let baseRev='';", + "for(const content of revisions){", + " const blob=new Blob([content],{type:'text/plain'});", + " const now=Date.now();", + " const result=await core.localDatabase.putDBEntry({", + " _id:id,", + " path,", + " data:blob,", + " ctime:now,", + " mtime:now,", + " size:(await blob.arrayBuffer()).byteLength,", + " children:[],", + " datatype:'plain',", + " type:'plain',", + " eden:{},", + " },false,baseRev||undefined);", + " if(!result?.ok) throw new Error(`Could not store revision for ${path}`);", + " baseRev=result.rev;", + " await sleep(100);", + "}", + `await app.vault.create(path,revisions[revisions.length-1]);`, + "await core.services.fileProcessing.commitPendingFileEvents();", + "const raw=await core.localDatabase.getRaw(id,{revs_info:true});", + "const revCount=(raw._revs_info||[]).filter((e)=>e&&e.status==='available').length;", + "return JSON.stringify({revCount,id});", + "})()", + ].join(""), + env + ); +} + +async function openDocumentHistory(cliBinary: string, env: NodeJS.ProcessEnv): Promise { + return await evalObsidianJson( + cliBinary, + [ + "(async()=>{", + `const path=${JSON.stringify(notePath)};`, + "const file=app.vault.getAbstractFileByPath(path);", + "if(!file) throw new Error('Note missing before opening history');", + "document.querySelectorAll('.modal-close-button').forEach((btn)=>btn.click());", + "await new Promise((resolve)=>setTimeout(resolve,300));", + "const leaf=app.workspace.getLeaf(false);", + "await leaf.openFile(file);", + "await new Promise((resolve)=>setTimeout(resolve,300));", + "await app.commands.executeCommandById('obsidian-livesync:livesync-history');", + "await new Promise((resolve)=>setTimeout(resolve,500));", + "const modal=document.querySelector('.modal-container .modal-title');", + "return JSON.stringify({opened:!!modal,modalTitle:modal?modal.textContent:null});", + "})()", + ].join(""), + env + ); +} + +async function main(): Promise { + const binary = requireObsidianBinary(); + const cli = discoverObsidianCli(); + if (!cli.binary) throw new Error(`Could not find obsidian-cli. Checked paths: ${cli.checked.join(", ")}`); + + const vault = await createTemporaryVault(); + let session: ObsidianLiveSyncSession | undefined; + + const screenshotDir = + process.env.E2E_OBSIDIAN_HISTORY_SCREENSHOT_DIR ?? + join(process.env.E2E_OBSIDIAN_DIAGNOSTICS_DIR ?? "/tmp/obsidian-livesync-e2e", "document-history-nav"); + const reportPath = process.env.E2E_OBSIDIAN_HISTORY_REPORT ?? join(screenshotDir, "report.txt"); + + async function captureStep(page: import("playwright").Page, step: string): Promise { + await mkdir(screenshotDir, { recursive: true }); + const path = join(screenshotDir, `${step}.png`); + await page.screenshot({ path, fullPage: true }); + console.log(`Screenshot: ${path}`); + return path; + } + + try { + console.log(`Using Obsidian executable: ${binary}`); + console.log(`Temporary vault: ${vault.path}`); + + session = await startObsidianLiveSyncSession({ + binary, + cliBinary: cli.binary, + vault, + startupGraceMs: Number(process.env.E2E_OBSIDIAN_STARTUP_GRACE_MS ?? 1000), + pluginData: { + doctorProcessedVersion: "1.0.0", + isConfigured: true, + liveSync: false, + remoteType: "", + couchDB_URI: "", + couchDB_DBNAME: "", + couchDB_USER: "", + couchDB_PASSWORD: "", + remoteConfigurations: {}, + activeConfigurationId: "", + notifyThresholdOfRemoteStorageSize: -1, + periodicReplication: false, + syncAfterMerge: false, + syncOnEditorSave: false, + syncOnFileOpen: false, + syncOnSave: false, + syncOnStart: false, + }, + localStorageEntries: createE2eObsidianDeviceLocalState(vault.name), + }); + await waitForLiveSyncCoreReady(cli.binary, session.cliEnv); + + await dismissWelcomeWizard(session.remoteDebuggingPort); + + const revisionInfo = await seedRevisions(cli.binary, session.cliEnv); + console.log(`Seeded local history: ${revisionInfo.revCount} revisions for ${revisionInfo.id}`); + assertEqual(revisionInfo.revCount, revisions.length, "Unexpected number of seeded revisions."); + + const opened = await openDocumentHistory(cli.binary, session.cliEnv); + assertEqual(opened.opened, true, "Document History modal did not open."); + assertEqual(opened.modalTitle, "Document History", "Unexpected modal title."); + + const report = await withObsidianPage(session.remoteDebuggingPort, async (page) => { + const modal = page.locator(".modal-container").filter({ hasText: "Document History" }); + await modal.waitFor({ state: "visible", timeout: 10000 }); + + const revNavRow = modal.locator(".history-rev-nav-row"); + await revNavRow.waitFor({ state: "visible", timeout: 10000 }); + + const indicator = revNavRow.locator(".history-rev-indicator"); + const initialIndicator = (await indicator.innerText()).trim(); + + const prevBtn = revNavRow.locator(".history-rev-nav-btn").first(); + const nextBtn = revNavRow.locator(".history-rev-nav-btn").last(); + const range = revNavRow.locator('input[type="range"]'); + + assertTrue(/Rev \d+\/\d+/.test(initialIndicator), `Unexpected initial indicator: ${initialIndicator}`); + + const initialRange = await range.inputValue(); + + const screenshotPaths: string[] = []; + screenshotPaths.push(await captureStep(page, "01-initial-latest-rev")); + assertEqual(initialIndicator, "Rev 3/3", "History did not open at the latest revision."); + assertEqual(initialRange, "2", "History slider did not open at the latest revision."); + assertTrue( + !(await prevBtn.isDisabled()), + "Older revision button should be enabled at the latest revision." + ); + assertTrue(await nextBtn.isDisabled(), "Newer revision button should be disabled at the latest revision."); + + await prevBtn.click(); + await page.waitForTimeout(1000); + const afterPrevIndicator = (await indicator.innerText()).trim(); + const afterPrevRange = await range.inputValue(); + assertTrue( + Number(afterPrevRange) < Number(initialRange), + `◀ did not move to an older revision. before=${initialRange}, after=${afterPrevRange}` + ); + assertTrue(afterPrevIndicator !== initialIndicator, "◀ did not update Rev indicator."); + assertTrue(!(await prevBtn.isDisabled()), "Older revision button was disabled before the oldest revision."); + assertTrue(!(await nextBtn.isDisabled()), "Newer revision button was not enabled after moving backwards."); + screenshotPaths.push(await captureStep(page, "02-after-click-older-rev")); + + await prevBtn.click(); + await page.waitForTimeout(1000); + assertEqual(await range.inputValue(), "0", "◀ did not reach the oldest revision."); + assertTrue(await prevBtn.isDisabled(), "Older revision button should be disabled at the oldest revision."); + assertTrue( + !(await nextBtn.isDisabled()), + "Newer revision button should be enabled at the oldest revision." + ); + screenshotPaths.push(await captureStep(page, "03-at-oldest-rev")); + + await nextBtn.click(); + await page.waitForTimeout(1000); + await nextBtn.click(); + await page.waitForTimeout(1000); + const afterNextIndicator = (await indicator.innerText()).trim(); + const afterNextRange = await range.inputValue(); + assertEqual(afterNextRange, initialRange, "▶ did not return to the original revision."); + assertEqual(afterNextIndicator, initialIndicator, "▶ did not restore the Rev indicator."); + assertTrue( + await nextBtn.isDisabled(), + "Newer revision button should be disabled after returning to latest." + ); + screenshotPaths.push(await captureStep(page, "04-after-click-newer-rev")); + + const searchInput = modal.locator(".history-search-input"); + await searchInput.fill("keyword"); + await page.waitForTimeout(1500); + + const searchIndicator = modal.locator(".history-search-result-indicator"); + const searchText = (await searchIndicator.innerText()).trim(); + assertTrue(/matches/.test(searchText), `Search indicator did not report matches: ${searchText}`); + screenshotPaths.push(await captureStep(page, "05-after-search-keyword")); + + const searchPrev = modal.locator(".history-search-row button").nth(0); + const searchNext = modal.locator(".history-search-row button").nth(1); + assertTrue(!(await searchPrev.isDisabled()), "Search ▲ should be enabled when matches exist."); + assertTrue(!(await searchNext.isDisabled()), "Search ▼ should be enabled when matches exist."); + + await searchNext.click(); + await page.waitForTimeout(1000); + + const afterSearchIndicator = (await searchIndicator.innerText()).trim(); + assertTrue( + /1\/\d+ matches/.test(afterSearchIndicator), + `Search navigation failed: ${afterSearchIndicator}` + ); + screenshotPaths.push(await captureStep(page, "06-after-search-next-match")); + + return [ + `initialIndicator: ${initialIndicator}`, + `afterPrevIndicator: ${afterPrevIndicator}`, + `afterNextIndicator: ${afterNextIndicator}`, + `searchIndicator: ${searchText}`, + `afterSearchIndicator: ${afterSearchIndicator}`, + "", + "Screenshots:", + ...screenshotPaths.map((p) => `- ${p}`), + ].join("\n"); + }); + + await writeFile(reportPath, report, "utf-8"); + console.log(`Document History UI test passed.`); + console.log(`Report: ${reportPath}`); + console.log(`Screenshots: ${screenshotDir}`); + } finally { + if (session) await session.app.stop(); + await vault.dispose(); + } +} + +main().catch((error: unknown) => { + console.error(error instanceof Error ? error.stack : error); + process.exit(1); +}); diff --git a/test/e2e-obsidian/scripts/run-focused.ts b/test/e2e-obsidian/scripts/run-focused.ts index a46bc515..957d6fd8 100644 --- a/test/e2e-obsidian/scripts/run-focused.ts +++ b/test/e2e-obsidian/scripts/run-focused.ts @@ -9,6 +9,7 @@ const focusedScenarios = new Set([ "onboarding-invitation", "dialog-mounts", "revision-repair", + "document-history-nav", "settings-ui", "review-harness", "p2p-pane", diff --git a/updates.md b/updates.md index f6605723..38793a43 100644 --- a/updates.md +++ b/updates.md @@ -12,6 +12,10 @@ Earlier releases remain available in the 0.25 release history and the legacy rel ## Unreleased +### Improved + +- Downloaded document batches retain best-effort screen-awake and lifecycle protection until every queued file has been applied to local storage, without extending the remote-activity indicator. + ## 1.0.1 29th July, 2026