@wonseok-han/confluence-sync 1.8.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -410
- package/dist/cli/args.js +1 -1
- package/dist/cli/help.js +214 -115
- package/dist/cli/init.js +44 -5
- package/dist/cli/main.js +42 -11
- package/dist/cli/status.js +83 -0
- package/dist/confluence/client.js +121 -57
- package/dist/confluence/config.js +12 -8
- package/dist/confluence/env-file.js +23 -0
- package/dist/confluence/links.js +18 -0
- package/dist/conversion/asset-paths.js +5 -0
- package/dist/conversion/attachments.js +29 -7
- package/dist/conversion/convert.js +10 -22
- package/dist/conversion/footnotes.js +114 -11
- package/dist/conversion/markdown.js +26 -0
- package/dist/conversion/pdf-pages.js +10 -8
- package/dist/documents/anchors.js +9 -0
- package/dist/documents/callout-roundtrip.js +75 -0
- package/dist/documents/callouts.js +74 -0
- package/dist/documents/catalog.js +2 -2
- package/dist/documents/footnote-roundtrip.js +96 -0
- package/dist/documents/format.js +116 -0
- package/dist/documents/html-tables.js +30 -0
- package/dist/documents/html-to-markdown.js +47 -13
- package/dist/documents/markdown.js +46 -4
- package/dist/documents/obsidian.js +6 -3
- package/dist/documents/tables.js +89 -0
- package/dist/runtime/network.js +4 -0
- package/dist/shared/colors.js +2 -2
- package/dist/shared/progress.js +164 -0
- package/dist/shared/version.js +12 -0
- package/dist/site/assets/Monaco-LICENSE.txt +21 -0
- package/dist/site/assets/Monaco-ThirdPartyNotices.txt +448 -0
- package/dist/site/assets/PDFJS-LICENSE.txt +177 -0
- package/dist/site/assets/app.css +1 -0
- package/dist/site/assets/app.js +4 -0
- package/dist/site/assets/chunks/chunk-TEW74QPN.js +35 -0
- package/dist/site/assets/chunks/markdown-S6623E66.js +1 -0
- package/dist/site/assets/chunks/monaco-36ZGUH4Y.js +897 -0
- package/dist/site/assets/chunks/monaco-HFLEBJTI.css +1 -0
- package/dist/site/assets/chunks/pdf-DDN7TXTP.js +55 -0
- package/dist/site/assets/confluence-env-example.txt +32 -0
- package/dist/site/assets/editor.worker.js +1 -0
- package/dist/site/assets/favicon.svg +3 -0
- package/dist/site/assets/guide/01-account-settings.png +0 -0
- package/dist/site/assets/guide/02-atlassian-security.png +0 -0
- package/dist/site/assets/guide/03-api-tokens.png +0 -0
- package/dist/site/assets/guide/04-scope-api-token-step1.png +0 -0
- package/dist/site/assets/guide/05-scope-api-token-step2.png +0 -0
- package/dist/site/assets/guide/06-scope-api-token-step3.png +0 -0
- package/dist/site/assets/guide/07-scope-api-token-step4.png +0 -0
- package/dist/site/assets/guide/web/document-preview.png +0 -0
- package/dist/site/assets/guide/web/remote-diff.png +0 -0
- package/dist/site/assets/guide/web/sync-workspace.png +0 -0
- package/dist/site/assets/pdf/cmaps/78-EUC-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/78-EUC-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/78-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/78-RKSJ-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/78-RKSJ-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/78-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/78ms-RKSJ-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/78ms-RKSJ-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/83pv-RKSJ-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/90ms-RKSJ-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/90ms-RKSJ-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/90msp-RKSJ-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/90msp-RKSJ-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/90pv-RKSJ-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/90pv-RKSJ-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Add-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Add-RKSJ-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Add-RKSJ-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Add-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-CNS1-0.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-CNS1-1.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-CNS1-2.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-CNS1-3.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-CNS1-4.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-CNS1-5.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-CNS1-6.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-GB1-0.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-GB1-1.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-GB1-2.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-GB1-3.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-GB1-4.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-GB1-5.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-Japan1-0.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-Japan1-1.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-Japan1-2.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-Japan1-3.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-Japan1-4.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-Japan1-5.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-Japan1-6.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-Korea1-0.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-Korea1-1.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-Korea1-2.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/B5-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/B5-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/B5pc-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/B5pc-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/CNS-EUC-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/CNS-EUC-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/CNS1-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/CNS1-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/CNS2-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/CNS2-V.bcmap +3 -0
- package/dist/site/assets/pdf/cmaps/ETHK-B5-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/ETHK-B5-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/ETen-B5-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/ETen-B5-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/ETenms-B5-H.bcmap +3 -0
- package/dist/site/assets/pdf/cmaps/ETenms-B5-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/EUC-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/EUC-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Ext-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Ext-RKSJ-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Ext-RKSJ-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Ext-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/GB-EUC-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/GB-EUC-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/GB-H.bcmap +4 -0
- package/dist/site/assets/pdf/cmaps/GB-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/GBK-EUC-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/GBK-EUC-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/GBK2K-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/GBK2K-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/GBKp-EUC-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/GBKp-EUC-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/GBT-EUC-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/GBT-EUC-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/GBT-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/GBT-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/GBTpc-EUC-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/GBTpc-EUC-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/GBpc-EUC-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/GBpc-EUC-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/HKdla-B5-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/HKdla-B5-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/HKdlb-B5-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/HKdlb-B5-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/HKgccs-B5-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/HKgccs-B5-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/HKm314-B5-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/HKm314-B5-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/HKm471-B5-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/HKm471-B5-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/HKscs-B5-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/HKscs-B5-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Hankaku.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Hiragana.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/KSC-EUC-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/KSC-EUC-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/KSC-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/KSC-Johab-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/KSC-Johab-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/KSC-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/KSCms-UHC-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/KSCms-UHC-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/KSCpc-EUC-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/KSCpc-EUC-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Katakana.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/LICENSE +36 -0
- package/dist/site/assets/pdf/cmaps/NWP-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/NWP-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/RKSJ-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/RKSJ-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/Roman.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniCNS-UCS2-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniCNS-UCS2-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniCNS-UTF16-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniCNS-UTF16-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniCNS-UTF32-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniCNS-UTF32-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniCNS-UTF8-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniCNS-UTF8-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniGB-UCS2-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniGB-UCS2-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniGB-UTF16-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniGB-UTF16-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniGB-UTF32-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniGB-UTF32-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniGB-UTF8-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniGB-UTF8-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJIS-UCS2-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJIS-UCS2-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJIS-UTF16-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJIS-UTF16-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJIS-UTF32-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJIS-UTF32-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJIS-UTF8-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJIS-UTF8-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniKS-UCS2-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniKS-UCS2-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniKS-UTF16-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniKS-UTF16-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniKS-UTF32-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniKS-UTF32-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniKS-UTF8-H.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/UniKS-UTF8-V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/V.bcmap +0 -0
- package/dist/site/assets/pdf/cmaps/WP-Symbol.bcmap +0 -0
- package/dist/site/assets/pdf/standard_fonts/FoxitDingbats.pfb +0 -0
- package/dist/site/assets/pdf/standard_fonts/FoxitFixed.pfb +0 -0
- package/dist/site/assets/pdf/standard_fonts/FoxitFixedBold.pfb +0 -0
- package/dist/site/assets/pdf/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
- package/dist/site/assets/pdf/standard_fonts/FoxitFixedItalic.pfb +0 -0
- package/dist/site/assets/pdf/standard_fonts/FoxitSerif.pfb +0 -0
- package/dist/site/assets/pdf/standard_fonts/FoxitSerifBold.pfb +0 -0
- package/dist/site/assets/pdf/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
- package/dist/site/assets/pdf/standard_fonts/FoxitSerifItalic.pfb +0 -0
- package/dist/site/assets/pdf/standard_fonts/FoxitSymbol.pfb +0 -0
- package/dist/site/assets/pdf/standard_fonts/LICENSE_FOXIT +27 -0
- package/dist/site/assets/pdf/standard_fonts/LICENSE_LIBERATION +363 -0
- package/dist/site/assets/pdf/standard_fonts/LiberationSans-Bold.ttf +0 -0
- package/dist/site/assets/pdf/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
- package/dist/site/assets/pdf/standard_fonts/LiberationSans-Italic.ttf +0 -0
- package/dist/site/assets/pdf/standard_fonts/LiberationSans-Regular.ttf +0 -0
- package/dist/site/assets/pdf/wasm/LICENSE_JBIG2 +196 -0
- package/dist/site/assets/pdf/wasm/LICENSE_OPENJPEG +39 -0
- package/dist/site/assets/pdf/wasm/LICENSE_PDFJS_JBIG2 +13 -0
- package/dist/site/assets/pdf/wasm/LICENSE_PDFJS_OPENJPEG +22 -0
- package/dist/site/assets/pdf/wasm/LICENSE_PDFJS_QCMS +19 -0
- package/dist/site/assets/pdf/wasm/LICENSE_QCMS +21 -0
- package/dist/site/assets/pdf/wasm/jbig2.wasm +0 -0
- package/dist/site/assets/pdf/wasm/jbig2_nowasm_fallback.js +15 -0
- package/dist/site/assets/pdf/wasm/openjpeg.wasm +0 -0
- package/dist/site/assets/pdf/wasm/openjpeg_nowasm_fallback.js +17 -0
- package/dist/site/assets/pdf/wasm/qcms_bg.wasm +0 -0
- package/dist/site/assets/pdf/wasm/quickjs-eval.js +16 -0
- package/dist/site/assets/pdf/wasm/quickjs-eval.wasm +0 -0
- package/dist/site/assets/pdf.worker.min.mjs +29 -0
- package/dist/site/assets/workspace.worker.js +409 -0
- package/dist/site/index.html +253 -0
- package/dist/sync/baseline.js +45 -0
- package/dist/sync/changes.js +51 -0
- package/dist/sync/diff.js +80 -0
- package/dist/sync/fetch.js +287 -0
- package/dist/sync/ignore.js +4 -4
- package/dist/sync/local-state.js +12 -0
- package/dist/sync/mapping.js +31 -8
- package/dist/sync/metadata.js +57 -0
- package/dist/sync/prepare.js +52 -0
- package/dist/sync/pull.js +618 -141
- package/dist/sync/push.js +260 -213
- package/dist/sync/reconcile.js +51 -0
- package/dist/sync/references.js +2 -2
- package/dist/sync/remap.js +17 -5
- package/dist/sync/render.js +3 -2
- package/dist/sync/restore.js +28 -0
- package/dist/sync/scope.js +47 -0
- package/dist/sync/staging.js +193 -0
- package/dist/sync/workspace.js +100 -0
- package/dist/web/assets/PDFJS-LICENSE.txt +177 -0
- package/dist/web/assets/app.css +1 -1
- package/dist/web/assets/app.js +3 -938
- package/dist/web/assets/chunks/chunk-TEW74QPN.js +35 -0
- package/dist/web/assets/chunks/markdown-S6623E66.js +1 -0
- package/dist/web/assets/chunks/monaco-36ZGUH4Y.js +897 -0
- package/dist/web/assets/chunks/monaco-HFLEBJTI.css +1 -0
- package/dist/web/assets/chunks/pdf-DDN7TXTP.js +55 -0
- package/dist/web/assets/confluence-env-example.txt +32 -0
- package/dist/web/assets/editor.worker.js +1 -30
- package/dist/web/assets/favicon.svg +3 -0
- package/dist/web/assets/guide/01-account-settings.png +0 -0
- package/dist/web/assets/guide/02-atlassian-security.png +0 -0
- package/dist/web/assets/guide/03-api-tokens.png +0 -0
- package/dist/web/assets/guide/04-scope-api-token-step1.png +0 -0
- package/dist/web/assets/guide/05-scope-api-token-step2.png +0 -0
- package/dist/web/assets/guide/06-scope-api-token-step3.png +0 -0
- package/dist/web/assets/guide/07-scope-api-token-step4.png +0 -0
- package/dist/web/assets/guide/web/document-preview.png +0 -0
- package/dist/web/assets/guide/web/remote-diff.png +0 -0
- package/dist/web/assets/guide/web/sync-workspace.png +0 -0
- package/dist/web/assets/pdf/cmaps/78-EUC-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/78-EUC-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/78-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/78-RKSJ-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/78-RKSJ-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/78-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/78ms-RKSJ-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/78ms-RKSJ-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/83pv-RKSJ-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/90ms-RKSJ-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/90ms-RKSJ-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/90msp-RKSJ-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/90msp-RKSJ-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/90pv-RKSJ-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/90pv-RKSJ-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Add-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Add-RKSJ-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Add-RKSJ-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Add-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-CNS1-0.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-CNS1-1.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-CNS1-2.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-CNS1-3.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-CNS1-4.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-CNS1-5.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-CNS1-6.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-GB1-0.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-GB1-1.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-GB1-2.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-GB1-3.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-GB1-4.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-GB1-5.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-Japan1-0.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-Japan1-1.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-Japan1-2.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-Japan1-3.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-Japan1-4.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-Japan1-5.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-Japan1-6.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-Korea1-0.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-Korea1-1.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-Korea1-2.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/B5-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/B5-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/B5pc-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/B5pc-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/CNS-EUC-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/CNS-EUC-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/CNS1-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/CNS1-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/CNS2-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/CNS2-V.bcmap +3 -0
- package/dist/web/assets/pdf/cmaps/ETHK-B5-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/ETHK-B5-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/ETen-B5-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/ETen-B5-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/ETenms-B5-H.bcmap +3 -0
- package/dist/web/assets/pdf/cmaps/ETenms-B5-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/EUC-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/EUC-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Ext-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Ext-RKSJ-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Ext-RKSJ-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Ext-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/GB-EUC-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/GB-EUC-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/GB-H.bcmap +4 -0
- package/dist/web/assets/pdf/cmaps/GB-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/GBK-EUC-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/GBK-EUC-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/GBK2K-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/GBK2K-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/GBKp-EUC-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/GBKp-EUC-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/GBT-EUC-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/GBT-EUC-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/GBT-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/GBT-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/GBTpc-EUC-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/GBTpc-EUC-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/GBpc-EUC-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/GBpc-EUC-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/HKdla-B5-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/HKdla-B5-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/HKdlb-B5-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/HKdlb-B5-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/HKgccs-B5-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/HKgccs-B5-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/HKm314-B5-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/HKm314-B5-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/HKm471-B5-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/HKm471-B5-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/HKscs-B5-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/HKscs-B5-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Hankaku.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Hiragana.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/KSC-EUC-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/KSC-EUC-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/KSC-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/KSC-Johab-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/KSC-Johab-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/KSC-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/KSCms-UHC-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/KSCms-UHC-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/KSCpc-EUC-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/KSCpc-EUC-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Katakana.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/LICENSE +36 -0
- package/dist/web/assets/pdf/cmaps/NWP-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/NWP-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/RKSJ-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/RKSJ-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/Roman.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniCNS-UCS2-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniCNS-UCS2-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniCNS-UTF16-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniCNS-UTF16-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniCNS-UTF32-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniCNS-UTF32-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniCNS-UTF8-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniCNS-UTF8-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniGB-UCS2-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniGB-UCS2-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniGB-UTF16-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniGB-UTF16-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniGB-UTF32-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniGB-UTF32-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniGB-UTF8-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniGB-UTF8-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJIS-UCS2-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJIS-UCS2-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJIS-UTF16-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJIS-UTF16-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJIS-UTF32-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJIS-UTF32-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJIS-UTF8-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJIS-UTF8-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniKS-UCS2-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniKS-UCS2-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniKS-UTF16-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniKS-UTF16-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniKS-UTF32-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniKS-UTF32-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniKS-UTF8-H.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/UniKS-UTF8-V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/V.bcmap +0 -0
- package/dist/web/assets/pdf/cmaps/WP-Symbol.bcmap +0 -0
- package/dist/web/assets/pdf/standard_fonts/FoxitDingbats.pfb +0 -0
- package/dist/web/assets/pdf/standard_fonts/FoxitFixed.pfb +0 -0
- package/dist/web/assets/pdf/standard_fonts/FoxitFixedBold.pfb +0 -0
- package/dist/web/assets/pdf/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
- package/dist/web/assets/pdf/standard_fonts/FoxitFixedItalic.pfb +0 -0
- package/dist/web/assets/pdf/standard_fonts/FoxitSerif.pfb +0 -0
- package/dist/web/assets/pdf/standard_fonts/FoxitSerifBold.pfb +0 -0
- package/dist/web/assets/pdf/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
- package/dist/web/assets/pdf/standard_fonts/FoxitSerifItalic.pfb +0 -0
- package/dist/web/assets/pdf/standard_fonts/FoxitSymbol.pfb +0 -0
- package/dist/web/assets/pdf/standard_fonts/LICENSE_FOXIT +27 -0
- package/dist/web/assets/pdf/standard_fonts/LICENSE_LIBERATION +363 -0
- package/dist/web/assets/pdf/standard_fonts/LiberationSans-Bold.ttf +0 -0
- package/dist/web/assets/pdf/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
- package/dist/web/assets/pdf/standard_fonts/LiberationSans-Italic.ttf +0 -0
- package/dist/web/assets/pdf/standard_fonts/LiberationSans-Regular.ttf +0 -0
- package/dist/web/assets/pdf/wasm/LICENSE_JBIG2 +196 -0
- package/dist/web/assets/pdf/wasm/LICENSE_OPENJPEG +39 -0
- package/dist/web/assets/pdf/wasm/LICENSE_PDFJS_JBIG2 +13 -0
- package/dist/web/assets/pdf/wasm/LICENSE_PDFJS_OPENJPEG +22 -0
- package/dist/web/assets/pdf/wasm/LICENSE_PDFJS_QCMS +19 -0
- package/dist/web/assets/pdf/wasm/LICENSE_QCMS +21 -0
- package/dist/web/assets/pdf/wasm/jbig2.wasm +0 -0
- package/dist/web/assets/pdf/wasm/jbig2_nowasm_fallback.js +15 -0
- package/dist/web/assets/pdf/wasm/openjpeg.wasm +0 -0
- package/dist/web/assets/pdf/wasm/openjpeg_nowasm_fallback.js +17 -0
- package/dist/web/assets/pdf/wasm/qcms_bg.wasm +0 -0
- package/dist/web/assets/pdf/wasm/quickjs-eval.js +16 -0
- package/dist/web/assets/pdf/wasm/quickjs-eval.wasm +0 -0
- package/dist/web/assets/pdf.worker.min.mjs +29 -0
- package/dist/web/assets/workspace.worker.js +409 -0
- package/dist/web/document-source.js +14 -0
- package/dist/web/hosted-files.js +189 -0
- package/dist/web/hosted.js +316 -0
- package/dist/web/node-runner.js +26 -0
- package/dist/web/preview.js +74 -0
- package/dist/web/server.js +85 -240
- package/dist/web/sync.js +364 -70
- package/dist/web/table-editor-script.js +99 -0
- package/dist/web/table-format.js +224 -0
- package/dist/web/views/help.js +15 -10
- package/dist/web/views/sync-panel.js +90 -19
- package/dist/web/views/token-guide.js +27 -0
- package/dist/web/views/usage-guide.js +12 -0
- package/dist/web/views/workspace.js +85 -15
- package/dist/web/workspace-api.js +371 -0
- package/docs/user/CLI.md +366 -0
- package/docs/user/CONFIGURATION.md +125 -0
- package/docs/user/OBSIDIAN.md +117 -0
- package/docs/user/WEB.md +90 -0
- package/docs/user/images/web/document-preview.png +0 -0
- package/docs/user/images/web/remote-diff.png +0 -0
- package/docs/user/images/web/sync-workspace.png +0 -0
- package/package.json +23 -6
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="ko"><head><meta charset="utf-8"><meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'sha256-gC1xP5ikAuS9OEjIyx77wCJoX4h4jhP+0cQnKC4FHD4='; connect-src 'self' http://127.0.0.1:* http://localhost:* https://*.blob.vercel-storage.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; frame-src 'self'; worker-src 'self'; object-src 'none'; base-uri 'none'; form-action 'none'"><meta name="referrer" content="no-referrer"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="csync-token" content=""><meta name="csync-runtime" content="standalone"><meta name="csync-version" content="2.0.0"><title>문서 워크스페이스 · confluence-sync</title><link rel="icon" type="image/svg+xml" href="/assets/favicon.svg?v=paperlink"><link rel="stylesheet" href="/assets/app.css"></head><body>
|
|
3
|
+
<header class="app-header"><a class="brand" href="/" aria-label="confluence-sync 홈"><img class="brand-symbol" src="/assets/favicon.svg?v=paperlink" alt="" aria-hidden="true" width="30" height="30">confluence<span class="brand-light">sync</span></a><span class="app-version" aria-label="현재 버전">v2.0.0</span><span class="local-status"><i></i><span id="local-connection-status">브라우저 폴더 선택 필요</span></span><button id="local-disconnect" class="quiet" type="button" hidden>연결 해제</button></header>
|
|
4
|
+
<main id="workspace-interface" class="app-main">
|
|
5
|
+
<div class="page-heading"><div><div class="eyebrow">DOCUMENT WORKSPACE</div><h1>문서 워크스페이스<span class="title-dot">.</span></h1></div><div class="page-heading-actions"><p>문서를 변환하고, Confluence에서 가져오거나 업로드하세요.</p><button id="open-help" aria-haspopup="dialog" aria-controls="help-dialog">사용 도움말</button></div></div>
|
|
6
|
+
<div class="mode-tabs" role="tablist" aria-label="문서 작업"><button id="tab-convert" role="tab" aria-selected="true" aria-controls="convert-view">문서 변환</button><button id="tab-sync" role="tab" aria-selected="false" aria-controls="sync-view" tabindex="-1">Confluence</button></div>
|
|
7
|
+
<div class="workspace">
|
|
8
|
+
<aside class="panel explorer" aria-label="파일 탐색">
|
|
9
|
+
<div class="panel-heading"><h2>로컬 문서</h2><span id="count" class="count">폴더 탐색</span></div>
|
|
10
|
+
<div class="folder-picker root-picker">
|
|
11
|
+
<section class="workspace-root-card" aria-labelledby="root-heading">
|
|
12
|
+
<div class="workspace-root-heading"><h3 id="root-heading">기준 폴더</h3><span id="root-purpose" class="root-purpose">변환 기준</span></div>
|
|
13
|
+
<strong id="root-name" class="root-name">폴더를 선택하세요</strong>
|
|
14
|
+
<p id="root-path" class="root-path">아직 설정되지 않았습니다.</p>
|
|
15
|
+
<p id="root-hint" class="root-hint">문서와 참조 링크를 찾는 기준입니다.</p>
|
|
16
|
+
</section>
|
|
17
|
+
<button id="choose-base" class="folder-button"><span aria-hidden="true">↻</span>기준 폴더 변경…</button>
|
|
18
|
+
<details id="root-path-editor" class="root-path-editor"><summary>경로를 직접 입력해 변경</summary><label for="base-input">새 기준 폴더 경로</label><input id="base-input" class="path-input" placeholder="폴더의 전체 경로"><button id="apply-base" type="button">이 폴더를 기준으로 설정</button></details>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="explorer-navigation">
|
|
21
|
+
<div class="explorer-nav-heading"><span>문서 탐색</span><button id="base-home" class="quiet" type="button" aria-label="기준 폴더로 돌아가기">기준 폴더로</button></div>
|
|
22
|
+
<div class="explorer-nav-row"><button id="up" class="quiet" aria-label="상위 폴더" title="상위 폴더">↑</button><p id="path" class="path" aria-label="현재 탐색 위치"></p></div>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="search-wrap"><span aria-hidden="true">⌕</span><input id="search" type="search" placeholder="하위 폴더까지 파일 이름 검색" aria-label="파일 이름 검색"></div>
|
|
25
|
+
<div id="files" class="files"></div>
|
|
26
|
+
<div class="explorer-footer"><span class="file-type">MD</span><span id="explorer-note">파일·폴더를 선택해 변환하세요</span></div>
|
|
27
|
+
</aside>
|
|
28
|
+
<div id="convert-view" class="workspace-content" role="tabpanel" aria-labelledby="tab-convert">
|
|
29
|
+
<section id="document-preview-panel" class="panel document-preview" aria-label="문서 미리보기">
|
|
30
|
+
<div class="panel-heading document-preview-heading"><h2><button id="document-preview-toggle" class="preview-disclosure" aria-expanded="false" aria-controls="document-preview-body"><span id="document-preview-chevron" aria-hidden="true">▸</span>문서 미리보기<span id="document-preview-toggle-label" class="preview-disclosure-label">펼치기</span></button></h2><div id="document-preview-actions" class="actions" hidden><button id="document-format-toggle" class="quiet format-entry" aria-expanded="false" aria-controls="document-format-controls" disabled><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 5h16M4 10h10M4 15h8m4-2 4 4m-5 3 5-5 2 2-5 5h-2v-2Z"/></svg>문서 서식 정리</button><button id="document-preview-refresh" class="quiet" title="문서를 다시 읽기" disabled><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 7v5h-5M4 17v-5h5M6 7a7 7 0 0 1 12-1l2 3M4 15l2 3a7 7 0 0 0 12-1"/></svg>새로고침</button></div></div>
|
|
31
|
+
<div id="document-preview-body" hidden>
|
|
32
|
+
<p id="document-preview-status" class="document-preview-status" role="status" aria-live="polite">Markdown 파일을 선택하면 본문이 표시됩니다.</p>
|
|
33
|
+
<div id="document-format-controls" class="document-format-controls" hidden>
|
|
34
|
+
<div class="format-toolbar" role="group" aria-label="문서 서식 정리 도구">
|
|
35
|
+
<div class="format-tool-group"><span class="format-group-label">문서</span><button id="document-format-basic" class="format-tool-button" title="제목·문단 간격, 목록 기호, 공백과 Markdown 표 정리 결과를 비교합니다" disabled><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 5h16M4 10h16M4 15h10M4 20h10"/></svg>기본 서식 정리</button></div>
|
|
36
|
+
<div class="format-tool-group"><label class="format-group-label" for="document-format-tables">모든 표</label><select id="document-format-tables" title="문서 안의 모든 표 열 너비"><option value="keep">기존 너비 유지</option><option value="fit">내용에 맞춤</option><option value="equal">균등 배분</option></select><button id="table-edit-toggle" class="format-tool-button" aria-pressed="false" aria-controls="table-format-controls" disabled><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 4h18v16H3zM3 9h18M9 4v16M15 4v16"/></svg>표 직접 편집</button></div>
|
|
37
|
+
<div class="format-toolbar-actions"><button id="table-revert-all" class="quiet" title="모든 표 너비 변경 취소" disabled><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 4v6h6M4 10a8 8 0 1 1 1 8"/></svg>표 변경 취소</button><button id="document-format-review" class="primary" disabled><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 4H4v16h5M15 4h5v16h-5M9 9l-3 3 3 3M15 9l3 3-3 3"/></svg>변경 비교</button></div>
|
|
38
|
+
</div>
|
|
39
|
+
<div id="table-format-controls" class="table-format-controls" hidden>
|
|
40
|
+
<div class="format-context-heading"><span class="format-context-label">선택한 표</span><p id="table-format-status" role="status" aria-live="polite">미리보기에서 조절할 표를 클릭하세요.</p></div>
|
|
41
|
+
<div class="table-format-actions"><label>표 너비 <input id="table-total-width" type="range" min="320" max="1200" step="1" disabled><output id="table-total-label"></output></label><div class="format-button-set"><button id="table-fit" title="선택한 표의 글자 길이에 맞춰 열 너비 배분" disabled>내용에 맞춤</button><button id="table-equal" disabled>균등 배분</button></div><button id="table-revert" class="quiet" disabled>선택 표 취소</button></div>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="format-toolbar-footer"><span id="format-summary" role="status">변경 비교 후 원본 파일에 저장합니다.</span><details><summary>적용 범위</summary><p>기본 서식 정리를 누르면 정리 결과를 바로 비교합니다. 코드·링크 경로·HTML 표는 보존하며 저장 전에는 파일을 바꾸지 않습니다. 모든 표의 너비를 일괄 배분한 뒤 개별 표를 추가로 조절할 수 있습니다. 너비를 지정한 Markdown 표는 HTML로 바뀝니다. 비교창을 닫으면 저장하지 않습니다.</p></details></div>
|
|
44
|
+
</div>
|
|
45
|
+
<iframe id="document-preview-frame" class="document-preview-frame" title="선택한 Markdown 문서 미리보기" sandbox="allow-scripts" hidden></iframe>
|
|
46
|
+
<p class="document-preview-note">로컬 문서 미리보기이며 Confluence의 실제 표시와 다를 수 있습니다.</p>
|
|
47
|
+
</div>
|
|
48
|
+
</section>
|
|
49
|
+
<section class="panel settings" aria-label="변환 설정">
|
|
50
|
+
<div class="panel-heading"><h2>변환 설정</h2><span id="convert-save-mode" class="subtle-label">별도 폴더 저장</span></div>
|
|
51
|
+
<div class="settings-body">
|
|
52
|
+
<div class="document-summary"><span class="document-symbol" aria-hidden="true">MD</span><div><div id="selected" class="selected-name">변환할 문서를 선택하세요</div><div id="base" class="base">왼쪽에서 폴더를 열어 시작하세요.</div></div></div>
|
|
53
|
+
<div class="convert-target-actions"><button id="convert-select-all" type="button" disabled>기준 폴더 전체 선택</button><span id="convert-target-note" class="hint">파일·폴더를 선택하거나 기준 폴더 전체를 선택하세요.</span></div>
|
|
54
|
+
<p id="convert-output-hint" class="hint"></p><div class="settings-grid"><div class="field"><label for="direction">변환 형식</label><select id="direction"><option value="markdown">Markdown</option><option value="obsidian">Obsidian</option><option value="repair">Confluence 오류 보정만</option></select></div><div class="field output-field"><label for="out-input">출력 폴더 <span id="out-mode-hint">선택 사항</span></label><div class="path-row"><input id="out-input" class="path-input" placeholder="자동으로 새 폴더 생성"><button id="choose-out">폴더 선택…</button></div></div></div>
|
|
55
|
+
<div class="settings-notes"><p id="direction-hint" class="hint">위키링크를 상대 링크로, PDF 페이지 참조를 이미지로 변환합니다.</p><div class="repair-help"><label class="repair-option"><input id="fix" type="checkbox">Confluence 변환 오류 보정</label><button id="repair-help-button" class="info-mark" type="button" aria-label="Confluence 변환 오류 보정 설명" aria-describedby="repair-tooltip">i</button><div id="repair-tooltip" class="help-tooltip" role="tooltip" hidden>옛 Confluence 문서의 CSS 잔해, 중복 제목, 코드블록 언어와 불필요한 이스케이프를 보정합니다. 미리보기에서 변경 내용을 확인하세요.</div></div></div>
|
|
56
|
+
</div>
|
|
57
|
+
<div class="action-bar"><span class="save-note">선택한 대상과 참조 첨부파일을 저장합니다.</span><div class="actions"><button id="next-document" class="quiet" disabled>다른 문서 선택</button><button id="preview" disabled>변환 미리보기</button><button id="save" class="primary" disabled>변환 후 저장 <span aria-hidden="true">↗</span></button></div></div>
|
|
58
|
+
<div class="feedback"><div id="status" class="status" role="status" aria-live="polite"></div><div id="result" class="result" hidden><div><strong>변환 결과 저장 완료</strong><p id="output"></p></div><button id="open">결과 폴더 열기 ↗</button></div><details id="details" hidden><summary>변환 내역</summary><pre id="log"></pre></details></div>
|
|
59
|
+
</section>
|
|
60
|
+
<section class="panel comparison" aria-label="본문 비교">
|
|
61
|
+
<div class="panel-heading comparison-heading"><h2>본문 비교</h2><div class="diff-toolbar"><span id="preview-label" class="count">미리보기 대기</span><span class="toolbar-divider"></span><label class="layout-toggle"><input id="side-by-side" type="checkbox" checked>나란히</label><div class="diff-navigation"><button id="previous-change" class="quiet" aria-label="이전 변경" title="이전 변경" disabled>↑</button><button id="next-change" class="quiet" aria-label="다음 변경" title="다음 변경" disabled>↓</button></div></div></div>
|
|
62
|
+
<div id="preview-documents" class="preview-documents" hidden><label for="preview-document">비교할 문서</label><select id="preview-document"></select><span id="preview-count" class="hint"></span></div><div class="diff-labels"><span><i class="legend-before"></i>원본</span><span><i class="legend-after"></i>변환 결과</span><span class="read-only">읽기 전용</span></div>
|
|
63
|
+
<div id="editor-error" role="alert" hidden></div><div class="editor-shell"><div id="diff" class="diff" aria-label="Monaco 본문 비교"></div><div id="comparison-empty" class="comparison-empty"><span class="empty-symbol" aria-hidden="true">⇄</span><strong>변경된 부분을 한눈에</strong><p>문서를 선택하고 미리보기를 누르면<br>원본과 변환 결과를 비교할 수 있습니다.</p><div class="empty-legend"><span><i class="legend-before"></i>삭제</span><span><i class="legend-after"></i>추가</span></div></div></div>
|
|
64
|
+
</section>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<div id="sync-view" class="workspace-content" role="tabpanel" aria-labelledby="tab-sync" hidden>
|
|
68
|
+
<section class="panel env-settings" aria-labelledby="sync-env-heading">
|
|
69
|
+
<div class="panel-heading"><h2 id="sync-env-heading"><button id="sync-env-toggle" class="preview-disclosure" type="button" aria-expanded="false" aria-controls="sync-env-body"><span id="sync-env-chevron" aria-hidden="true">▸</span>.env 연결 설정<span id="sync-env-toggle-label" class="preview-disclosure-label">펼치기</span></button></h2><div class="actions"><button id="sync-load" type="button">설정 확인</button><button id="sync-connect" type="button" disabled>스페이스 연결</button></div></div>
|
|
70
|
+
<div id="sync-env-body" class="env-settings-body" hidden>
|
|
71
|
+
<div class="env-help-actions"><a class="env-template-download" href="/assets/confluence-env-example.txt" download="confluence.env.example"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v12m-5-5 5 5 5-5M4 17v4h16v-4"/></svg>.env 샘플 다운로드</a>
|
|
72
|
+
<p class="hint">API 토큰이 없나요? <button id="open-token-guide" class="quiet" type="button" aria-haspopup="dialog" aria-controls="help-dialog">API 토큰 발급 가이드</button></p></div>
|
|
73
|
+
<p class="hint">샘플의 빈 값을 채운 뒤 .env 가져오기로 선택하거나, 이름을 .env로 바꿔 기준 폴더에 저장하세요.</p>
|
|
74
|
+
<fieldset class="env-source-options"><legend class="sr-only">환경변수 설정 방식</legend>
|
|
75
|
+
<label><input type="radio" name="sync-env-source" id="sync-env-base-mode" checked><span><strong>기준 폴더의 .env 사용</strong><small>로컬 문서에서 선택한 폴더의 설정을 읽습니다.</small></span></label>
|
|
76
|
+
<label><input type="radio" name="sync-env-source" id="sync-env-import-mode"><span><strong>.env 가져오기</strong><small>파일을 선택해 현재 웹 작업에 적용합니다.</small></span></label>
|
|
77
|
+
</fieldset>
|
|
78
|
+
<div id="sync-env-import-controls" class="env-import-controls" hidden>
|
|
79
|
+
<input type="file" id="sync-env-file" hidden>
|
|
80
|
+
<div class="env-file-row"><button id="sync-env-choose" type="button">.env 파일 선택…</button><span id="sync-env-file-name">선택한 파일 없음</span></div>
|
|
81
|
+
<button id="sync-env-save" type="button" disabled>기준 폴더에 .env 저장</button>
|
|
82
|
+
</div>
|
|
83
|
+
<p id="sync-env-source-note" class="hint">로컬 문서에서 선택한 기준 폴더의 .env만 읽습니다. 파일이 없으면 .env를 가져오세요.</p>
|
|
84
|
+
<div class="env-config-summary"><h4>적용된 연결 정보</h4>
|
|
85
|
+
<dl id="sync-config" class="sync-config"><dt>연결 설정</dt><dd>설정 확인을 누르면 서버·계정·스페이스를 볼 수 있습니다.</dd></dl>
|
|
86
|
+
<p id="sync-config-status" class="hint" role="status"></p>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
</section>
|
|
90
|
+
<section class="panel sync-workbench" aria-label="Confluence 작업 설정">
|
|
91
|
+
<div class="panel-heading"><h2>Confluence</h2><span id="sync-stage-count" class="count">0개 업로드 예정</span></div>
|
|
92
|
+
<div class="sync-workbench-body">
|
|
93
|
+
<p id="sync-target" class="sync-target">로컬 문서에서 스페이스 전체를 보관할 기준 폴더를 선택하세요.</p>
|
|
94
|
+
<div class="sync-workbench-toolbar">
|
|
95
|
+
<div class="actions" aria-label="원격 변경 확인 및 가져오기">
|
|
96
|
+
<button id="sync-fetch" type="button" title="스페이스의 새 문서와 버전·위치 변경을 확인합니다. 2분 이내 결과는 재사용합니다." disabled>원격 변경 확인 (Fetch)</button>
|
|
97
|
+
<button id="sync-pull-remote" type="button" disabled>↓ 원격 변경 가져오기 (Pull)</button>
|
|
98
|
+
<label class="sync-pull-format" for="sync-pull-format">가져오기 형식<select id="sync-pull-format" aria-describedby="sync-pull-format-help"><option value="markdown">Markdown</option><option value="obsidian">Obsidian</option></select></label>
|
|
99
|
+
<button hidden id="sync-stage-scan" type="button">↻ 로컬 다시 확인</button>
|
|
100
|
+
</div>
|
|
101
|
+
<div class="actions" aria-label="업로드 대상 일괄 선택">
|
|
102
|
+
<button id="sync-stage-add" type="button" disabled><span aria-hidden="true">+</span> 변경 문서 모두 포함</button>
|
|
103
|
+
<button id="sync-stage-remove" type="button" disabled><span aria-hidden="true">−</span> 모두 제외</button>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
<p id="sync-pull-format-help" class="hint sync-pull-format-help">일반 Markdown 링크와 제목이 있는 인용문으로 받습니다. 이 설정은 새로 받는 문서와 복구·원복에 적용하며 기존 파일을 일괄 변환하지 않습니다.</p>
|
|
107
|
+
<div class="sync-observation"><span id="sync-stage-checking" class="stage-checking" aria-hidden="true"><i class="activity-spinner" aria-hidden="true"></i>로컬 확인 중…</span><span>로컬 자동 확인 · 5초 간격 · API 호출 없음</span><span id="sync-stage-remote-note">원격 상태 미확인 · Fetch로 갱신하세요.</span></div>
|
|
108
|
+
<div class="sync-change-heading"><h3 id="sync-stage-heading">변경사항</h3><span>받을 문서는 Pull · 보낼 변경은 체크 후 Push</span></div>
|
|
109
|
+
<p id="sync-stage-note" class="hint" role="status">로컬 변경을 자동으로 확인합니다. 원격 상태는 Fetch를 눌러 확인하세요.</p>
|
|
110
|
+
<div id="sync-stage-list" class="sync-stage-list" aria-label="업로드 문서 선택"></div>
|
|
111
|
+
</div>
|
|
112
|
+
<div class="sync-execution">
|
|
113
|
+
<div class="sync-execution-heading"><h3>선택 문서 업로드</h3><span class="count">로컬 → Confluence</span></div>
|
|
114
|
+
<p class="sync-intro">체크한 문서를 미리보기한 뒤 업로드하세요.</p>
|
|
115
|
+
<details class="sync-advanced"><summary>추가 설정 <span>참조 문서 · 원격 검증</span></summary>
|
|
116
|
+
<div class="sync-settings">
|
|
117
|
+
<div id="sync-push-options" class="sync-push-options">
|
|
118
|
+
<section class="sync-option-section" aria-labelledby="sync-reference-heading">
|
|
119
|
+
<h3 id="sync-reference-heading">참조 문서 연결 <span class="subtle-label">선택 사항</span></h3>
|
|
120
|
+
<p id="sync-references-help" class="hint">다른 동기화 폴더의 게시 매핑을 이용해 문서 링크를 연결합니다. 같은 Confluence 서버의 폴더를 지정하세요. 참조 문서는 업로드하지 않습니다.</p>
|
|
121
|
+
<div class="field"><label for="sync-references">참조 문서 폴더 <span>한 줄에 한 경로</span></label><textarea id="sync-references" class="path-input" rows="3" placeholder="다른 동기화 폴더 경로" aria-describedby="sync-references-help"></textarea></div>
|
|
122
|
+
<button id="sync-add-reference" type="button">참조 폴더 추가…</button>
|
|
123
|
+
</section>
|
|
124
|
+
<section class="sync-option-section" aria-labelledby="sync-verify-heading">
|
|
125
|
+
<h3 id="sync-verify-heading">미리보기 확인 옵션</h3>
|
|
126
|
+
<label class="repair-option sync-verify-option"><input id="sync-verify" type="checkbox" aria-describedby="sync-verify-help">Confluence의 원격 버전과 페이지 존재 여부도 확인</label>
|
|
127
|
+
<p id="sync-verify-help" class="hint">선택하면 미리보기 중 Confluence를 조회하므로 시간이 더 걸릴 수 있습니다. 파일과 원격 내용은 변경하지 않습니다.</p>
|
|
128
|
+
</section>
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
</details>
|
|
132
|
+
</div>
|
|
133
|
+
<div class="action-bar"><span class="save-note">받을 변경과 체크한 업로드 문서를 확인하세요.</span><div class="actions"><button id="sync-preview" disabled>업로드 미리보기</button><button id="sync-push" class="primary" disabled>Confluence에 업로드</button></div></div>
|
|
134
|
+
<div class="feedback"><p id="sync-status" class="status" role="status" aria-live="polite">변경사항을 확인하고 받을 문서와 보낼 문서를 선택하세요.</p><button id="sync-reconnect" hidden>진행 상태 다시 확인</button></div>
|
|
135
|
+
</section>
|
|
136
|
+
|
|
137
|
+
<dialog id="sync-diff-dialog" class="sync-diff-dialog" aria-labelledby="sync-diff-title">
|
|
138
|
+
<div class="panel-heading"><h2 id="sync-diff-title">문서 변경 비교</h2><button id="sync-diff-close" type="button">닫기</button></div>
|
|
139
|
+
<div class="settings-body"><p id="sync-diff-path" class="sync-diff-path"></p><p id="sync-diff-note" class="hint" role="status"></p>
|
|
140
|
+
<div class="actions"><button id="sync-diff-remote" type="button" hidden>원격과 비교 · 본문 1회 조회</button></div>
|
|
141
|
+
<div id="sync-diff-labels" class="sync-diff-labels" hidden><span id="sync-diff-before-label">기준 Markdown</span><span>현재 로컬 Markdown</span></div>
|
|
142
|
+
<div id="sync-diff-editor" class="sync-diff-editor" hidden></div>
|
|
143
|
+
</div>
|
|
144
|
+
</dialog>
|
|
145
|
+
<dialog id="sync-restore-dialog" class="env-confirm-dialog restore-dialog" aria-labelledby="sync-restore-title" aria-describedby="sync-restore-warning">
|
|
146
|
+
<h3 id="sync-restore-title">문서를 원격 최신으로 복구할까요?</h3>
|
|
147
|
+
<p id="sync-restore-path" class="sync-diff-path"></p>
|
|
148
|
+
<p id="sync-restore-warning" class="restore-warning"></p>
|
|
149
|
+
<p class="hint">원격 문서는 변경하지 않습니다. 복구 후 업로드 선택에서 제외합니다. 다운로드 도중 추가 수정이 생기면 중단합니다.</p>
|
|
150
|
+
<div class="actions"><button id="sync-restore-cancel" type="button">취소</button><button id="sync-restore-confirm" type="button" class="restore-confirm">원격에서 복구</button></div>
|
|
151
|
+
</dialog>
|
|
152
|
+
<dialog id="sync-env-confirm" class="env-confirm-dialog" aria-labelledby="sync-env-confirm-title">
|
|
153
|
+
<h3 id="sync-env-confirm-title">기존 .env의 연결 설정을 바꿀까요?</h3>
|
|
154
|
+
<p id="sync-env-confirm-path" class="hint"></p>
|
|
155
|
+
<p>서버 주소, 계정, API 토큰, 스페이스 키를 가져온 값으로 교체합니다. 다른 환경변수는 유지합니다.</p>
|
|
156
|
+
<div class="actions"><button id="sync-env-confirm-cancel" type="button">취소</button><button id="sync-env-confirm-save" type="button" class="primary">연결 설정 교체 후 저장</button></div>
|
|
157
|
+
</dialog>
|
|
158
|
+
<section id="sync-results" class="panel sync-results" aria-label="Confluence 작업 내역">
|
|
159
|
+
<div class="panel-heading"><h2>대상 및 실행 내역</h2><div class="actions sync-log-actions"><span id="sync-job-state" class="count sync-job-status" role="status" hidden></span><button id="sync-log-download" type="button" disabled title="현재 작업의 실행 내역을 내려받습니다. 실행 중에도 현재까지의 로그를 저장할 수 있습니다."><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v12m-5-5 5 5 5-5M4 17v4h16v-4"/></svg>로그 다운로드</button></div></div>
|
|
160
|
+
<div class="sync-result-body"><p id="sync-job-summary" class="hint" hidden></p><p id="sync-log-empty" class="empty">미리보기하면 문서별 신규·변경·동일 상태와 부모 계층을 확인할 수 있습니다.</p><pre id="sync-log" tabindex="0" aria-label="Confluence 작업 로그" hidden></pre></div>
|
|
161
|
+
</section>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
<footer><span id="workspace-note"><i></i>변환은 이 컴퓨터에서 처리됩니다.</span><span>Markdown · Confluence</span></footer>
|
|
165
|
+
<dialog id="local-connect-dialog" class="local-connect-dialog" aria-labelledby="local-connect-title">
|
|
166
|
+
<h2 id="local-connect-title">내 컴퓨터의 csync 연결</h2>
|
|
167
|
+
<p>이 웹은 화면만 제공합니다. 로컬 csync가 문서·첨부·연결 정보를 처리합니다.</p>
|
|
168
|
+
<ol><li>내 컴퓨터에서 아래 명령을 실행하세요.</li><li>터미널에 표시된 연결 링크를 이 브라우저에서 여세요.</li><li>로컬 네트워크 접근 요청이 나오면 허용하고 연결을 누르세요.</li></ol>
|
|
169
|
+
<pre id="local-connect-command">csync web --ui https://배포주소 --base /문서폴더</pre>
|
|
170
|
+
<form id="local-connect-form">
|
|
171
|
+
<label for="local-connect-endpoint">로컬 실행기 주소</label><input id="local-connect-endpoint" type="url" value="http://127.0.0.1:4318" required autocomplete="off">
|
|
172
|
+
<label for="local-connect-token">연결 키</label><input id="local-connect-token" type="password" required autocomplete="off" spellcheck="false">
|
|
173
|
+
<p>연결한 웹에 로컬 csync의 파일 작업 권한을 부여합니다. 신뢰하는 웹만 연결하세요. 연결 키는 이 탭의 세션에만 보관하며 csync를 종료하면 만료됩니다.</p>
|
|
174
|
+
<p id="local-connect-note" role="status" aria-live="polite"></p><button id="local-connect-submit" class="primary" type="submit">내 컴퓨터에 연결</button>
|
|
175
|
+
</form>
|
|
176
|
+
</dialog>
|
|
177
|
+
<dialog id="browser-folder-dialog" class="local-connect-dialog" aria-labelledby="browser-folder-title">
|
|
178
|
+
<h2 id="browser-folder-title">내 컴퓨터의 문서 폴더 열기</h2>
|
|
179
|
+
<p>로컬 프로그램 설치 없이 브라우저에서 문서 폴더를 선택하세요. 읽기·쓰기 권한을 허용하면 결과를 같은 폴더에 반영할 수 있습니다.</p>
|
|
180
|
+
<p>변환과 변경 확인은 브라우저에서 처리합니다. Confluence 통신에 필요한 인증과 업로드 대상 문서·첨부만 중계 API로 전달합니다. 큰 첨부는 전송 동안 비공개 임시 저장소를 거칩니다. 작업 중에는 이 탭을 열어 두세요.</p>
|
|
181
|
+
<p>데스크톱 Chrome·Edge와 HTTPS가 필요합니다. 파일별 100MiB, 전체 512MiB까지 처리합니다.</p>
|
|
182
|
+
<p id="browser-folder-status" role="status" aria-live="polite"></p>
|
|
183
|
+
<button id="browser-folder-resume" class="primary" type="button" hidden>이전 폴더 다시 연결</button>
|
|
184
|
+
<button id="browser-folder-open" class="primary" type="button">문서 폴더 열기</button>
|
|
185
|
+
</dialog>
|
|
186
|
+
<dialog id="browser-apply-dialog" class="local-connect-dialog" aria-labelledby="browser-apply-title">
|
|
187
|
+
<h2 id="browser-apply-title">로컬 파일 적용 확인</h2><p id="browser-apply-status" role="alert"></p>
|
|
188
|
+
<p>처리 결과는 아직 보관 중입니다. 로컬 수정 사항을 다른 곳에 보관하거나 충돌을 해결한 뒤 다시 시도하세요. 이 창을 닫거나 새 작업으로 덮어쓰지 않습니다.</p>
|
|
189
|
+
<button id="browser-apply-retry" class="primary" type="button">다시 적용 확인</button>
|
|
190
|
+
</dialog>
|
|
191
|
+
<dialog id="overwrite-dialog" class="env-confirm-dialog overwrite-dialog" aria-labelledby="overwrite-title" aria-describedby="overwrite-warning">
|
|
192
|
+
<h3 id="overwrite-title">파일 덮어쓰기 확인</h3>
|
|
193
|
+
<p class="hint">저장 위치</p><p id="overwrite-path" class="overwrite-path"></p>
|
|
194
|
+
<p id="overwrite-warning" class="restore-warning"></p>
|
|
195
|
+
<ul id="overwrite-files" class="overwrite-files" aria-label="덮어쓸 파일"></ul>
|
|
196
|
+
<div class="actions"><button id="overwrite-cancel" type="button" autofocus>취소</button><button id="overwrite-confirm" type="button" class="primary">덮어쓰기</button></div>
|
|
197
|
+
</dialog>
|
|
198
|
+
|
|
199
|
+
<dialog id="help-dialog" class="help-dialog" aria-labelledby="help-title">
|
|
200
|
+
<header class="help-heading"><div><span class="eyebrow">WORKSPACE GUIDE</span><h2 id="help-title">사용 도움말</h2></div><form method="dialog"><button aria-label="도움말 닫기" autofocus>닫기</button></form></header>
|
|
201
|
+
<nav class="help-nav" aria-label="도움말 목차"><a href="#help-screens">화면으로 보기</a><a href="#help-convert">문서 변환</a><a href="#help-sync">Confluence</a><a href="#help-token">API 토큰 발급</a><a href="#help-links">참조 링크</a><a href="#help-faq">자주 묻는 질문</a></nav>
|
|
202
|
+
<div class="help-body" tabindex="0" aria-label="사용 도움말 내용">
|
|
203
|
+
<p class="help-intro">Obsidian에서 작업한 문서를 변환한 다음, 변환 결과 폴더를 기준으로 Confluence에 올릴 수 있습니다. 로컬 실행에서는 두 탭의 기준 폴더를 각각 설정합니다. 배포 웹은 로컬 CLI 없이 브라우저에서 문서 폴더를 선택합니다. Vercel 배포에서는 변환·변경 확인을 브라우저에서 처리하고 Confluence 요청만 중계합니다. Docker 배포에서는 문서·첨부·.env를 서버의 임시 공간으로 전달해 처리합니다. 두 방식 모두 로컬 편집 충돌을 확인한 뒤 브라우저가 결과를 저장합니다. 데스크톱 Chrome·Edge와 HTTPS가 필요합니다. 변환 저장 전에 출력 폴더를 선택하세요. 원본과 같은 폴더를 지정하면 저장 시 덮어쓰기 확인창이 뜹니다.</p>
|
|
204
|
+
<section id="help-screens"><h3>화면으로 보기</h3>
|
|
205
|
+
<p>문서와 Confluence 데이터는 사용법 설명용 예시입니다. 필요한 화면을 펼쳐 보세요.</p>
|
|
206
|
+
<div class="guide-steps usage-guide-steps"><details><summary>Fetch·Pull과 업로드할 문서 선택</summary><p>Fetch로 원격 신규·변경을 확인하고 받을 문서는 Pull로 가져옵니다. 보낼 문서만 체크한 뒤 업로드 미리보기를 실행해야 업로드 버튼이 활성화됩니다.</p><figure><a href="/assets/guide/web/sync-workspace.png" target="_blank" rel="noopener noreferrer" aria-label="Fetch·Pull과 업로드할 문서 선택 화면 원본 크기로 보기"><img src="/assets/guide/web/sync-workspace.png" alt="Fetch·Pull과 업로드할 문서 선택 사용 화면" width="1440" height="1280" loading="lazy" decoding="async"></a><figcaption>이미지를 누르면 새 탭에서 원본 크기로 볼 수 있습니다.</figcaption></figure></details><details><summary>원격 본문과 로컬 문서 비교</summary><p>문서 행의 diff 보기를 누르면 현재 원격 본문과 로컬 Markdown을 비교합니다. 왼쪽은 원격 HTML의 근사 변환본, 오른쪽은 로컬 본문입니다.</p><figure><a href="/assets/guide/web/remote-diff.png" target="_blank" rel="noopener noreferrer" aria-label="원격 본문과 로컬 문서 비교 화면 원본 크기로 보기"><img src="/assets/guide/web/remote-diff.png" alt="원격 본문과 로컬 문서 비교 사용 화면" width="1120" height="718" loading="lazy" decoding="async"></a><figcaption>이미지를 누르면 새 탭에서 원본 크기로 볼 수 있습니다.</figcaption></figure></details><details><summary>문서 미리보기와 표 서식 정리</summary><p>왼쪽에서 파일을 선택하고 문서 미리보기를 펼칩니다. 문서 서식 정리에서 기본 서식이나 모든 표의 내용에 맞춤·균등 배분을 적용하고, 변경 비교 후 저장합니다.</p><figure><a href="/assets/guide/web/document-preview.png" target="_blank" rel="noopener noreferrer" aria-label="문서 미리보기와 표 서식 정리 화면 원본 크기로 보기"><img src="/assets/guide/web/document-preview.png" alt="문서 미리보기와 표 서식 정리 사용 화면" width="1078" height="867" loading="lazy" decoding="async"></a><figcaption>이미지를 누르면 새 탭에서 원본 크기로 볼 수 있습니다.</figcaption></figure></details></div>
|
|
207
|
+
</section>
|
|
208
|
+
<section id="help-convert"><h3>문서 변환</h3>
|
|
209
|
+
<ol><li><strong>기준 폴더 변경…</strong>으로 원본 폴더를 엽니다. 화살표는 폴더를 펼치고, 이름을 누르면 변환 대상을 선택합니다.</li><li>파일을 선택하고 기본적으로 접힌 <strong>문서 미리보기</strong>를 펼치면 표와 이미지를 포함한 본문이 표시됩니다. 파일 하나를 선택하면 그 파일만, 폴더를 선택하면 하위 Markdown 전체를 변환합니다. 변환 설정의 기준 폴더 전체 선택을 누르면 현재 탐색 위치와 관계없이 기준 폴더 아래 모든 Markdown을 대상으로 합니다. 선택 후 변환 미리보기와 변환 후 저장을 사용하세요.</li><li>변환 형식과 출력 폴더를 정하고 <strong>변환 미리보기</strong>로 원본과 결과를 비교합니다.</li><li><strong>변환 후 저장</strong>을 누른 뒤 <strong>결과 폴더 열기</strong>로 확인합니다. 웹 변환은 지정한 출력 폴더에 저장하며, 첨부와 PDF 페이지 이미지는 각 문서 옆의 attachments/문서명/에 모읍니다.</li></ol>
|
|
210
|
+
<dl><dt>Markdown</dt><dd>찾을 수 있는 위키링크를 상대 링크로 바꾸고 PDF 페이지 참조를 이미지로 변환합니다. 찾지 못한 문서 위키링크는 그대로 남습니다.</dd><dt>Obsidian</dt><dd>해석 가능한 Markdown 문서 링크를 위키링크로 바꿉니다.</dd><dt>Confluence 변환 오류 보정</dt><dd>옛 변환 결과의 CSS 잔해, 불필요한 이스케이프와 코드블록 언어 등을 보정합니다. 미리보기로 바뀐 내용을 확인하세요.</dd><dt>출력 위치</dt><dd>파일 하나는 출력 폴더 바로 아래에, 폴더 전체는 선택 폴더 내부 구조를 유지해 저장합니다. 출력 폴더를 원본과 같게 지정하면 선택 범위의 원래 위치에 반영합니다. 실제 덮어쓰기 전 변경 파일을 확인하며, 확인 이후 원본이 바뀌면 저장을 중단합니다. 로컬 실행에서 출력 경로를 비우면 원본 기준 폴더 옆에 새 결과 폴더를 만듭니다.</dd></dl>
|
|
211
|
+
</section>
|
|
212
|
+
<section id="help-sync"><h3>Confluence: Push / Pull</h3>
|
|
213
|
+
<p>로컬 문서에서 스페이스 문서를 보관할 기준 폴더를 선택하고, .env 연결 설정에서 설정 확인 후 스페이스 연결을 누르세요. 별도 파일·폴더 스코프 설정은 없습니다.</p>
|
|
214
|
+
<dl><dt>변경사항과 Fetch</dt><dd>로컬은 5초 간격으로 자동 확인하며 Confluence API를 호출하지 않습니다. Fetch는 스페이스 페이지를 100개씩 조회해 새 문서와 버전·위치 변경을 확인하고 2분 동안 결과를 재사용합니다. Push·Pull 성공 후에는 캐시를 건너뛰고 한 번 더 Fetch해 목록을 갱신합니다. 후속 Fetch만 실패하면 완료된 Push·Pull은 유지하고 경고를 표시합니다. 문서와 동기화 기준은 유지합니다.</dd><dt>업로드(Push)</dt><dd>업로드할 문서를 체크하고 미리보기를 완료한 뒤 업로드하세요. 체크한 문서만 처리하며 원격 충돌 검사는 유지합니다. 선택 후 문서를 수정하면 최신 내용 반영과 미리보기가 다시 필요합니다.</dd><dt>가져오기(Pull)</dt><dd>변경 목록 위의 ‘원격 문서 n개 가져오기’로 원격 신규 문서와 원격에서만 바뀐 문서를 받습니다. 로컬이 비어 있어도 같은 기능을 사용합니다. 로컬 수정·의도적인 삭제·양쪽 변경은 보존하며 업로드 체크는 적용되지 않습니다. 문서 버전이 그대로인 첨부 단독 변경은 Fetch에서 감지하지 않습니다. 가져오기 형식은 Markdown 또는 Obsidian을 선택하며, 가져오기와 복구·원복에 적용합니다. 내부 링크 표기와 패널 복원 방식이 달라집니다. Markdown은 제목이 있는 인용문과 위첨자 각주 목록으로, Obsidian은 콜아웃과 정의형·인라인 각주로 복원합니다. 정확한 각주 복원 정보는 새 업로드부터 보관합니다. 기존 파일을 일괄 변환하지 않습니다.</dd><dt>문서 복구·원복</dt><dd>각 문서 행에서 원격에서 복구 또는 원격으로 원복을 누르고 확인하세요. 원복은 해당 문서와 참조 첨부의 로컬 수정을 버립니다. 원격 문서는 변경하지 않으며 복구한 문서는 업로드 선택에서 제외됩니다.</dd><dt>왼쪽 문서 탐색</dt><dd>파일을 선택하면 문서를 미리볼 수 있습니다. 탐색 위치를 바꿔도 작업공간이나 업로드 선택은 바뀌지 않습니다. 제외 규칙과 독립된 하위 작업공간은 유지합니다.</dd><dt>다운로드</dt><dd>.env 연결 설정에서 빈 .env 샘플을 내려받아 값을 채우세요. 대상 및 실행 내역의 로그 다운로드는 현재 작업의 진행·성공·실패 로그를 저장합니다. 토큰은 가려지지만 문서 경로와 오류 메시지는 포함됩니다.</dd><dt>설정 파일</dt><dd>기준 폴더의 .env 또는 직접 가져온 .env를 사용합니다. 가져온 값은 현재 웹 작업에만 적용되며 별도 저장 버튼으로 기준 폴더에 저장할 수 있습니다. 서버 실행 환경을 대신 사용하지 않습니다.</dd></dl>
|
|
215
|
+
<p class="help-note">Pull은 원격 삭제를 로컬에 자동 반영하거나 양쪽 변경을 자동 병합하지 않습니다. 누락된 원격 첨부는 원격 참조를 유지하고 경고하며, 권한·네트워크 오류는 중단합니다. 기존 원격 루트 연결과 문서 매핑은 임의로 변경하지 않습니다.</p>
|
|
216
|
+
</section>
|
|
217
|
+
<section id="help-token"><h3>API 토큰 발급 가이드</h3>
|
|
218
|
+
<p>빨간 테두리와 Click 표시를 따라 진행하세요. 계정 정보는 가려져 있습니다. API 토큰의 권한(scope)은 csync에서 처리할 로컬 파일·폴더 작업 스코프와 별개의 설정입니다.</p>
|
|
219
|
+
<p><a href="https://id.atlassian.com/manage-profile/security/api-tokens" target="_blank" rel="noopener noreferrer">Atlassian API 토큰 관리 열기 ↗</a></p>
|
|
220
|
+
<div class="token-guide-steps guide-steps"><details open><summary>1. 계정 설정 열기</summary><p>Confluence 오른쪽 위 프로필 아이콘을 누른 다음 Account settings를 선택합니다.</p><figure><a href="/assets/guide/01-account-settings.png" target="_blank" rel="noopener noreferrer" aria-label="1단계 이미지 원본 크기로 보기"><img src="/assets/guide/01-account-settings.png" alt="계정 설정 열기: 빨간 테두리로 표시한 조작 위치" loading="lazy"></a><figcaption>이미지를 누르면 원본 크기로 볼 수 있습니다.</figcaption></figure></details><details><summary>2. 보안 → API 토큰 관리</summary><p>상단 보안 탭에서 API 토큰 만들기 및 관리를 누릅니다. 아래 바로가기 링크로도 이동할 수 있습니다.</p><figure><a href="/assets/guide/02-atlassian-security.png" target="_blank" rel="noopener noreferrer" aria-label="2단계 이미지 원본 크기로 보기"><img src="/assets/guide/02-atlassian-security.png" alt="보안 → API 토큰 관리: 빨간 테두리로 표시한 조작 위치" loading="lazy"></a><figcaption>이미지를 누르면 원본 크기로 볼 수 있습니다.</figcaption></figure></details><details><summary>3. 범위를 포함한 토큰 만들기</summary><p>범위를 포함하여 API 토큰 만들기를 선택합니다.</p><figure><a href="/assets/guide/03-api-tokens.png" target="_blank" rel="noopener noreferrer" aria-label="3단계 이미지 원본 크기로 보기"><img src="/assets/guide/03-api-tokens.png" alt="범위를 포함한 토큰 만들기: 빨간 테두리로 표시한 조작 위치" loading="lazy"></a><figcaption>이미지를 누르면 원본 크기로 볼 수 있습니다.</figcaption></figure></details><details><summary>4. 이름과 만료일 입력</summary><p>Name에 용도를 알 수 있는 이름(예: csync)을 입력하고 만료일을 정한 뒤 다음으로 진행합니다. 스크린샷의 날짜는 예시입니다.</p><figure><a href="/assets/guide/04-scope-api-token-step1.png" target="_blank" rel="noopener noreferrer" aria-label="4단계 이미지 원본 크기로 보기"><img src="/assets/guide/04-scope-api-token-step1.png" alt="이름과 만료일 입력: 빨간 테두리로 표시한 조작 위치" loading="lazy"></a><figcaption>이미지를 누르면 원본 크기로 볼 수 있습니다.</figcaption></figure></details><details><summary>5. Confluence 앱 선택</summary><p>앱 목록에서 Confluence를 선택하고 다음을 누릅니다.</p><figure><a href="/assets/guide/05-scope-api-token-step2.png" target="_blank" rel="noopener noreferrer" aria-label="5단계 이미지 원본 크기로 보기"><img src="/assets/guide/05-scope-api-token-step2.png" alt="Confluence 앱 선택: 빨간 테두리로 표시한 조작 위치" loading="lazy"></a><figcaption>이미지를 누르면 원본 크기로 볼 수 있습니다.</figcaption></figure></details><details><summary>6. 필요한 권한 검색·선택</summary><p>권한 이름을 검색하고 결과 왼쪽 체크박스를 선택합니다. 필요한 권한마다 반복한 뒤 다음으로 진행합니다. 아래 표를 기준으로 선택하세요.</p><figure><a href="/assets/guide/06-scope-api-token-step3.png" target="_blank" rel="noopener noreferrer" aria-label="6단계 이미지 원본 크기로 보기"><img src="/assets/guide/06-scope-api-token-step3.png" alt="필요한 권한 검색·선택: 빨간 테두리로 표시한 조작 위치" loading="lazy"></a><figcaption>이미지를 누르면 원본 크기로 볼 수 있습니다.</figcaption></figure></details><details><summary>7. 검토 후 토큰 만들기</summary><p>이름·만료일·앱·선택한 권한을 확인하고 토큰 만들기를 누릅니다. 화면의 read:space 하나는 예시이며 csync 전체 기능에 충분하지 않습니다.</p><figure><a href="/assets/guide/07-scope-api-token-step4.png" target="_blank" rel="noopener noreferrer" aria-label="7단계 이미지 원본 크기로 보기"><img src="/assets/guide/07-scope-api-token-step4.png" alt="검토 후 토큰 만들기: 빨간 테두리로 표시한 조작 위치" loading="lazy"></a><figcaption>이미지를 누르면 원본 크기로 볼 수 있습니다.</figcaption></figure></details></div>
|
|
221
|
+
<h4>csync에서 사용하는 권한</h4>
|
|
222
|
+
<p>아래 이름 전체를 검색하세요. 조회·Pull에는 기본 읽기 권한을, Push에는 필요한 쓰기 권한을 추가합니다. 토큰 계정 자체에도 대상 스페이스의 해당 권한이 있어야 합니다.</p>
|
|
223
|
+
<div class="token-scope-table"><table><thead><tr><th>작업</th><th>권한</th></tr></thead><tbody>
|
|
224
|
+
<tr><td>스코프 탐색·문서 조회·Pull</td><td><code>read:space:confluence</code><br><code>read:page:confluence</code><br><code>read:content-details:confluence</code></td></tr>
|
|
225
|
+
<tr><td>페이지 Push</td><td><code>write:page:confluence</code></td></tr>
|
|
226
|
+
<tr><td>이미지·첨부 다운로드</td><td><code>read:attachment:confluence</code></td></tr>
|
|
227
|
+
<tr><td>이미지·첨부 업로드</td><td><code>read:content-details:confluence</code><br><code>write:attachment:confluence</code></td></tr>
|
|
228
|
+
<tr><td>README 없는 폴더 생성</td><td><code>write:folder:confluence</code></td></tr>
|
|
229
|
+
</tbody></table></div>
|
|
230
|
+
<h4>발급한 토큰 적용</h4><p>생성 직후 Copy to clipboard로 복사하여 <code>.env</code>의 <code>CONFLUENCE_API_TOKEN</code>에 넣습니다. 토큰은 발급 화면을 닫은 뒤 다시 확인할 수 없습니다. 웹의 <strong>.env 가져오기</strong>로 적용하거나 기준 폴더의 <code>.env</code>를 갱신한 뒤 <strong>설정 확인</strong>을 누르세요.</p>
|
|
231
|
+
<p>범위를 포함한 토큰의 <code>CONFLUENCE_BASE_URL</code>은 <code>https://api.atlassian.com/ex/confluence/<CLOUD_ID>/wiki</code> 형식입니다. Cloud ID는 <code>https://<사이트>.atlassian.net/_edge/tenant_info</code>의 <code>cloudId</code> 값입니다.</p>
|
|
232
|
+
<p><a href="https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/" target="_blank" rel="noopener noreferrer">Atlassian 공식 발급 안내 ↗</a> · <a href="https://developer.atlassian.com/cloud/confluence/rest/v1/api-group-content---children-and-descendants/" target="_blank" rel="noopener noreferrer">Confluence API 권한 문서 ↗</a></p>
|
|
233
|
+
</section>
|
|
234
|
+
<section id="help-links"><h3>다른 폴더의 문서와 연결하기</h3>
|
|
235
|
+
<p>업로드할 문서는 프로젝트 폴더에 있고, 연결할 문서는 별도 DBP 폴더에 있다면 <strong>참조 문서 폴더</strong>에 DBP의 동기화 루트를 추가하세요. 여러 경로를 한 줄씩 입력하거나 폴더 선택창으로 추가할 수 있습니다.</p>
|
|
236
|
+
<pre><code>[[원본/긴/경로/문서명|표시 이름]]
|
|
237
|
+
[표시 이름](../이전/문서명.md)</code></pre>
|
|
238
|
+
<p>먼저 경로로 찾고, 찾지 못하면 기준·참조 폴더에서 파일명으로 찾습니다. 후보가 하나일 때만 연결하며 <code>|</code> 오른쪽은 화면에 표시할 이름입니다.</p>
|
|
239
|
+
<ul><li>현재 루트의 문서는 그 문서의 페이지 제목으로 연결합니다. 파일명과 H1이 달라도 됩니다.</li><li>참조 문서는 <code>.csync/mapping.json</code>의 게시된 페이지 ID로 연결합니다. 참조 문서 자체는 업로드하지 않습니다.</li><li>같은 Confluence 서버의 별도 동기화 폴더를 지정하세요. 중복 파일명, 문서 누락, 게시 매핑 누락은 경고로 표시합니다.</li></ul>
|
|
240
|
+
<p class="help-note">링크 경고가 있어도 업로드할 수 있습니다. 해결하지 못한 링크는 원문으로 남으므로 실행 전에 경고를 확인하세요.</p>
|
|
241
|
+
</section>
|
|
242
|
+
<section id="help-faq"><h3>자주 묻는 질문</h3>
|
|
243
|
+
<details><summary>문서와 표 서식을 한 번에 정리할 수 있나요?</summary><p>문서를 선택하고 문서 미리보기의 문서 서식 정리를 열고 기본 서식 정리 버튼을 누르면 정리 결과를 바로 비교합니다. 저장을 눌러야 파일에 반영됩니다. 기존 너비 유지가 기본입니다. 문서 서식 정리 안의 모든 표 메뉴에서 내용에 맞춤·균등 배분을 선택할 수 있습니다. 표 하나를 조절하려면 같은 툴바의 표 직접 편집을 누른 뒤 표를 클릭하세요. 미저장 표 조절도 기본 서식 정리 결과와 함께 확인할 수 있습니다. 오른쪽 변경 비교는 표 조절만 비교합니다. 내용에 맞춤으로 글자 길이에 따라 자동 배분하거나, 열 경계 드래그·균등 배분·전체 너비를 조절한 뒤, 변경 비교에서 원본 파일에 저장합니다. 일반 Markdown 표는 HTML로 변환됩니다. 파일을 바꾸거나 새로고침하면 미저장 변경은 취소됩니다.</p></details>
|
|
244
|
+
<details><summary>기존 파일이 있는데 덮어쓰기 확인창이 안 나와요.</summary><p>내용이 같으면 파일을 건드리지 않고 재사용합니다. 내용이 다른 경우에만 대상 목록을 보여주고 덮어쓸지 확인합니다. 취소하면 저장하지 않습니다.</p></details>
|
|
245
|
+
<details><summary>문서를 검색했는데 나오지 않아요.</summary><p>검색은 선택한 기준 폴더의 모든 하위 Markdown 파일명을 대상으로 합니다. 본문은 검색하지 않으며 숨김 폴더·node_modules·attachments는 탐색과 검색에서 제외됩니다. 문서가 참조하는 첨부는 미리보기·변환·업로드에서 계속 사용합니다.</p></details>
|
|
246
|
+
<details><summary>폴더를 변환했는데 비교 화면에 일부만 보여요.</summary><p>본문 비교는 최대 20개 문서, 문서당 200KB까지 지원합니다. 실제 저장은 선택 폴더의 전체 변환 대상에 적용됩니다.</p></details>
|
|
247
|
+
<details><summary>실행 내역의 색은 무엇을 뜻하나요?</summary><p>초록은 신규·생성·완료, 황갈색은 변경·갱신, 보라는 참조·연결, 회색은 동일·재사용입니다. 주황 배경은 경고, 빨강 배경은 오류입니다. 함께 표시된 문구로 상세 내용을 확인하세요.</p></details>
|
|
248
|
+
<details><summary>새로고침하면 설정이 사라지나요?</summary><p>기준 폴더, 출력 경로, 참조 폴더와 작업 옵션은 같은 브라우저에 저장됩니다. 브라우저 데이터를 지우거나 다른 주소·포트에서 열면 설정이 다를 수 있습니다. 업로드 승인은 저장하지 않으므로 다시 미리보기하세요.</p></details>
|
|
249
|
+
</section>
|
|
250
|
+
</div>
|
|
251
|
+
</dialog>
|
|
252
|
+
<dialog id="table-review-dialog" class="table-review-dialog" aria-labelledby="table-review-title"><div class="panel-heading"><h2 id="table-review-title">문서 서식 변경 확인</h2><button id="table-review-close">닫기</button></div><p id="format-review-note" class="table-review-note">기본 서식과 표 조절을 함께 확인한 뒤 저장하세요.</p><div id="table-review-diff" class="table-review-diff"></div><p id="table-save-status" role="status" aria-live="polite"></p><div class="table-review-footer"><button id="table-save" class="primary">원본 파일에 저장</button></div></dialog>
|
|
253
|
+
</main><aside id="activity-panel" class="activity-panel" role="status" aria-live="polite" aria-atomic="false" hidden><span class="activity-spinner" aria-hidden="true"></span><div class="activity-content"><strong id="activity-title"></strong><p id="activity-detail"></p><div class="activity-meta"><time id="activity-elapsed" aria-hidden="true"></time><a id="activity-link" href="#sync-results" hidden>실행 내역 보기 ↓</a></div></div></aside><aside id="snackbars" class="snackbars" aria-label="작업 알림"></aside><script src="/assets/app.js" type="module"></script></body></html>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** Immutable Markdown baselines for local diff; hashes never substitute for source text. */
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { existsSync, lstatSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { workspacePath } from './metadata.js';
|
|
6
|
+
const digest = (text) => createHash('sha256').update(text).digest('hex');
|
|
7
|
+
function objectPath(base, id) {
|
|
8
|
+
if (!/^[a-f0-9]{64}$/.test(id))
|
|
9
|
+
throw new Error('비교 기준 식별자가 올바르지 않습니다.');
|
|
10
|
+
workspacePath(base);
|
|
11
|
+
const dir = join(base, '.csync/objects');
|
|
12
|
+
try {
|
|
13
|
+
if (!lstatSync(dir).isDirectory())
|
|
14
|
+
throw new Error('비교 기준 폴더는 일반 폴더여야 합니다.');
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
if (e.code !== 'ENOENT')
|
|
18
|
+
throw e;
|
|
19
|
+
}
|
|
20
|
+
const path = join(dir, id + '.md');
|
|
21
|
+
try {
|
|
22
|
+
if (!lstatSync(path).isFile())
|
|
23
|
+
throw new Error('비교 기준은 일반 파일이어야 합니다.');
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
if (e.code !== 'ENOENT')
|
|
27
|
+
throw e;
|
|
28
|
+
}
|
|
29
|
+
return path;
|
|
30
|
+
}
|
|
31
|
+
export function storeBaseline(base, text) {
|
|
32
|
+
const id = digest(text), path = objectPath(base, id);
|
|
33
|
+
mkdirSync(join(base, '.csync/objects'), { recursive: true });
|
|
34
|
+
if (!existsSync(path))
|
|
35
|
+
writeFileSync(path, text, { flag: 'wx', mode: 0o600 });
|
|
36
|
+
if (readFileSync(path, 'utf8') !== text)
|
|
37
|
+
throw new Error('저장된 비교 기준의 내용이 올바르지 않습니다.');
|
|
38
|
+
return id;
|
|
39
|
+
}
|
|
40
|
+
export function readBaseline(base, id) {
|
|
41
|
+
const text = readFileSync(objectPath(base, id), 'utf8');
|
|
42
|
+
if (digest(text) !== id)
|
|
43
|
+
throw new Error('저장된 비교 기준이 손상되었습니다.');
|
|
44
|
+
return text;
|
|
45
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/** Shared local/last-observed-remote view. Reading this view never calls Confluence. */
|
|
2
|
+
import { readFetchSnapshot, FETCH_TTL_MS } from './fetch.js';
|
|
3
|
+
import { loadMapping } from './mapping.js';
|
|
4
|
+
import { mappingPath } from './metadata.js';
|
|
5
|
+
import { buildIgnorer } from './ignore.js';
|
|
6
|
+
import { existsSync } from 'node:fs';
|
|
7
|
+
import { resolve } from 'node:path';
|
|
8
|
+
import { inNestedWorkspace } from './workspace.js';
|
|
9
|
+
export function observeChanges(base, rows, env) {
|
|
10
|
+
let snapshot = null, remoteError;
|
|
11
|
+
try {
|
|
12
|
+
snapshot = readFetchSnapshot(base, env);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
remoteError = '원격 조회 캐시를 사용할 수 없습니다. 연결 설정을 확인하고 csync fetch로 다시 조회하세요.';
|
|
16
|
+
}
|
|
17
|
+
const remoteById = new Map(snapshot?.items.map(item => [item.pageId, item]) ?? []);
|
|
18
|
+
const observed = rows.map(({ entry, ...row }) => {
|
|
19
|
+
const remote = remoteById.get(row.pageId ?? '');
|
|
20
|
+
return { ...row, ...(row.unmapped ? { recoverable: !!row.recoverable && remote?.state === 'new' && remote.path === row.path } : {}), remoteState: remote?.state, remoteVersion: remote?.remoteVersion, baselineVersion: remote?.baselineVersion, remoteReasons: remote?.reasons };
|
|
21
|
+
});
|
|
22
|
+
const seen = new Set(observed.map(row => row.pageId));
|
|
23
|
+
const ignore = buildIgnorer(base, []);
|
|
24
|
+
for (const [path, entry] of Object.entries(loadMapping(mappingPath(base)))) {
|
|
25
|
+
if (!/\.md$/i.test(path) || entry.type === 'folder' || ignore.ignores(path) || inNestedWorkspace(base, path) || seen.has(entry.pageId))
|
|
26
|
+
continue;
|
|
27
|
+
const remote = remoteById.get(entry.pageId);
|
|
28
|
+
seen.add(entry.pageId);
|
|
29
|
+
observed.push({ path, pageId: entry.pageId, status: 'unavailable', staged: false, stale: false, remoteState: remote?.state, remoteVersion: remote?.remoteVersion, baselineVersion: entry.remoteVersion, remoteReasons: remote?.reasons });
|
|
30
|
+
}
|
|
31
|
+
for (const item of snapshot?.items ?? []) {
|
|
32
|
+
if (item.state !== 'new' || seen.has(item.pageId) || ignore.ignores(item.path) || inNestedWorkspace(base, item.path))
|
|
33
|
+
continue;
|
|
34
|
+
observed.push({ path: item.path, pageId: item.pageId, status: existsSync(resolve(base, item.path)) ? 'new' : 'unavailable', staged: false, stale: false, remoteState: 'new', remoteVersion: item.remoteVersion, remoteReasons: item.reasons });
|
|
35
|
+
seen.add(item.pageId);
|
|
36
|
+
}
|
|
37
|
+
return { rows: observed, remoteCheckedAt: snapshot?.checkedAt ?? null, remoteExpired: !!snapshot && Date.now() - Date.parse(snapshot.checkedAt) >= FETCH_TTL_MS, remoteError };
|
|
38
|
+
}
|
|
39
|
+
export function changeGroup(row) {
|
|
40
|
+
if (row.remoteState === 'new')
|
|
41
|
+
return row.recoverable || row.status === 'unavailable' ? 'receive' : 'conflict';
|
|
42
|
+
if (row.unmapped)
|
|
43
|
+
return 'attention';
|
|
44
|
+
if (row.remoteState === 'changed' && ['new', 'changed', 'moved'].includes(row.status))
|
|
45
|
+
return 'conflict';
|
|
46
|
+
if (row.status === 'unavailable' || row.stale || ['unknown', 'unavailable'].includes(row.remoteState ?? ''))
|
|
47
|
+
return 'attention';
|
|
48
|
+
if (row.status === 'same' && row.remoteState === 'changed')
|
|
49
|
+
return 'receive';
|
|
50
|
+
return row.status !== 'same' || row.staged ? 'send' : 'same';
|
|
51
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/** Compare local Markdown with a saved baseline, or explicitly requested remote body. */
|
|
2
|
+
import { bold, cyan, red, green, dim } from '../shared/colors.js';
|
|
3
|
+
import { readFileSync, statSync } from 'node:fs';
|
|
4
|
+
import { resolve } from 'node:path';
|
|
5
|
+
import { readBaseline } from './baseline.js';
|
|
6
|
+
import { loadMapping } from './mapping.js';
|
|
7
|
+
import { mappingPath } from './metadata.js';
|
|
8
|
+
import { loadWorkspace, requireScope, inScope, inNestedWorkspace, scopePath, assertWorkspaceConnection, resolveSyncBase } from './workspace.js';
|
|
9
|
+
import { buildIgnorer } from './ignore.js';
|
|
10
|
+
import { scopeClient } from './scope.js';
|
|
11
|
+
import { readEnv } from '../confluence/config.js';
|
|
12
|
+
import { htmlToMarkdown, codeLanguagesFromStorage } from '../documents/html-to-markdown.js';
|
|
13
|
+
import { splitFrontmatter } from '../documents/obsidian.js';
|
|
14
|
+
import { positionalArgs } from '../cli/args.js';
|
|
15
|
+
export async function documentDiff(base, input, options = {}) {
|
|
16
|
+
const workspace = loadWorkspace(base);
|
|
17
|
+
requireScope(workspace);
|
|
18
|
+
const path = scopePath(base, input);
|
|
19
|
+
if (!/\.md$/i.test(path) || !inScope(path, workspace) || inNestedWorkspace(base, path) || buildIgnorer(base, []).ignores(path))
|
|
20
|
+
throw new Error('작업공간 안의 Markdown 문서를 선택하세요.');
|
|
21
|
+
const file = resolve(base, path);
|
|
22
|
+
if (!statSync(file).isFile() || statSync(file).size > 2_000_000)
|
|
23
|
+
throw new Error('비교할 문서는 2MB 이하 일반 파일이어야 합니다.');
|
|
24
|
+
const after = readFileSync(file, 'utf8'), mapping = loadMapping(mappingPath(base));
|
|
25
|
+
const pageId = splitFrontmatter(after).data.pageId;
|
|
26
|
+
const entry = mapping[path] ?? Object.values(mapping).find(e => e.pageId === String(pageId));
|
|
27
|
+
if (options.remote) {
|
|
28
|
+
if (!entry?.pageId)
|
|
29
|
+
return { path, before: '', after, source: 'new', canRemote: false, note: '원격 연결이 없는 새 문서입니다. 전체 내용이 추가로 표시됩니다.' };
|
|
30
|
+
const env = options.env ?? readEnv(base);
|
|
31
|
+
assertWorkspaceConnection(workspace, env);
|
|
32
|
+
const node = await scopeClient(env).getNode(entry.pageId);
|
|
33
|
+
if (String(node.id) !== entry.pageId || node.type !== 'page')
|
|
34
|
+
throw new Error('연결된 원격 페이지를 확인하세요.');
|
|
35
|
+
const localBody = splitFrontmatter(after).body;
|
|
36
|
+
// buildFrontmatter adds one blank separator. Keep intentional body whitespace.
|
|
37
|
+
const comparisonBody = localBody !== after ? localBody.replace(/^\r?\n/, '') : localBody;
|
|
38
|
+
return { path, before: htmlToMarkdown(node.html, { obsidian: /^ {0,3}(?:> ?)+\[![\w-]+\]|\[\^[^\]\s]+\]:|(?<!\\)\^\[/m.test(comparisonBody), pageId: entry.pageId, storage: node.storage, codeLangs: codeLanguagesFromStorage(node.storage) }), after: comparisonBody,
|
|
39
|
+
source: 'remote', canRemote: true, note: `현재 원격 v${node.version ?? '?'} → 로컬 본문 비교입니다. 원격 HTML의 근사 변환이며 frontmatter는 제외합니다. 과거 동기화 기준과의 비교는 아닙니다. 변경 목록에는 본문 외 제목·원격 위치 변경도 포함됩니다.` };
|
|
40
|
+
}
|
|
41
|
+
if (entry?.sourceObject)
|
|
42
|
+
return { path, before: readBaseline(base, entry.sourceObject), after, source: 'baseline', canRemote: true, note: '마지막 Pull·Push 성공 시 저장한 Markdown → 현재 로컬 문서입니다. 첨부 파일의 바이트 차이는 본문 diff에 표시하지 않습니다.' };
|
|
43
|
+
if (!entry)
|
|
44
|
+
return { path, before: '', after, source: 'new', canRemote: false, note: '새 문서입니다. 전체 내용이 추가로 표시됩니다.' };
|
|
45
|
+
return { path, before: null, after, source: 'unavailable', canRemote: true, note: '이 문서의 과거 본문은 저장되어 있지 않아 해시만으로 diff를 복원할 수 없습니다. 원격과 비교를 누르면 해당 페이지 본문만 1회 조회합니다. 이후 Pull·Push 성공부터 로컬 기준본이 저장됩니다.' };
|
|
46
|
+
}
|
|
47
|
+
/** A valid unified diff with one containing hunk; the web editor provides fine-grained changes. */
|
|
48
|
+
export function formatDocumentDiff(before, after, path) {
|
|
49
|
+
if (before === after)
|
|
50
|
+
return '본문 변경 없음\n';
|
|
51
|
+
const lines = (text) => (text.match(/[^\n]*(?:\n|$)/g) ?? []).filter(Boolean);
|
|
52
|
+
const a = lines(before), b = lines(after);
|
|
53
|
+
let start = 0, end = 0;
|
|
54
|
+
while (start < a.length && start < b.length && a[start] === b[start])
|
|
55
|
+
start++;
|
|
56
|
+
while (end < a.length - start && end < b.length - start && a[a.length - 1 - end] === b[b.length - 1 - end])
|
|
57
|
+
end++;
|
|
58
|
+
const display = (line, prefix) => [prefix + line.replace(/\n$/, ''), ...(!line.endsWith('\n') ? ['\'] : [])];
|
|
59
|
+
const aCount = a.length - start - end, bCount = b.length - start - end;
|
|
60
|
+
return [`--- 기준/${path}`, `+++ 로컬/${path}`, `@@ -${aCount ? start + 1 : start},${aCount} +${bCount ? start + 1 : start},${bCount} @@`, ...a.slice(start, a.length - end).flatMap(s => display(s, '-')), ...b.slice(start, b.length - end).flatMap(s => display(s, '+'))].join('\n') + '\n';
|
|
61
|
+
}
|
|
62
|
+
export async function runDiff(argv) {
|
|
63
|
+
const at = argv.indexOf('--base'), base = resolveSyncBase(at < 0 ? undefined : argv[at + 1]), paths = positionalArgs(argv).slice(1);
|
|
64
|
+
if (!base || paths.length !== 1)
|
|
65
|
+
throw new Error('csync diff <파일> [--base <dir>] [--remote]');
|
|
66
|
+
const result = await documentDiff(base, paths[0], { remote: argv.includes('--remote') });
|
|
67
|
+
console.log(dim(result.note));
|
|
68
|
+
if (result.before !== null)
|
|
69
|
+
console.log(formatDocumentDiff(result.before, result.after, result.path).split('\n').map(line => {
|
|
70
|
+
if (line.startsWith('--- ') || line.startsWith('+++ '))
|
|
71
|
+
return bold(line);
|
|
72
|
+
if (line.startsWith('@@'))
|
|
73
|
+
return cyan(line);
|
|
74
|
+
if (line.startsWith('-'))
|
|
75
|
+
return red(line);
|
|
76
|
+
if (line.startsWith('+') || line === '본문 변경 없음')
|
|
77
|
+
return green(line);
|
|
78
|
+
return line;
|
|
79
|
+
}).join('\n'));
|
|
80
|
+
}
|