@templatical/editor 0.35.0 → 0.37.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/dist/{AiChatSidebar-DPHbCGu4.js → AiChatSidebar-tu4eLcf_.js} +57 -57
- package/dist/{AiFeatureMenu--8z7qvg1.js → AiFeatureMenu-BF0i0vA4.js} +17 -17
- package/dist/{BlockIssueBadge-BGCsJqqM.js → BlockIssueBadge-DT-FqKeC.js} +9 -9
- package/dist/{BlockPreviewCanvas-DKspIy8V.js → BlockPreviewCanvas-DDCmMram.js} +28 -28
- package/dist/CloudHeaderExtras-NPhudovT.js +59 -0
- package/dist/{CloudPanels-Bp5gFtaL.js → CloudPanels-Iwnky0iA.js} +78 -108
- package/dist/{CollaboratorBar-DvwZm5u7.js → CollaboratorBar-DAITu0hz.js} +17 -17
- package/dist/{ColorPicker-DtozuN75.js → ColorPicker-BqlZ_TqG.js} +193 -193
- package/dist/{CommentsPanel-3C-DsEjy.js → CommentsPanel-CDvgmWP1.js} +3 -3
- package/dist/{CommentsSidebar-go1FnjDW.js → CommentsSidebar-X_xqM3dR.js} +158 -158
- package/dist/{CountdownBlock-D1fsNsyS.js → CountdownBlock-ZFJIdbP6.js} +12 -12
- package/dist/{CountdownToolbar-SLBuij7Q.js → CountdownToolbar-DBFoG3a6.js} +67 -67
- package/dist/{DesignReferenceSidebar-rcE_BvUd.js → DesignReferenceSidebar--QtXjLrw.js} +57 -57
- package/dist/{FieldRow-BWt7ECqo.js → FieldRow-C8nOknr_.js} +39 -39
- package/dist/{IssuesPanel-Cig46N1i.js → IssuesPanel-BLbNFMSX.js} +38 -38
- package/dist/{LoadingTrack-SQXoZVf2.js → LoadingTrack-BlTL4zFv.js} +2 -2
- package/dist/MediaPanels-CMTAhDXB.js +43 -0
- package/dist/{MergeTagInput-D1hzsn2b.js → MergeTagInput-BEjzj4Iu.js} +115 -115
- package/dist/{MergeTagModeToggle-CH9wR5YF.js → MergeTagModeToggle-DKN6ihI5.js} +40 -40
- package/dist/{MergeTagSuggestion-CoCuzEmW.js → MergeTagSuggestion-DKoLEeoj.js} +21 -21
- package/dist/{ParagraphEditor-CT2AdMdZ.js → ParagraphEditor-1E9yzOfk.js} +231 -258
- package/dist/{RestoreVersionDialog-mdqgQxFR.js → RestoreVersionDialog-BMGUkcd8.js} +28 -28
- package/dist/{RichTextEditorContent-riOB-rKD.js → RichTextEditorContent-BnxbQUV9.js} +49 -59
- package/dist/{SaveBlockDialog-Cn2v4Lpj.js → SaveBlockDialog-WKASpCCT.js} +78 -78
- package/dist/SavedBlocksBrowserModal-AYEXTMtQ.js +323 -0
- package/dist/{SavedBlocksPanels-ffBnWuVU.js → SavedBlocksPanels-D_CpacTl.js} +6 -6
- package/dist/{SavedBlocksPickBar-BmQC2tWN.js → SavedBlocksPickBar-BHMwg-1G.js} +11 -11
- package/dist/{TemplateScoringPanel-CxAtdreR.js → TemplateScoringPanel-CSin43YM.js} +99 -98
- package/dist/{TestEmailModal-Cjn1padY.js → TestEmailModal-BxizsRCd.js} +59 -59
- package/dist/{TestEmailPanel-Bf3XZ1jn.js → TestEmailPanel-vd2e5HzT.js} +3 -3
- package/dist/TitleEditor-CLJ68Ty4.js +199 -0
- package/dist/TplModal-Q9fDgS1M.js +51 -0
- package/dist/{VersionHistoryMenu-CrNrGsaa.js → VersionHistoryMenu-eGYVhM4H.js} +41 -47
- package/dist/{VersionHistoryPanels-CsuQk6W3.js → VersionHistoryPanels-C7Ntrrfq.js} +4 -4
- package/dist/{VersionPreviewBanner-BqbO0Zss.js → VersionPreviewBanner-BbQXnR0M.js} +9 -9
- package/dist/{blockTypeIcons-D_4HdaY9.js → blockTypeIcons-5qD4bB76.js} +5 -17
- package/dist/bundle-stats.json +8 -8
- package/dist/ca-Jx2CDwtn.js +83 -0
- package/dist/cdn/chunks/{AiChatSidebar-D0f74_nS.js → AiChatSidebar-dyqqHAcI.js} +4 -4
- package/dist/cdn/chunks/{AiChatSidebar-D0f74_nS.js.map → AiChatSidebar-dyqqHAcI.js.map} +1 -1
- package/dist/cdn/chunks/{AiFeatureMenu-DwGb3eF9.js → AiFeatureMenu-BjVMwhW8.js} +5 -5
- package/dist/cdn/chunks/{AiFeatureMenu-DwGb3eF9.js.map → AiFeatureMenu-BjVMwhW8.js.map} +1 -1
- package/dist/cdn/chunks/{BlockIssueBadge-CosQgeJ-.js → BlockIssueBadge-BJ__oEtm.js} +4 -4
- package/dist/cdn/chunks/{BlockIssueBadge-CosQgeJ-.js.map → BlockIssueBadge-BJ__oEtm.js.map} +1 -1
- package/dist/cdn/chunks/{BlockPreviewCanvas-CIpZ2a6g.js → BlockPreviewCanvas-B5f26eLE.js} +5 -5
- package/dist/cdn/chunks/{BlockPreviewCanvas-CIpZ2a6g.js.map → BlockPreviewCanvas-B5f26eLE.js.map} +1 -1
- package/dist/cdn/chunks/{CloudHeaderExtras-CQzQwKFB.js → CloudHeaderExtras-D5P5IEKA.js} +4 -4
- package/dist/cdn/chunks/{CloudHeaderExtras-CQzQwKFB.js.map → CloudHeaderExtras-D5P5IEKA.js.map} +1 -1
- package/dist/cdn/chunks/{CloudPanels-BmexuLOU.js → CloudPanels-DkmR05nB.js} +15 -45
- package/dist/cdn/chunks/{CloudPanels-BmexuLOU.js.map → CloudPanels-DkmR05nB.js.map} +1 -1
- package/dist/cdn/chunks/{CollaboratorBar-DEICobpp.js → CollaboratorBar-Yn7KSpt4.js} +4 -4
- package/dist/cdn/chunks/{CollaboratorBar-DEICobpp.js.map → CollaboratorBar-Yn7KSpt4.js.map} +1 -1
- package/dist/cdn/chunks/{ColorPicker-C7yC58FK.js → ColorPicker-LcrzgMoW.js} +7 -7
- package/dist/cdn/chunks/{ColorPicker-C7yC58FK.js.map → ColorPicker-LcrzgMoW.js.map} +1 -1
- package/dist/cdn/chunks/{CommentsPanel-OjmKxLL7.js → CommentsPanel-CntwwocI.js} +2 -2
- package/dist/cdn/chunks/{CommentsPanel-OjmKxLL7.js.map → CommentsPanel-CntwwocI.js.map} +1 -1
- package/dist/cdn/chunks/{CommentsSidebar-C4pWZGpy.js → CommentsSidebar-BLDKnKy7.js} +4 -4
- package/dist/cdn/chunks/{CommentsSidebar-C4pWZGpy.js.map → CommentsSidebar-BLDKnKy7.js.map} +1 -1
- package/dist/cdn/chunks/{CountdownBlock-rK055jpy.js → CountdownBlock-B4AfqJwb.js} +2 -2
- package/dist/cdn/chunks/{CountdownBlock-rK055jpy.js.map → CountdownBlock-B4AfqJwb.js.map} +1 -1
- package/dist/cdn/chunks/{CountdownToolbar-wlJOxyAl.js → CountdownToolbar-CA1dpuOI.js} +3 -3
- package/dist/cdn/chunks/{CountdownToolbar-wlJOxyAl.js.map → CountdownToolbar-CA1dpuOI.js.map} +1 -1
- package/dist/cdn/chunks/{DesignReferenceSidebar-DELhnh8h.js → DesignReferenceSidebar-D1Y9Hswe.js} +5 -5
- package/dist/cdn/chunks/{DesignReferenceSidebar-DELhnh8h.js.map → DesignReferenceSidebar-D1Y9Hswe.js.map} +1 -1
- package/dist/cdn/chunks/{IssuesPanel-C9i3o8aE.js → IssuesPanel-Q62LTqvd.js} +5 -5
- package/dist/cdn/chunks/{IssuesPanel-C9i3o8aE.js.map → IssuesPanel-Q62LTqvd.js.map} +1 -1
- package/dist/cdn/chunks/MediaPanels-D21M6shx.js +45 -0
- package/dist/cdn/chunks/MediaPanels-D21M6shx.js.map +1 -0
- package/dist/cdn/chunks/{MergeTagInput-D76Kyvgu.js → MergeTagInput-l7paaAml.js} +7 -7
- package/dist/cdn/chunks/{MergeTagInput-D76Kyvgu.js.map → MergeTagInput-l7paaAml.js.map} +1 -1
- package/dist/cdn/chunks/{MergeTagModeToggle-Dz3gxN2y.js → MergeTagModeToggle-DYxkAGtA.js} +4 -4
- package/dist/cdn/chunks/{MergeTagModeToggle-Dz3gxN2y.js.map → MergeTagModeToggle-DYxkAGtA.js.map} +1 -1
- package/dist/cdn/chunks/{ParagraphEditor-DQn0HMfV.js → ParagraphEditor-Bd-GQXee.js} +15 -15
- package/dist/cdn/chunks/{ParagraphEditor-DQn0HMfV.js.map → ParagraphEditor-Bd-GQXee.js.map} +1 -1
- package/dist/cdn/chunks/{RestoreVersionDialog-BdjOL8Oy.js → RestoreVersionDialog-2X9RpM9A.js} +4 -4
- package/dist/cdn/chunks/{RestoreVersionDialog-BdjOL8Oy.js.map → RestoreVersionDialog-2X9RpM9A.js.map} +1 -1
- package/dist/cdn/chunks/{RichTextEditorContent-Drzwgh0J.js → RichTextEditorContent-D_rb0rmU.js} +8 -8
- package/dist/cdn/chunks/{RichTextEditorContent-Drzwgh0J.js.map → RichTextEditorContent-D_rb0rmU.js.map} +1 -1
- package/dist/cdn/chunks/{SaveBlockDialog-B3rbmXSM.js → SaveBlockDialog-CufdTomT.js} +15 -15
- package/dist/cdn/chunks/{SaveBlockDialog-B3rbmXSM.js.map → SaveBlockDialog-CufdTomT.js.map} +1 -1
- package/dist/cdn/chunks/{SavedBlocksBrowserModal-CkUXlnd2.js → SavedBlocksBrowserModal-CqpaNsk7.js} +8 -8
- package/dist/cdn/chunks/{SavedBlocksBrowserModal-CkUXlnd2.js.map → SavedBlocksBrowserModal-CqpaNsk7.js.map} +1 -1
- package/dist/cdn/chunks/{SavedBlocksPanels-BPi3PZKP.js → SavedBlocksPanels-DpxYxddo.js} +2 -2
- package/dist/cdn/chunks/{SavedBlocksPanels-BPi3PZKP.js.map → SavedBlocksPanels-DpxYxddo.js.map} +1 -1
- package/dist/cdn/chunks/{SavedBlocksPickBar-BvB9A5W2.js → SavedBlocksPickBar-Drpoav1B.js} +4 -4
- package/dist/cdn/chunks/{SavedBlocksPickBar-BvB9A5W2.js.map → SavedBlocksPickBar-Drpoav1B.js.map} +1 -1
- package/dist/cdn/chunks/{TemplateScoringPanel-BBCyLnOi.js → TemplateScoringPanel-DBjUNULq.js} +5 -5
- package/dist/cdn/chunks/{TemplateScoringPanel-BBCyLnOi.js.map → TemplateScoringPanel-DBjUNULq.js.map} +1 -1
- package/dist/cdn/chunks/{TestEmailModal-DAGTsBqi.js → TestEmailModal-BTNlSW6f.js} +10 -10
- package/dist/cdn/chunks/{TestEmailModal-DAGTsBqi.js.map → TestEmailModal-BTNlSW6f.js.map} +1 -1
- package/dist/cdn/chunks/{TestEmailPanel-BfenVvfx.js → TestEmailPanel-D0A9Zgxr.js} +2 -2
- package/dist/cdn/chunks/{TestEmailPanel-BfenVvfx.js.map → TestEmailPanel-D0A9Zgxr.js.map} +1 -1
- package/dist/cdn/chunks/{TitleEditor-oQ4gr6wS.js → TitleEditor-CrnuIq62.js} +9 -9
- package/dist/cdn/chunks/{TitleEditor-oQ4gr6wS.js.map → TitleEditor-CrnuIq62.js.map} +1 -1
- package/dist/cdn/chunks/{TplModal-DxOMcVwp.js → TplModal-DYXrTz42.js} +5 -5
- package/dist/cdn/chunks/{TplModal-DxOMcVwp.js.map → TplModal-DYXrTz42.js.map} +1 -1
- package/dist/cdn/chunks/{VersionHistoryMenu-BfVUvWHT.js → VersionHistoryMenu-bDGnE4hb.js} +4 -4
- package/dist/cdn/chunks/VersionHistoryMenu-bDGnE4hb.js.map +1 -0
- package/dist/cdn/chunks/{VersionHistoryPanels-NpDb641L.js → VersionHistoryPanels-82P0Q0HM.js} +2 -2
- package/dist/cdn/chunks/{VersionHistoryPanels-NpDb641L.js.map → VersionHistoryPanels-82P0Q0HM.js.map} +1 -1
- package/dist/cdn/chunks/{VersionPreviewBanner-Cpgt4xHc.js → VersionPreviewBanner-BJiwKkVC.js} +3 -3
- package/dist/cdn/chunks/{VersionPreviewBanner-Cpgt4xHc.js.map → VersionPreviewBanner-BJiwKkVC.js.map} +1 -1
- package/dist/cdn/chunks/{blockTypeIcons-t9vvaiuH.js → blockTypeIcons-CNjJSFun.js} +2 -2
- package/dist/cdn/chunks/{blockTypeIcons-t9vvaiuH.js.map → blockTypeIcons-CNjJSFun.js.map} +1 -1
- package/dist/cdn/chunks/{ca-CNRWAMHI.js → ca-Jx2CDwtn.js} +2 -6
- package/dist/cdn/chunks/ca-Jx2CDwtn.js.map +1 -0
- package/dist/cdn/chunks/{cloud-CullB76F.js → cloud-BLgCKP7Z.js} +452 -227
- package/dist/cdn/chunks/cloud-BLgCKP7Z.js.map +1 -0
- package/dist/cdn/chunks/createCloudRuntime-U-qCH-dq.js +385 -0
- package/dist/cdn/chunks/createCloudRuntime-U-qCH-dq.js.map +1 -0
- package/dist/cdn/chunks/{de-DFYCT4QU.js → de-Ck0pBGHu.js} +2 -6
- package/dist/cdn/chunks/de-Ck0pBGHu.js.map +1 -0
- package/dist/cdn/chunks/{src-CaXeO-gG.js → editor-modal-MXgtarMl.js} +1474 -1935
- package/dist/cdn/chunks/editor-modal-MXgtarMl.js.map +1 -0
- package/dist/cdn/chunks/en-C9U7N77n.js +2 -0
- package/dist/cdn/chunks/{es-OgkdMZGX.js → es-lagTvUfX.js} +2 -6
- package/dist/cdn/chunks/es-lagTvUfX.js.map +1 -0
- package/dist/cdn/chunks/{extensions-BpXY7jO5.js → extensions-B8_jnIkD.js} +3 -3
- package/dist/cdn/chunks/{extensions-BpXY7jO5.js.map → extensions-B8_jnIkD.js.map} +1 -1
- package/dist/cdn/chunks/{fr-Dswns199.js → fr-C4hVl5Lk.js} +2 -6
- package/dist/cdn/chunks/fr-C4hVl5Lk.js.map +1 -0
- package/dist/cdn/chunks/{icons-BLxcQUck.js → icons-BUlqGSgd.js} +24 -24
- package/dist/cdn/chunks/{icons-BLxcQUck.js.map → icons-BUlqGSgd.js.map} +1 -1
- package/dist/cdn/chunks/{keys-DQp8x7Nx.js → keys-DBFhDFng.js} +4 -4
- package/dist/cdn/chunks/{keys-DQp8x7Nx.js.map → keys-DBFhDFng.js.map} +1 -1
- package/dist/cdn/chunks/{nl-CbcPJlrL.js → nl-CReD7Apd.js} +2 -6
- package/dist/cdn/chunks/nl-CReD7Apd.js.map +1 -0
- package/dist/cdn/chunks/{pt-BR-BibOQm-o.js → pt-BR-BRA0-vGP.js} +2 -6
- package/dist/cdn/chunks/pt-BR-BRA0-vGP.js.map +1 -0
- package/dist/cdn/chunks/{src-BC-eolWY.js → src-Ozknnj-v.js} +2 -2
- package/dist/cdn/chunks/{src-BC-eolWY.js.map → src-Ozknnj-v.js.map} +1 -1
- package/dist/cdn/chunks/{useCloudI18n-MxgHWrV6.js → useCloudI18n-DSWSGj-A.js} +2 -2
- package/dist/cdn/chunks/{useCloudI18n-MxgHWrV6.js.map → useCloudI18n-DSWSGj-A.js.map} +1 -1
- package/dist/cdn/chunks/{useEditorCore-D4MytYB9.js → useEditorCore-Cs7rYVBo.js} +488 -406
- package/dist/cdn/chunks/useEditorCore-Cs7rYVBo.js.map +1 -0
- package/dist/cdn/chunks/{useEditorRoot-CteADR3y.js → useEditorRoot-B0zW2nT4.js} +2 -2
- package/dist/cdn/chunks/{useEditorRoot-CteADR3y.js.map → useEditorRoot-B0zW2nT4.js.map} +1 -1
- package/dist/cdn/chunks/{useI18n-Ct1VIFcf.js → useI18n-Dlo7R9RA.js} +2 -2
- package/dist/cdn/chunks/{useI18n-Ct1VIFcf.js.map → useI18n-Dlo7R9RA.js.map} +1 -1
- package/dist/cdn/chunks/{useMergeTag-CSocWpxV.js → useMergeTag-BYAifvh8.js} +3 -3
- package/dist/cdn/chunks/{useMergeTag-CSocWpxV.js.map → useMergeTag-BYAifvh8.js.map} +1 -1
- package/dist/cdn/chunks/{usePopoverPosition-BxVWE5_0.js → usePopoverPosition-ElP3ABaV.js} +2 -2
- package/dist/cdn/chunks/{usePopoverPosition-BxVWE5_0.js.map → usePopoverPosition-ElP3ABaV.js.map} +1 -1
- package/dist/cdn/chunks/{useScrollToBlock-Cz3fpgTK.js → useScrollToBlock-nTbWkgaU.js} +2 -2
- package/dist/cdn/chunks/{useScrollToBlock-Cz3fpgTK.js.map → useScrollToBlock-nTbWkgaU.js.map} +1 -1
- package/dist/cdn/editor.css +1 -1
- package/dist/cdn/editor.js +1094 -1005
- package/dist/cdn/editor.js.map +1 -1
- package/dist/{check-CY-Ec6FV.js → check-DWtkBzBU.js} +1 -1
- package/dist/{chevron-down-BghbWA9p.js → chevron-down-C-Fjxcqj.js} +1 -1
- package/dist/chevron-right-SOkn2d4P.js +11 -0
- package/dist/{chevron-up-n3qFAPS3.js → chevron-up-lntU1ypp.js} +1 -1
- package/dist/{circle-alert-L5uGGFRP.js → circle-alert-CjzUTwy3.js} +1 -1
- package/dist/{clock-Dgnwp18n.js → clock-pB2QKPsJ.js} +1 -1
- package/dist/{cloud-B1c4XIsn.js → cloud-DdidMW6f.js} +445 -200
- package/dist/copy-CId1E038.js +19 -0
- package/dist/createCloudRuntime-x5WZm3p8.js +383 -0
- package/dist/{createLucideIcon-05lB8iWe.js → createLucideIcon-Cwf_nTzE.js} +6 -6
- package/dist/de-Ck0pBGHu.js +83 -0
- package/dist/{dist-BxFbxpgW.js → dist-BVqAYoRB.js} +125 -125
- package/dist/dist-D8i1ixHK.js +177 -0
- package/dist/dist-DBirAJIs.js +410 -0
- package/dist/editor-modal-B_LaQf0s.js +5998 -0
- package/dist/en-DcmpWV53.js +2 -0
- package/dist/es-lagTvUfX.js +83 -0
- package/dist/{extensions-Bawm4BOM.js → extensions-CHOBZRab.js} +42 -42
- package/dist/eye-BuGtFUoJ.js +16 -0
- package/dist/fr-C4hVl5Lk.js +83 -0
- package/dist/{image-up-ovhjl9u9.js → image-up-gH4JEpU5.js} +1 -1
- package/dist/index.d.ts +90 -11
- package/dist/{info-c3KI927I.js → info-BQ60P82u.js} +1 -1
- package/dist/{keys-C3P1yxnr.js → keys-DQA2i1k1.js} +4 -4
- package/dist/link-3R8it3J7.js +14 -0
- package/dist/list-Ccdgj46T.js +33 -0
- package/dist/{loader-circle-B2Y8xZQb.js → loader-circle-B_tAD4k6.js} +1 -1
- package/dist/{message-circle-B7K-naUa.js → message-circle-P-KSc6V0.js} +1 -1
- package/dist/nl-CReD7Apd.js +83 -0
- package/dist/{pencil-BhWTFcp4.js → pencil-9ZiwqS4r.js} +1 -1
- package/dist/plus-BwJEzCaO.js +14 -0
- package/dist/pt-BR-BRA0-vGP.js +83 -0
- package/dist/{refresh-cw-BqUR5vgO.js → refresh-cw-DEgfb2FK.js} +2 -14
- package/dist/{runtime-dom.esm-bundler-BuG03jBM.js → runtime-dom.esm-bundler-PnoZU512.js} +106 -106
- package/dist/search-DqQ8Li5E.js +16 -0
- package/dist/{send-D1vvuW79.js → send-CE6uvqop.js} +1 -1
- package/dist/{shield-check-DjK54PnW.js → shield-check-DhD1Z3rd.js} +1 -1
- package/dist/{sparkles-DNdS9V_3.js → sparkles-R0ZQHa6F.js} +1 -1
- package/dist/style.css +1 -1
- package/dist/templatical-editor.js +2491 -2408
- package/dist/{text-align-start-Bcmo_VUY.js → text-align-start-DSux2UNn.js} +1 -1
- package/dist/{trash-C9bMXvw4.js → trash-Cf_SqsER.js} +1 -1
- package/dist/{triangle-alert-Bn8Bd2Yv.js → triangle-alert-C6tGa6jw.js} +1 -1
- package/dist/{upload-DKgg1gno.js → upload-DusKjpVr.js} +1 -1
- package/dist/{useAliveFlag-PVmp95MT.js → useAliveFlag-oyByIcjy.js} +1 -1
- package/dist/{useCloudI18n-BKoiYsWZ.js → useCloudI18n-BLyh_e2T.js} +2 -2
- package/dist/{useEditorCore-CYGvurZa.js → useEditorCore-DhlKOYwe.js} +1552 -1486
- package/dist/{useEditorRoot-DkRGTQRs.js → useEditorRoot-ds57-l6F.js} +2 -2
- package/dist/{useI18n-CL6RfPzK.js → useI18n-BbdxxpOE.js} +2 -2
- package/dist/{useMergeTag-C9GEpljB.js → useMergeTag-DlvOBW_B.js} +3 -3
- package/dist/{usePopoverPosition-CWxaIWd3.js → usePopoverPosition-CprM5p-c.js} +2 -2
- package/dist/{useScrollToBlock-oUx1HIZ2.js → useScrollToBlock-BTFw0b9O.js} +3 -3
- package/dist/{vue.runtime.esm-bundler-D9JUcKrV.js → vue.runtime.esm-bundler-DShF3P6k.js} +1192 -1181
- package/dist/{x-BPKoRPTG.js → x-D_-42Ukq.js} +1 -1
- package/package.json +9 -12
- package/dist/CloudHeaderExtras-CRUQvgSV.js +0 -59
- package/dist/SavedBlocksBrowserModal-BORqqASb.js +0 -322
- package/dist/TitleEditor-pYEUX6lR.js +0 -198
- package/dist/TplModal-DRx4ytx8.js +0 -51
- package/dist/cdn/chunks/VersionHistoryMenu-BfVUvWHT.js.map +0 -1
- package/dist/cdn/chunks/ca-CNRWAMHI.js.map +0 -1
- package/dist/cdn/chunks/cloud-CullB76F.js.map +0 -1
- package/dist/cdn/chunks/createCloudRuntime-Cx2JpUYU.js +0 -443
- package/dist/cdn/chunks/createCloudRuntime-Cx2JpUYU.js.map +0 -1
- package/dist/cdn/chunks/de-DFYCT4QU.js.map +0 -1
- package/dist/cdn/chunks/en-rGHphLWo.js +0 -2
- package/dist/cdn/chunks/es-OgkdMZGX.js.map +0 -1
- package/dist/cdn/chunks/fr-Dswns199.js.map +0 -1
- package/dist/cdn/chunks/nl-CbcPJlrL.js.map +0 -1
- package/dist/cdn/chunks/pt-BR-BibOQm-o.js.map +0 -1
- package/dist/cdn/chunks/src-CaXeO-gG.js.map +0 -1
- package/dist/cdn/chunks/useEditorCore-D4MytYB9.js.map +0 -1
- package/dist/createCloudRuntime-PevFSH74.js +0 -441
- package/dist/dist-dNiknO7j.js +0 -251
- package/dist/dist-heatwAdo.js +0 -150
|
@@ -11,6 +11,7 @@ var e = { mediaLibrary: {
|
|
|
11
11
|
newFolder: "Nueva carpeta",
|
|
12
12
|
folderName: "Nombre de la carpeta",
|
|
13
13
|
noFiles: "No se han encontrado archivos",
|
|
14
|
+
noSearchResults: "Ningún archivo coincide con tu búsqueda",
|
|
14
15
|
dropOrClick: "Suelta los archivos aquí o haz clic para subirlos",
|
|
15
16
|
acceptedFormats: "Imágenes, PDF, vídeo, audio y documentos (máx. 10 MB)",
|
|
16
17
|
uploading: "Subiendo...",
|
|
@@ -56,11 +57,6 @@ var e = { mediaLibrary: {
|
|
|
56
57
|
import: "Importar",
|
|
57
58
|
importing: "Importando...",
|
|
58
59
|
importError: "No se ha podido importar desde la URL",
|
|
59
|
-
conversionLabel: "Tamaño",
|
|
60
|
-
conversionOriginal: "Original",
|
|
61
|
-
conversionSmall: "Pequeño (150 px)",
|
|
62
|
-
conversionMedium: "Mediano (600 px)",
|
|
63
|
-
conversionLarge: "Grande (1200 px)",
|
|
64
60
|
replaceFile: "Reemplazar archivo",
|
|
65
61
|
replaceWarningTitle: "Reemplazar archivo",
|
|
66
62
|
replaceWarningMessage: "Estás a punto de reemplazar este archivo. El archivo de reemplazo debe tener la misma extensión ({extension}).",
|
|
@@ -86,4 +82,4 @@ var e = { mediaLibrary: {
|
|
|
86
82
|
//#endregion
|
|
87
83
|
export { e as default };
|
|
88
84
|
|
|
89
|
-
//# sourceMappingURL=es-
|
|
85
|
+
//# sourceMappingURL=es-lagTvUfX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"es-lagTvUfX.js","names":[],"sources":["../../../../media-library/src/i18n/locales/es.ts"],"sourcesContent":["const es = {\n mediaLibrary: {\n title: \"Biblioteca multimedia\",\n searchPlaceholder: \"Buscar archivos...\",\n allFiles: \"Todos los archivos\",\n filterAll: \"Todos los tipos\",\n filterImages: \"Imágenes\",\n filterDocuments: \"Documentos\",\n filterVideos: \"Vídeos\",\n filterAudio: \"Audio\",\n newFolder: \"Nueva carpeta\",\n folderName: \"Nombre de la carpeta\",\n noFiles: \"No se han encontrado archivos\",\n noSearchResults: \"Ningún archivo coincide con tu búsqueda\",\n dropOrClick: \"Suelta los archivos aquí o haz clic para subirlos\",\n acceptedFormats: \"Imágenes, PDF, vídeo, audio y documentos (máx. 10 MB)\",\n uploading: \"Subiendo...\",\n uploadingProgress: \"Subiendo {current} de {total}...\",\n selectImage: \"Seleccionar imagen\",\n selectFile: \"Seleccionar archivo\",\n deleteSelected: \"Eliminar\",\n copyUrl: \"Copiar URL\",\n copied: \"¡Copiada!\",\n browseMedia: \"Explorar la biblioteca multimedia\",\n renameFolder: \"Cambiar nombre de la carpeta\",\n addSubfolder: \"Añadir subcarpeta\",\n subfolderName: \"Nombre de la subcarpeta\",\n sortNewest: \"Más recientes primero\",\n sortOldest: \"Más antiguos primero\",\n sortNameAsc: \"Nombre de A a Z\",\n sortNameDesc: \"Nombre de Z a A\",\n sortSizeAsc: \"Más pequeños primero\",\n sortSizeDesc: \"Más grandes primero\",\n moveSelected: \"Mover\",\n moveToRoot: \"Todos los archivos\",\n currentFolder: \"(actual)\",\n confirmDelete: \"¿Confirmar?\",\n renameFile: \"Cambiar nombre\",\n editFile: \"Editar archivo\",\n fileName: \"Nombre del archivo\",\n altText: \"Texto alternativo\",\n altTextPlaceholder: \"Describe esta imagen para mejorar la accesibilidad\",\n saveChanges: \"Guardar\",\n cancel: \"Cancelar\",\n frequentlyUsed: \"Usados frecuentemente\",\n deleteWarningTitle: \"Eliminar archivo\",\n deleteWarningMessage: \"¿Estás seguro? Esta acción es irreversible.\",\n deleteWarningUsageNote:\n \"Los siguientes archivos se utilizan en plantillas. Si los eliminas, es posible que esas plantillas dejen de funcionar correctamente.\",\n deleteAnyway: \"Eliminar\",\n usedInTemplates: \"Usado en {count} plantilla(s)\",\n viewGrid: \"Vista de cuadrícula\",\n viewList: \"Vista de lista\",\n showFolders: \"Mostrar carpetas\",\n hideFolders: \"Ocultar carpetas\",\n importFromUrl: \"Importar desde URL\",\n importUrlPlaceholder: \"https://example.com/image.jpg\",\n import: \"Importar\",\n importing: \"Importando...\",\n importError: \"No se ha podido importar desde la URL\",\n replaceFile: \"Reemplazar archivo\",\n replaceWarningTitle: \"Reemplazar archivo\",\n replaceWarningMessage:\n \"Estás a punto de reemplazar este archivo. El archivo de reemplazo debe tener la misma extensión ({extension}).\",\n replaceWarningUsageNote:\n \"Este archivo se utiliza en {count} plantilla(s). Al reemplazarlo, se actualizarán todas las referencias.\",\n replaceSelectFile: \"Seleccionar archivo de reemplazo\",\n replace: \"Reemplazar\",\n replacing: \"Reemplazando...\",\n replaceError: \"No se ha podido reemplazar el archivo\",\n saving: \"Guardando...\",\n cropAspectRatio: \"Relación de aspecto\",\n cropFree: \"Libre\",\n cropSquare: \"1:1\",\n cropLandscape43: \"4:3\",\n cropLandscape169: \"16:9\",\n cropOriginal: \"Original\",\n cropMaxWidth: \"Anchura máxima\",\n cropMaxHeight: \"Altura máxima\",\n cropOutputSize: \"Tamaño de salida\",\n cropPixels: \"px\",\n cropOptional: \"(opcional)\",\n storageTooltip: \"{used} de {total} usados ({remaining} restantes)\",\n },\n};\n\nexport default es;\n"],"mappings":";AAAA,IAAM,IAAK,EACT,cAAc;CACZ,OAAO;CACP,mBAAmB;CACnB,UAAU;CACV,WAAW;CACX,cAAc;CACd,iBAAiB;CACjB,cAAc;CACd,aAAa;CACb,WAAW;CACX,YAAY;CACZ,SAAS;CACT,iBAAiB;CACjB,aAAa;CACb,iBAAiB;CACjB,WAAW;CACX,mBAAmB;CACnB,aAAa;CACb,YAAY;CACZ,gBAAgB;CAChB,SAAS;CACT,QAAQ;CACR,aAAa;CACb,cAAc;CACd,cAAc;CACd,eAAe;CACf,YAAY;CACZ,YAAY;CACZ,aAAa;CACb,cAAc;CACd,aAAa;CACb,cAAc;CACd,cAAc;CACd,YAAY;CACZ,eAAe;CACf,eAAe;CACf,YAAY;CACZ,UAAU;CACV,UAAU;CACV,SAAS;CACT,oBAAoB;CACpB,aAAa;CACb,QAAQ;CACR,gBAAgB;CAChB,oBAAoB;CACpB,sBAAsB;CACtB,wBACE;CACF,cAAc;CACd,iBAAiB;CACjB,UAAU;CACV,UAAU;CACV,aAAa;CACb,aAAa;CACb,eAAe;CACf,sBAAsB;CACtB,QAAQ;CACR,WAAW;CACX,aAAa;CACb,aAAa;CACb,qBAAqB;CACrB,uBACE;CACF,yBACE;CACF,mBAAmB;CACnB,SAAS;CACT,WAAW;CACX,cAAc;CACd,QAAQ;CACR,iBAAiB;CACjB,UAAU;CACV,YAAY;CACZ,iBAAiB;CACjB,kBAAkB;CAClB,cAAc;CACd,cAAc;CACd,eAAe;CACf,gBAAgB;CAChB,YAAY;CACZ,cAAc;CACd,gBAAgB;AAClB,EACF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { H as e, N as t, Q as n, S as r, U as i, at as a, c as o, ct as s, f as c, g as l, h as u, k as d, l as f, lt as p, m, o as h, p as g, ut as _ } from "./draggable-kbOhCgnk.js";
|
|
2
2
|
import { a as v, d as y, o as b, r as x } from "./src-Dwgq7hf4.js";
|
|
3
|
-
import { t as S } from "./useI18n-
|
|
4
|
-
import { t as C } from "./useMergeTag-
|
|
3
|
+
import { t as S } from "./useI18n-Dlo7R9RA.js";
|
|
4
|
+
import { t as C } from "./useMergeTag-BYAifvh8.js";
|
|
5
5
|
import { _ as w, g as T, h as E, n as D, t as O, v as k, y as A } from "./tiptap-Epe8m3Vo.js";
|
|
6
6
|
import { i as j, r as M, t as N } from "./MergeTagSuggestion-t8Uj00Er.js";
|
|
7
7
|
//#region src/extensions/FontSize.ts
|
|
@@ -442,4 +442,4 @@ var W = w.create({
|
|
|
442
442
|
//#endregion
|
|
443
443
|
export { P as FontSize, F as LetterSpacing, I as LineBoundaryKeys, L as LineHeight, W as LogicMergeTagNode, J as MergeTagNode, N as MergeTagSuggestion, M as filterMergeTags, j as handleSuggestionKeyDown };
|
|
444
444
|
|
|
445
|
-
//# sourceMappingURL=extensions-
|
|
445
|
+
//# sourceMappingURL=extensions-B8_jnIkD.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extensions-BpXY7jO5.js","names":[],"sources":["../../../src/extensions/FontSize.ts","../../../src/extensions/LetterSpacing.ts","../../../src/extensions/LineBoundaryKeys.ts","../../../src/extensions/LineHeight.ts","../../../src/extensions/LogicMergeTagNodeView.vue","../../../src/extensions/LogicMergeTagNodeView.vue","../../../src/extensions/isNodeSelected.ts","../../../src/extensions/renderVueNodeView.ts","../../../src/extensions/LogicMergeTagNode.ts","../../../src/extensions/MergeTagNodeView.vue","../../../src/extensions/MergeTagNodeView.vue","../../../src/extensions/MergeTagNode.ts"],"sourcesContent":["import { Extension } from \"@tiptap/core\";\n\nexport interface FontSizeOptions {\n types: string[];\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n fontSize: {\n setFontSize: (size: string) => ReturnType;\n unsetFontSize: () => ReturnType;\n };\n }\n}\n\nexport const FontSize = Extension.create<FontSizeOptions>({\n name: \"fontSize\",\n\n addOptions() {\n return {\n types: [\"textStyle\"],\n };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n fontSize: {\n default: null,\n parseHTML: (element) =>\n element.style.fontSize?.replace(/['\"]+/g, \"\") || null,\n renderHTML: (attributes) => {\n if (!attributes.fontSize) {\n return {};\n }\n return {\n style: `font-size: ${attributes.fontSize}`,\n };\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n setFontSize:\n (size: string) =>\n ({ chain }) => {\n return chain().setMark(\"textStyle\", { fontSize: size }).run();\n },\n unsetFontSize:\n () =>\n ({ chain }) => {\n return chain()\n .setMark(\"textStyle\", { fontSize: null })\n .removeEmptyTextStyle()\n .run();\n },\n };\n },\n});\n","import { Extension } from \"@tiptap/core\";\n\nexport interface LetterSpacingOptions {\n types: string[];\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n letterSpacing: {\n setLetterSpacing: (spacing: string) => ReturnType;\n unsetLetterSpacing: () => ReturnType;\n };\n }\n}\n\nexport const LetterSpacing = Extension.create<LetterSpacingOptions>({\n name: \"letterSpacing\",\n\n addOptions() {\n return {\n types: [\"textStyle\"],\n };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n letterSpacing: {\n default: null,\n parseHTML: (element) =>\n element.style.letterSpacing?.replace(/['\"]+/g, \"\") || null,\n renderHTML: (attributes) => {\n if (!attributes.letterSpacing) {\n return {};\n }\n return {\n style: `letter-spacing: ${attributes.letterSpacing}`,\n };\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n setLetterSpacing:\n (spacing: string) =>\n ({ chain }) => {\n return chain().setMark(\"textStyle\", { letterSpacing: spacing }).run();\n },\n unsetLetterSpacing:\n () =>\n ({ chain }) => {\n return chain()\n .setMark(\"textStyle\", { letterSpacing: null })\n .removeEmptyTextStyle()\n .run();\n },\n };\n },\n});\n","import { Extension } from \"@tiptap/core\";\n\n/**\n * Routes plain End/Home through `Selection.modify` instead of the browser's\n * native caret movement.\n *\n * Chromium (verified 140–151, including stable Chrome) has a bug where a\n * native End or Home pressed while a triple-click selection is active puts\n * Blink's selection state into a mode where the next typed character\n * natively smooth-scrolls the nearest scrollable ancestor (the editor's\n * canvas, `.tpl-body`) to its very bottom (End) or top (Home), dragging the\n * caret out of view. The state cannot be repaired after the fact — clearing\n * or re-setting the DOM selection, blur/refocus, and preventDefault on the\n * clicks all fail — but a programmatic caret move never arms it.\n *\n * `Selection.modify(\"move\", direction, \"lineboundary\")` is the exact\n * equivalent of the native key (visual line boundary, bidi-aware via the\n * logical forward/backward directions), so behavior is unchanged for users.\n * Shift+End / Shift+Home extend selections natively and do not trigger the\n * bug, so only the plain keys are bound — a keymap entry without modifiers\n * never matches the shifted keys.\n */\nexport const LineBoundaryKeys = Extension.create({\n name: \"lineBoundaryKeys\",\n\n addKeyboardShortcuts() {\n const moveToLineBoundary =\n (direction: \"forward\" | \"backward\") =>\n ({ editor }: { editor: { view: unknown } }): boolean => {\n const view = editor.view as {\n composing: boolean;\n root: DocumentOrShadowRoot & {\n getSelection?: () => Selection | null;\n };\n dom: HTMLElement;\n };\n // During IME composition End/Home commit the composition; leave\n // that to the browser.\n if (!view || view.composing) return false;\n // `view.root` is the editable's Document or ShadowRoot, so the\n // selection resolves correctly in both mount modes. ShadowRoot's\n // getSelection is Chromium-only; elsewhere fall back to the owner\n // document (Chromium is also the only engine with the bug).\n const selection =\n typeof view.root?.getSelection === \"function\"\n ? view.root.getSelection()\n : (view.dom?.ownerDocument?.getSelection?.() ?? null);\n // `modify` is non-standard; without it, or with a selection that\n // is not ours, native handling is the safer default.\n if (!selection || typeof selection.modify !== \"function\") return false;\n if (!selection.anchorNode || !view.dom.contains(selection.anchorNode)) {\n return false;\n }\n selection.modify(\"move\", direction, \"lineboundary\");\n return true;\n };\n\n return {\n End: moveToLineBoundary(\"forward\"),\n Home: moveToLineBoundary(\"backward\"),\n };\n },\n});\n","import { Extension } from \"@tiptap/core\";\n\nexport interface LineHeightOptions {\n types: string[];\n defaultLineHeight: string;\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n lineHeight: {\n setLineHeight: (lineHeight: string) => ReturnType;\n unsetLineHeight: () => ReturnType;\n };\n }\n}\n\nexport const LineHeight = Extension.create<LineHeightOptions>({\n name: \"lineHeight\",\n\n addOptions() {\n return {\n types: [\"paragraph\"],\n defaultLineHeight: \"1.5\",\n };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n lineHeight: {\n default: null,\n parseHTML: (element) => element.style.lineHeight || null,\n renderHTML: (attributes) => {\n if (!attributes.lineHeight) {\n return {};\n }\n return {\n style: `line-height: ${attributes.lineHeight}`,\n };\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n setLineHeight:\n (lineHeight: string) =>\n ({ commands }) => {\n return this.options.types.every((type) =>\n commands.updateAttributes(type, { lineHeight }),\n );\n },\n unsetLineHeight:\n () =>\n ({ commands }) => {\n return this.options.types.every((type) =>\n commands.resetAttributes(type, \"lineHeight\"),\n );\n },\n };\n },\n});\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../composables/useI18n\";\nimport { useMergeTag } from \"../composables/useMergeTag\";\nimport {\n getLogicMergeTagKeyword,\n isLogicMergeTagValue,\n} from \"@templatical/types\";\nimport type { Editor } from \"@tiptap/core\";\nimport { NodeViewWrapper } from \"@tiptap/vue-3\";\nimport { computed, nextTick, ref } from \"vue\";\n\nconst props = defineProps<{\n node: {\n attrs: {\n value: string;\n keyword: string;\n };\n };\n editor: Editor;\n getPos: () => number;\n deleteNode: () => void;\n updateAttributes: (attrs: Record<string, unknown>) => void;\n}>();\n\nconst { syntax } = useMergeTag();\nconst { t } = useI18n();\n\nconst isValid = computed(() =>\n isLogicMergeTagValue(props.node.attrs.value, syntax),\n);\nconst displayKeyword = computed(() =>\n getLogicMergeTagKeyword(props.node.attrs.value, syntax),\n);\n\nconst isEditing = ref(false);\nconst editValue = ref(\"\");\nconst inputRef = ref<HTMLInputElement | null>(null);\nlet handled = false;\n\nfunction startEditing(): void {\n editValue.value = props.node.attrs.value;\n handled = false;\n isEditing.value = true;\n nextTick(() => {\n inputRef.value?.focus();\n inputRef.value?.select();\n });\n}\n\nfunction finishEditing(): void {\n if (handled) {\n return;\n }\n handled = true;\n\n const newValue = editValue.value.trim();\n if (!newValue) {\n isEditing.value = false;\n return;\n }\n\n if (newValue !== props.node.attrs.value) {\n props.updateAttributes({\n value: newValue,\n keyword: isLogicMergeTagValue(newValue, syntax)\n ? getLogicMergeTagKeyword(newValue, syntax)\n : \"\",\n });\n }\n isEditing.value = false;\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\") {\n event.preventDefault();\n finishEditing();\n } else if (event.key === \"Escape\") {\n isEditing.value = false;\n }\n}\n</script>\n\n<template>\n <NodeViewWrapper\n as=\"span\"\n :class=\"\n isValid\n ? 'tpl-logic-merge-tag-node tpl:group tpl:mx-0.5 tpl:inline-flex tpl:items-center tpl:gap-1 tpl:rounded tpl:px-1.5 tpl:py-0.5 tpl:text-[0.8em] tpl:font-bold tpl:tracking-wide tpl:uppercase tpl:select-none'\n : ''\n \"\n :style=\"\n isValid\n ? 'background-color: transparent; border: 1.5px solid color-mix(in srgb, var(--tpl-primary) 50%, transparent); color: var(--tpl-primary);'\n : ''\n \"\n contenteditable=\"false\"\n >\n <!-- Edit mode -->\n <input\n v-if=\"isEditing\"\n ref=\"inputRef\"\n v-model=\"editValue\"\n type=\"text\"\n class=\"tpl:w-40 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-0.5 tpl:py-0 tpl:text-[1em] tpl:font-medium tpl:normal-case tpl:outline-none tpl:text-[var(--tpl-primary)]\"\n @blur=\"finishEditing\"\n @keydown=\"handleKeydown\"\n />\n <!-- Display mode: valid merge tag -->\n <span\n v-else-if=\"isValid\"\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n class=\"tpl-tooltip tpl:cursor-pointer\"\n :data-tooltip=\"node.attrs.value\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ displayKeyword }}\n </span>\n <!-- Display mode: invalid (plain text) -->\n <span\n v-else\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ node.attrs.value }}\n </span>\n <button\n v-if=\"isValid\"\n type=\"button\"\n :aria-label=\"t.mergeTag.deleteMergeTag\"\n class=\"tpl-merge-tag-delete tpl:flex tpl:size-5 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-none tpl:bg-transparent tpl:p-0 tpl:opacity-60 tpl:transition-all tpl:hover:opacity-100 tpl:text-[var(--tpl-primary)]\"\n contenteditable=\"false\"\n @click.stop.prevent=\"deleteNode\"\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </NodeViewWrapper>\n</template>\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../composables/useI18n\";\nimport { useMergeTag } from \"../composables/useMergeTag\";\nimport {\n getLogicMergeTagKeyword,\n isLogicMergeTagValue,\n} from \"@templatical/types\";\nimport type { Editor } from \"@tiptap/core\";\nimport { NodeViewWrapper } from \"@tiptap/vue-3\";\nimport { computed, nextTick, ref } from \"vue\";\n\nconst props = defineProps<{\n node: {\n attrs: {\n value: string;\n keyword: string;\n };\n };\n editor: Editor;\n getPos: () => number;\n deleteNode: () => void;\n updateAttributes: (attrs: Record<string, unknown>) => void;\n}>();\n\nconst { syntax } = useMergeTag();\nconst { t } = useI18n();\n\nconst isValid = computed(() =>\n isLogicMergeTagValue(props.node.attrs.value, syntax),\n);\nconst displayKeyword = computed(() =>\n getLogicMergeTagKeyword(props.node.attrs.value, syntax),\n);\n\nconst isEditing = ref(false);\nconst editValue = ref(\"\");\nconst inputRef = ref<HTMLInputElement | null>(null);\nlet handled = false;\n\nfunction startEditing(): void {\n editValue.value = props.node.attrs.value;\n handled = false;\n isEditing.value = true;\n nextTick(() => {\n inputRef.value?.focus();\n inputRef.value?.select();\n });\n}\n\nfunction finishEditing(): void {\n if (handled) {\n return;\n }\n handled = true;\n\n const newValue = editValue.value.trim();\n if (!newValue) {\n isEditing.value = false;\n return;\n }\n\n if (newValue !== props.node.attrs.value) {\n props.updateAttributes({\n value: newValue,\n keyword: isLogicMergeTagValue(newValue, syntax)\n ? getLogicMergeTagKeyword(newValue, syntax)\n : \"\",\n });\n }\n isEditing.value = false;\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\") {\n event.preventDefault();\n finishEditing();\n } else if (event.key === \"Escape\") {\n isEditing.value = false;\n }\n}\n</script>\n\n<template>\n <NodeViewWrapper\n as=\"span\"\n :class=\"\n isValid\n ? 'tpl-logic-merge-tag-node tpl:group tpl:mx-0.5 tpl:inline-flex tpl:items-center tpl:gap-1 tpl:rounded tpl:px-1.5 tpl:py-0.5 tpl:text-[0.8em] tpl:font-bold tpl:tracking-wide tpl:uppercase tpl:select-none'\n : ''\n \"\n :style=\"\n isValid\n ? 'background-color: transparent; border: 1.5px solid color-mix(in srgb, var(--tpl-primary) 50%, transparent); color: var(--tpl-primary);'\n : ''\n \"\n contenteditable=\"false\"\n >\n <!-- Edit mode -->\n <input\n v-if=\"isEditing\"\n ref=\"inputRef\"\n v-model=\"editValue\"\n type=\"text\"\n class=\"tpl:w-40 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-0.5 tpl:py-0 tpl:text-[1em] tpl:font-medium tpl:normal-case tpl:outline-none tpl:text-[var(--tpl-primary)]\"\n @blur=\"finishEditing\"\n @keydown=\"handleKeydown\"\n />\n <!-- Display mode: valid merge tag -->\n <span\n v-else-if=\"isValid\"\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n class=\"tpl-tooltip tpl:cursor-pointer\"\n :data-tooltip=\"node.attrs.value\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ displayKeyword }}\n </span>\n <!-- Display mode: invalid (plain text) -->\n <span\n v-else\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ node.attrs.value }}\n </span>\n <button\n v-if=\"isValid\"\n type=\"button\"\n :aria-label=\"t.mergeTag.deleteMergeTag\"\n class=\"tpl-merge-tag-delete tpl:flex tpl:size-5 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-none tpl:bg-transparent tpl:p-0 tpl:opacity-60 tpl:transition-all tpl:hover:opacity-100 tpl:text-[var(--tpl-primary)]\"\n contenteditable=\"false\"\n @click.stop.prevent=\"deleteNode\"\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </NodeViewWrapper>\n</template>\n","import type { Editor } from \"@tiptap/core\";\n\n/**\n * Decides whether MergeTagNode / LogicMergeTagNode should swallow a\n * Backspace/Delete keystroke (returning `true` from a TipTap keymap\n * suppresses the default behavior).\n *\n * Only suppresses in the cursor-adjacent case so the \"first press\n * selects the atom, second press deletes it\" UX works. Range selections\n * (Cmd+A, drag-select, double-click-word) explicitly fall through —\n * default `replaceSelection` then deletes the entire range including\n * any merge-tag atoms inside it.\n *\n * Earlier revisions also returned `true` whenever `nodesBetween($from,\n * $to)` found a merge tag anywhere in the selection range — which\n * silently broke Cmd+A + Backspace for any paragraph containing a\n * merge tag (entire deletion was cancelled, nothing happened). The\n * cursor-adjacent protection is the only piece that should survive.\n */\nexport function isNodeSelected(editor: Editor, nodeTypeName: string): boolean {\n const { $from, $to } = editor.state.selection;\n\n // Range selection: let TipTap's default range-delete run. Even when\n // the range contains atom nodes, ProseMirror's replaceSelection\n // handles atomic deletion correctly.\n if ($from.pos !== $to.pos) return false;\n\n // Cursor-adjacent atom: protect from single-keystroke deletion.\n // (`$from.pos > 0` guards against reading `nodeBefore` at doc start\n // where ProseMirror's index would be undefined for nodeBefore.)\n if ($from.pos > 0 && $from.nodeBefore?.type.name === nodeTypeName) {\n return true;\n }\n if ($from.nodeAfter?.type.name === nodeTypeName) {\n return true;\n }\n\n return false;\n}\n","import type { Component } from \"vue\";\nimport { VueNodeViewRenderer } from \"@tiptap/vue-3\";\n\n/**\n * Typed wrapper for VueNodeViewRenderer that handles the known type mismatch\n * between Vue SFC default exports and TipTap's expected component type.\n */\nexport function renderVueNodeView(component: Component) {\n return VueNodeViewRenderer(\n component as Parameters<typeof VueNodeViewRenderer>[0],\n );\n}\n","import LogicMergeTagNodeView from \"./LogicMergeTagNodeView.vue\";\nimport type { SyntaxPreset } from \"@templatical/types\";\nimport {\n getLogicMergeTagKeyword,\n isLogicMergeTagValue,\n SYNTAX_PRESETS,\n} from \"@templatical/types\";\nimport { InputRule, mergeAttributes, Node, PasteRule } from \"@tiptap/core\";\nimport { isNodeSelected } from \"./isNodeSelected\";\nimport { renderVueNodeView } from \"./renderVueNodeView\";\n\nexport interface LogicMergeTagNodeOptions {\n syntax: SyntaxPreset;\n}\n\nexport const LogicMergeTagNode = Node.create<LogicMergeTagNodeOptions>({\n name: \"logicMergeTagNode\",\n\n group: \"inline\",\n\n inline: true,\n\n atom: true,\n\n addOptions() {\n return {\n syntax: SYNTAX_PRESETS.liquid,\n };\n },\n\n addAttributes() {\n return {\n // Both attributes are state, not markup, same as `MergeTagNode`:\n // `renderHTML()` emits the canonical `data-logic-merge-tag` /\n // `data-keyword` pair and `parseHTML` reads only those. `rendered: false`\n // keeps TipTap from also serializing each attribute under its own name,\n // which would put a write-only duplicate of the same data on every tag.\n value: {\n default: \"\",\n rendered: false,\n parseHTML: (element) =>\n element.getAttribute(\"data-logic-merge-tag\") || \"\",\n },\n keyword: {\n default: \"\",\n rendered: false,\n parseHTML: (element) =>\n element.getAttribute(\"data-keyword\") || element.textContent || \"\",\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: \"span[data-logic-merge-tag]\",\n },\n ];\n },\n\n renderHTML({ node, HTMLAttributes }) {\n if (!isLogicMergeTagValue(node.attrs.value, this.options.syntax)) {\n return [\"span\", {}, node.attrs.value];\n }\n\n const keyword = getLogicMergeTagKeyword(\n node.attrs.value,\n this.options.syntax,\n );\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-logic-merge-tag\": node.attrs.value,\n \"data-keyword\": keyword,\n }),\n keyword,\n ];\n },\n\n addNodeView() {\n return renderVueNodeView(LogicMergeTagNodeView);\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () => isNodeSelected(this.editor, this.name),\n Delete: () => isNodeSelected(this.editor, this.name),\n };\n },\n\n addInputRules() {\n const inputRegex = new RegExp(this.options.syntax.logic.source + \"$\", \"\");\n\n return [\n new InputRule({\n find: inputRegex,\n handler: ({ state, range, match }) => {\n const fullValue = match[0];\n if (!isLogicMergeTagValue(fullValue, this.options.syntax)) {\n return;\n }\n\n const keyword = getLogicMergeTagKeyword(\n fullValue,\n this.options.syntax,\n );\n\n const node = this.type.create({\n value: fullValue,\n keyword,\n });\n\n state.tr.replaceWith(range.from, range.to, node);\n },\n }),\n ];\n },\n\n addPasteRules() {\n const pasteRegex = new RegExp(this.options.syntax.logic.source, \"g\");\n\n return [\n new PasteRule({\n find: pasteRegex,\n handler: ({ state, range, match }) => {\n const fullValue = match[0];\n if (!isLogicMergeTagValue(fullValue, this.options.syntax)) {\n return;\n }\n\n const keyword = getLogicMergeTagKeyword(\n fullValue,\n this.options.syntax,\n );\n\n const node = this.type.create({\n value: fullValue,\n keyword,\n });\n\n state.tr.replaceWith(range.from, range.to, node);\n },\n }),\n ];\n },\n});\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../composables/useI18n\";\nimport { useMergeTag } from \"../composables/useMergeTag\";\nimport { NodeViewWrapper } from \"@tiptap/vue-3\";\nimport { computed, nextTick, ref } from \"vue\";\n\nconst props = defineProps<{\n node: {\n attrs: {\n label: string;\n value: string;\n };\n };\n deleteNode: () => void;\n updateAttributes: (attrs: Record<string, unknown>) => void;\n}>();\n\nconst { getMergeTagLabel } = useMergeTag();\nconst { t } = useI18n();\n\nconst displayLabel = computed(() => getMergeTagLabel(props.node.attrs.value));\n\nconst isEditing = ref(false);\nconst editValue = ref(\"\");\nconst inputRef = ref<HTMLInputElement | null>(null);\n\nfunction startEditing(): void {\n editValue.value = props.node.attrs.value;\n isEditing.value = true;\n nextTick(() => {\n inputRef.value?.focus();\n inputRef.value?.select();\n });\n}\n\nfunction finishEditing(): void {\n const newValue = editValue.value.trim();\n if (newValue && newValue !== props.node.attrs.value) {\n // Update with new value and derive label from it\n props.updateAttributes({\n value: newValue,\n label: getMergeTagLabel(newValue),\n });\n }\n isEditing.value = false;\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\") {\n event.preventDefault();\n finishEditing();\n } else if (event.key === \"Escape\") {\n isEditing.value = false;\n }\n}\n</script>\n\n<template>\n <NodeViewWrapper\n as=\"span\"\n class=\"tpl-merge-tag-node tpl:group tpl:mx-0.5 tpl:inline-flex tpl:items-center tpl:gap-1 tpl:rounded tpl:px-1.5 tpl:py-0.5 tpl:text-[0.9em] tpl:font-medium tpl:select-none tpl:text-[var(--tpl-primary)]\"\n style=\"\n background-color: color-mix(in srgb, var(--tpl-primary) 20%, transparent);\n \"\n contenteditable=\"false\"\n >\n <!-- Edit mode -->\n <input\n v-if=\"isEditing\"\n ref=\"inputRef\"\n v-model=\"editValue\"\n type=\"text\"\n class=\"tpl:w-32 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-0.5 tpl:py-0 tpl:text-[1em] tpl:font-medium tpl:outline-none tpl:text-[var(--tpl-primary)]\"\n @blur=\"finishEditing\"\n @keydown=\"handleKeydown\"\n />\n <!-- Display mode -->\n <span\n v-else\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n class=\"tpl-tooltip tpl:cursor-pointer\"\n :data-tooltip=\"node.attrs.value\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ displayLabel }}\n </span>\n <button\n type=\"button\"\n :aria-label=\"t.mergeTag.deleteMergeTag\"\n class=\"tpl-merge-tag-delete tpl:flex tpl:size-5 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-none tpl:bg-transparent tpl:p-0 tpl:opacity-60 tpl:transition-all tpl:hover:opacity-100 tpl:text-[var(--tpl-primary)]\"\n contenteditable=\"false\"\n @click.stop.prevent=\"deleteNode\"\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </NodeViewWrapper>\n</template>\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../composables/useI18n\";\nimport { useMergeTag } from \"../composables/useMergeTag\";\nimport { NodeViewWrapper } from \"@tiptap/vue-3\";\nimport { computed, nextTick, ref } from \"vue\";\n\nconst props = defineProps<{\n node: {\n attrs: {\n label: string;\n value: string;\n };\n };\n deleteNode: () => void;\n updateAttributes: (attrs: Record<string, unknown>) => void;\n}>();\n\nconst { getMergeTagLabel } = useMergeTag();\nconst { t } = useI18n();\n\nconst displayLabel = computed(() => getMergeTagLabel(props.node.attrs.value));\n\nconst isEditing = ref(false);\nconst editValue = ref(\"\");\nconst inputRef = ref<HTMLInputElement | null>(null);\n\nfunction startEditing(): void {\n editValue.value = props.node.attrs.value;\n isEditing.value = true;\n nextTick(() => {\n inputRef.value?.focus();\n inputRef.value?.select();\n });\n}\n\nfunction finishEditing(): void {\n const newValue = editValue.value.trim();\n if (newValue && newValue !== props.node.attrs.value) {\n // Update with new value and derive label from it\n props.updateAttributes({\n value: newValue,\n label: getMergeTagLabel(newValue),\n });\n }\n isEditing.value = false;\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\") {\n event.preventDefault();\n finishEditing();\n } else if (event.key === \"Escape\") {\n isEditing.value = false;\n }\n}\n</script>\n\n<template>\n <NodeViewWrapper\n as=\"span\"\n class=\"tpl-merge-tag-node tpl:group tpl:mx-0.5 tpl:inline-flex tpl:items-center tpl:gap-1 tpl:rounded tpl:px-1.5 tpl:py-0.5 tpl:text-[0.9em] tpl:font-medium tpl:select-none tpl:text-[var(--tpl-primary)]\"\n style=\"\n background-color: color-mix(in srgb, var(--tpl-primary) 20%, transparent);\n \"\n contenteditable=\"false\"\n >\n <!-- Edit mode -->\n <input\n v-if=\"isEditing\"\n ref=\"inputRef\"\n v-model=\"editValue\"\n type=\"text\"\n class=\"tpl:w-32 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-0.5 tpl:py-0 tpl:text-[1em] tpl:font-medium tpl:outline-none tpl:text-[var(--tpl-primary)]\"\n @blur=\"finishEditing\"\n @keydown=\"handleKeydown\"\n />\n <!-- Display mode -->\n <span\n v-else\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n class=\"tpl-tooltip tpl:cursor-pointer\"\n :data-tooltip=\"node.attrs.value\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ displayLabel }}\n </span>\n <button\n type=\"button\"\n :aria-label=\"t.mergeTag.deleteMergeTag\"\n class=\"tpl-merge-tag-delete tpl:flex tpl:size-5 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-none tpl:bg-transparent tpl:p-0 tpl:opacity-60 tpl:transition-all tpl:hover:opacity-100 tpl:text-[var(--tpl-primary)]\"\n contenteditable=\"false\"\n @click.stop.prevent=\"deleteNode\"\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </NodeViewWrapper>\n</template>\n","import MergeTagNodeView from \"./MergeTagNodeView.vue\";\nimport type { MergeTag, SyntaxPreset } from \"@templatical/types\";\nimport { getMergeTagLabel, SYNTAX_PRESETS } from \"@templatical/types\";\nimport { InputRule, mergeAttributes, Node, PasteRule } from \"@tiptap/core\";\nimport { isNodeSelected } from \"./isNodeSelected\";\nimport { renderVueNodeView } from \"./renderVueNodeView\";\n\nexport interface MergeTagNodeOptions {\n mergeTags: MergeTag[];\n syntax: SyntaxPreset;\n}\n\n/**\n * Inserted-node attrs are intentionally limited to `label` + `value`. The\n * `MergeTag` interface also carries optional `group` / `description` for\n * the built-in picker, but those are display-only and must NOT leak into\n * the document JSON — they would bloat templates and pollute serialized\n * state. `Pick<>` makes the constraint explicit at the type level.\n */\nexport type InsertMergeTagAttrs = Pick<MergeTag, \"label\" | \"value\">;\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n mergeTagNode: {\n insertMergeTag: (attrs: InsertMergeTagAttrs) => ReturnType;\n };\n }\n}\n\nexport const MergeTagNode = Node.create<MergeTagNodeOptions>({\n name: \"mergeTagNode\",\n\n group: \"inline\",\n\n inline: true,\n\n atom: true,\n\n addOptions() {\n return {\n mergeTags: [],\n syntax: SYNTAX_PRESETS.liquid,\n };\n },\n\n addAttributes() {\n return {\n // Both attributes are state, not markup: `renderHTML()` below emits the\n // canonical `data-merge-tag` / `data-label` pair and `parseHTML` reads\n // only those. `rendered: false` keeps TipTap from also serializing each\n // attribute under its own name, which would put a write-only duplicate\n // of the same data on every tag — invalid on a `<span>`, and paid again\n // through storage, autosave, snapshots and version history.\n label: {\n default: \"\",\n rendered: false,\n parseHTML: (element) =>\n element.getAttribute(\"data-label\") || element.textContent || \"\",\n },\n value: {\n default: \"\",\n rendered: false,\n parseHTML: (element) => element.getAttribute(\"data-merge-tag\") || \"\",\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: \"span[data-merge-tag]\",\n },\n ];\n },\n\n renderHTML({ node, HTMLAttributes }) {\n const label = getMergeTagLabel(node.attrs.value, this.options.mergeTags);\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-merge-tag\": node.attrs.value,\n \"data-label\": label,\n }),\n label,\n ];\n },\n\n addNodeView() {\n return renderVueNodeView(MergeTagNodeView);\n },\n\n addCommands() {\n return {\n insertMergeTag:\n (attrs: InsertMergeTagAttrs) =>\n ({ commands }) => {\n // Whitelist explicitly — even if a caller smuggles extra keys via\n // a wider type assertion, only label/value reach the node attrs.\n return commands.insertContent({\n type: this.name,\n attrs: { label: attrs.label, value: attrs.value },\n });\n },\n };\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () => isNodeSelected(this.editor, this.name),\n Delete: () => isNodeSelected(this.editor, this.name),\n };\n },\n\n addInputRules() {\n const inputRegex = new RegExp(this.options.syntax.value.source + \"$\", \"\");\n\n return [\n new InputRule({\n find: inputRegex,\n handler: ({ state, range, match }) => {\n const fullValue = match[0];\n const label = getMergeTagLabel(fullValue, this.options.mergeTags);\n\n const node = this.type.create({\n label,\n value: fullValue,\n });\n\n state.tr.replaceWith(range.from, range.to, node);\n },\n }),\n ];\n },\n\n addPasteRules() {\n const pasteRegex = new RegExp(this.options.syntax.value.source, \"g\");\n\n return [\n new PasteRule({\n find: pasteRegex,\n handler: ({ state, range, match }) => {\n const fullValue = match[0];\n const label = getMergeTagLabel(fullValue, this.options.mergeTags);\n\n const node = this.type.create({\n label,\n value: fullValue,\n });\n\n state.tr.replaceWith(range.from, range.to, node);\n },\n }),\n ];\n },\n});\n"],"mappings":";;;;;;;AAeA,IAAa,IAAW,EAAU,OAAwB;CACxD,MAAM;CAEN,aAAa;EACX,OAAO,EACL,OAAO,CAAC,WAAW,EACrB;CACF;CAEA,sBAAsB;EACpB,OAAO,CACL;GACE,OAAO,KAAK,QAAQ;GACpB,YAAY,EACV,UAAU;IACR,SAAS;IACT,YAAY,MACV,EAAQ,MAAM,UAAU,QAAQ,UAAU,EAAE,KAAK;IACnD,aAAa,MACN,EAAW,WAGT,EACL,OAAO,cAAc,EAAW,WAClC,IAJS,CAAC;GAMd,EACF;EACF,CACF;CACF;CAEA,cAAc;EACZ,OAAO;GACL,cACG,OACA,EAAE,eACM,EAAM,CAAC,CAAC,QAAQ,aAAa,EAAE,UAAU,EAAK,CAAC,CAAC,CAAC,IAAI;GAEhE,sBAEG,EAAE,eACM,EAAM,CAAC,CACX,QAAQ,aAAa,EAAE,UAAU,KAAK,CAAC,CAAC,CACxC,qBAAqB,CAAC,CACtB,IAAI;EAEb;CACF;AACF,CAAC,GCjDY,IAAgB,EAAU,OAA6B;CAClE,MAAM;CAEN,aAAa;EACX,OAAO,EACL,OAAO,CAAC,WAAW,EACrB;CACF;CAEA,sBAAsB;EACpB,OAAO,CACL;GACE,OAAO,KAAK,QAAQ;GACpB,YAAY,EACV,eAAe;IACb,SAAS;IACT,YAAY,MACV,EAAQ,MAAM,eAAe,QAAQ,UAAU,EAAE,KAAK;IACxD,aAAa,MACN,EAAW,gBAGT,EACL,OAAO,mBAAmB,EAAW,gBACvC,IAJS,CAAC;GAMd,EACF;EACF,CACF;CACF;CAEA,cAAc;EACZ,OAAO;GACL,mBACG,OACA,EAAE,eACM,EAAM,CAAC,CAAC,QAAQ,aAAa,EAAE,eAAe,EAAQ,CAAC,CAAC,CAAC,IAAI;GAExE,2BAEG,EAAE,eACM,EAAM,CAAC,CACX,QAAQ,aAAa,EAAE,eAAe,KAAK,CAAC,CAAC,CAC7C,qBAAqB,CAAC,CACtB,IAAI;EAEb;CACF;AACF,CAAC,GC1CY,IAAmB,EAAU,OAAO;CAC/C,MAAM;CAEN,uBAAuB;EACrB,IAAM,KACH,OACA,EAAE,gBAAqD;GACtD,IAAM,IAAO,EAAO;GASpB,IAAI,CAAC,KAAQ,EAAK,WAAW,OAAO;GAKpC,IAAM,IACJ,OAAO,EAAK,MAAM,gBAAiB,aAC/B,EAAK,KAAK,aAAa,IACtB,EAAK,KAAK,eAAe,eAAe,KAAK;GAQpD,OALI,CAAC,KAAa,OAAO,EAAU,UAAW,cAC1C,CAAC,EAAU,cAAc,CAAC,EAAK,IAAI,SAAS,EAAU,UAAU,IAC3D,MAET,EAAU,OAAO,QAAQ,GAAW,cAAc,GAC3C;EACT;EAEF,OAAO;GACL,KAAK,EAAmB,SAAS;GACjC,MAAM,EAAmB,UAAU;EACrC;CACF;AACF,CAAC,GC9CY,IAAa,EAAU,OAA0B;CAC5D,MAAM;CAEN,aAAa;EACX,OAAO;GACL,OAAO,CAAC,WAAW;GACnB,mBAAmB;EACrB;CACF;CAEA,sBAAsB;EACpB,OAAO,CACL;GACE,OAAO,KAAK,QAAQ;GACpB,YAAY,EACV,YAAY;IACV,SAAS;IACT,YAAY,MAAY,EAAQ,MAAM,cAAc;IACpD,aAAa,MACN,EAAW,aAGT,EACL,OAAO,gBAAgB,EAAW,aACpC,IAJS,CAAC;GAMd,EACF;EACF,CACF;CACF;CAEA,cAAc;EACZ,OAAO;GACL,gBACG,OACA,EAAE,kBACM,KAAK,QAAQ,MAAM,OAAO,MAC/B,EAAS,iBAAiB,GAAM,EAAE,cAAW,CAAC,CAChD;GAEJ,wBAEG,EAAE,kBACM,KAAK,QAAQ,MAAM,OAAO,MAC/B,EAAS,gBAAgB,GAAM,YAAY,CAC7C;EAEN;CACF;AACF,CAAC;;;;;;;;;;;;;;ECvDD,IAAM,IAAQ,GAaR,EAAE,cAAW,EAAY,GACzB,EAAE,SAAM,EAAQ,GAEhB,IAAU,QACd,EAAqB,EAAM,KAAK,MAAM,OAAO,CAAM,CACrD,GACM,IAAiB,QACrB,EAAwB,EAAM,KAAK,MAAM,OAAO,CAAM,CACxD,GAEM,IAAY,EAAI,EAAK,GACrB,IAAY,EAAI,EAAE,GAClB,IAAW,EAA6B,IAAI,GAC9C,IAAU;EAEd,SAAS,IAAqB;GAI5B,AAHA,EAAU,QAAQ,EAAM,KAAK,MAAM,OACnC,IAAU,IACV,EAAU,QAAQ,IAClB,QAAe;IAEb,AADA,EAAS,OAAO,MAAM,GACtB,EAAS,OAAO,OAAO;GACzB,CAAC;EACH;EAEA,SAAS,IAAsB;GAC7B,IAAI,GACF;GAEF,IAAU;GAEV,IAAM,IAAW,EAAU,MAAM,KAAK;GACtC,IAAI,CAAC,GAAU;IACb,EAAU,QAAQ;IAClB;GACF;GAUA,AARI,MAAa,EAAM,KAAK,MAAM,SAChC,EAAM,iBAAiB;IACrB,OAAO;IACP,SAAS,EAAqB,GAAU,CAAM,IAC1C,EAAwB,GAAU,CAAM,IACxC;GACN,CAAC,GAEH,EAAU,QAAQ;EACpB;EAEA,SAAS,EAAc,GAA4B;GACjD,AAAI,EAAM,QAAQ,WAChB,EAAM,eAAe,GACrB,EAAc,KACL,EAAM,QAAQ,aACvB,EAAU,QAAQ;EAEtB;oBAIE,EAAA,GAAA,EAuEkB,EAAA,CAAA,GAAA;GAtEhB,IAAG;GACF,OAAK,EAAS,EAAA,QAAA,8MAAA,EAAA;GAKd,OAAK,EAAS,EAAA,QAAA,2IAAA,EAAA;GAKf,iBAAgB;;GAGhB,SAAA,QAQE,CAPM,EAAA,QADR,GAAA,EAAA,GAAA,EAQE,SAAA;;IANI,SAAA;IAAJ,KAAI;IACK,uBAAA,AAAA,EAAA,QAAA,MAAA,EAAS,QAAA;IAClB,MAAK;IACL,OAAM;IACL,QAAM;IACN,WAAS;GAJD,GAAA,MAAA,GAAA,IAAA,CAAA,CAAA,GAAA,EAAA,KAAS,CAAA,CAAA,IAQP,EAAA,SADb,EAAA,GAAA,EAYO,QAAA;;IAVL,MAAK;IACL,UAAS;IACR,cAAY,EAAA,CAAA,CAAC,CAAC,SAAS;IACxB,OAAM;IACL,gBAAc,EAAA,KAAK,MAAM;IACzB,SAAK,EAAO,GAAY,CAAA,MAAA,CAAA;IACxB,WAAO,CAAa,EAAA,EAAA,GAAY,CAAA,MAAA,CAAA,GAAA,CAAA,OAAA,CAAA,GACJ,EAAA,EAAA,GAAY,CAAA,WAAA,MAAA,CAAA,GAAA,CAAA,OAAA,CAAA,CAAA;GAEtC,GAAA,EAAA,EAAA,KAAc,GAAA,IAAA,CAAA,MAGnB,EAAA,GAAA,EAUO,QAAA;;IARL,MAAK;IACL,UAAS;IACR,cAAY,EAAA,CAAA,CAAC,CAAC,SAAS;IACvB,SAAK,EAAO,GAAY,CAAA,MAAA,CAAA;IACxB,WAAO,CAAa,EAAA,EAAA,GAAY,CAAA,MAAA,CAAA,GAAA,CAAA,OAAA,CAAA,GACJ,EAAA,EAAA,GAAY,CAAA,WAAA,MAAA,CAAA,GAAA,CAAA,OAAA,CAAA,CAAA;GAEtC,GAAA,EAAA,EAAA,KAAK,MAAM,KAAK,GAAA,IAAA,CAAA,IAGb,EAAA,SADR,EAAA,GAAA,EAoBS,UAAA;;IAlBP,MAAK;IACJ,cAAY,EAAA,CAAA,CAAC,CAAC,SAAS;IACxB,OAAM;IACN,iBAAgB;IACf,SAAK,AAAA,EAAA,OAAA,GAAe,GAAA,MAAA,EAAA,cAAA,EAAA,WAAA,GAAA,CAAA,GAAU,CAAA,QAAA,SAAA,CAAA;GAE/B,GAAA,CAAA,GAAA,AAAA,EAAA,OAAA,CAAA,EAWM,OAAA;IAVJ,OAAM;IACN,QAAO;IACP,SAAQ;IACR,MAAK;IACL,QAAO;IACP,gBAAa;IACb,eAAY;GAEZ,GAAA,CAAA,EAAsC,QAAA;IAAhC,IAAG;IAAK,IAAG;IAAI,IAAG;IAAI,IAAG;GAC/B,CAAA,GAAA,EAAsC,QAAA;IAAhC,IAAG;IAAI,IAAG;IAAI,IAAG;IAAK,IAAG;;;;;;;;AEpIvC,SAAgB,EAAe,GAAgB,GAA+B;CAC5E,IAAM,EAAE,UAAO,WAAQ,EAAO,MAAM;CAiBpC,OAZI,EAAM,QAAQ,EAAI,MAKlB,EAAM,MAAM,KAAK,EAAM,YAAY,KAAK,SAAS,KAGjD,EAAM,WAAW,KAAK,SAAS,IARD;AAapC;;;AC/BA,SAAgB,EAAkB,GAAsB;CACtD,OAAO,EACL,CACF;AACF;;;ACIA,IAAa,IAAoB,EAAK,OAAiC;CACrE,MAAM;CAEN,OAAO;CAEP,QAAQ;CAER,MAAM;CAEN,aAAa;EACX,OAAO,EACL,QAAQ,EAAe,OACzB;CACF;CAEA,gBAAgB;EACd,OAAO;GAML,OAAO;IACL,SAAS;IACT,UAAU;IACV,YAAY,MACV,EAAQ,aAAa,sBAAsB,KAAK;GACpD;GACA,SAAS;IACP,SAAS;IACT,UAAU;IACV,YAAY,MACV,EAAQ,aAAa,cAAc,KAAK,EAAQ,eAAe;GACnE;EACF;CACF;CAEA,YAAY;EACV,OAAO,CACL,EACE,KAAK,6BACP,CACF;CACF;CAEA,WAAW,EAAE,SAAM,qBAAkB;EACnC,IAAI,CAAC,EAAqB,EAAK,MAAM,OAAO,KAAK,QAAQ,MAAM,GAC7D,OAAO;GAAC;GAAQ,CAAC;GAAG,EAAK,MAAM;EAAK;EAGtC,IAAM,IAAU,EACd,EAAK,MAAM,OACX,KAAK,QAAQ,MACf;EAEA,OAAO;GACL;GACA,EAAgB,GAAgB;IAC9B,wBAAwB,EAAK,MAAM;IACnC,gBAAgB;GAClB,CAAC;GACD;EACF;CACF;CAEA,cAAc;EACZ,OAAO,EAAkB,CAAqB;CAChD;CAEA,uBAAuB;EACrB,OAAO;GACL,iBAAiB,EAAe,KAAK,QAAQ,KAAK,IAAI;GACtD,cAAc,EAAe,KAAK,QAAQ,KAAK,IAAI;EACrD;CACF;CAEA,gBAAgB;EACd,IAAM,IAAiB,OAAO,KAAK,QAAQ,OAAO,MAAM,SAAS,KAAK,EAAE;EAExE,OAAO,CACL,IAAI,EAAU;GACZ,MAAM;GACN,UAAU,EAAE,UAAO,UAAO,eAAY;IACpC,IAAM,IAAY,EAAM;IACxB,IAAI,CAAC,EAAqB,GAAW,KAAK,QAAQ,MAAM,GACtD;IAGF,IAAM,IAAU,EACd,GACA,KAAK,QAAQ,MACf,GAEM,IAAO,KAAK,KAAK,OAAO;KAC5B,OAAO;KACP;IACF,CAAC;IAED,EAAM,GAAG,YAAY,EAAM,MAAM,EAAM,IAAI,CAAI;GACjD;EACF,CAAC,CACH;CACF;CAEA,gBAAgB;EACd,IAAM,IAAa,IAAI,OAAO,KAAK,QAAQ,OAAO,MAAM,QAAQ,GAAG;EAEnE,OAAO,CACL,IAAI,EAAU;GACZ,MAAM;GACN,UAAU,EAAE,UAAO,UAAO,eAAY;IACpC,IAAM,IAAY,EAAM;IACxB,IAAI,CAAC,EAAqB,GAAW,KAAK,QAAQ,MAAM,GACtD;IAGF,IAAM,IAAU,EACd,GACA,KAAK,QAAQ,MACf,GAEM,IAAO,KAAK,KAAK,OAAO;KAC5B,OAAO;KACP;IACF,CAAC;IAED,EAAM,GAAG,YAAY,EAAM,MAAM,EAAM,IAAI,CAAI;GACjD;EACF,CAAC,CACH;CACF;AACF,CAAC;;;;;;;;;;;;EC5ID,IAAM,IAAQ,GAWR,EAAE,wBAAqB,EAAY,GACnC,EAAE,SAAM,EAAQ,GAEhB,IAAe,QAAe,EAAiB,EAAM,KAAK,MAAM,KAAK,CAAC,GAEtE,IAAY,EAAI,EAAK,GACrB,IAAY,EAAI,EAAE,GAClB,IAAW,EAA6B,IAAI;EAElD,SAAS,IAAqB;GAG5B,AAFA,EAAU,QAAQ,EAAM,KAAK,MAAM,OACnC,EAAU,QAAQ,IAClB,QAAe;IAEb,AADA,EAAS,OAAO,MAAM,GACtB,EAAS,OAAO,OAAO;GACzB,CAAC;EACH;EAEA,SAAS,IAAsB;GAC7B,IAAM,IAAW,EAAU,MAAM,KAAK;GAQtC,AAPI,KAAY,MAAa,EAAM,KAAK,MAAM,SAE5C,EAAM,iBAAiB;IACrB,OAAO;IACP,OAAO,EAAiB,CAAQ;GAClC,CAAC,GAEH,EAAU,QAAQ;EACpB;EAEA,SAAS,EAAc,GAA4B;GACjD,AAAI,EAAM,QAAQ,WAChB,EAAM,eAAe,GACrB,EAAc,KACL,EAAM,QAAQ,aACvB,EAAU,QAAQ;EAEtB;oBAIE,EAAA,GAAA,EAoDkB,EAAA,CAAA,GAAA;GAnDhB,IAAG;GACH,OAAM;GACN,OAAA,EAAA,oBAAA,0DAAA;GAGA,iBAAgB;;GAGhB,SAAA,QAQE,CAPM,EAAA,QADR,GAAA,EAAA,GAAA,EAQE,SAAA;;IANI,SAAA;IAAJ,KAAI;IACK,uBAAA,AAAA,EAAA,QAAA,MAAA,EAAS,QAAA;IAClB,MAAK;IACL,OAAM;IACL,QAAM;IACN,WAAS;GAJD,GAAA,MAAA,GAAA,IAAA,CAAA,CAAA,GAAA,EAAA,KAAS,CAAA,CAAA,KAOpB,EAAA,GAAA,EAYO,QAAA;;IAVL,MAAK;IACL,UAAS;IACR,cAAY,EAAA,CAAA,CAAC,CAAC,SAAS;IACxB,OAAM;IACL,gBAAc,EAAA,KAAK,MAAM;IACzB,SAAK,EAAO,GAAY,CAAA,MAAA,CAAA;IACxB,WAAO,CAAa,EAAA,EAAA,GAAY,CAAA,MAAA,CAAA,GAAA,CAAA,OAAA,CAAA,GACJ,EAAA,EAAA,GAAY,CAAA,WAAA,MAAA,CAAA,GAAA,CAAA,OAAA,CAAA,CAAA;GAEtC,GAAA,EAAA,EAAA,KAAY,GAAA,IAAA,CAAA,IAEjB,EAmBS,UAAA;IAlBP,MAAK;IACJ,cAAY,EAAA,CAAA,CAAC,CAAC,SAAS;IACxB,OAAM;IACN,iBAAgB;IACf,SAAK,AAAA,EAAA,OAAA,GAAe,GAAA,MAAA,EAAA,cAAA,EAAA,WAAA,GAAA,CAAA,GAAU,CAAA,QAAA,SAAA,CAAA;GAE/B,GAAA,CAAA,GAAA,AAAA,EAAA,OAAA,CAAA,EAWM,OAAA;IAVJ,OAAM;IACN,QAAO;IACP,SAAQ;IACR,MAAK;IACL,QAAO;IACP,gBAAa;IACb,eAAY;GAEZ,GAAA,CAAA,EAAsC,QAAA;IAAhC,IAAG;IAAK,IAAG;IAAI,IAAG;IAAI,IAAG;GAC/B,CAAA,GAAA,EAAsC,QAAA;IAAhC,IAAG;IAAI,IAAG;IAAI,IAAG;IAAK,IAAG;;;;;IE9E1B,IAAe,EAAK,OAA4B;CAC3D,MAAM;CAEN,OAAO;CAEP,QAAQ;CAER,MAAM;CAEN,aAAa;EACX,OAAO;GACL,WAAW,CAAC;GACZ,QAAQ,EAAe;EACzB;CACF;CAEA,gBAAgB;EACd,OAAO;GAOL,OAAO;IACL,SAAS;IACT,UAAU;IACV,YAAY,MACV,EAAQ,aAAa,YAAY,KAAK,EAAQ,eAAe;GACjE;GACA,OAAO;IACL,SAAS;IACT,UAAU;IACV,YAAY,MAAY,EAAQ,aAAa,gBAAgB,KAAK;GACpE;EACF;CACF;CAEA,YAAY;EACV,OAAO,CACL,EACE,KAAK,uBACP,CACF;CACF;CAEA,WAAW,EAAE,SAAM,qBAAkB;EACnC,IAAM,IAAQ,EAAiB,EAAK,MAAM,OAAO,KAAK,QAAQ,SAAS;EAEvE,OAAO;GACL;GACA,EAAgB,GAAgB;IAC9B,kBAAkB,EAAK,MAAM;IAC7B,cAAc;GAChB,CAAC;GACD;EACF;CACF;CAEA,cAAc;EACZ,OAAO,EAAkB,CAAgB;CAC3C;CAEA,cAAc;EACZ,OAAO,EACL,iBACG,OACA,EAAE,kBAGM,EAAS,cAAc;GAC5B,MAAM,KAAK;GACX,OAAO;IAAE,OAAO,EAAM;IAAO,OAAO,EAAM;GAAM;EAClD,CAAC,EAEP;CACF;CAEA,uBAAuB;EACrB,OAAO;GACL,iBAAiB,EAAe,KAAK,QAAQ,KAAK,IAAI;GACtD,cAAc,EAAe,KAAK,QAAQ,KAAK,IAAI;EACrD;CACF;CAEA,gBAAgB;EACd,IAAM,IAAiB,OAAO,KAAK,QAAQ,OAAO,MAAM,SAAS,KAAK,EAAE;EAExE,OAAO,CACL,IAAI,EAAU;GACZ,MAAM;GACN,UAAU,EAAE,UAAO,UAAO,eAAY;IACpC,IAAM,IAAY,EAAM,IAClB,IAAQ,EAAiB,GAAW,KAAK,QAAQ,SAAS,GAE1D,IAAO,KAAK,KAAK,OAAO;KAC5B;KACA,OAAO;IACT,CAAC;IAED,EAAM,GAAG,YAAY,EAAM,MAAM,EAAM,IAAI,CAAI;GACjD;EACF,CAAC,CACH;CACF;CAEA,gBAAgB;EACd,IAAM,IAAa,IAAI,OAAO,KAAK,QAAQ,OAAO,MAAM,QAAQ,GAAG;EAEnE,OAAO,CACL,IAAI,EAAU;GACZ,MAAM;GACN,UAAU,EAAE,UAAO,UAAO,eAAY;IACpC,IAAM,IAAY,EAAM,IAClB,IAAQ,EAAiB,GAAW,KAAK,QAAQ,SAAS,GAE1D,IAAO,KAAK,KAAK,OAAO;KAC5B;KACA,OAAO;IACT,CAAC;IAED,EAAM,GAAG,YAAY,EAAM,MAAM,EAAM,IAAI,CAAI;GACjD;EACF,CAAC,CACH;CACF;AACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"extensions-B8_jnIkD.js","names":[],"sources":["../../../src/extensions/FontSize.ts","../../../src/extensions/LetterSpacing.ts","../../../src/extensions/LineBoundaryKeys.ts","../../../src/extensions/LineHeight.ts","../../../src/extensions/LogicMergeTagNodeView.vue","../../../src/extensions/LogicMergeTagNodeView.vue","../../../src/extensions/isNodeSelected.ts","../../../src/extensions/renderVueNodeView.ts","../../../src/extensions/LogicMergeTagNode.ts","../../../src/extensions/MergeTagNodeView.vue","../../../src/extensions/MergeTagNodeView.vue","../../../src/extensions/MergeTagNode.ts"],"sourcesContent":["import { Extension } from \"@tiptap/core\";\n\nexport interface FontSizeOptions {\n types: string[];\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n fontSize: {\n setFontSize: (size: string) => ReturnType;\n unsetFontSize: () => ReturnType;\n };\n }\n}\n\nexport const FontSize = Extension.create<FontSizeOptions>({\n name: \"fontSize\",\n\n addOptions() {\n return {\n types: [\"textStyle\"],\n };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n fontSize: {\n default: null,\n parseHTML: (element) =>\n element.style.fontSize?.replace(/['\"]+/g, \"\") || null,\n renderHTML: (attributes) => {\n if (!attributes.fontSize) {\n return {};\n }\n return {\n style: `font-size: ${attributes.fontSize}`,\n };\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n setFontSize:\n (size: string) =>\n ({ chain }) => {\n return chain().setMark(\"textStyle\", { fontSize: size }).run();\n },\n unsetFontSize:\n () =>\n ({ chain }) => {\n return chain()\n .setMark(\"textStyle\", { fontSize: null })\n .removeEmptyTextStyle()\n .run();\n },\n };\n },\n});\n","import { Extension } from \"@tiptap/core\";\n\nexport interface LetterSpacingOptions {\n types: string[];\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n letterSpacing: {\n setLetterSpacing: (spacing: string) => ReturnType;\n unsetLetterSpacing: () => ReturnType;\n };\n }\n}\n\nexport const LetterSpacing = Extension.create<LetterSpacingOptions>({\n name: \"letterSpacing\",\n\n addOptions() {\n return {\n types: [\"textStyle\"],\n };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n letterSpacing: {\n default: null,\n parseHTML: (element) =>\n element.style.letterSpacing?.replace(/['\"]+/g, \"\") || null,\n renderHTML: (attributes) => {\n if (!attributes.letterSpacing) {\n return {};\n }\n return {\n style: `letter-spacing: ${attributes.letterSpacing}`,\n };\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n setLetterSpacing:\n (spacing: string) =>\n ({ chain }) => {\n return chain().setMark(\"textStyle\", { letterSpacing: spacing }).run();\n },\n unsetLetterSpacing:\n () =>\n ({ chain }) => {\n return chain()\n .setMark(\"textStyle\", { letterSpacing: null })\n .removeEmptyTextStyle()\n .run();\n },\n };\n },\n});\n","import { Extension } from \"@tiptap/core\";\n\n/**\n * Routes plain End/Home through `Selection.modify` instead of the browser's\n * native caret movement.\n *\n * Chromium (verified 140–151, including stable Chrome) has a bug where a\n * native End or Home pressed while a triple-click selection is active puts\n * Blink's selection state into a mode where the next typed character\n * natively smooth-scrolls the nearest scrollable ancestor (the editor's\n * canvas, `.tpl-body`) to its very bottom (End) or top (Home), dragging the\n * caret out of view. The state cannot be repaired after the fact — clearing\n * or re-setting the DOM selection, blur/refocus, and preventDefault on the\n * clicks all fail — but a programmatic caret move never arms it.\n *\n * `Selection.modify(\"move\", direction, \"lineboundary\")` is the exact\n * equivalent of the native key (visual line boundary, bidi-aware via the\n * logical forward/backward directions), so behavior is unchanged for users.\n * Shift+End / Shift+Home extend selections natively and do not trigger the\n * bug, so only the plain keys are bound — a keymap entry without modifiers\n * never matches the shifted keys.\n */\nexport const LineBoundaryKeys = Extension.create({\n name: \"lineBoundaryKeys\",\n\n addKeyboardShortcuts() {\n const moveToLineBoundary =\n (direction: \"forward\" | \"backward\") =>\n ({ editor }: { editor: { view: unknown } }): boolean => {\n const view = editor.view as {\n composing: boolean;\n root: DocumentOrShadowRoot & {\n getSelection?: () => Selection | null;\n };\n dom: HTMLElement;\n };\n // During IME composition End/Home commit the composition; leave\n // that to the browser.\n if (!view || view.composing) return false;\n // `view.root` is the editable's Document or ShadowRoot, so the\n // selection resolves correctly in both mount modes. ShadowRoot's\n // getSelection is Chromium-only; elsewhere fall back to the owner\n // document (Chromium is also the only engine with the bug).\n const selection =\n typeof view.root?.getSelection === \"function\"\n ? view.root.getSelection()\n : (view.dom?.ownerDocument?.getSelection?.() ?? null);\n // `modify` is non-standard; without it, or with a selection that\n // is not ours, native handling is the safer default.\n if (!selection || typeof selection.modify !== \"function\") return false;\n if (!selection.anchorNode || !view.dom.contains(selection.anchorNode)) {\n return false;\n }\n selection.modify(\"move\", direction, \"lineboundary\");\n return true;\n };\n\n return {\n End: moveToLineBoundary(\"forward\"),\n Home: moveToLineBoundary(\"backward\"),\n };\n },\n});\n","import { Extension } from \"@tiptap/core\";\n\nexport interface LineHeightOptions {\n types: string[];\n defaultLineHeight: string;\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n lineHeight: {\n setLineHeight: (lineHeight: string) => ReturnType;\n unsetLineHeight: () => ReturnType;\n };\n }\n}\n\nexport const LineHeight = Extension.create<LineHeightOptions>({\n name: \"lineHeight\",\n\n addOptions() {\n return {\n types: [\"paragraph\"],\n defaultLineHeight: \"1.5\",\n };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n lineHeight: {\n default: null,\n parseHTML: (element) => element.style.lineHeight || null,\n renderHTML: (attributes) => {\n if (!attributes.lineHeight) {\n return {};\n }\n return {\n style: `line-height: ${attributes.lineHeight}`,\n };\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n setLineHeight:\n (lineHeight: string) =>\n ({ commands }) => {\n return this.options.types.every((type) =>\n commands.updateAttributes(type, { lineHeight }),\n );\n },\n unsetLineHeight:\n () =>\n ({ commands }) => {\n return this.options.types.every((type) =>\n commands.resetAttributes(type, \"lineHeight\"),\n );\n },\n };\n },\n});\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../composables/useI18n\";\nimport { useMergeTag } from \"../composables/useMergeTag\";\nimport {\n getLogicMergeTagKeyword,\n isLogicMergeTagValue,\n} from \"@templatical/types\";\nimport type { Editor } from \"@tiptap/core\";\nimport { NodeViewWrapper } from \"@tiptap/vue-3\";\nimport { computed, nextTick, ref } from \"vue\";\n\nconst props = defineProps<{\n node: {\n attrs: {\n value: string;\n keyword: string;\n };\n };\n editor: Editor;\n getPos: () => number;\n deleteNode: () => void;\n updateAttributes: (attrs: Record<string, unknown>) => void;\n}>();\n\nconst { syntax } = useMergeTag();\nconst { t } = useI18n();\n\nconst isValid = computed(() =>\n isLogicMergeTagValue(props.node.attrs.value, syntax),\n);\nconst displayKeyword = computed(() =>\n getLogicMergeTagKeyword(props.node.attrs.value, syntax),\n);\n\nconst isEditing = ref(false);\nconst editValue = ref(\"\");\nconst inputRef = ref<HTMLInputElement | null>(null);\nlet handled = false;\n\nfunction startEditing(): void {\n editValue.value = props.node.attrs.value;\n handled = false;\n isEditing.value = true;\n nextTick(() => {\n inputRef.value?.focus();\n inputRef.value?.select();\n });\n}\n\nfunction finishEditing(): void {\n if (handled) {\n return;\n }\n handled = true;\n\n const newValue = editValue.value.trim();\n if (!newValue) {\n isEditing.value = false;\n return;\n }\n\n if (newValue !== props.node.attrs.value) {\n props.updateAttributes({\n value: newValue,\n keyword: isLogicMergeTagValue(newValue, syntax)\n ? getLogicMergeTagKeyword(newValue, syntax)\n : \"\",\n });\n }\n isEditing.value = false;\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\") {\n event.preventDefault();\n finishEditing();\n } else if (event.key === \"Escape\") {\n isEditing.value = false;\n }\n}\n</script>\n\n<template>\n <NodeViewWrapper\n as=\"span\"\n :class=\"\n isValid\n ? 'tpl-logic-merge-tag-node tpl:group tpl:mx-0.5 tpl:inline-flex tpl:items-center tpl:gap-1 tpl:rounded tpl:px-1.5 tpl:py-0.5 tpl:text-[0.8em] tpl:font-bold tpl:tracking-wide tpl:uppercase tpl:select-none'\n : ''\n \"\n :style=\"\n isValid\n ? 'background-color: transparent; border: 1.5px solid color-mix(in srgb, var(--tpl-primary) 50%, transparent); color: var(--tpl-primary);'\n : ''\n \"\n contenteditable=\"false\"\n >\n <!-- Edit mode -->\n <input\n v-if=\"isEditing\"\n ref=\"inputRef\"\n v-model=\"editValue\"\n type=\"text\"\n class=\"tpl:w-40 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-0.5 tpl:py-0 tpl:text-[1em] tpl:font-medium tpl:normal-case tpl:outline-none tpl:text-[var(--tpl-primary)]\"\n @blur=\"finishEditing\"\n @keydown=\"handleKeydown\"\n />\n <!-- Display mode: valid merge tag -->\n <span\n v-else-if=\"isValid\"\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n class=\"tpl-tooltip tpl:cursor-pointer\"\n :data-tooltip=\"node.attrs.value\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ displayKeyword }}\n </span>\n <!-- Display mode: invalid (plain text) -->\n <span\n v-else\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ node.attrs.value }}\n </span>\n <button\n v-if=\"isValid\"\n type=\"button\"\n :aria-label=\"t.mergeTag.deleteMergeTag\"\n class=\"tpl-merge-tag-delete tpl:flex tpl:size-5 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-none tpl:bg-transparent tpl:p-0 tpl:opacity-60 tpl:transition-all tpl:hover:opacity-100 tpl:text-[var(--tpl-primary)]\"\n contenteditable=\"false\"\n @click.stop.prevent=\"deleteNode\"\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </NodeViewWrapper>\n</template>\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../composables/useI18n\";\nimport { useMergeTag } from \"../composables/useMergeTag\";\nimport {\n getLogicMergeTagKeyword,\n isLogicMergeTagValue,\n} from \"@templatical/types\";\nimport type { Editor } from \"@tiptap/core\";\nimport { NodeViewWrapper } from \"@tiptap/vue-3\";\nimport { computed, nextTick, ref } from \"vue\";\n\nconst props = defineProps<{\n node: {\n attrs: {\n value: string;\n keyword: string;\n };\n };\n editor: Editor;\n getPos: () => number;\n deleteNode: () => void;\n updateAttributes: (attrs: Record<string, unknown>) => void;\n}>();\n\nconst { syntax } = useMergeTag();\nconst { t } = useI18n();\n\nconst isValid = computed(() =>\n isLogicMergeTagValue(props.node.attrs.value, syntax),\n);\nconst displayKeyword = computed(() =>\n getLogicMergeTagKeyword(props.node.attrs.value, syntax),\n);\n\nconst isEditing = ref(false);\nconst editValue = ref(\"\");\nconst inputRef = ref<HTMLInputElement | null>(null);\nlet handled = false;\n\nfunction startEditing(): void {\n editValue.value = props.node.attrs.value;\n handled = false;\n isEditing.value = true;\n nextTick(() => {\n inputRef.value?.focus();\n inputRef.value?.select();\n });\n}\n\nfunction finishEditing(): void {\n if (handled) {\n return;\n }\n handled = true;\n\n const newValue = editValue.value.trim();\n if (!newValue) {\n isEditing.value = false;\n return;\n }\n\n if (newValue !== props.node.attrs.value) {\n props.updateAttributes({\n value: newValue,\n keyword: isLogicMergeTagValue(newValue, syntax)\n ? getLogicMergeTagKeyword(newValue, syntax)\n : \"\",\n });\n }\n isEditing.value = false;\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\") {\n event.preventDefault();\n finishEditing();\n } else if (event.key === \"Escape\") {\n isEditing.value = false;\n }\n}\n</script>\n\n<template>\n <NodeViewWrapper\n as=\"span\"\n :class=\"\n isValid\n ? 'tpl-logic-merge-tag-node tpl:group tpl:mx-0.5 tpl:inline-flex tpl:items-center tpl:gap-1 tpl:rounded tpl:px-1.5 tpl:py-0.5 tpl:text-[0.8em] tpl:font-bold tpl:tracking-wide tpl:uppercase tpl:select-none'\n : ''\n \"\n :style=\"\n isValid\n ? 'background-color: transparent; border: 1.5px solid color-mix(in srgb, var(--tpl-primary) 50%, transparent); color: var(--tpl-primary);'\n : ''\n \"\n contenteditable=\"false\"\n >\n <!-- Edit mode -->\n <input\n v-if=\"isEditing\"\n ref=\"inputRef\"\n v-model=\"editValue\"\n type=\"text\"\n class=\"tpl:w-40 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-0.5 tpl:py-0 tpl:text-[1em] tpl:font-medium tpl:normal-case tpl:outline-none tpl:text-[var(--tpl-primary)]\"\n @blur=\"finishEditing\"\n @keydown=\"handleKeydown\"\n />\n <!-- Display mode: valid merge tag -->\n <span\n v-else-if=\"isValid\"\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n class=\"tpl-tooltip tpl:cursor-pointer\"\n :data-tooltip=\"node.attrs.value\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ displayKeyword }}\n </span>\n <!-- Display mode: invalid (plain text) -->\n <span\n v-else\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ node.attrs.value }}\n </span>\n <button\n v-if=\"isValid\"\n type=\"button\"\n :aria-label=\"t.mergeTag.deleteMergeTag\"\n class=\"tpl-merge-tag-delete tpl:flex tpl:size-5 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-none tpl:bg-transparent tpl:p-0 tpl:opacity-60 tpl:transition-all tpl:hover:opacity-100 tpl:text-[var(--tpl-primary)]\"\n contenteditable=\"false\"\n @click.stop.prevent=\"deleteNode\"\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </NodeViewWrapper>\n</template>\n","import type { Editor } from \"@tiptap/core\";\n\n/**\n * Decides whether MergeTagNode / LogicMergeTagNode should swallow a\n * Backspace/Delete keystroke (returning `true` from a TipTap keymap\n * suppresses the default behavior).\n *\n * Only suppresses in the cursor-adjacent case so the \"first press\n * selects the atom, second press deletes it\" UX works. Range selections\n * (Cmd+A, drag-select, double-click-word) explicitly fall through —\n * default `replaceSelection` then deletes the entire range including\n * any merge-tag atoms inside it.\n *\n * Earlier revisions also returned `true` whenever `nodesBetween($from,\n * $to)` found a merge tag anywhere in the selection range — which\n * silently broke Cmd+A + Backspace for any paragraph containing a\n * merge tag (entire deletion was cancelled, nothing happened). The\n * cursor-adjacent protection is the only piece that should survive.\n */\nexport function isNodeSelected(editor: Editor, nodeTypeName: string): boolean {\n const { $from, $to } = editor.state.selection;\n\n // Range selection: let TipTap's default range-delete run. Even when\n // the range contains atom nodes, ProseMirror's replaceSelection\n // handles atomic deletion correctly.\n if ($from.pos !== $to.pos) return false;\n\n // Cursor-adjacent atom: protect from single-keystroke deletion.\n // (`$from.pos > 0` guards against reading `nodeBefore` at doc start\n // where ProseMirror's index would be undefined for nodeBefore.)\n if ($from.pos > 0 && $from.nodeBefore?.type.name === nodeTypeName) {\n return true;\n }\n if ($from.nodeAfter?.type.name === nodeTypeName) {\n return true;\n }\n\n return false;\n}\n","import type { Component } from \"vue\";\nimport { VueNodeViewRenderer } from \"@tiptap/vue-3\";\n\n/**\n * Typed wrapper for VueNodeViewRenderer that handles the known type mismatch\n * between Vue SFC default exports and TipTap's expected component type.\n */\nexport function renderVueNodeView(component: Component) {\n return VueNodeViewRenderer(\n component as Parameters<typeof VueNodeViewRenderer>[0],\n );\n}\n","import LogicMergeTagNodeView from \"./LogicMergeTagNodeView.vue\";\nimport type { SyntaxPreset } from \"@templatical/types\";\nimport {\n getLogicMergeTagKeyword,\n isLogicMergeTagValue,\n SYNTAX_PRESETS,\n} from \"@templatical/types\";\nimport { InputRule, mergeAttributes, Node, PasteRule } from \"@tiptap/core\";\nimport { isNodeSelected } from \"./isNodeSelected\";\nimport { renderVueNodeView } from \"./renderVueNodeView\";\n\nexport interface LogicMergeTagNodeOptions {\n syntax: SyntaxPreset;\n}\n\nexport const LogicMergeTagNode = Node.create<LogicMergeTagNodeOptions>({\n name: \"logicMergeTagNode\",\n\n group: \"inline\",\n\n inline: true,\n\n atom: true,\n\n addOptions() {\n return {\n syntax: SYNTAX_PRESETS.liquid,\n };\n },\n\n addAttributes() {\n return {\n // Both attributes are state, not markup, same as `MergeTagNode`:\n // `renderHTML()` emits the canonical `data-logic-merge-tag` /\n // `data-keyword` pair and `parseHTML` reads only those. `rendered: false`\n // keeps TipTap from also serializing each attribute under its own name,\n // which would put a write-only duplicate of the same data on every tag.\n value: {\n default: \"\",\n rendered: false,\n parseHTML: (element) =>\n element.getAttribute(\"data-logic-merge-tag\") || \"\",\n },\n keyword: {\n default: \"\",\n rendered: false,\n parseHTML: (element) =>\n element.getAttribute(\"data-keyword\") || element.textContent || \"\",\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: \"span[data-logic-merge-tag]\",\n },\n ];\n },\n\n renderHTML({ node, HTMLAttributes }) {\n if (!isLogicMergeTagValue(node.attrs.value, this.options.syntax)) {\n return [\"span\", {}, node.attrs.value];\n }\n\n const keyword = getLogicMergeTagKeyword(\n node.attrs.value,\n this.options.syntax,\n );\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-logic-merge-tag\": node.attrs.value,\n \"data-keyword\": keyword,\n }),\n keyword,\n ];\n },\n\n addNodeView() {\n return renderVueNodeView(LogicMergeTagNodeView);\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () => isNodeSelected(this.editor, this.name),\n Delete: () => isNodeSelected(this.editor, this.name),\n };\n },\n\n addInputRules() {\n const inputRegex = new RegExp(this.options.syntax.logic.source + \"$\", \"\");\n\n return [\n new InputRule({\n find: inputRegex,\n handler: ({ state, range, match }) => {\n const fullValue = match[0];\n if (!isLogicMergeTagValue(fullValue, this.options.syntax)) {\n return;\n }\n\n const keyword = getLogicMergeTagKeyword(\n fullValue,\n this.options.syntax,\n );\n\n const node = this.type.create({\n value: fullValue,\n keyword,\n });\n\n state.tr.replaceWith(range.from, range.to, node);\n },\n }),\n ];\n },\n\n addPasteRules() {\n const pasteRegex = new RegExp(this.options.syntax.logic.source, \"g\");\n\n return [\n new PasteRule({\n find: pasteRegex,\n handler: ({ state, range, match }) => {\n const fullValue = match[0];\n if (!isLogicMergeTagValue(fullValue, this.options.syntax)) {\n return;\n }\n\n const keyword = getLogicMergeTagKeyword(\n fullValue,\n this.options.syntax,\n );\n\n const node = this.type.create({\n value: fullValue,\n keyword,\n });\n\n state.tr.replaceWith(range.from, range.to, node);\n },\n }),\n ];\n },\n});\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../composables/useI18n\";\nimport { useMergeTag } from \"../composables/useMergeTag\";\nimport { NodeViewWrapper } from \"@tiptap/vue-3\";\nimport { computed, nextTick, ref } from \"vue\";\n\nconst props = defineProps<{\n node: {\n attrs: {\n label: string;\n value: string;\n };\n };\n deleteNode: () => void;\n updateAttributes: (attrs: Record<string, unknown>) => void;\n}>();\n\nconst { getMergeTagLabel } = useMergeTag();\nconst { t } = useI18n();\n\nconst displayLabel = computed(() => getMergeTagLabel(props.node.attrs.value));\n\nconst isEditing = ref(false);\nconst editValue = ref(\"\");\nconst inputRef = ref<HTMLInputElement | null>(null);\n\nfunction startEditing(): void {\n editValue.value = props.node.attrs.value;\n isEditing.value = true;\n nextTick(() => {\n inputRef.value?.focus();\n inputRef.value?.select();\n });\n}\n\nfunction finishEditing(): void {\n const newValue = editValue.value.trim();\n if (newValue && newValue !== props.node.attrs.value) {\n // Update with new value and derive label from it\n props.updateAttributes({\n value: newValue,\n label: getMergeTagLabel(newValue),\n });\n }\n isEditing.value = false;\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\") {\n event.preventDefault();\n finishEditing();\n } else if (event.key === \"Escape\") {\n isEditing.value = false;\n }\n}\n</script>\n\n<template>\n <NodeViewWrapper\n as=\"span\"\n class=\"tpl-merge-tag-node tpl:group tpl:mx-0.5 tpl:inline-flex tpl:items-center tpl:gap-1 tpl:rounded tpl:px-1.5 tpl:py-0.5 tpl:text-[0.9em] tpl:font-medium tpl:select-none tpl:text-[var(--tpl-primary)]\"\n style=\"\n background-color: color-mix(in srgb, var(--tpl-primary) 20%, transparent);\n \"\n contenteditable=\"false\"\n >\n <!-- Edit mode -->\n <input\n v-if=\"isEditing\"\n ref=\"inputRef\"\n v-model=\"editValue\"\n type=\"text\"\n class=\"tpl:w-32 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-0.5 tpl:py-0 tpl:text-[1em] tpl:font-medium tpl:outline-none tpl:text-[var(--tpl-primary)]\"\n @blur=\"finishEditing\"\n @keydown=\"handleKeydown\"\n />\n <!-- Display mode -->\n <span\n v-else\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n class=\"tpl-tooltip tpl:cursor-pointer\"\n :data-tooltip=\"node.attrs.value\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ displayLabel }}\n </span>\n <button\n type=\"button\"\n :aria-label=\"t.mergeTag.deleteMergeTag\"\n class=\"tpl-merge-tag-delete tpl:flex tpl:size-5 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-none tpl:bg-transparent tpl:p-0 tpl:opacity-60 tpl:transition-all tpl:hover:opacity-100 tpl:text-[var(--tpl-primary)]\"\n contenteditable=\"false\"\n @click.stop.prevent=\"deleteNode\"\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </NodeViewWrapper>\n</template>\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../composables/useI18n\";\nimport { useMergeTag } from \"../composables/useMergeTag\";\nimport { NodeViewWrapper } from \"@tiptap/vue-3\";\nimport { computed, nextTick, ref } from \"vue\";\n\nconst props = defineProps<{\n node: {\n attrs: {\n label: string;\n value: string;\n };\n };\n deleteNode: () => void;\n updateAttributes: (attrs: Record<string, unknown>) => void;\n}>();\n\nconst { getMergeTagLabel } = useMergeTag();\nconst { t } = useI18n();\n\nconst displayLabel = computed(() => getMergeTagLabel(props.node.attrs.value));\n\nconst isEditing = ref(false);\nconst editValue = ref(\"\");\nconst inputRef = ref<HTMLInputElement | null>(null);\n\nfunction startEditing(): void {\n editValue.value = props.node.attrs.value;\n isEditing.value = true;\n nextTick(() => {\n inputRef.value?.focus();\n inputRef.value?.select();\n });\n}\n\nfunction finishEditing(): void {\n const newValue = editValue.value.trim();\n if (newValue && newValue !== props.node.attrs.value) {\n // Update with new value and derive label from it\n props.updateAttributes({\n value: newValue,\n label: getMergeTagLabel(newValue),\n });\n }\n isEditing.value = false;\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\") {\n event.preventDefault();\n finishEditing();\n } else if (event.key === \"Escape\") {\n isEditing.value = false;\n }\n}\n</script>\n\n<template>\n <NodeViewWrapper\n as=\"span\"\n class=\"tpl-merge-tag-node tpl:group tpl:mx-0.5 tpl:inline-flex tpl:items-center tpl:gap-1 tpl:rounded tpl:px-1.5 tpl:py-0.5 tpl:text-[0.9em] tpl:font-medium tpl:select-none tpl:text-[var(--tpl-primary)]\"\n style=\"\n background-color: color-mix(in srgb, var(--tpl-primary) 20%, transparent);\n \"\n contenteditable=\"false\"\n >\n <!-- Edit mode -->\n <input\n v-if=\"isEditing\"\n ref=\"inputRef\"\n v-model=\"editValue\"\n type=\"text\"\n class=\"tpl:w-32 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-0.5 tpl:py-0 tpl:text-[1em] tpl:font-medium tpl:outline-none tpl:text-[var(--tpl-primary)]\"\n @blur=\"finishEditing\"\n @keydown=\"handleKeydown\"\n />\n <!-- Display mode -->\n <span\n v-else\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n class=\"tpl-tooltip tpl:cursor-pointer\"\n :data-tooltip=\"node.attrs.value\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ displayLabel }}\n </span>\n <button\n type=\"button\"\n :aria-label=\"t.mergeTag.deleteMergeTag\"\n class=\"tpl-merge-tag-delete tpl:flex tpl:size-5 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-none tpl:bg-transparent tpl:p-0 tpl:opacity-60 tpl:transition-all tpl:hover:opacity-100 tpl:text-[var(--tpl-primary)]\"\n contenteditable=\"false\"\n @click.stop.prevent=\"deleteNode\"\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </NodeViewWrapper>\n</template>\n","import MergeTagNodeView from \"./MergeTagNodeView.vue\";\nimport type { MergeTag, SyntaxPreset } from \"@templatical/types\";\nimport { getMergeTagLabel, SYNTAX_PRESETS } from \"@templatical/types\";\nimport { InputRule, mergeAttributes, Node, PasteRule } from \"@tiptap/core\";\nimport { isNodeSelected } from \"./isNodeSelected\";\nimport { renderVueNodeView } from \"./renderVueNodeView\";\n\nexport interface MergeTagNodeOptions {\n mergeTags: MergeTag[];\n syntax: SyntaxPreset;\n}\n\n/**\n * Inserted-node attrs are intentionally limited to `label` + `value`. The\n * `MergeTag` interface also carries optional `group` / `description` for\n * the built-in picker, but those are display-only and must NOT leak into\n * the document JSON — they would bloat templates and pollute serialized\n * state. `Pick<>` makes the constraint explicit at the type level.\n */\nexport type InsertMergeTagAttrs = Pick<MergeTag, \"label\" | \"value\">;\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n mergeTagNode: {\n insertMergeTag: (attrs: InsertMergeTagAttrs) => ReturnType;\n };\n }\n}\n\nexport const MergeTagNode = Node.create<MergeTagNodeOptions>({\n name: \"mergeTagNode\",\n\n group: \"inline\",\n\n inline: true,\n\n atom: true,\n\n addOptions() {\n return {\n mergeTags: [],\n syntax: SYNTAX_PRESETS.liquid,\n };\n },\n\n addAttributes() {\n return {\n // Both attributes are state, not markup: `renderHTML()` below emits the\n // canonical `data-merge-tag` / `data-label` pair and `parseHTML` reads\n // only those. `rendered: false` keeps TipTap from also serializing each\n // attribute under its own name, which would put a write-only duplicate\n // of the same data on every tag — invalid on a `<span>`, and paid again\n // through storage, autosave, snapshots and version history.\n label: {\n default: \"\",\n rendered: false,\n parseHTML: (element) =>\n element.getAttribute(\"data-label\") || element.textContent || \"\",\n },\n value: {\n default: \"\",\n rendered: false,\n parseHTML: (element) => element.getAttribute(\"data-merge-tag\") || \"\",\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: \"span[data-merge-tag]\",\n },\n ];\n },\n\n renderHTML({ node, HTMLAttributes }) {\n const label = getMergeTagLabel(node.attrs.value, this.options.mergeTags);\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-merge-tag\": node.attrs.value,\n \"data-label\": label,\n }),\n label,\n ];\n },\n\n addNodeView() {\n return renderVueNodeView(MergeTagNodeView);\n },\n\n addCommands() {\n return {\n insertMergeTag:\n (attrs: InsertMergeTagAttrs) =>\n ({ commands }) => {\n // Whitelist explicitly — even if a caller smuggles extra keys via\n // a wider type assertion, only label/value reach the node attrs.\n return commands.insertContent({\n type: this.name,\n attrs: { label: attrs.label, value: attrs.value },\n });\n },\n };\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () => isNodeSelected(this.editor, this.name),\n Delete: () => isNodeSelected(this.editor, this.name),\n };\n },\n\n addInputRules() {\n const inputRegex = new RegExp(this.options.syntax.value.source + \"$\", \"\");\n\n return [\n new InputRule({\n find: inputRegex,\n handler: ({ state, range, match }) => {\n const fullValue = match[0];\n const label = getMergeTagLabel(fullValue, this.options.mergeTags);\n\n const node = this.type.create({\n label,\n value: fullValue,\n });\n\n state.tr.replaceWith(range.from, range.to, node);\n },\n }),\n ];\n },\n\n addPasteRules() {\n const pasteRegex = new RegExp(this.options.syntax.value.source, \"g\");\n\n return [\n new PasteRule({\n find: pasteRegex,\n handler: ({ state, range, match }) => {\n const fullValue = match[0];\n const label = getMergeTagLabel(fullValue, this.options.mergeTags);\n\n const node = this.type.create({\n label,\n value: fullValue,\n });\n\n state.tr.replaceWith(range.from, range.to, node);\n },\n }),\n ];\n },\n});\n"],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@ var e = { mediaLibrary: {
|
|
|
11
11
|
newFolder: "Nouveau dossier",
|
|
12
12
|
folderName: "Nom du dossier",
|
|
13
13
|
noFiles: "Aucun fichier trouvé",
|
|
14
|
+
noSearchResults: "Aucun fichier ne correspond à votre recherche",
|
|
14
15
|
dropOrClick: "Déposez des fichiers ici ou cliquez pour téléverser",
|
|
15
16
|
acceptedFormats: "Images, PDF, vidéo, audio, documents (max 10 Mo)",
|
|
16
17
|
uploading: "Téléversement...",
|
|
@@ -56,11 +57,6 @@ var e = { mediaLibrary: {
|
|
|
56
57
|
import: "Importer",
|
|
57
58
|
importing: "Importation...",
|
|
58
59
|
importError: "Échec de l'importation depuis l'URL",
|
|
59
|
-
conversionLabel: "Taille",
|
|
60
|
-
conversionOriginal: "Originale",
|
|
61
|
-
conversionSmall: "Petite (150px)",
|
|
62
|
-
conversionMedium: "Moyenne (600px)",
|
|
63
|
-
conversionLarge: "Grande (1200px)",
|
|
64
60
|
replaceFile: "Remplacer le fichier",
|
|
65
61
|
replaceWarningTitle: "Remplacer le fichier",
|
|
66
62
|
replaceWarningMessage: "Vous êtes sur le point de remplacer ce fichier. Le remplacement doit avoir la même extension ({extension}).",
|
|
@@ -86,4 +82,4 @@ var e = { mediaLibrary: {
|
|
|
86
82
|
//#endregion
|
|
87
83
|
export { e as default };
|
|
88
84
|
|
|
89
|
-
//# sourceMappingURL=fr-
|
|
85
|
+
//# sourceMappingURL=fr-C4hVl5Lk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fr-C4hVl5Lk.js","names":[],"sources":["../../../../media-library/src/i18n/locales/fr.ts"],"sourcesContent":["const fr = {\n mediaLibrary: {\n title: \"Médiathèque\",\n searchPlaceholder: \"Rechercher des fichiers...\",\n allFiles: \"Tous les fichiers\",\n filterAll: \"Tous les types\",\n filterImages: \"Images\",\n filterDocuments: \"Documents\",\n filterVideos: \"Vidéos\",\n filterAudio: \"Audio\",\n newFolder: \"Nouveau dossier\",\n folderName: \"Nom du dossier\",\n noFiles: \"Aucun fichier trouvé\",\n noSearchResults: \"Aucun fichier ne correspond à votre recherche\",\n dropOrClick: \"Déposez des fichiers ici ou cliquez pour téléverser\",\n acceptedFormats: \"Images, PDF, vidéo, audio, documents (max 10 Mo)\",\n uploading: \"Téléversement...\",\n uploadingProgress: \"Téléversement de {current} sur {total}...\",\n selectImage: \"Sélectionner l'image\",\n selectFile: \"Sélectionner le fichier\",\n deleteSelected: \"Supprimer\",\n copyUrl: \"Copier l'URL\",\n copied: \"Copié !\",\n browseMedia: \"Parcourir la médiathèque\",\n renameFolder: \"Renommer le dossier\",\n addSubfolder: \"Ajouter un sous-dossier\",\n subfolderName: \"Nom du sous-dossier\",\n sortNewest: \"Plus récents d'abord\",\n sortOldest: \"Plus anciens d'abord\",\n sortNameAsc: \"Nom A-Z\",\n sortNameDesc: \"Nom Z-A\",\n sortSizeAsc: \"Plus petits d'abord\",\n sortSizeDesc: \"Plus grands d'abord\",\n moveSelected: \"Déplacer\",\n moveToRoot: \"Tous les fichiers\",\n currentFolder: \"(actuel)\",\n confirmDelete: \"Confirmer ?\",\n renameFile: \"Renommer\",\n editFile: \"Modifier le fichier\",\n fileName: \"Nom de fichier\",\n altText: \"Texte alternatif\",\n altTextPlaceholder: \"Décrivez cette image pour l'accessibilité\",\n saveChanges: \"Enregistrer\",\n cancel: \"Annuler\",\n frequentlyUsed: \"Fréquemment utilisés\",\n deleteWarningTitle: \"Supprimer le fichier\",\n deleteWarningMessage: \"Êtes-vous sûr ? Cette action est irréversible.\",\n deleteWarningUsageNote:\n \"Les fichiers suivants sont utilisés dans des modèles. Les supprimer peut casser ces modèles.\",\n deleteAnyway: \"Supprimer\",\n usedInTemplates: \"Utilisé dans {count} modèle(s)\",\n viewGrid: \"Vue en grille\",\n viewList: \"Vue en liste\",\n showFolders: \"Afficher les dossiers\",\n hideFolders: \"Masquer les dossiers\",\n importFromUrl: \"Importer depuis une URL\",\n importUrlPlaceholder: \"https://example.com/image.jpg\",\n import: \"Importer\",\n importing: \"Importation...\",\n importError: \"Échec de l'importation depuis l'URL\",\n replaceFile: \"Remplacer le fichier\",\n replaceWarningTitle: \"Remplacer le fichier\",\n replaceWarningMessage:\n \"Vous êtes sur le point de remplacer ce fichier. Le remplacement doit avoir la même extension ({extension}).\",\n replaceWarningUsageNote:\n \"Ce fichier est utilisé dans {count} modèle(s). Le remplacer mettra à jour toutes les références.\",\n replaceSelectFile: \"Sélectionner le fichier de remplacement\",\n replace: \"Remplacer\",\n replacing: \"Remplacement...\",\n replaceError: \"Échec du remplacement du fichier\",\n saving: \"Enregistrement...\",\n cropAspectRatio: \"Proportions\",\n cropFree: \"Libre\",\n cropSquare: \"1:1\",\n cropLandscape43: \"4:3\",\n cropLandscape169: \"16:9\",\n cropOriginal: \"Originales\",\n cropMaxWidth: \"Largeur max\",\n cropMaxHeight: \"Hauteur max\",\n cropOutputSize: \"Taille de sortie\",\n cropPixels: \"px\",\n cropOptional: \"(facultatif)\",\n storageTooltip: \"{used} sur {total} utilisés ({remaining} restants)\",\n },\n};\n\nexport default fr;\n"],"mappings":";AAAA,IAAM,IAAK,EACT,cAAc;CACZ,OAAO;CACP,mBAAmB;CACnB,UAAU;CACV,WAAW;CACX,cAAc;CACd,iBAAiB;CACjB,cAAc;CACd,aAAa;CACb,WAAW;CACX,YAAY;CACZ,SAAS;CACT,iBAAiB;CACjB,aAAa;CACb,iBAAiB;CACjB,WAAW;CACX,mBAAmB;CACnB,aAAa;CACb,YAAY;CACZ,gBAAgB;CAChB,SAAS;CACT,QAAQ;CACR,aAAa;CACb,cAAc;CACd,cAAc;CACd,eAAe;CACf,YAAY;CACZ,YAAY;CACZ,aAAa;CACb,cAAc;CACd,aAAa;CACb,cAAc;CACd,cAAc;CACd,YAAY;CACZ,eAAe;CACf,eAAe;CACf,YAAY;CACZ,UAAU;CACV,UAAU;CACV,SAAS;CACT,oBAAoB;CACpB,aAAa;CACb,QAAQ;CACR,gBAAgB;CAChB,oBAAoB;CACpB,sBAAsB;CACtB,wBACE;CACF,cAAc;CACd,iBAAiB;CACjB,UAAU;CACV,UAAU;CACV,aAAa;CACb,aAAa;CACb,eAAe;CACf,sBAAsB;CACtB,QAAQ;CACR,WAAW;CACX,aAAa;CACb,aAAa;CACb,qBAAqB;CACrB,uBACE;CACF,yBACE;CACF,mBAAmB;CACnB,SAAS;CACT,WAAW;CACX,cAAc;CACd,QAAQ;CACR,iBAAiB;CACjB,UAAU;CACV,YAAY;CACZ,iBAAiB;CACjB,kBAAkB;CAClB,cAAc;CACd,cAAc;CACd,eAAe;CACf,gBAAgB;CAChB,YAAY;CACZ,cAAc;CACd,gBAAgB;AAClB,EACF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { E as e, w as t } from "./draggable-kbOhCgnk.js";
|
|
2
|
-
//#region ../../node_modules/.pnpm/@lucide+vue@1.
|
|
2
|
+
//#region ../../node_modules/.pnpm/@lucide+vue@1.43.0_vue@3.5.42_typescript@6.0.3_/node_modules/@lucide/vue/dist/esm/shared/src/build/defaultAttributes.mjs
|
|
3
3
|
var n = {
|
|
4
4
|
xmlns: "http://www.w3.org/2000/svg",
|
|
5
5
|
width: 24,
|
|
@@ -12,7 +12,7 @@ var n = {
|
|
|
12
12
|
"stroke-linejoin": "round"
|
|
13
13
|
}, r = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) === t).join(" ").trim();
|
|
14
14
|
//#endregion
|
|
15
|
-
//#region ../../node_modules/.pnpm/@lucide+vue@1.
|
|
15
|
+
//#region ../../node_modules/.pnpm/@lucide+vue@1.43.0_vue@3.5.42_typescript@6.0.3_/node_modules/@lucide/vue/dist/esm/shared/src/build/buildLucideIconNode.mjs
|
|
16
16
|
function i(e) {
|
|
17
17
|
return e != null;
|
|
18
18
|
}
|
|
@@ -49,7 +49,7 @@ function a(e, t = {}) {
|
|
|
49
49
|
];
|
|
50
50
|
}
|
|
51
51
|
//#endregion
|
|
52
|
-
//#region ../../node_modules/.pnpm/@lucide+vue@1.
|
|
52
|
+
//#region ../../node_modules/.pnpm/@lucide+vue@1.43.0_vue@3.5.42_typescript@6.0.3_/node_modules/@lucide/vue/dist/esm/shared/src/utils/hasA11yProp.mjs
|
|
53
53
|
var o = (e) => {
|
|
54
54
|
for (let t in e) if (t.startsWith("aria-") || t === "role" || t === "title") return !0;
|
|
55
55
|
return !1;
|
|
@@ -58,7 +58,7 @@ function u() {
|
|
|
58
58
|
return e(l, {});
|
|
59
59
|
}
|
|
60
60
|
//#endregion
|
|
61
|
-
//#region ../../node_modules/.pnpm/@lucide+vue@1.
|
|
61
|
+
//#region ../../node_modules/.pnpm/@lucide+vue@1.43.0_vue@3.5.42_typescript@6.0.3_/node_modules/@lucide/vue/dist/esm/Icon.mjs
|
|
62
62
|
var d = ({ name: e, iconNode: n, "icon-node": r, icon: i = {
|
|
63
63
|
name: c(e),
|
|
64
64
|
node: n ?? r,
|
|
@@ -81,7 +81,7 @@ var d = ({ name: e, iconNode: n, "icon-node": r, icon: i = {
|
|
|
81
81
|
return t("svg", j, [...M.map((e) => t(...e)), ...A ?? []]);
|
|
82
82
|
};
|
|
83
83
|
//#endregion
|
|
84
|
-
//#region ../../node_modules/.pnpm/@lucide+vue@1.
|
|
84
|
+
//#region ../../node_modules/.pnpm/@lucide+vue@1.43.0_vue@3.5.42_typescript@6.0.3_/node_modules/@lucide/vue/dist/esm/createLucideIcon.mjs
|
|
85
85
|
function f(e, n = []) {
|
|
86
86
|
let r = typeof e == "string" ? {
|
|
87
87
|
name: e,
|
|
@@ -1425,6 +1425,24 @@ var p = f({
|
|
|
1425
1425
|
],
|
|
1426
1426
|
aliases: ["align-justify"]
|
|
1427
1427
|
}), $ = f({
|
|
1428
|
+
name: "text-align-start",
|
|
1429
|
+
size: 24,
|
|
1430
|
+
node: [
|
|
1431
|
+
["path", {
|
|
1432
|
+
d: "M21 5H3",
|
|
1433
|
+
key: "1fi0y6"
|
|
1434
|
+
}],
|
|
1435
|
+
["path", {
|
|
1436
|
+
d: "M15 12H3",
|
|
1437
|
+
key: "6jk70r"
|
|
1438
|
+
}],
|
|
1439
|
+
["path", {
|
|
1440
|
+
d: "M17 19H3",
|
|
1441
|
+
key: "z6ezky"
|
|
1442
|
+
}]
|
|
1443
|
+
],
|
|
1444
|
+
aliases: ["text", "align-left"]
|
|
1445
|
+
}), He = f({
|
|
1428
1446
|
name: "text-cursor-input",
|
|
1429
1447
|
size: 24,
|
|
1430
1448
|
node: [
|
|
@@ -1449,24 +1467,6 @@ var p = f({
|
|
|
1449
1467
|
key: "velyjx"
|
|
1450
1468
|
}]
|
|
1451
1469
|
]
|
|
1452
|
-
}), He = f({
|
|
1453
|
-
name: "text-align-start",
|
|
1454
|
-
size: 24,
|
|
1455
|
-
node: [
|
|
1456
|
-
["path", {
|
|
1457
|
-
d: "M21 5H3",
|
|
1458
|
-
key: "1fi0y6"
|
|
1459
|
-
}],
|
|
1460
|
-
["path", {
|
|
1461
|
-
d: "M15 12H3",
|
|
1462
|
-
key: "6jk70r"
|
|
1463
|
-
}],
|
|
1464
|
-
["path", {
|
|
1465
|
-
d: "M17 19H3",
|
|
1466
|
-
key: "z6ezky"
|
|
1467
|
-
}]
|
|
1468
|
-
],
|
|
1469
|
-
aliases: ["text", "align-left"]
|
|
1470
1470
|
}), Ue = f({
|
|
1471
1471
|
name: "timer",
|
|
1472
1472
|
size: 24,
|
|
@@ -1672,4 +1672,4 @@ var p = f({
|
|
|
1672
1672
|
//#endregion
|
|
1673
1673
|
export { re as $, Ee as A, T as At, ge as B, h as Bt, Ne as C, M as Ct, ke as D, O as Dt, Ae as E, k as Et, xe as F, b as Ft, de as G, me as H, p as Ht, be as I, y as It, ce as J, ue as K, ye as L, v as Lt, we as M, C as Mt, Ce as N, S as Nt, Oe as O, D as Ot, Se as P, x as Pt, ie as Q, ve as R, _ as Rt, Pe as S, ee as St, je as T, A as Tt, pe as U, he as V, m as Vt, fe as W, oe as X, se as Y, ae as Z, ze as _, I as _t, Xe as a, J as at, Ie as b, N as bt, qe as c, G as ct, We as d, H as dt, ne as et, Ue as f, V as ft, Be as g, L as gt, Ve as h, R as ht, Ze as i, Y as it, Te as j, w as jt, De as k, E as kt, Ke as l, W as lt, $ as m, z as mt, $e as n, Z as nt, Ye as o, q as ot, He as p, B as pt, le as q, Qe as r, X as rt, Je as s, K as st, et as t, Q as tt, Ge as u, U as ut, Re as v, F as vt, Me as w, j as wt, Fe as x, te as xt, Le as y, P as yt, _e as z, g as zt };
|
|
1674
1674
|
|
|
1675
|
-
//# sourceMappingURL=icons-
|
|
1675
|
+
//# sourceMappingURL=icons-BUlqGSgd.js.map
|