@templatical/editor 0.4.0 → 0.5.1

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.
Files changed (76) hide show
  1. package/dist/{AiFeatureMenu-vatvCD-m.js → AiFeatureMenu-D7Od4cI2.js} +1 -1
  2. package/dist/{CloudEditor-Bxe8Jt9u.js → CloudEditor-DG8fWnXI.js} +4 -4
  3. package/dist/{CollaboratorBar-Dv7VT09N.js → CollaboratorBar-BdXfCYAr.js} +1 -1
  4. package/dist/{ModuleBrowserModal-DAnqdlyq.js → ModuleBrowserModal-DpMInJoP.js} +4 -4
  5. package/dist/{ModulePreviewCanvas-CXApEVEG.js → ModulePreviewCanvas-MjIGlxVI.js} +1 -1
  6. package/dist/{ParagraphEditor-Bjdakcoz.js → ParagraphEditor-B5qZL5c2.js} +7 -7
  7. package/dist/{SaveModuleDialog-CZXltahx.js → SaveModuleDialog-BGFYMJby.js} +2 -2
  8. package/dist/{SnapshotHistory-OqEkaA0W.js → SnapshotHistory-4aWE_-GM.js} +1 -1
  9. package/dist/{TestEmailModal-CvEK6MTy.js → TestEmailModal-p-iH28wl.js} +2 -2
  10. package/dist/{TitleEditor-CxCD70Bs.js → TitleEditor-BHxJ6Oxd.js} +3 -3
  11. package/dist/{TplModal-C2Hoz1it.js → TplModal-BiUCSfou.js} +1 -1
  12. package/dist/{blockTypeIcons-DpJa9awv.js → blockTypeIcons-8GJD96Tw.js} +1 -1
  13. package/dist/bundle-stats.json +6 -6
  14. package/dist/cdn/chunks/{AiFeatureMenu-BggCm6wN.js → AiFeatureMenu-DSXAYiMk.js} +2 -2
  15. package/dist/cdn/chunks/{AiFeatureMenu-BggCm6wN.js.map → AiFeatureMenu-DSXAYiMk.js.map} +1 -1
  16. package/dist/cdn/chunks/{CloudEditor-CTNhzoZ1.js → CloudEditor-CRYF-bR3.js} +6 -6
  17. package/dist/cdn/chunks/{CloudEditor-CTNhzoZ1.js.map → CloudEditor-CRYF-bR3.js.map} +1 -1
  18. package/dist/cdn/chunks/{CollaboratorBar-De-3lvDy.js → CollaboratorBar-CTFgLtUt.js} +3 -3
  19. package/dist/cdn/chunks/{CollaboratorBar-De-3lvDy.js.map → CollaboratorBar-CTFgLtUt.js.map} +1 -1
  20. package/dist/cdn/chunks/{CountdownBlock-CUAl8R-c.js → CountdownBlock-BKg-e3Uo.js} +2 -2
  21. package/dist/cdn/chunks/{CountdownBlock-CUAl8R-c.js.map → CountdownBlock-BKg-e3Uo.js.map} +1 -1
  22. package/dist/cdn/chunks/{CountdownToolbar-3zLcGAcb.js → CountdownToolbar-CPAOXOwI.js} +3 -3
  23. package/dist/cdn/chunks/{CountdownToolbar-3zLcGAcb.js.map → CountdownToolbar-CPAOXOwI.js.map} +1 -1
  24. package/dist/cdn/chunks/{ModuleBrowserModal-CxICY31A.js → ModuleBrowserModal-B70ZM4KG.js} +5 -5
  25. package/dist/cdn/chunks/{ModuleBrowserModal-CxICY31A.js.map → ModuleBrowserModal-B70ZM4KG.js.map} +1 -1
  26. package/dist/cdn/chunks/{ModulePreviewCanvas-Cv0zciNS.js → ModulePreviewCanvas-VHhQwuFP.js} +2 -2
  27. package/dist/cdn/chunks/{ModulePreviewCanvas-Cv0zciNS.js.map → ModulePreviewCanvas-VHhQwuFP.js.map} +1 -1
  28. package/dist/cdn/chunks/{NumberWithSuffix-BaVxnNI4.js → NumberWithSuffix-DnqYqSKs.js} +2 -2
  29. package/dist/cdn/chunks/{NumberWithSuffix-BaVxnNI4.js.map → NumberWithSuffix-DnqYqSKs.js.map} +1 -1
  30. package/dist/cdn/chunks/{ParagraphEditor-BrzlI8vp.js → ParagraphEditor-oVEaeerJ.js} +21 -21
  31. package/dist/cdn/chunks/ParagraphEditor-oVEaeerJ.js.map +1 -0
  32. package/dist/cdn/chunks/{RichTextEditorContent-9vq4MRDp.js → RichTextEditorContent-CmOwLOeY.js} +2 -2
  33. package/dist/cdn/chunks/{RichTextEditorContent-9vq4MRDp.js.map → RichTextEditorContent-CmOwLOeY.js.map} +1 -1
  34. package/dist/cdn/chunks/{SaveModuleDialog-Lco3k1xX.js → SaveModuleDialog-B6kNizps.js} +2 -2
  35. package/dist/cdn/chunks/{SaveModuleDialog-Lco3k1xX.js.map → SaveModuleDialog-B6kNizps.js.map} +1 -1
  36. package/dist/cdn/chunks/{TitleEditor-BiiEtH7x.js → TitleEditor-CvZe3neh.js} +9 -9
  37. package/dist/cdn/chunks/TitleEditor-CvZe3neh.js.map +1 -0
  38. package/dist/cdn/chunks/{blockTypeIcons-DWhn7E7O.js → blockTypeIcons-Bs9B-yft.js} +3 -3
  39. package/dist/cdn/chunks/{blockTypeIcons-DWhn7E7O.js.map → blockTypeIcons-Bs9B-yft.js.map} +1 -1
  40. package/dist/cdn/chunks/{de-DEg-6TsA.js → de-BSWt7lYu.js} +4 -4
  41. package/dist/cdn/chunks/de-BSWt7lYu.js.map +1 -0
  42. package/dist/cdn/chunks/{dist-DFfcnJJB.js → dist-MGrg9tLo.js} +2 -2
  43. package/dist/cdn/chunks/{dist-DFfcnJJB.js.map → dist-MGrg9tLo.js.map} +1 -1
  44. package/dist/cdn/chunks/{en-DpHxxBnH.js → en-9-vIGlc7.js} +4 -4
  45. package/dist/cdn/chunks/en-9-vIGlc7.js.map +1 -0
  46. package/dist/cdn/chunks/{extensions-C6oPJqKD.js → extensions-D13MqxlW.js} +16 -7
  47. package/dist/cdn/chunks/{extensions-C6oPJqKD.js.map → extensions-D13MqxlW.js.map} +1 -1
  48. package/dist/cdn/chunks/{features-DV4PhoBs.js → features-BnG-dhzy.js} +18 -15
  49. package/dist/cdn/chunks/{features-DV4PhoBs.js.map → features-BnG-dhzy.js.map} +1 -1
  50. package/dist/cdn/chunks/{icons-LJ8U8lWI.js → icons-B_185qj_.js} +2 -2
  51. package/dist/cdn/chunks/{icons-LJ8U8lWI.js.map → icons-B_185qj_.js.map} +1 -1
  52. package/dist/cdn/chunks/{media-library-CWQAvfov.js → media-library-DxpFw4Tt.js} +3 -3
  53. package/dist/cdn/chunks/{media-library-CWQAvfov.js.map → media-library-DxpFw4Tt.js.map} +1 -1
  54. package/dist/cdn/chunks/{src-CVBDXDBH.js → src-Cw7KAyui.js} +4 -4
  55. package/dist/cdn/chunks/{src-CVBDXDBH.js.map → src-Cw7KAyui.js.map} +1 -1
  56. package/dist/cdn/chunks/{styles-CFnn-xE6.js → styles-DYDpAUsJ.js} +12 -12
  57. package/dist/cdn/chunks/styles-DYDpAUsJ.js.map +1 -0
  58. package/dist/cdn/chunks/{tiptap-kGWe8qnA.js → tiptap-CPAwPMop.js} +2 -2
  59. package/dist/cdn/chunks/{tiptap-kGWe8qnA.js.map → tiptap-CPAwPMop.js.map} +1 -1
  60. package/dist/cdn/editor.css +1 -1
  61. package/dist/cdn/editor.js +7 -7
  62. package/dist/{de-tDioEErp.js → de-DwLWZn6p.js} +3 -3
  63. package/dist/{en-W2p7oPaa.js → en-BrlGVpmd.js} +3 -3
  64. package/dist/{extensions-BQjnrlGT.js → extensions-Cmf6XVn9.js} +14 -5
  65. package/dist/index.d.ts +8 -8
  66. package/dist/style.css +1 -1
  67. package/dist/{styles-CdrFC7-K.js → styles-C-FrkTA9.js} +8 -8
  68. package/dist/templatical-editor.js +5 -5
  69. package/dist/{useEditorCore-JdLcaPeJ.js → useEditorCore-D0uZbPKG.js} +1717 -1714
  70. package/dist/{useMergeTag-BfFykpYl.js → useMergeTag-CEE4CG-D.js} +1 -1
  71. package/package.json +5 -5
  72. package/dist/cdn/chunks/ParagraphEditor-BrzlI8vp.js.map +0 -1
  73. package/dist/cdn/chunks/TitleEditor-BiiEtH7x.js.map +0 -1
  74. package/dist/cdn/chunks/de-DEg-6TsA.js.map +0 -1
  75. package/dist/cdn/chunks/en-DpHxxBnH.js.map +0 -1
  76. package/dist/cdn/chunks/styles-CFnn-xE6.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"SaveModuleDialog-Lco3k1xX.js","names":[],"sources":["../../../src/cloud/components/SaveModuleDialog.vue","../../../src/cloud/components/SaveModuleDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport TplModal from \"./TplModal.vue\";\nimport { useI18n } from \"../../composables\";\nimport { useCloudI18nStrict } from \"../../composables\";\nimport {\n EDITOR_KEY,\n SAVED_MODULES_HEADLESS_KEY,\n requireInject,\n} from \"../../keys\";\nimport type { Block } from \"@templatical/types\";\nimport { LoaderCircle } from \"@lucide/vue\";\nimport { computed, ref, watch } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n preSelectedBlockId: string | null;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n (e: \"saved\"): void;\n}>();\n\nconst { t } = useI18n();\nconst { t: cloudT } = useCloudI18nStrict();\nconst editor = requireInject(EDITOR_KEY, \"SaveModuleDialog\");\nconst savedModules = requireInject(\n SAVED_MODULES_HEADLESS_KEY,\n \"SaveModuleDialog\",\n);\n\nconst moduleName = ref(\"\");\nconst selectedBlockIds = ref<Set<string>>(new Set());\nconst isSaving = ref(false);\nconst error = ref<string | null>(null);\n\nconst topLevelBlocks = computed(() => editor.content.value.blocks);\n\nfunction blockLabel(block: Block, index: number): string {\n const typeKey = block.type as keyof typeof t.blocks;\n const label = t.blocks[typeKey] ?? block.type;\n return `${label} ${index + 1}`;\n}\n\nwatch(\n () => props.visible,\n (visible) => {\n if (visible) {\n moduleName.value = \"\";\n error.value = null;\n selectedBlockIds.value = new Set(\n props.preSelectedBlockId ? [props.preSelectedBlockId] : [],\n );\n }\n },\n);\n\nfunction toggleBlock(blockId: string): void {\n const newSet = new Set(selectedBlockIds.value);\n if (newSet.has(blockId)) {\n newSet.delete(blockId);\n } else {\n newSet.add(blockId);\n }\n selectedBlockIds.value = newSet;\n}\n\nconst canSave = computed(\n () =>\n moduleName.value.trim().length > 0 &&\n selectedBlockIds.value.size > 0 &&\n !isSaving.value,\n);\n\nasync function handleSave(): Promise<void> {\n if (!canSave.value) return;\n\n isSaving.value = true;\n error.value = null;\n\n try {\n const selectedBlocks = topLevelBlocks.value.filter((b) =>\n selectedBlockIds.value.has(b.id),\n );\n await savedModules.createModule(moduleName.value.trim(), selectedBlocks);\n emit(\"saved\");\n emit(\"close\");\n } catch (err) {\n error.value = (err as Error).message;\n } finally {\n isSaving.value = false;\n }\n}\n\nfunction handleClose(): void {\n if (!isSaving.value) {\n emit(\"close\");\n }\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n handleSave();\n }\n if (event.key === \"Escape\") {\n handleClose();\n }\n}\n</script>\n\n<template>\n <TplModal :visible=\"visible\" @close=\"handleClose\" @keydown=\"handleKeydown\">\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-busy=\"isSaving\"\n aria-labelledby=\"tpl-save-module-title\"\n class=\"tpl-scale-in tpl:mx-4 tpl:w-full tpl:max-w-sm tpl:rounded-[var(--tpl-radius-lg)] tpl:p-5\"\n style=\"\n background-color: var(--tpl-bg-elevated);\n box-shadow: var(--tpl-shadow-xl);\n \"\n >\n <h3\n id=\"tpl-save-module-title\"\n class=\"tpl:mb-4 tpl:text-sm tpl:font-semibold tpl:text-[var(--tpl-text)]\"\n >\n {{ cloudT.modules.saveAsModule }}\n </h3>\n\n <!-- Module name -->\n <div class=\"tpl:mb-3\">\n <label\n class=\"tpl:mb-1.5 tpl:block tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.modules.moduleName }}\n </label>\n <input\n v-model=\"moduleName\"\n type=\"text\"\n :placeholder=\"cloudT.modules.moduleNamePlaceholder\"\n class=\"tpl:h-9 tpl:w-full tpl:rounded-md tpl:border tpl:px-3 tpl:py-1 tpl:text-sm tpl:shadow-xs tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n :disabled=\"isSaving\"\n />\n </div>\n\n <!-- Block selection -->\n <div class=\"tpl:mb-3\">\n <label\n class=\"tpl:mb-1.5 tpl:block tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.modules.selectBlocks }}\n </label>\n <div\n class=\"tpl:max-h-40 tpl:space-y-1 tpl:overflow-y-auto tpl:rounded-md tpl:border tpl:p-2 tpl:border-[var(--tpl-border)]\"\n >\n <label\n v-for=\"(block, index) in topLevelBlocks\"\n :key=\"block.id\"\n class=\"tpl:flex tpl:cursor-pointer tpl:items-center tpl:gap-2 tpl:rounded-sm tpl:px-2 tpl:py-1.5 tpl:text-sm tpl:transition-colors tpl:duration-100\"\n :style=\"{\n color: 'var(--tpl-text)',\n backgroundColor: selectedBlockIds.has(block.id)\n ? 'var(--tpl-primary-light)'\n : 'transparent',\n }\"\n >\n <input\n type=\"checkbox\"\n :checked=\"selectedBlockIds.has(block.id)\"\n class=\"tpl:accent-[var(--tpl-primary)]\"\n :disabled=\"isSaving\"\n @change=\"toggleBlock(block.id)\"\n />\n {{ blockLabel(block, index) }}\n </label>\n </div>\n </div>\n\n <!-- Error message -->\n <p\n v-if=\"error\"\n role=\"alert\"\n class=\"tpl:mb-3 tpl:text-xs tpl:text-[var(--tpl-danger)]\"\n >\n {{ error }}\n </p>\n\n <!-- Actions -->\n <div class=\"tpl:flex tpl:justify-end tpl:gap-2\">\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:border-[var(--tpl-border)] tpl:text-[var(--tpl-text)] tpl:bg-[var(--tpl-bg)]\"\n :disabled=\"isSaving\"\n :class=\"{\n 'tpl:cursor-not-allowed tpl:opacity-50': isSaving,\n }\"\n @click=\"handleClose\"\n >\n {{ cloudT.modules.cancel }}\n </button>\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:hover:opacity-90 tpl:disabled:cursor-not-allowed tpl:disabled:opacity-50 tpl:bg-[var(--tpl-primary)] tpl:text-[var(--tpl-bg)]\"\n :disabled=\"!canSave\"\n @click=\"handleSave\"\n >\n <span v-if=\"isSaving\" class=\"tpl:flex tpl:items-center tpl:gap-1.5\">\n <LoaderCircle\n class=\"tpl:animate-spin\"\n :size=\"12\"\n :stroke-width=\"2\"\n />\n {{ cloudT.modules.saving }}\n </span>\n <span v-else>\n {{ cloudT.modules.save }}\n </span>\n </button>\n </div>\n </div>\n </TplModal>\n</template>\n","<script setup lang=\"ts\">\nimport TplModal from \"./TplModal.vue\";\nimport { useI18n } from \"../../composables\";\nimport { useCloudI18nStrict } from \"../../composables\";\nimport {\n EDITOR_KEY,\n SAVED_MODULES_HEADLESS_KEY,\n requireInject,\n} from \"../../keys\";\nimport type { Block } from \"@templatical/types\";\nimport { LoaderCircle } from \"@lucide/vue\";\nimport { computed, ref, watch } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n preSelectedBlockId: string | null;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n (e: \"saved\"): void;\n}>();\n\nconst { t } = useI18n();\nconst { t: cloudT } = useCloudI18nStrict();\nconst editor = requireInject(EDITOR_KEY, \"SaveModuleDialog\");\nconst savedModules = requireInject(\n SAVED_MODULES_HEADLESS_KEY,\n \"SaveModuleDialog\",\n);\n\nconst moduleName = ref(\"\");\nconst selectedBlockIds = ref<Set<string>>(new Set());\nconst isSaving = ref(false);\nconst error = ref<string | null>(null);\n\nconst topLevelBlocks = computed(() => editor.content.value.blocks);\n\nfunction blockLabel(block: Block, index: number): string {\n const typeKey = block.type as keyof typeof t.blocks;\n const label = t.blocks[typeKey] ?? block.type;\n return `${label} ${index + 1}`;\n}\n\nwatch(\n () => props.visible,\n (visible) => {\n if (visible) {\n moduleName.value = \"\";\n error.value = null;\n selectedBlockIds.value = new Set(\n props.preSelectedBlockId ? [props.preSelectedBlockId] : [],\n );\n }\n },\n);\n\nfunction toggleBlock(blockId: string): void {\n const newSet = new Set(selectedBlockIds.value);\n if (newSet.has(blockId)) {\n newSet.delete(blockId);\n } else {\n newSet.add(blockId);\n }\n selectedBlockIds.value = newSet;\n}\n\nconst canSave = computed(\n () =>\n moduleName.value.trim().length > 0 &&\n selectedBlockIds.value.size > 0 &&\n !isSaving.value,\n);\n\nasync function handleSave(): Promise<void> {\n if (!canSave.value) return;\n\n isSaving.value = true;\n error.value = null;\n\n try {\n const selectedBlocks = topLevelBlocks.value.filter((b) =>\n selectedBlockIds.value.has(b.id),\n );\n await savedModules.createModule(moduleName.value.trim(), selectedBlocks);\n emit(\"saved\");\n emit(\"close\");\n } catch (err) {\n error.value = (err as Error).message;\n } finally {\n isSaving.value = false;\n }\n}\n\nfunction handleClose(): void {\n if (!isSaving.value) {\n emit(\"close\");\n }\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n handleSave();\n }\n if (event.key === \"Escape\") {\n handleClose();\n }\n}\n</script>\n\n<template>\n <TplModal :visible=\"visible\" @close=\"handleClose\" @keydown=\"handleKeydown\">\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-busy=\"isSaving\"\n aria-labelledby=\"tpl-save-module-title\"\n class=\"tpl-scale-in tpl:mx-4 tpl:w-full tpl:max-w-sm tpl:rounded-[var(--tpl-radius-lg)] tpl:p-5\"\n style=\"\n background-color: var(--tpl-bg-elevated);\n box-shadow: var(--tpl-shadow-xl);\n \"\n >\n <h3\n id=\"tpl-save-module-title\"\n class=\"tpl:mb-4 tpl:text-sm tpl:font-semibold tpl:text-[var(--tpl-text)]\"\n >\n {{ cloudT.modules.saveAsModule }}\n </h3>\n\n <!-- Module name -->\n <div class=\"tpl:mb-3\">\n <label\n class=\"tpl:mb-1.5 tpl:block tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.modules.moduleName }}\n </label>\n <input\n v-model=\"moduleName\"\n type=\"text\"\n :placeholder=\"cloudT.modules.moduleNamePlaceholder\"\n class=\"tpl:h-9 tpl:w-full tpl:rounded-md tpl:border tpl:px-3 tpl:py-1 tpl:text-sm tpl:shadow-xs tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n :disabled=\"isSaving\"\n />\n </div>\n\n <!-- Block selection -->\n <div class=\"tpl:mb-3\">\n <label\n class=\"tpl:mb-1.5 tpl:block tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.modules.selectBlocks }}\n </label>\n <div\n class=\"tpl:max-h-40 tpl:space-y-1 tpl:overflow-y-auto tpl:rounded-md tpl:border tpl:p-2 tpl:border-[var(--tpl-border)]\"\n >\n <label\n v-for=\"(block, index) in topLevelBlocks\"\n :key=\"block.id\"\n class=\"tpl:flex tpl:cursor-pointer tpl:items-center tpl:gap-2 tpl:rounded-sm tpl:px-2 tpl:py-1.5 tpl:text-sm tpl:transition-colors tpl:duration-100\"\n :style=\"{\n color: 'var(--tpl-text)',\n backgroundColor: selectedBlockIds.has(block.id)\n ? 'var(--tpl-primary-light)'\n : 'transparent',\n }\"\n >\n <input\n type=\"checkbox\"\n :checked=\"selectedBlockIds.has(block.id)\"\n class=\"tpl:accent-[var(--tpl-primary)]\"\n :disabled=\"isSaving\"\n @change=\"toggleBlock(block.id)\"\n />\n {{ blockLabel(block, index) }}\n </label>\n </div>\n </div>\n\n <!-- Error message -->\n <p\n v-if=\"error\"\n role=\"alert\"\n class=\"tpl:mb-3 tpl:text-xs tpl:text-[var(--tpl-danger)]\"\n >\n {{ error }}\n </p>\n\n <!-- Actions -->\n <div class=\"tpl:flex tpl:justify-end tpl:gap-2\">\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:border-[var(--tpl-border)] tpl:text-[var(--tpl-text)] tpl:bg-[var(--tpl-bg)]\"\n :disabled=\"isSaving\"\n :class=\"{\n 'tpl:cursor-not-allowed tpl:opacity-50': isSaving,\n }\"\n @click=\"handleClose\"\n >\n {{ cloudT.modules.cancel }}\n </button>\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:hover:opacity-90 tpl:disabled:cursor-not-allowed tpl:disabled:opacity-50 tpl:bg-[var(--tpl-primary)] tpl:text-[var(--tpl-bg)]\"\n :disabled=\"!canSave\"\n @click=\"handleSave\"\n >\n <span v-if=\"isSaving\" class=\"tpl:flex tpl:items-center tpl:gap-1.5\">\n <LoaderCircle\n class=\"tpl:animate-spin\"\n :size=\"12\"\n :stroke-width=\"2\"\n />\n {{ cloudT.modules.saving }}\n </span>\n <span v-else>\n {{ cloudT.modules.save }}\n </span>\n </button>\n </div>\n </div>\n </TplModal>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"SaveModuleDialog-B6kNizps.js","names":[],"sources":["../../../src/cloud/components/SaveModuleDialog.vue","../../../src/cloud/components/SaveModuleDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport TplModal from \"./TplModal.vue\";\nimport { useI18n } from \"../../composables\";\nimport { useCloudI18nStrict } from \"../../composables\";\nimport {\n EDITOR_KEY,\n SAVED_MODULES_HEADLESS_KEY,\n requireInject,\n} from \"../../keys\";\nimport type { Block } from \"@templatical/types\";\nimport { LoaderCircle } from \"@lucide/vue\";\nimport { computed, ref, watch } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n preSelectedBlockId: string | null;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n (e: \"saved\"): void;\n}>();\n\nconst { t } = useI18n();\nconst { t: cloudT } = useCloudI18nStrict();\nconst editor = requireInject(EDITOR_KEY, \"SaveModuleDialog\");\nconst savedModules = requireInject(\n SAVED_MODULES_HEADLESS_KEY,\n \"SaveModuleDialog\",\n);\n\nconst moduleName = ref(\"\");\nconst selectedBlockIds = ref<Set<string>>(new Set());\nconst isSaving = ref(false);\nconst error = ref<string | null>(null);\n\nconst topLevelBlocks = computed(() => editor.content.value.blocks);\n\nfunction blockLabel(block: Block, index: number): string {\n const typeKey = block.type as keyof typeof t.blocks;\n const label = t.blocks[typeKey] ?? block.type;\n return `${label} ${index + 1}`;\n}\n\nwatch(\n () => props.visible,\n (visible) => {\n if (visible) {\n moduleName.value = \"\";\n error.value = null;\n selectedBlockIds.value = new Set(\n props.preSelectedBlockId ? [props.preSelectedBlockId] : [],\n );\n }\n },\n);\n\nfunction toggleBlock(blockId: string): void {\n const newSet = new Set(selectedBlockIds.value);\n if (newSet.has(blockId)) {\n newSet.delete(blockId);\n } else {\n newSet.add(blockId);\n }\n selectedBlockIds.value = newSet;\n}\n\nconst canSave = computed(\n () =>\n moduleName.value.trim().length > 0 &&\n selectedBlockIds.value.size > 0 &&\n !isSaving.value,\n);\n\nasync function handleSave(): Promise<void> {\n if (!canSave.value) return;\n\n isSaving.value = true;\n error.value = null;\n\n try {\n const selectedBlocks = topLevelBlocks.value.filter((b) =>\n selectedBlockIds.value.has(b.id),\n );\n await savedModules.createModule(moduleName.value.trim(), selectedBlocks);\n emit(\"saved\");\n emit(\"close\");\n } catch (err) {\n error.value = (err as Error).message;\n } finally {\n isSaving.value = false;\n }\n}\n\nfunction handleClose(): void {\n if (!isSaving.value) {\n emit(\"close\");\n }\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n handleSave();\n }\n if (event.key === \"Escape\") {\n handleClose();\n }\n}\n</script>\n\n<template>\n <TplModal :visible=\"visible\" @close=\"handleClose\" @keydown=\"handleKeydown\">\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-busy=\"isSaving\"\n aria-labelledby=\"tpl-save-module-title\"\n class=\"tpl-scale-in tpl:mx-4 tpl:w-full tpl:max-w-sm tpl:rounded-[var(--tpl-radius-lg)] tpl:p-5\"\n style=\"\n background-color: var(--tpl-bg-elevated);\n box-shadow: var(--tpl-shadow-xl);\n \"\n >\n <h3\n id=\"tpl-save-module-title\"\n class=\"tpl:mb-4 tpl:text-sm tpl:font-semibold tpl:text-[var(--tpl-text)]\"\n >\n {{ cloudT.modules.saveAsModule }}\n </h3>\n\n <!-- Module name -->\n <div class=\"tpl:mb-3\">\n <label\n class=\"tpl:mb-1.5 tpl:block tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.modules.moduleName }}\n </label>\n <input\n v-model=\"moduleName\"\n type=\"text\"\n :placeholder=\"cloudT.modules.moduleNamePlaceholder\"\n class=\"tpl:h-9 tpl:w-full tpl:rounded-md tpl:border tpl:px-3 tpl:py-1 tpl:text-sm tpl:shadow-xs tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n :disabled=\"isSaving\"\n />\n </div>\n\n <!-- Block selection -->\n <div class=\"tpl:mb-3\">\n <label\n class=\"tpl:mb-1.5 tpl:block tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.modules.selectBlocks }}\n </label>\n <div\n class=\"tpl:max-h-40 tpl:space-y-1 tpl:overflow-y-auto tpl:rounded-md tpl:border tpl:p-2 tpl:border-[var(--tpl-border)]\"\n >\n <label\n v-for=\"(block, index) in topLevelBlocks\"\n :key=\"block.id\"\n class=\"tpl:flex tpl:cursor-pointer tpl:items-center tpl:gap-2 tpl:rounded-sm tpl:px-2 tpl:py-1.5 tpl:text-sm tpl:transition-colors tpl:duration-100\"\n :style=\"{\n color: 'var(--tpl-text)',\n backgroundColor: selectedBlockIds.has(block.id)\n ? 'var(--tpl-primary-light)'\n : 'transparent',\n }\"\n >\n <input\n type=\"checkbox\"\n :checked=\"selectedBlockIds.has(block.id)\"\n class=\"tpl:accent-[var(--tpl-primary)]\"\n :disabled=\"isSaving\"\n @change=\"toggleBlock(block.id)\"\n />\n {{ blockLabel(block, index) }}\n </label>\n </div>\n </div>\n\n <!-- Error message -->\n <p\n v-if=\"error\"\n role=\"alert\"\n class=\"tpl:mb-3 tpl:text-xs tpl:text-[var(--tpl-danger)]\"\n >\n {{ error }}\n </p>\n\n <!-- Actions -->\n <div class=\"tpl:flex tpl:justify-end tpl:gap-2\">\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:border-[var(--tpl-border)] tpl:text-[var(--tpl-text)] tpl:bg-[var(--tpl-bg)]\"\n :disabled=\"isSaving\"\n :class=\"{\n 'tpl:cursor-not-allowed tpl:opacity-50': isSaving,\n }\"\n @click=\"handleClose\"\n >\n {{ cloudT.modules.cancel }}\n </button>\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:hover:opacity-90 tpl:disabled:cursor-not-allowed tpl:disabled:opacity-50 tpl:bg-[var(--tpl-primary)] tpl:text-[var(--tpl-bg)]\"\n :disabled=\"!canSave\"\n @click=\"handleSave\"\n >\n <span v-if=\"isSaving\" class=\"tpl:flex tpl:items-center tpl:gap-1.5\">\n <LoaderCircle\n class=\"tpl:animate-spin\"\n :size=\"12\"\n :stroke-width=\"2\"\n />\n {{ cloudT.modules.saving }}\n </span>\n <span v-else>\n {{ cloudT.modules.save }}\n </span>\n </button>\n </div>\n </div>\n </TplModal>\n</template>\n","<script setup lang=\"ts\">\nimport TplModal from \"./TplModal.vue\";\nimport { useI18n } from \"../../composables\";\nimport { useCloudI18nStrict } from \"../../composables\";\nimport {\n EDITOR_KEY,\n SAVED_MODULES_HEADLESS_KEY,\n requireInject,\n} from \"../../keys\";\nimport type { Block } from \"@templatical/types\";\nimport { LoaderCircle } from \"@lucide/vue\";\nimport { computed, ref, watch } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n preSelectedBlockId: string | null;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n (e: \"saved\"): void;\n}>();\n\nconst { t } = useI18n();\nconst { t: cloudT } = useCloudI18nStrict();\nconst editor = requireInject(EDITOR_KEY, \"SaveModuleDialog\");\nconst savedModules = requireInject(\n SAVED_MODULES_HEADLESS_KEY,\n \"SaveModuleDialog\",\n);\n\nconst moduleName = ref(\"\");\nconst selectedBlockIds = ref<Set<string>>(new Set());\nconst isSaving = ref(false);\nconst error = ref<string | null>(null);\n\nconst topLevelBlocks = computed(() => editor.content.value.blocks);\n\nfunction blockLabel(block: Block, index: number): string {\n const typeKey = block.type as keyof typeof t.blocks;\n const label = t.blocks[typeKey] ?? block.type;\n return `${label} ${index + 1}`;\n}\n\nwatch(\n () => props.visible,\n (visible) => {\n if (visible) {\n moduleName.value = \"\";\n error.value = null;\n selectedBlockIds.value = new Set(\n props.preSelectedBlockId ? [props.preSelectedBlockId] : [],\n );\n }\n },\n);\n\nfunction toggleBlock(blockId: string): void {\n const newSet = new Set(selectedBlockIds.value);\n if (newSet.has(blockId)) {\n newSet.delete(blockId);\n } else {\n newSet.add(blockId);\n }\n selectedBlockIds.value = newSet;\n}\n\nconst canSave = computed(\n () =>\n moduleName.value.trim().length > 0 &&\n selectedBlockIds.value.size > 0 &&\n !isSaving.value,\n);\n\nasync function handleSave(): Promise<void> {\n if (!canSave.value) return;\n\n isSaving.value = true;\n error.value = null;\n\n try {\n const selectedBlocks = topLevelBlocks.value.filter((b) =>\n selectedBlockIds.value.has(b.id),\n );\n await savedModules.createModule(moduleName.value.trim(), selectedBlocks);\n emit(\"saved\");\n emit(\"close\");\n } catch (err) {\n error.value = (err as Error).message;\n } finally {\n isSaving.value = false;\n }\n}\n\nfunction handleClose(): void {\n if (!isSaving.value) {\n emit(\"close\");\n }\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n handleSave();\n }\n if (event.key === \"Escape\") {\n handleClose();\n }\n}\n</script>\n\n<template>\n <TplModal :visible=\"visible\" @close=\"handleClose\" @keydown=\"handleKeydown\">\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-busy=\"isSaving\"\n aria-labelledby=\"tpl-save-module-title\"\n class=\"tpl-scale-in tpl:mx-4 tpl:w-full tpl:max-w-sm tpl:rounded-[var(--tpl-radius-lg)] tpl:p-5\"\n style=\"\n background-color: var(--tpl-bg-elevated);\n box-shadow: var(--tpl-shadow-xl);\n \"\n >\n <h3\n id=\"tpl-save-module-title\"\n class=\"tpl:mb-4 tpl:text-sm tpl:font-semibold tpl:text-[var(--tpl-text)]\"\n >\n {{ cloudT.modules.saveAsModule }}\n </h3>\n\n <!-- Module name -->\n <div class=\"tpl:mb-3\">\n <label\n class=\"tpl:mb-1.5 tpl:block tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.modules.moduleName }}\n </label>\n <input\n v-model=\"moduleName\"\n type=\"text\"\n :placeholder=\"cloudT.modules.moduleNamePlaceholder\"\n class=\"tpl:h-9 tpl:w-full tpl:rounded-md tpl:border tpl:px-3 tpl:py-1 tpl:text-sm tpl:shadow-xs tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n :disabled=\"isSaving\"\n />\n </div>\n\n <!-- Block selection -->\n <div class=\"tpl:mb-3\">\n <label\n class=\"tpl:mb-1.5 tpl:block tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.modules.selectBlocks }}\n </label>\n <div\n class=\"tpl:max-h-40 tpl:space-y-1 tpl:overflow-y-auto tpl:rounded-md tpl:border tpl:p-2 tpl:border-[var(--tpl-border)]\"\n >\n <label\n v-for=\"(block, index) in topLevelBlocks\"\n :key=\"block.id\"\n class=\"tpl:flex tpl:cursor-pointer tpl:items-center tpl:gap-2 tpl:rounded-sm tpl:px-2 tpl:py-1.5 tpl:text-sm tpl:transition-colors tpl:duration-100\"\n :style=\"{\n color: 'var(--tpl-text)',\n backgroundColor: selectedBlockIds.has(block.id)\n ? 'var(--tpl-primary-light)'\n : 'transparent',\n }\"\n >\n <input\n type=\"checkbox\"\n :checked=\"selectedBlockIds.has(block.id)\"\n class=\"tpl:accent-[var(--tpl-primary)]\"\n :disabled=\"isSaving\"\n @change=\"toggleBlock(block.id)\"\n />\n {{ blockLabel(block, index) }}\n </label>\n </div>\n </div>\n\n <!-- Error message -->\n <p\n v-if=\"error\"\n role=\"alert\"\n class=\"tpl:mb-3 tpl:text-xs tpl:text-[var(--tpl-danger)]\"\n >\n {{ error }}\n </p>\n\n <!-- Actions -->\n <div class=\"tpl:flex tpl:justify-end tpl:gap-2\">\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:border-[var(--tpl-border)] tpl:text-[var(--tpl-text)] tpl:bg-[var(--tpl-bg)]\"\n :disabled=\"isSaving\"\n :class=\"{\n 'tpl:cursor-not-allowed tpl:opacity-50': isSaving,\n }\"\n @click=\"handleClose\"\n >\n {{ cloudT.modules.cancel }}\n </button>\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:hover:opacity-90 tpl:disabled:cursor-not-allowed tpl:disabled:opacity-50 tpl:bg-[var(--tpl-primary)] tpl:text-[var(--tpl-bg)]\"\n :disabled=\"!canSave\"\n @click=\"handleSave\"\n >\n <span v-if=\"isSaving\" class=\"tpl:flex tpl:items-center tpl:gap-1.5\">\n <LoaderCircle\n class=\"tpl:animate-spin\"\n :size=\"12\"\n :stroke-width=\"2\"\n />\n {{ cloudT.modules.saving }}\n </span>\n <span v-else>\n {{ cloudT.modules.save }}\n </span>\n </button>\n </div>\n </div>\n </TplModal>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;EAaA,IAAM,IAAQ,GAKR,IAAO,GAKP,EAAE,SAAM,IAAS,EACjB,EAAE,GAAG,MAAW,GAAoB,EACpC,IAAS,EAAc,IAAY,mBAAmB,EACtD,IAAe,EACnB,GACA,mBACD,EAEK,IAAa,EAAI,GAAG,EACpB,IAAmB,kBAAiB,IAAI,KAAK,CAAC,EAC9C,IAAW,EAAI,GAAM,EACrB,IAAQ,EAAmB,KAAK,EAEhC,IAAiB,QAAe,EAAO,QAAQ,MAAM,OAAO;EAElE,SAAS,EAAW,GAAc,GAAuB;AAGvD,UAAO,GADO,EAAE,OADA,EAAM,SACa,EAAM,KACzB,GAAG,IAAQ;;AAG7B,UACQ,EAAM,UACX,MAAY;AACX,GAAI,MACF,EAAW,QAAQ,IACnB,EAAM,QAAQ,MACd,EAAiB,QAAQ,IAAI,IAC3B,EAAM,qBAAqB,CAAC,EAAM,mBAAmB,GAAG,EAAE,CAC3D;IAGN;EAED,SAAS,GAAY,GAAuB;GAC1C,IAAM,IAAS,IAAI,IAAI,EAAiB,MAAM;AAM9C,GALI,EAAO,IAAI,EAAQ,GACrB,EAAO,OAAO,EAAQ,GAEtB,EAAO,IAAI,EAAQ,EAErB,EAAiB,QAAQ;;EAG3B,IAAM,IAAU,QAEZ,EAAW,MAAM,MAAM,CAAC,SAAS,KACjC,EAAiB,MAAM,OAAO,KAC9B,CAAC,EAAS,MACb;EAED,eAAe,IAA4B;AACpC,SAAQ,OAGb;IADA,EAAS,QAAQ,IACjB,EAAM,QAAQ;AAEd,QAAI;KACF,IAAM,IAAiB,EAAe,MAAM,QAAQ,MAClD,EAAiB,MAAM,IAAI,EAAE,GAAG,CACjC;AAGD,KAFA,MAAM,EAAa,aAAa,EAAW,MAAM,MAAM,EAAE,EAAe,EACxE,EAAK,QAAQ,EACb,EAAK,QAAQ;aACN,GAAK;AACZ,OAAM,QAAS,EAAc;cACrB;AACR,OAAS,QAAQ;;;;EAIrB,SAAS,IAAoB;AAC3B,GAAK,EAAS,SACZ,EAAK,QAAQ;;EAIjB,SAAS,GAAc,GAA4B;AAKjD,GAJI,EAAM,QAAQ,WAAW,CAAC,EAAM,aAClC,EAAM,gBAAgB,EACtB,GAAY,GAEV,EAAM,QAAQ,YAChB,GAAa;;yBAMf,EA8GW,GAAA;GA9GA,SAAS,EAAA;GAAU,SAAO;GAAc,WAAS;;oBA6GpD,CA5GN,EA4GM,OAAA;IA3GJ,MAAK;IACL,cAAW;IACV,aAAW,EAAA;IACZ,mBAAgB;IAChB,OAAM;IACN,OAAA;KAAA,oBAAA;KAAA,cAAA;KAGC;;IAED,EAKK,MALL,GAKK,EADA,EAAA,EAAM,CAAC,QAAQ,aAAY,EAAA,EAAA;IAIhC,EAaM,OAbN,GAaM,CAZJ,EAIQ,SAJR,GAIQ,EADH,EAAA,EAAM,CAAC,QAAQ,WAAU,EAAA,EAAA,EAAA,EAE9B,EAME,SAAA;8CALmB,QAAA;KACnB,MAAK;KACJ,aAAa,EAAA,EAAM,CAAC,QAAQ;KAC7B,OAAM;KACL,UAAU,EAAA;yBAJF,EAAA,MAAU,CAAA,CAAA,CAAA,CAAA;IASvB,EA8BM,OA9BN,GA8BM,CA7BJ,EAIQ,SAJR,GAIQ,EADH,EAAA,EAAM,CAAC,QAAQ,aAAY,EAAA,EAAA,EAEhC,EAuBM,OAvBN,GAuBM,EAAA,EAAA,GAAA,EApBJ,EAmBQ,GAAA,MAAA,EAlBmB,EAAA,QAAjB,GAAO,YADjB,EAmBQ,SAAA;KAjBL,KAAK,EAAM;KACZ,OAAM;KACL,OAAK,EAAA;;uBAA2E,EAAA,MAAiB,IAAI,EAAM,GAAE,GAAA,6BAAA;;QAO9G,EAME,SAAA;KALA,MAAK;KACJ,SAAS,EAAA,MAAiB,IAAI,EAAM,GAAE;KACvC,OAAM;KACL,UAAU,EAAA;KACV,WAAM,MAAE,GAAY,EAAM,GAAE;uBAC7B,MACF,EAAG,EAAW,GAAO,EAAK,CAAA,EAAA,EAAA,CAAA,EAAA,EAAA;IAOxB,EAAA,SAAA,GAAA,EADR,EAMI,KANJ,GAMI,EADC,EAAA,MAAK,EAAA,EAAA,IAAA,GAAA,IAAA,GAAA;IAIV,EA8BM,OA9BN,GA8BM,CA7BJ,EAUS,UAAA;KATP,MAAK;KACL,OAAK,EAAA,CAAC,mOAAiO,EAAA,yCAExK,EAAA,OAAA,CAAA,CAAA;KAD9D,UAAU,EAAA;KAIV,SAAO;SAEL,EAAA,EAAM,CAAC,QAAQ,OAAM,EAAA,IAAA,EAAA,EAE1B,EAiBS,UAAA;KAhBP,MAAK;KACL,OAAM;KACL,UAAQ,CAAG,EAAA;KACX,SAAO;QAEI,EAAA,SAAA,GAAA,EAAZ,EAOO,QAPP,IAOO,CANL,EAIE,EAAA,EAAA,EAAA;KAHA,OAAM;KACL,MAAM;KACN,gBAAc;UACf,MACF,EAAG,EAAA,EAAM,CAAC,QAAQ,OAAM,EAAA,EAAA,CAAA,CAAA,KAAA,GAAA,EAE1B,EAEO,QAAA,GAAA,EADF,EAAA,EAAM,CAAC,QAAQ,KAAI,EAAA,EAAA,EAAA,EAAA,GAAA,EAAA,CAAA,CAAA"}
@@ -1,7 +1,7 @@
1
1
  import { E as e, J as t, N as n, S as r, _ as i, at as a, b as o, ct as s, d as c, f as l, g as u, h as d, lt as f, m as p, st as m, y as h } from "./draggable-Bcb86AsV.js";
2
- import { Mt as g, Xt as _, Zt as v, ht as y, q as b } from "./features-DV4PhoBs.js";
3
- import { J as x, V as S, b as C, z as w } from "./icons-LJ8U8lWI.js";
4
- import { n as T, t as E } from "./RichTextEditorContent-9vq4MRDp.js";
2
+ import { Mt as g, Xt as _, Zt as v, ht as y, q as b } from "./features-BnG-dhzy.js";
3
+ import { J as x, V as S, b as C, z as w } from "./icons-B_185qj_.js";
4
+ import { n as T, t as E } from "./RichTextEditorContent-CmOwLOeY.js";
5
5
  //#region src/components/blocks/TitleEditor.vue?vue&type=script&setup=true&lang.ts
6
6
  var ee = { class: "tpl-text-editor-wrapper tpl:relative" }, D = ["data-tpl-theme", "aria-label"], O = ["aria-label", "title"], k = ["aria-label", "title"], A = ["aria-label", "title"], j = {
7
7
  key: 0,
@@ -17,17 +17,17 @@ var ee = { class: "tpl-text-editor-wrapper tpl:relative" }, D = ["data-tpl-theme
17
17
  },
18
18
  emits: ["done"],
19
19
  setup(r, { emit: P }) {
20
- let F = r, I = P, L = e(_, null), R = e(v, null), { t: z } = g(), { editor: B, EditorContent: V, isLoading: H, initError: U, retry: W, showLinkDialog: G, linkUrl: K, linkDialogRef: q, mergeTagEnabled: J, openLinkDialog: Y, insertLink: X, removeLink: Z, closeLinkDialog: Q, handleLinkKeydown: te, handleAddMergeTag: $ } = b({
20
+ let F = r, I = P, L = e(_, null), R = e(v, null), { t: z } = g(), { editor: B, EditorContent: V, isLoading: H, initError: U, retry: W, showLinkDialog: G, linkUrl: K, linkDialogRef: q, canRequestMergeTag: J, openLinkDialog: Y, insertLink: X, removeLink: Z, closeLinkDialog: Q, handleLinkKeydown: te, handleAddMergeTag: $ } = b({
21
21
  blockId: () => F.block.id,
22
22
  blockContent: () => F.block.content,
23
23
  onDone: () => I("done"),
24
24
  editorName: "TitleEditor",
25
25
  async loadExtensions({ mergeTags: e, syntax: t, triggerChar: n, autocompleteEnabled: r, suggestionEmptyText: i }) {
26
26
  let [{ Editor: a, EditorContent: o }, { default: s }, { default: c }, { MergeTagNode: l, MergeTagSuggestion: u, LogicMergeTagNode: d }] = await Promise.all([
27
- import("./tiptap-kGWe8qnA.js").then((e) => e.i),
28
- import("./tiptap-kGWe8qnA.js").then((e) => e.a),
29
- import("./tiptap-kGWe8qnA.js").then((e) => e.u),
30
- import("./extensions-C6oPJqKD.js")
27
+ import("./tiptap-CPAwPMop.js").then((e) => e.i),
28
+ import("./tiptap-CPAwPMop.js").then((e) => e.a),
29
+ import("./tiptap-CPAwPMop.js").then((e) => e.u),
30
+ import("./extensions-D13MqxlW.js")
31
31
  ]);
32
32
  return {
33
33
  TiptapEditor: a,
@@ -168,4 +168,4 @@ var ee = { class: "tpl-text-editor-wrapper tpl:relative" }, D = ["data-tpl-theme
168
168
  //#endregion
169
169
  export { P as default };
170
170
 
171
- //# sourceMappingURL=TitleEditor-BiiEtH7x.js.map
171
+ //# sourceMappingURL=TitleEditor-CvZe3neh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TitleEditor-CvZe3neh.js","names":[],"sources":["../../../src/components/blocks/TitleEditor.vue","../../../src/components/blocks/TitleEditor.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useI18n } from \"../../composables\";\nimport { useRichTextEditor } from \"../../composables/useRichTextEditor\";\nimport type { TitleBlock as TitleBlockType } from \"@templatical/types\";\nimport { Bold, Italic, Link, LoaderCircle, ScanLine } from \"@lucide/vue\";\nimport { inject } from \"vue\";\nimport { THEME_STYLES_KEY, UI_THEME_KEY } from \"../../keys\";\nimport RichTextLinkDialog from \"./RichTextLinkDialog.vue\";\nimport RichTextEditorContent from \"./RichTextEditorContent.vue\";\n\nconst props = defineProps<{\n block: TitleBlockType;\n toolbarPosition: { top: number; left: number };\n}>();\n\nconst emit = defineEmits<{\n (e: \"done\"): void;\n}>();\n\nconst themeStyles = inject(THEME_STYLES_KEY, null);\nconst tplUiTheme = inject(UI_THEME_KEY, null);\n\nconst { t } = useI18n();\n\nconst {\n editor,\n EditorContent,\n isLoading,\n initError,\n retry,\n showLinkDialog,\n linkUrl,\n linkDialogRef,\n canRequestMergeTag,\n openLinkDialog,\n insertLink,\n removeLink,\n closeLinkDialog,\n handleLinkKeydown,\n handleAddMergeTag,\n} = useRichTextEditor({\n blockId: () => props.block.id,\n blockContent: () => props.block.content,\n onDone: () => emit(\"done\"),\n editorName: \"TitleEditor\",\n async loadExtensions({\n mergeTags,\n syntax,\n triggerChar,\n autocompleteEnabled,\n suggestionEmptyText,\n }) {\n const [\n { Editor: TiptapEditor, EditorContent: EC },\n { default: StarterKit },\n { default: LinkExt },\n { MergeTagNode, MergeTagSuggestion, LogicMergeTagNode },\n ] = await Promise.all([\n import(\"@tiptap/vue-3\"),\n import(\"@tiptap/starter-kit\"),\n import(\"@tiptap/extension-link\"),\n import(\"../../extensions\"),\n ]);\n\n return {\n TiptapEditor,\n EC,\n extensions: [\n StarterKit.configure({\n heading: false,\n codeBlock: false,\n blockquote: false,\n horizontalRule: false,\n bulletList: false,\n orderedList: false,\n listItem: false,\n strike: false,\n }),\n LinkExt.configure({\n openOnClick: false,\n HTMLAttributes: {\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n },\n }),\n MergeTagNode.configure({ mergeTags, syntax }),\n LogicMergeTagNode.configure({ syntax }),\n ...(autocompleteEnabled && triggerChar && mergeTags.length > 0\n ? [\n MergeTagSuggestion.configure({\n mergeTags,\n char: triggerChar,\n emptyText: suggestionEmptyText,\n }),\n ]\n : []),\n ],\n };\n },\n});\n</script>\n\n<template>\n <div class=\"tpl-text-editor-wrapper tpl:relative\">\n <Teleport to=\"body\">\n <div\n :data-tpl-theme=\"tplUiTheme\"\n role=\"toolbar\"\n :aria-label=\"t.titleEditor.toolbar\"\n class=\"tpl tpl-text-toolbar tpl:fixed tpl:z-popover tpl:flex tpl:items-center tpl:gap-1 tpl:rounded-lg tpl:border tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:px-3 tpl:py-2 tpl:shadow-lg\"\n :style=\"{\n ...themeStyles,\n top: `${toolbarPosition.top}px`,\n left: `${toolbarPosition.left}px`,\n transform: 'translateY(-100%)',\n }\"\n >\n <template v-if=\"!isLoading && editor\">\n <!-- Bold -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('bold'),\n }\"\n :aria-label=\"t.titleEditor.bold\"\n :title=\"t.titleEditor.bold\"\n @click=\"editor?.chain().focus().toggleBold().run()\"\n >\n <Bold :size=\"16\" :stroke-width=\"2.5\" />\n </button>\n <!-- Italic -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('italic'),\n }\"\n :aria-label=\"t.titleEditor.italic\"\n :title=\"t.titleEditor.italic\"\n @click=\"editor?.chain().focus().toggleItalic().run()\"\n >\n <Italic :size=\"16\" :stroke-width=\"2\" />\n </button>\n <span\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n aria-hidden=\"true\"\n ></span>\n <!-- Link -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('link'),\n }\"\n :aria-label=\"t.titleEditor.addLink\"\n :title=\"t.titleEditor.addLink\"\n @click=\"openLinkDialog\"\n >\n <Link :size=\"16\" :stroke-width=\"2\" />\n </button>\n <!-- Add Merge Tag -->\n <span\n v-if=\"canRequestMergeTag\"\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n ></span>\n <button\n v-if=\"canRequestMergeTag\"\n type=\"button\"\n class=\"tpl:flex tpl:h-8 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-2.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)] tpl:transition-all tpl:duration-150 tpl:hover:bg-[var(--tpl-bg-active)]\"\n :aria-label=\"t.mergeTag.add\"\n :title=\"t.mergeTag.add\"\n @click=\"handleAddMergeTag\"\n >\n <ScanLine :size=\"16\" :stroke-width=\"2\" />\n {{ t.mergeTag.add }}\n </button>\n </template>\n <template v-else>\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-2 tpl:px-2 tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n <LoaderCircle class=\"tpl-spinner\" :size=\"14\" :stroke-width=\"2\" />\n {{ t.errors.editorLoading }}\n </div>\n </template>\n </div>\n </Teleport>\n\n <RichTextEditorContent\n :editor=\"editor\"\n :editor-content=\"EditorContent\"\n :is-loading=\"isLoading\"\n :init-error=\"initError\"\n @retry=\"retry\"\n />\n\n <RichTextLinkDialog\n :visible=\"showLinkDialog\"\n :is-editing-link=\"editor?.isActive('link') ?? false\"\n v-model:dialog-ref=\"linkDialogRef\"\n v-model:link-url=\"linkUrl\"\n @close=\"closeLinkDialog\"\n @insert=\"insertLink\"\n @remove=\"removeLink\"\n @keydown=\"handleLinkKeydown\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../../composables\";\nimport { useRichTextEditor } from \"../../composables/useRichTextEditor\";\nimport type { TitleBlock as TitleBlockType } from \"@templatical/types\";\nimport { Bold, Italic, Link, LoaderCircle, ScanLine } from \"@lucide/vue\";\nimport { inject } from \"vue\";\nimport { THEME_STYLES_KEY, UI_THEME_KEY } from \"../../keys\";\nimport RichTextLinkDialog from \"./RichTextLinkDialog.vue\";\nimport RichTextEditorContent from \"./RichTextEditorContent.vue\";\n\nconst props = defineProps<{\n block: TitleBlockType;\n toolbarPosition: { top: number; left: number };\n}>();\n\nconst emit = defineEmits<{\n (e: \"done\"): void;\n}>();\n\nconst themeStyles = inject(THEME_STYLES_KEY, null);\nconst tplUiTheme = inject(UI_THEME_KEY, null);\n\nconst { t } = useI18n();\n\nconst {\n editor,\n EditorContent,\n isLoading,\n initError,\n retry,\n showLinkDialog,\n linkUrl,\n linkDialogRef,\n canRequestMergeTag,\n openLinkDialog,\n insertLink,\n removeLink,\n closeLinkDialog,\n handleLinkKeydown,\n handleAddMergeTag,\n} = useRichTextEditor({\n blockId: () => props.block.id,\n blockContent: () => props.block.content,\n onDone: () => emit(\"done\"),\n editorName: \"TitleEditor\",\n async loadExtensions({\n mergeTags,\n syntax,\n triggerChar,\n autocompleteEnabled,\n suggestionEmptyText,\n }) {\n const [\n { Editor: TiptapEditor, EditorContent: EC },\n { default: StarterKit },\n { default: LinkExt },\n { MergeTagNode, MergeTagSuggestion, LogicMergeTagNode },\n ] = await Promise.all([\n import(\"@tiptap/vue-3\"),\n import(\"@tiptap/starter-kit\"),\n import(\"@tiptap/extension-link\"),\n import(\"../../extensions\"),\n ]);\n\n return {\n TiptapEditor,\n EC,\n extensions: [\n StarterKit.configure({\n heading: false,\n codeBlock: false,\n blockquote: false,\n horizontalRule: false,\n bulletList: false,\n orderedList: false,\n listItem: false,\n strike: false,\n }),\n LinkExt.configure({\n openOnClick: false,\n HTMLAttributes: {\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n },\n }),\n MergeTagNode.configure({ mergeTags, syntax }),\n LogicMergeTagNode.configure({ syntax }),\n ...(autocompleteEnabled && triggerChar && mergeTags.length > 0\n ? [\n MergeTagSuggestion.configure({\n mergeTags,\n char: triggerChar,\n emptyText: suggestionEmptyText,\n }),\n ]\n : []),\n ],\n };\n },\n});\n</script>\n\n<template>\n <div class=\"tpl-text-editor-wrapper tpl:relative\">\n <Teleport to=\"body\">\n <div\n :data-tpl-theme=\"tplUiTheme\"\n role=\"toolbar\"\n :aria-label=\"t.titleEditor.toolbar\"\n class=\"tpl tpl-text-toolbar tpl:fixed tpl:z-popover tpl:flex tpl:items-center tpl:gap-1 tpl:rounded-lg tpl:border tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:px-3 tpl:py-2 tpl:shadow-lg\"\n :style=\"{\n ...themeStyles,\n top: `${toolbarPosition.top}px`,\n left: `${toolbarPosition.left}px`,\n transform: 'translateY(-100%)',\n }\"\n >\n <template v-if=\"!isLoading && editor\">\n <!-- Bold -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('bold'),\n }\"\n :aria-label=\"t.titleEditor.bold\"\n :title=\"t.titleEditor.bold\"\n @click=\"editor?.chain().focus().toggleBold().run()\"\n >\n <Bold :size=\"16\" :stroke-width=\"2.5\" />\n </button>\n <!-- Italic -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('italic'),\n }\"\n :aria-label=\"t.titleEditor.italic\"\n :title=\"t.titleEditor.italic\"\n @click=\"editor?.chain().focus().toggleItalic().run()\"\n >\n <Italic :size=\"16\" :stroke-width=\"2\" />\n </button>\n <span\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n aria-hidden=\"true\"\n ></span>\n <!-- Link -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('link'),\n }\"\n :aria-label=\"t.titleEditor.addLink\"\n :title=\"t.titleEditor.addLink\"\n @click=\"openLinkDialog\"\n >\n <Link :size=\"16\" :stroke-width=\"2\" />\n </button>\n <!-- Add Merge Tag -->\n <span\n v-if=\"canRequestMergeTag\"\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n ></span>\n <button\n v-if=\"canRequestMergeTag\"\n type=\"button\"\n class=\"tpl:flex tpl:h-8 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-2.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)] tpl:transition-all tpl:duration-150 tpl:hover:bg-[var(--tpl-bg-active)]\"\n :aria-label=\"t.mergeTag.add\"\n :title=\"t.mergeTag.add\"\n @click=\"handleAddMergeTag\"\n >\n <ScanLine :size=\"16\" :stroke-width=\"2\" />\n {{ t.mergeTag.add }}\n </button>\n </template>\n <template v-else>\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-2 tpl:px-2 tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n <LoaderCircle class=\"tpl-spinner\" :size=\"14\" :stroke-width=\"2\" />\n {{ t.errors.editorLoading }}\n </div>\n </template>\n </div>\n </Teleport>\n\n <RichTextEditorContent\n :editor=\"editor\"\n :editor-content=\"EditorContent\"\n :is-loading=\"isLoading\"\n :init-error=\"initError\"\n @retry=\"retry\"\n />\n\n <RichTextLinkDialog\n :visible=\"showLinkDialog\"\n :is-editing-link=\"editor?.isActive('link') ?? false\"\n v-model:dialog-ref=\"linkDialogRef\"\n v-model:link-url=\"linkUrl\"\n @close=\"closeLinkDialog\"\n @insert=\"insertLink\"\n @remove=\"removeLink\"\n @keydown=\"handleLinkKeydown\"\n />\n </div>\n</template>\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { St as e, _t as t, lt as n, ot as r, pt as i } from "./features-DV4PhoBs.js";
2
- import { D as a, E as o, H as s, K as c, P as l, i as u, j as d, w as f } from "./icons-LJ8U8lWI.js";
1
+ import { St as e, _t as t, lt as n, ot as r, pt as i } from "./features-BnG-dhzy.js";
2
+ import { D as a, E as o, H as s, K as c, P as l, i as u, j as d, w as f } from "./icons-B_185qj_.js";
3
3
  //#region src/utils/blockTypeIcons.ts
4
4
  var p = {
5
5
  section: c,
@@ -19,4 +19,4 @@ var p = {
19
19
  //#endregion
20
20
  export { p as t };
21
21
 
22
- //# sourceMappingURL=blockTypeIcons-DWhn7E7O.js.map
22
+ //# sourceMappingURL=blockTypeIcons-Bs9B-yft.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"blockTypeIcons-DWhn7E7O.js","names":[],"sources":["../../../src/utils/blockTypeIcons.ts"],"sourcesContent":["import {\n Code,\n Columns3,\n Heading,\n Image,\n Minus,\n MoveVertical,\n Navigation,\n Pilcrow,\n Play,\n RectangleHorizontal,\n Share2,\n Table,\n Timer,\n} from \"@lucide/vue\";\nimport type { Component } from \"vue\";\n\nexport const blockTypeIcons: Record<string, Component> = {\n section: Columns3,\n title: Heading,\n paragraph: Pilcrow,\n image: Image,\n button: RectangleHorizontal,\n divider: Minus,\n video: Play,\n social: Share2,\n menu: Navigation,\n table: Table,\n spacer: MoveVertical,\n countdown: Timer,\n html: Code,\n};\n"],"mappings":";;;AAiBA,IAAa,IAA4C;CACvD,SAAS;CACT,OAAO;CACP,WAAW;CACX,OAAO;CACP,QAAQ;CACR,SAAS;CACT,OAAO;CACP,QAAQ;CACR,MAAM;CACN,OAAO;CACP,QAAQ;CACR,WAAW;CACX,MAAM;CACP"}
1
+ {"version":3,"file":"blockTypeIcons-Bs9B-yft.js","names":[],"sources":["../../../src/utils/blockTypeIcons.ts"],"sourcesContent":["import {\n Code,\n Columns3,\n Heading,\n Image,\n Minus,\n MoveVertical,\n Navigation,\n Pilcrow,\n Play,\n RectangleHorizontal,\n Share2,\n Table,\n Timer,\n} from \"@lucide/vue\";\nimport type { Component } from \"vue\";\n\nexport const blockTypeIcons: Record<string, Component> = {\n section: Columns3,\n title: Heading,\n paragraph: Pilcrow,\n image: Image,\n button: RectangleHorizontal,\n divider: Minus,\n video: Play,\n social: Share2,\n menu: Navigation,\n table: Table,\n spacer: MoveVertical,\n countdown: Timer,\n html: Code,\n};\n"],"mappings":";;;AAiBA,IAAa,IAA4C;CACvD,SAAS;CACT,OAAO;CACP,WAAW;CACX,OAAO;CACP,QAAQ;CACR,SAAS;CACT,OAAO;CACP,QAAQ;CACR,MAAM;CACN,OAAO;CACP,QAAQ;CACR,WAAW;CACX,MAAM;CACP"}
@@ -143,7 +143,7 @@ var e = {
143
143
  openInNewTab: "In neuem Tab öffnen",
144
144
  placeholderUrl: "Platzhalterbild",
145
145
  placeholderUrlPlaceholder: "https://... (nur zur Gestaltung)",
146
- placeholderUrlTooltip: "Da die Bild-URL einen Platzhalter verwendet, können Sie hier ein echtes Bild angeben, um das Layout während der Gestaltung in der Vorschau anzuzeigen. Dies wird nicht in die endgültige Ausgabe aufgenommen.",
146
+ placeholderUrlTooltip: "Da die Bild-URL ein Merge-Tag verwendet, können Sie hier ein echtes Bild angeben, um das Layout während der Gestaltung in der Vorschau anzuzeigen. Dies wird nicht in die endgültige Ausgabe aufgenommen.",
147
147
  clickToAdd: "Klicken Sie, um eine Bild-URL hinzuzufügen",
148
148
  browseMedia: "Medien durchsuchen"
149
149
  },
@@ -163,7 +163,7 @@ var e = {
163
163
  fullWidth: "Volle Breite",
164
164
  placeholderUrl: "Platzhalter-Thumbnail",
165
165
  placeholderUrlPlaceholder: "https://... (nur zur Gestaltung)",
166
- placeholderUrlTooltip: "Da die Video-URL einen Platzhalter verwendet, können Sie hier ein echtes Thumbnail angeben, um das Layout während der Gestaltung in der Vorschau anzuzeigen. Dies wird nicht in die endgültige Ausgabe aufgenommen.",
166
+ placeholderUrlTooltip: "Da die Video-URL ein Merge-Tag verwendet, können Sie hier ein echtes Thumbnail angeben, um das Layout während der Gestaltung in der Vorschau anzuzeigen. Dies wird nicht in die endgültige Ausgabe aufgenommen.",
167
167
  addVideo: "Video-URL hinzufügen"
168
168
  },
169
169
  button: {
@@ -353,7 +353,7 @@ var e = {
353
353
  fontFamily: "Schriftfamilie",
354
354
  preheaderText: "Preheader-Text",
355
355
  preheaderTextPlaceholder: "Vorschautext, der nach der Betreffzeile im Posteingang angezeigt wird...",
356
- preheaderTextHint: "Dieser Text erscheint nach der Betreffzeile in der E-Mail-Vorschau. Unterstützt Platzhalter.",
356
+ preheaderTextHint: "Dieser Text erscheint nach der Betreffzeile in der E-Mail-Vorschau. Unterstützt Merge-Tags.",
357
357
  tips: "Tipps",
358
358
  tip1: "600px ist die Standardbreite für E-Mail-Vorlagen",
359
359
  tip2: "Verwenden Sie websichere Schriften für beste Kompatibilität",
@@ -502,4 +502,4 @@ var e = {
502
502
  //#endregion
503
503
  export { e as default };
504
504
 
505
- //# sourceMappingURL=de-DEg-6TsA.js.map
505
+ //# sourceMappingURL=de-BSWt7lYu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"de-BSWt7lYu.js","names":[],"sources":["../../../src/i18n/locales/de.ts"],"sourcesContent":["import type en from \"./en\";\n\nconst de: typeof en = {\n // Footer (OSS only)\n footer: {\n poweredBy: \"Erstellt mit\",\n openSource: \"Open Source\",\n },\n\n // History (undo/redo)\n history: {\n undo: \"Rückgängig\",\n redo: \"Wiederholen\",\n collabWarning:\n \"Rückgängig machen kann die Änderungen anderer Mitarbeiter beeinflussen\",\n },\n\n // Viewport toggle\n viewport: {\n label: \"Ansichtsgröße\",\n desktop: \"Desktop\",\n tablet: \"Tablet\",\n mobile: \"Mobil\",\n },\n\n // Dark mode preview\n darkMode: {\n enable: \"Dunkelmodus-Vorschau\",\n disable: \"Hellmodus-Vorschau\",\n },\n\n // Preview mode\n previewMode: {\n enable: \"Vorschaumodus\",\n disable: \"Vorschau beenden\",\n },\n\n // Sidebar - Block types\n blocks: {\n section: \"Abschnitt\",\n image: \"Bild\",\n title: \"Titel\",\n paragraph: \"Absatz\",\n button: \"Schaltfläche\",\n divider: \"Trennlinie\",\n video: \"Video\",\n social: \"Sozial\",\n spacer: \"Abstand\",\n html: \"HTML\",\n menu: \"Menü\",\n table: \"Tabelle\",\n countdown: \"Countdown\",\n },\n\n // Right sidebar\n sidebar: {\n content: \"Inhalt\",\n settings: \"Einstellungen\",\n noSelection: \"Kein Element ausgewählt\",\n noSelectionHint:\n \"Wählen Sie einen Block auf der Leinwand aus, um ihn zu bearbeiten\",\n },\n\n // Toolbar - Common\n toolbar: {\n duplicate: \"Duplizieren\",\n delete: \"Löschen\",\n },\n\n // Title editor toolbar\n titleEditor: {\n toolbar: \"Titelformatierung\",\n bold: \"Fett (Strg+B)\",\n italic: \"Kursiv (Strg+I)\",\n addLink: \"Link hinzufügen\",\n },\n\n // Paragraph editor toolbar\n paragraphEditor: {\n toolbar: \"Textformatierung\",\n bold: \"Fett (Strg+B)\",\n italic: \"Kursiv (Strg+I)\",\n underline: \"Unterstrichen (Strg+U)\",\n strikethrough: \"Durchgestrichen\",\n subscript: \"Tiefgestellt\",\n superscript: \"Hochgestellt\",\n addLink: \"Link hinzufügen\",\n bulletList: \"Aufzählungsliste\",\n numberedList: \"Nummerierte Liste\",\n alignLeft: \"Linksbündig\",\n alignCenter: \"Zentriert\",\n alignRight: \"Rechtsbündig\",\n clearFormatting: \"Formatierung entfernen\",\n insertEmoji: \"Emoji einfügen\",\n fontFamily: \"Schriftart\",\n defaultFont: \"Standard\",\n fontSize: \"Schriftgröße\",\n defaultSize: \"Standard\",\n textColor: \"Textfarbe\",\n highlightColor: \"Hervorhebungsfarbe\",\n lineHeight: \"Zeilenhöhe\",\n letterSpacing: \"Zeichenabstand\",\n emojiItemLabel: \"Emoji {emoji} einfügen\",\n closeEmojiPicker: \"Emoji-Auswahl schließen\",\n },\n\n // Block actions (BlockWrapper)\n blockActions: {\n drag: \"Zum Sortieren ziehen oder Leertaste drücken, um mit der Tastatur zu verschieben\",\n dragLifted:\n \"{block} wird verschoben. Pfeiltasten zum Positionieren, Leer- oder Eingabetaste zum Ablegen, Esc zum Abbrechen.\",\n duplicate: \"Block duplizieren\",\n delete: \"Block löschen\",\n hiddenOnViewport: \"Ausgeblendet auf {viewport}\",\n saveAsModule: \"Als Modul speichern\",\n conditionToggle: \"Anzeigebedingung umschalten\",\n comments: \"Kommentare ({count})\",\n lifted: \"{block} angehoben. Position {position} von {total}.\",\n moved: \"{block} auf Position {position} von {total} verschoben.\",\n dropped: \"{block} auf Position {position} von {total} abgelegt.\",\n cancelled:\n \"Verschieben abgebrochen. {block} auf Position {position} zurückgesetzt.\",\n },\n\n // Toolbar - Section\n section: {\n dropHere: \"Blöcke hierher ziehen\",\n columns: \"Spalten\",\n column1: \"1 Spalte\",\n column2: \"2 Spalten\",\n column3: \"3 Spalten\",\n ratio12: \"1:2 Verhältnis\",\n ratio21: \"2:1 Verhältnis\",\n },\n\n // Text editor link dialog\n linkDialog: {\n editLink: \"Link bearbeiten\",\n insertLink: \"Link einfügen\",\n updateLink: \"Link aktualisieren\",\n removeLink: \"Link entfernen\",\n cancel: \"Abbrechen\",\n urlPlaceholder: \"https://beispiel.de\",\n urlLabel: \"URL\",\n },\n\n // Toolbar - Title\n title: {\n level: \"Überschriftenebene\",\n heading1: \"Überschrift 1 (36px)\",\n heading2: \"Überschrift 2 (28px)\",\n heading3: \"Überschrift 3 (22px)\",\n heading4: \"Überschrift 4 (18px)\",\n fontFamily: \"Schriftart\",\n inheritFont: \"Vorlagenschrift verwenden\",\n color: \"Farbe\",\n align: \"Ausrichtung\",\n alignLeft: \"Links\",\n alignCenter: \"Zentriert\",\n alignRight: \"Rechts\",\n },\n\n // Emoji picker\n emoji: {\n smileys: \"Smileys\",\n gestures: \"Gesten\",\n objects: \"Objekte\",\n },\n\n // Toolbar - Image\n image: {\n imageUrl: \"Bild-URL\",\n imageUrlPlaceholder: \"https://...\",\n altText: \"Alternativtext\",\n altTextPlaceholder: \"Bildbeschreibung\",\n width: \"Breite\",\n fullWidth: \"Volle Breite\",\n linkUrl: \"Link-URL\",\n openInNewTab: \"In neuem Tab öffnen\",\n placeholderUrl: \"Platzhalterbild\",\n placeholderUrlPlaceholder: \"https://... (nur zur Gestaltung)\",\n placeholderUrlTooltip:\n \"Da die Bild-URL ein Merge-Tag verwendet, können Sie hier ein echtes Bild angeben, um das Layout während der Gestaltung in der Vorschau anzuzeigen. Dies wird nicht in die endgültige Ausgabe aufgenommen.\",\n clickToAdd: \"Klicken Sie, um eine Bild-URL hinzuzufügen\",\n browseMedia: \"Medien durchsuchen\",\n },\n\n // Toolbar - Video\n video: {\n videoUrl: \"Video-URL\",\n videoUrlPlaceholder: \"https://youtube.com/...\",\n youtube: \"YouTube\",\n vimeo: \"Vimeo\",\n detected: \"Video erkannt — Vorschaubild wird automatisch generiert\",\n openInNewTab: \"In neuem Tab öffnen\",\n customThumbnail: \"Eigenes Vorschaubild\",\n optional: \"(optional)\",\n thumbnailPlaceholder: \"Automatisch aus Video-URL generiert\",\n altText: \"Alternativtext\",\n altTextPlaceholder: \"Videobeschreibung\",\n width: \"Breite\",\n fullWidth: \"Volle Breite\",\n placeholderUrl: \"Platzhalter-Thumbnail\",\n placeholderUrlPlaceholder: \"https://... (nur zur Gestaltung)\",\n placeholderUrlTooltip:\n \"Da die Video-URL ein Merge-Tag verwendet, können Sie hier ein echtes Thumbnail angeben, um das Layout während der Gestaltung in der Vorschau anzuzeigen. Dies wird nicht in die endgültige Ausgabe aufgenommen.\",\n addVideo: \"Video-URL hinzufügen\",\n },\n\n // Toolbar - Button\n button: {\n fontFamily: \"Schriftart\",\n inheritFont: \"Vorlagenschrift verwenden\",\n text: \"Text\",\n url: \"URL\",\n urlPlaceholder: \"https://...\",\n openInNewTab: \"In neuem Tab öffnen\",\n background: \"Hintergrund\",\n textColor: \"Textfarbe\",\n borderRadius: \"Eckenradius\",\n fontSize: \"Schriftgröße\",\n },\n\n // Toolbar - Divider\n divider: {\n style: \"Stil\",\n solid: \"Durchgehend\",\n dashed: \"Gestrichelt\",\n dotted: \"Gepunktet\",\n color: \"Farbe\",\n thickness: \"Stärke\",\n },\n\n // Toolbar - Social Icons\n social: {\n icons: \"Symbole\",\n addIcon: \"Symbol hinzufügen\",\n addIcons: \"Soziale Symbole hinzufügen\",\n removeIcon: \"Entfernen\",\n platform: \"Plattform\",\n url: \"URL\",\n urlPlaceholder: \"https://...\",\n style: \"Stil\",\n styleSolid: \"Gefüllt\",\n styleOutlined: \"Umrandet\",\n styleRounded: \"Abgerundet\",\n styleSquare: \"Eckig\",\n styleCircle: \"Rund\",\n size: \"Größe\",\n sizeSmall: \"K\",\n sizeMedium: \"M\",\n sizeLarge: \"G\",\n spacing: \"Abstand\",\n align: \"Ausrichtung\",\n platforms: {\n facebook: \"Facebook\",\n twitter: \"X (Twitter)\",\n instagram: \"Instagram\",\n linkedin: \"LinkedIn\",\n youtube: \"YouTube\",\n tiktok: \"TikTok\",\n pinterest: \"Pinterest\",\n email: \"E-Mail\",\n whatsapp: \"WhatsApp\",\n telegram: \"Telegram\",\n discord: \"Discord\",\n snapchat: \"Snapchat\",\n reddit: \"Reddit\",\n github: \"GitHub\",\n dribbble: \"Dribbble\",\n behance: \"Behance\",\n },\n },\n\n // Toolbar - Menu\n menu: {\n items: \"Menüpunkte\",\n addItem: \"Punkt hinzufügen\",\n removeItem: \"Entfernen\",\n text: \"Text\",\n url: \"URL\",\n urlPlaceholder: \"https://beispiel.de\",\n openInNewTab: \"In neuem Tab öffnen\",\n bold: \"Fett\",\n underline: \"Unterstrichen\",\n color: \"Farbe\",\n linkColor: \"Linkfarbe\",\n fontSize: \"Schriftgröße\",\n fontFamily: \"Schriftfamilie\",\n separator: \"Trennzeichen\",\n separatorColor: \"Trennzeichenfarbe\",\n spacing: \"Abstand\",\n textAlign: \"Ausrichtung\",\n addLinks: \"Menülinks hinzufügen\",\n },\n\n // Toolbar - Table\n table: {\n dimensions: \"Abmessungen\",\n rows: \"Zeilen\",\n columns: \"Spalten\",\n addRow: \"Zeile hinzufügen\",\n removeRow: \"Zeile entfernen\",\n addColumn: \"Spalte hinzufügen\",\n removeColumn: \"Spalte entfernen\",\n hasHeaderRow: \"Kopfzeile\",\n headerBackgroundColor: \"Kopfzeilen-Hintergrund\",\n noHeaderBg: \"Kein Hintergrund\",\n borderColor: \"Rahmenfarbe\",\n borderWidth: \"Rahmenbreite\",\n cellPadding: \"Zellenabstand\",\n fontFamily: \"Schriftart\",\n fontSize: \"Schriftgröße\",\n color: \"Textfarbe\",\n textAlign: \"Ausrichtung\",\n cellPlaceholder: \"Text eingeben...\",\n empty: \"Tabelle hinzufügen\",\n },\n\n // Toolbar - Spacer\n spacer: {\n height: \"Höhe\",\n },\n\n // Toolbar - Countdown\n countdown: {\n targetDate: \"Zieldatum\",\n timezone: \"Zeitzone\",\n display: \"Anzeige\",\n days: \"Tage\",\n hours: \"Stunden\",\n minutes: \"Minuten\",\n seconds: \"Sekunden\",\n separator: \"Trennzeichen\",\n fontFamily: \"Schriftart\",\n inheritFont: \"Standard\",\n digitFontSize: \"Zifferngröße\",\n digitColor: \"Ziffernfarbe\",\n labelColor: \"Beschriftungsfarbe\",\n labelFontSize: \"Beschriftungsgröße\",\n background: \"Hintergrund\",\n labels: \"Beschriftungen\",\n expiry: \"Ablaufnachricht\",\n expiredMessagePlaceholder: \"Dieses Angebot ist abgelaufen\",\n expiredImageUrl: \"Ablaufbild-URL\",\n hideOnExpiry: \"Bei Ablauf ausblenden\",\n setDate: \"Legen Sie ein Zieldatum im Einstellungsbereich fest\",\n hidden: \"Ausgeblendet (abgelaufen)\",\n },\n\n // Custom Blocks\n customBlocks: {\n definitionNotFound:\n \"Unbekannter Blocktyp — dieser Block ist nicht registriert\",\n renderError:\n \"Dieser Block konnte nicht gerendert werden. Überprüfen Sie die Block-Vorlage auf Fehler.\",\n fields: {\n required: \"Pflichtfeld\",\n addItem: \"Element hinzufügen\",\n removeItem: \"Entfernen\",\n maxItemsReached: \"Maximale Anzahl erreicht\",\n minItemsRequired: \"Mindestens {count} Elemente erforderlich\",\n },\n toolbar: {\n noDefinition:\n \"Registrieren Sie diesen Blocktyp in Ihrer SDK-Konfiguration, um seine Eigenschaften zu bearbeiten\",\n },\n dataSource: {\n fetchButton: \"Inhalt laden\",\n changeButton: \"Ändern\",\n fetching: \"Wird geladen...\",\n readOnlyTooltip: \"Dieser Wert wird aus Ihrer Datenquelle geladen\",\n fetchError: \"Inhalt konnte nicht geladen werden\",\n },\n },\n\n // Toolbar - HTML\n html: {\n content: \"HTML-Inhalt\",\n preview: \"Benutzerdefinierter HTML-Block\",\n empty: \"HTML-Inhalt im Bereich hinzufügen\",\n sanitizationHint:\n \"Skripte und unsichere Elemente werden beim Export entfernt.\",\n },\n\n // Toolbar - Common block settings\n blockSettings: {\n spacing: \"Abstände\",\n padding: \"Innenabstand\",\n margin: \"Außenabstand\",\n background: \"Hintergrund\",\n color: \"Farbe\",\n display: \"Anzeige\",\n showOnDesktop: \"Auf Desktop anzeigen\",\n showOnTablet: \"Auf Tablet anzeigen\",\n showOnMobile: \"Auf Mobilgerät anzeigen\",\n hiddenOnDevice: \"Ausgeblendet auf {device}\",\n customCss: \"Benutzerdefiniertes CSS\",\n css: \"CSS\",\n cssPlaceholder: \"/* Benutzerdefinierte Stile */\",\n displayCondition: \"Anzeigebedingung\",\n selectCondition: \"Bedingung auswählen\",\n removeCondition: \"Bedingung entfernen\",\n noCondition: \"Immer sichtbar\",\n conditionApplied: \"Bedingung angewendet\",\n customCondition: \"Eigene Bedingung\",\n customConditionLabel: \"Bedingungsname\",\n customConditionBefore: \"Vorher (öffnende Logik)\",\n customConditionAfter: \"Nachher (schließende Logik)\",\n applyCondition: \"Anwenden\",\n cancelCondition: \"Abbrechen\",\n customBadge: \"Eigene\",\n restoreHiddenBlocks: \"Alle ausgeblendeten Blöcke anzeigen\",\n },\n\n // Template settings\n templateSettings: {\n layout: \"Layout\",\n widthPreset: \"Breitenvoreinstellung\",\n customWidth: \"Benutzerdefinierte Breite\",\n appearance: \"Erscheinungsbild\",\n backgroundColor: \"Hintergrundfarbe\",\n fontFamily: \"Schriftfamilie\",\n preheaderText: \"Preheader-Text\",\n preheaderTextPlaceholder:\n \"Vorschautext, der nach der Betreffzeile im Posteingang angezeigt wird...\",\n preheaderTextHint:\n \"Dieser Text erscheint nach der Betreffzeile in der E-Mail-Vorschau. Unterstützt Merge-Tags.\",\n tips: \"Tipps\",\n tip1: \"600px ist die Standardbreite für E-Mail-Vorlagen\",\n tip2: \"Verwenden Sie websichere Schriften für beste Kompatibilität\",\n tip3: \"Helle Hintergründe eignen sich am besten für die Lesbarkeit\",\n },\n\n // Spacing control\n spacingControl: {\n lockAll: \"Alle Seiten sperren\",\n unlock: \"Seiten entsperren\",\n top: \"Oben\",\n right: \"Rechts\",\n bottom: \"Unten\",\n left: \"Links\",\n decreaseTop: \"Oben verringern\",\n increaseTop: \"Oben erhöhen\",\n decreaseLeft: \"Links verringern\",\n increaseLeft: \"Links erhöhen\",\n decreaseRight: \"Rechts verringern\",\n increaseRight: \"Rechts erhöhen\",\n decreaseBottom: \"Unten verringern\",\n increaseBottom: \"Unten erhöhen\",\n },\n\n // Color Picker\n colorPicker: {\n pickColor: \"Farbe auswählen\",\n hexValue: \"Hex-Farbwert\",\n },\n\n // Merge-Tag\n mergeTag: {\n clickToEdit: \"Zum Bearbeiten klicken\",\n remove: \"Merge-Tag entfernen\",\n insert: \"Merge-Tag einfügen\",\n add: \"Merge-Tag hinzufügen\",\n editValue: \"Merge-Tag-Wert bearbeiten\",\n deleteMergeTag: \"Merge-Tag löschen\",\n suggestionEmpty: \"Keine passenden Merge-Tags\",\n },\n\n // Canvas\n canvas: {\n noBlocks: \"Noch keine Blöcke\",\n dragHint:\n \"Beginnen Sie von Grund auf, indem Sie Blöcke aus der Seitenleiste ziehen\",\n dropHere: \"Hier ablegen\",\n aiHintChat: \"oder lassen Sie\",\n aiHintChatSuffix: \"in Sekunden eine komplette Vorlage für Sie erstellen\",\n aiHintDesign:\n \"Haben Sie ein bestehendes Design? Laden Sie einen Screenshot, ein Bild oder PDF hoch und\",\n aiHintDesignSuffix: \"erstellt es sofort nach\",\n },\n\n // Media Library (cloud)\n mediaLibrary: {\n title: \"Medienbibliothek\",\n searchPlaceholder: \"Dateien suchen...\",\n allFiles: \"Alle Dateien\",\n filterAll: \"Alle Typen\",\n filterImages: \"Bilder\",\n filterDocuments: \"Dokumente\",\n filterVideos: \"Videos\",\n filterAudio: \"Audio\",\n newFolder: \"Neuer Ordner\",\n folderName: \"Ordnername\",\n noFiles: \"Keine Dateien gefunden\",\n dropOrClick: \"Dateien hierher ziehen oder klicken zum Hochladen\",\n acceptedFormats: \"Bilder, PDF, Video, Audio, Dokumente (max. 10 MB)\",\n uploading: \"Wird hochgeladen...\",\n uploadingProgress: \"{current} von {total} wird hochgeladen...\",\n selectImage: \"Bild auswählen\",\n selectFile: \"Datei auswählen\",\n deleteSelected: \"Löschen\",\n copyUrl: \"URL kopieren\",\n copied: \"Kopiert!\",\n browseMedia: \"Medienbibliothek durchsuchen\",\n renameFolder: \"Ordner umbenennen\",\n addSubfolder: \"Unterordner hinzufügen\",\n subfolderName: \"Unterordnername\",\n sortNewest: \"Neueste zuerst\",\n sortOldest: \"Älteste zuerst\",\n sortNameAsc: \"Name A-Z\",\n sortNameDesc: \"Name Z-A\",\n sortSizeAsc: \"Kleinste zuerst\",\n sortSizeDesc: \"Größte zuerst\",\n moveSelected: \"Verschieben\",\n moveToRoot: \"Alle Dateien\",\n currentFolder: \"(aktuell)\",\n confirmDelete: \"Diese Datei löschen?\",\n renameFile: \"Umbenennen\",\n editFile: \"Datei bearbeiten\",\n fileName: \"Dateiname\",\n altText: \"Alternativtext\",\n altTextPlaceholder: \"Bildbeschreibung für Barrierefreiheit\",\n saveChanges: \"Speichern\",\n cancel: \"Abbrechen\",\n frequentlyUsed: \"Häufig verwendet\",\n deleteWarningTitle: \"Datei löschen\",\n deleteWarningMessage:\n \"Diese Datei wird dauerhaft gelöscht und kann nicht wiederhergestellt werden.\",\n deleteWarningUsageNote:\n \"Die folgenden Dateien werden in Vorlagen verwendet. Das Löschen kann diese Vorlagen beschädigen.\",\n deleteAnyway: \"Datei löschen\",\n usedInTemplates: \"In {count} Vorlage(n) verwendet\",\n viewGrid: \"Rasteransicht\",\n viewList: \"Listenansicht\",\n showFolders: \"Ordner anzeigen\",\n hideFolders: \"Ordner ausblenden\",\n importFromUrl: \"Von URL importieren\",\n importUrlPlaceholder: \"https://example.com/image.jpg\",\n import: \"Importieren\",\n importing: \"Wird importiert...\",\n importError: \"Import von URL fehlgeschlagen\",\n conversionLabel: \"Groesse\",\n conversionOriginal: \"Original\",\n conversionSmall: \"Klein (150px)\",\n conversionMedium: \"Mittel (600px)\",\n conversionLarge: \"Gross (1200px)\",\n replaceFile: \"Datei ersetzen\",\n replaceWarningTitle: \"Datei ersetzen\",\n replaceWarningMessage:\n \"Sie sind dabei, diese Datei zu ersetzen. Die Ersatzdatei muss dieselbe Dateierweiterung haben ({extension}).\",\n replaceWarningUsageNote:\n \"Diese Datei wird in {count} Vorlage(n) verwendet. Das Ersetzen aktualisiert alle Verweise.\",\n replaceSelectFile: \"Ersatzdatei auswählen\",\n replace: \"Ersetzen\",\n replacing: \"Wird ersetzt...\",\n replaceError: \"Ersetzen der Datei fehlgeschlagen\",\n saving: \"Wird gespeichert...\",\n cropAspectRatio: \"Seitenverhältnis\",\n cropFree: \"Frei\",\n cropSquare: \"1:1\",\n cropLandscape43: \"4:3\",\n cropLandscape169: \"16:9\",\n cropOriginal: \"Original\",\n cropMaxWidth: \"Max. Breite\",\n cropMaxHeight: \"Max. Höhe\",\n cropOutputSize: \"Ausgabegröße\",\n cropPixels: \"px\",\n cropOptional: \"(optional)\",\n storageTooltip: \"{used} von {total} verwendet ({remaining} verfügbar)\",\n },\n\n // Seitenleiste\n sidebarNav: {\n browseModules: \"Gespeicherte Module durchsuchen\",\n expandSidebar: \"Block-Seitenleiste erweitern\",\n palette: \"Blockpalette\",\n insertBlock: \"{block}-Block einfügen\",\n },\n\n // Landmark-Bezeichnungen für Hilfstechnologien\n landmarks: {\n canvas: \"E-Mail-Leinwand\",\n blockToolbar: \"Blockeigenschaften\",\n rightSidebar: \"Blockeigenschaften und Vorlageneinstellungen\",\n reorderAnnouncements: \"Block-Neuanordnungsmeldungen\",\n },\n\n // Design Reference (cloud)\n errors: {\n editorLoading: \"Editor wird geladen...\",\n editorLoadFailed: \"Editor konnte nicht geladen werden.\",\n retry: \"Erneut versuchen\",\n },\n};\n\nexport default de;\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { An as e, Cn as t, Dn as n, En as r, Mn as i, On as a, Sn as o, Tn as s, bn as c, jn as l, kn as u, wn as d, xn as f, yn as p } from "./features-DV4PhoBs.js";
1
+ import { An as e, Cn as t, Dn as n, En as r, Mn as i, On as a, Sn as o, Tn as s, bn as c, jn as l, kn as u, wn as d, xn as f, yn as p } from "./features-BnG-dhzy.js";
2
2
  //#region ../renderer/dist/index.js
3
3
  var m = {
4
4
  arial: "Arial, sans-serif",
@@ -493,4 +493,4 @@ function $(e, t) {
493
493
  //#endregion
494
494
  export { h as RenderContext, N as SOCIAL_ICONS, x as convertMergeTagsToValues, y as escapeAttr, v as escapeHtml, P as generateSocialIconDataUri, T as getCssClassAttr, E as getCssClasses, K as getWidthPercentages, q as getWidthPixels, w as isHiddenOnAll, X as renderBlock, oe as renderToMjml, S as toPaddingString };
495
495
 
496
- //# sourceMappingURL=dist-DFfcnJJB.js.map
496
+ //# sourceMappingURL=dist-MGrg9tLo.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dist-DFfcnJJB.js","names":["isSection2","isSection3","isCustomBlock2"],"sources":["../../../../renderer/dist/index.js"],"sourcesContent":["// src/index.ts\nimport { isSection as isSection3, isCustomBlock as isCustomBlock2 } from \"@templatical/types\";\n\n// src/render-context.ts\nvar BUILT_IN_FONT_FALLBACKS = {\n arial: \"Arial, sans-serif\",\n helvetica: \"Helvetica, sans-serif\",\n georgia: \"Georgia, serif\",\n \"times new roman\": \"'Times New Roman', serif\",\n verdana: \"Verdana, sans-serif\",\n \"trebuchet ms\": \"'Trebuchet MS', sans-serif\",\n \"courier new\": \"'Courier New', monospace\",\n tahoma: \"Tahoma, sans-serif\"\n};\nvar RenderContext = class _RenderContext {\n constructor(containerWidth, customFonts, defaultFallbackFont, allowHtmlBlocks, customBlockHtml = /* @__PURE__ */ new Map()) {\n this.containerWidth = containerWidth;\n this.customFonts = customFonts;\n this.defaultFallbackFont = defaultFallbackFont;\n this.allowHtmlBlocks = allowHtmlBlocks;\n this.customBlockHtml = customBlockHtml;\n }\n containerWidth;\n customFonts;\n defaultFallbackFont;\n allowHtmlBlocks;\n customBlockHtml;\n /**\n * Create a new context with a different container width.\n * Used when rendering columns with narrower widths.\n */\n withContainerWidth(width) {\n return new _RenderContext(\n width,\n this.customFonts,\n this.defaultFallbackFont,\n this.allowHtmlBlocks,\n this.customBlockHtml\n );\n }\n /**\n * Resolve a font family name to include custom font fallbacks.\n * If the font matches a custom font, returns `'FontName', fallback`.\n * Otherwise returns the original font family string.\n */\n resolveFontFamily(fontFamily) {\n for (const customFont of this.customFonts) {\n if (customFont.name.toLowerCase() === fontFamily.toLowerCase()) {\n const fallback = customFont.fallback ?? this.defaultFallbackFont;\n return `'${customFont.name}', ${fallback}`;\n }\n }\n const builtIn = BUILT_IN_FONT_FALLBACKS[fontFamily.toLowerCase()];\n if (builtIn) {\n return builtIn;\n }\n return fontFamily;\n }\n};\n\n// src/renderers/index.ts\nimport {\n isSection as isSection2,\n isTitle,\n isParagraph,\n isImage,\n isButton,\n isDivider,\n isSpacer,\n isHtml,\n isSocialIcons,\n isMenu,\n isTable,\n isVideo,\n isCustomBlock\n} from \"@templatical/types\";\n\n// src/renderers/title.ts\nimport { HEADING_LEVEL_FONT_SIZE } from \"@templatical/types\";\n\n// src/escape.ts\nvar HTML_ENTITIES = {\n \"&\": \"&amp;\",\n \"<\": \"&lt;\",\n \">\": \"&gt;\",\n '\"': \"&quot;\",\n \"'\": \"&#039;\"\n};\nvar HTML_ENTITY_REGEX = /[&<>\"']/g;\nfunction escapeHtml(text) {\n if (text === \"\") {\n return \"\";\n }\n return text.replace(HTML_ENTITY_REGEX, (char) => HTML_ENTITIES[char] ?? char);\n}\nfunction escapeAttr(text) {\n if (text === \"\") {\n return \"\";\n }\n return text.replace(HTML_ENTITY_REGEX, (char) => HTML_ENTITIES[char] ?? char);\n}\nfunction escapeCssValue(text) {\n if (text === \"\") {\n return \"\";\n }\n return escapeAttr(text).replace(/[;{}\\r\\n]/g, \"\");\n}\nfunction convertMergeTagsToValues(html) {\n if (html === \"\") {\n return \"\";\n }\n let result = html.replace(\n /<span[^>]*\\bdata-merge-tag=\"([^\"]*)\"[^>]*>.*?<\\/span>/gs,\n \"$1\"\n );\n result = result.replace(\n /<span[^>]*\\bdata-logic-merge-tag=\"([^\"]*)\"[^>]*>.*?<\\/span>/gs,\n \"$1\"\n );\n return result;\n}\n\n// src/padding.ts\nfunction toPaddingString(padding) {\n return `${padding.top}px ${padding.right}px ${padding.bottom}px ${padding.left}px`;\n}\n\n// src/utils.ts\nfunction bgAttr(backgroundColor, placement) {\n if (!backgroundColor) {\n return \"\";\n }\n const name = placement === \"native\" ? \"background-color\" : \"container-background-color\";\n return ` ${name}=\"${backgroundColor}\"`;\n}\n\n// src/visibility.ts\nfunction isHiddenOnAll(block) {\n const visibility = block.visibility;\n if (!visibility) {\n return false;\n }\n return !visibility.desktop && !visibility.tablet && !visibility.mobile;\n}\nfunction getCssClassAttr(block) {\n const classes = getCssClasses(block);\n if (classes === \"\") {\n return \"\";\n }\n return ` css-class=\"${classes}\"`;\n}\nfunction getCssClasses(block) {\n const visibility = block.visibility;\n if (!visibility) {\n return \"\";\n }\n const classes = [];\n if (!visibility.desktop) {\n classes.push(\"tpl-hide-desktop\");\n }\n if (!visibility.tablet) {\n classes.push(\"tpl-hide-tablet\");\n }\n if (!visibility.mobile) {\n classes.push(\"tpl-hide-mobile\");\n }\n return classes.join(\" \");\n}\n\n// src/renderers/title.ts\nfunction renderTitle(block, context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n const padding = toPaddingString(block.styles.padding);\n const bgColor = bgAttr(block.styles.backgroundColor, \"container\");\n const content = unwrapParagraph(convertMergeTagsToValues(block.content));\n const fontSize = HEADING_LEVEL_FONT_SIZE[block.level] ?? HEADING_LEVEL_FONT_SIZE[2];\n const color = block.color;\n const align = block.textAlign;\n const fontFamilyAttr = renderFontFamilyAttr(block.fontFamily, context);\n const visibilityAttr = getCssClassAttr(block);\n const safeLevel = HEADING_LEVEL_FONT_SIZE[block.level] ? block.level : 2;\n const tag = `h${safeLevel}`;\n return `<mj-text\n font-size=\"${fontSize}px\"\n color=\"${color}\"\n align=\"${align}\"\n line-height=\"1.3\"\n padding=\"${padding}\"${bgColor}${fontFamilyAttr}${visibilityAttr}\n><${tag} style=\"margin:0;font-size:inherit;color:inherit;line-height:inherit\">${content}</${tag}></mj-text>`;\n}\nfunction unwrapParagraph(html) {\n const match = html.match(/^\\s*<p\\b[^>]*>([\\s\\S]*)<\\/p>\\s*$/);\n if (!match) return html;\n if (/<\\/p>\\s*<p\\b/i.test(match[1])) return html;\n return match[1];\n}\nfunction renderFontFamilyAttr(fontFamily, context) {\n if (!fontFamily) {\n return \"\";\n }\n const resolved = context.resolveFontFamily(fontFamily);\n return ` font-family=\"${resolved}\"`;\n}\n\n// src/renderers/paragraph.ts\nfunction renderParagraph(block, _context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n const stripped = block.content.replace(/<\\/?p[^>]*>/gi, \"\").trim();\n if (stripped === \"\") {\n return \"\";\n }\n const padding = toPaddingString(block.styles.padding);\n const bgColor = bgAttr(block.styles.backgroundColor, \"container\");\n const content = convertMergeTagsToValues(block.content);\n const visibilityAttr = getCssClassAttr(block);\n return `<mj-text\n line-height=\"1.5\"\n padding=\"${padding}\"${bgColor}${visibilityAttr}\n>${content}</mj-text>`;\n}\n\n// src/renderers/image.ts\nfunction renderImage(block, context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n if (block.src === \"\") {\n return \"\";\n }\n const padding = toPaddingString(block.styles.padding);\n const bgColor = bgAttr(block.styles.backgroundColor, \"container\");\n const width = block.width === \"full\" ? context.containerWidth + \"px\" : block.width + \"px\";\n const visibilityAttr = getCssClassAttr(block);\n let linkAttr = \"\";\n if (block.linkUrl) {\n linkAttr = ` href=\"${escapeAttr(block.linkUrl)}\"`;\n if (block.linkOpenInNewTab) {\n linkAttr += ' target=\"_blank\" rel=\"noopener\"';\n }\n }\n const src = escapeAttr(block.src);\n const alt = escapeAttr(block.alt);\n const align = block.align;\n return `<mj-image\n src=\"${src}\"\n alt=\"${alt}\"\n width=\"${width}\"\n align=\"${align}\"\n padding=\"${padding}\"${bgColor}${linkAttr}${visibilityAttr}\n/>`;\n}\n\n// src/renderers/button.ts\nfunction renderButton(block, context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n const padding = toPaddingString(block.styles.padding);\n const bgColor = bgAttr(block.styles.backgroundColor, \"container\");\n const buttonPadding = toPaddingString(block.buttonPadding);\n const href = block.url === \"\" ? \"\" : escapeAttr(block.url);\n const hrefAttr = href === \"\" ? \"\" : ` href=\"${href}\"`;\n const backgroundColor = escapeAttr(block.backgroundColor);\n const textColor = escapeAttr(block.textColor);\n const fontSize = block.fontSize;\n const borderRadius = block.borderRadius;\n const text = escapeHtml(block.text);\n const targetAttr = block.openInNewTab ? ' target=\"_blank\" rel=\"noopener\"' : \"\";\n const fontFamilyAttr = renderFontFamilyAttr2(block.fontFamily, context);\n const visibilityAttr = getCssClassAttr(block);\n return `<mj-button${hrefAttr}${targetAttr}\n background-color=\"${backgroundColor}\"\n color=\"${textColor}\"\n font-size=\"${fontSize}px\"\n font-weight=\"bold\"\n border-radius=\"${borderRadius}px\"\n inner-padding=\"${buttonPadding}\"\n padding=\"${padding}\"${bgColor}${fontFamilyAttr}${visibilityAttr}\n>${text}</mj-button>`;\n}\nfunction renderFontFamilyAttr2(fontFamily, context) {\n if (!fontFamily) {\n return \"\";\n }\n const resolved = context.resolveFontFamily(fontFamily);\n return ` font-family=\"${resolved}\"`;\n}\n\n// src/renderers/divider.ts\nfunction renderDivider(block, _context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n const padding = toPaddingString(block.styles.padding);\n const bgColor = block.styles.backgroundColor ? ` container-background-color=\"${block.styles.backgroundColor}\"` : \"\";\n const width = block.width === \"full\" ? \"100%\" : block.width + \"px\";\n const thickness = block.thickness;\n const lineStyle = block.lineStyle;\n const color = block.color;\n const visibilityAttr = getCssClassAttr(block);\n return `<mj-divider\n border-width=\"${thickness}px\"\n border-style=\"${lineStyle}\"\n border-color=\"${color}\"\n width=\"${width}\"\n padding=\"${padding}\"${bgColor}${visibilityAttr}\n/>`;\n}\n\n// src/renderers/spacer.ts\nfunction renderSpacer(block, _context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n const height = block.height;\n const bgColor = block.styles.backgroundColor ? ` container-background-color=\"${block.styles.backgroundColor}\"` : \"\";\n const visibilityAttr = getCssClassAttr(block);\n return `<mj-spacer height=\"${height}px\" padding=\"0\"${bgColor}${visibilityAttr} />`;\n}\n\n// src/renderers/html.ts\nfunction renderHtml(block, context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n if (!context.allowHtmlBlocks) {\n return \"\";\n }\n const content = block.content;\n if (content === \"\") {\n return \"\";\n }\n const visibilityAttr = getCssClassAttr(block);\n return `<mj-text${visibilityAttr}>\n${content}\n</mj-text>`;\n}\n\n// src/social-icons.ts\nvar SOCIAL_ICONS = {\n facebook: {\n path: \"M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z\",\n color: \"#1877F2\"\n },\n twitter: {\n path: \"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z\",\n color: \"#000000\"\n },\n instagram: {\n path: \"M12 0C8.74 0 8.333.015 7.053.072 5.775.132 4.905.333 4.14.63c-.789.306-1.459.717-2.126 1.384S.935 3.35.63 4.14C.333 4.905.131 5.775.072 7.053.012 8.333 0 8.74 0 12s.015 3.667.072 4.947c.06 1.277.261 2.148.558 2.913.306.788.717 1.459 1.384 2.126.667.666 1.336 1.079 2.126 1.384.766.296 1.636.499 2.913.558C8.333 23.988 8.74 24 12 24s3.667-.015 4.947-.072c1.277-.06 2.148-.262 2.913-.558.788-.306 1.459-.718 2.126-1.384.666-.667 1.079-1.335 1.384-2.126.296-.765.499-1.636.558-2.913.06-1.28.072-1.687.072-4.947s-.015-3.667-.072-4.947c-.06-1.277-.262-2.149-.558-2.913-.306-.789-.718-1.459-1.384-2.126C21.319 1.347 20.651.935 19.86.63c-.765-.297-1.636-.499-2.913-.558C15.667.012 15.26 0 12 0zm0 2.16c3.203 0 3.585.016 4.85.071 1.17.055 1.805.249 2.227.415.562.217.96.477 1.382.896.419.42.679.819.896 1.381.164.422.36 1.057.413 2.227.057 1.266.07 1.646.07 4.85s-.015 3.585-.074 4.85c-.061 1.17-.256 1.805-.421 2.227-.224.562-.479.96-.899 1.382-.419.419-.824.679-1.38.896-.42.164-1.065.36-2.235.413-1.274.057-1.649.07-4.859.07-3.211 0-3.586-.015-4.859-.074-1.171-.061-1.816-.256-2.236-.421-.569-.224-.96-.479-1.379-.899-.421-.419-.69-.824-.9-1.38-.165-.42-.359-1.065-.42-2.235-.045-1.26-.061-1.649-.061-4.844 0-3.196.016-3.586.061-4.861.061-1.17.255-1.814.42-2.234.21-.57.479-.96.9-1.381.419-.419.81-.689 1.379-.898.42-.166 1.051-.361 2.221-.421 1.275-.045 1.65-.06 4.859-.06l.045.03zm0 3.678c-3.405 0-6.162 2.76-6.162 6.162 0 3.405 2.76 6.162 6.162 6.162 3.405 0 6.162-2.76 6.162-6.162 0-3.405-2.76-6.162-6.162-6.162zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm7.846-10.405c0 .795-.646 1.44-1.44 1.44-.795 0-1.44-.646-1.44-1.44 0-.794.646-1.439 1.44-1.439.793-.001 1.44.645 1.44 1.439z\",\n color: \"#E4405F\"\n },\n linkedin: {\n path: \"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z\",\n color: \"#0A66C2\"\n },\n youtube: {\n path: \"M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z\",\n color: \"#FF0000\"\n },\n tiktok: {\n path: \"M12.525.02c1.31-.02 2.61-.01 3.91-.02.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.05-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.93-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.08-1.03-2.02-1.19-3.44-3.37-3.65-5.71-.02-.5-.03-1-.01-1.49.18-1.9 1.12-3.72 2.58-4.96 1.66-1.44 3.98-2.13 6.15-1.72.02 1.48-.04 2.96-.04 4.44-.99-.32-2.15-.23-3.02.37-.63.41-1.11 1.04-1.36 1.75-.21.51-.15 1.07-.14 1.61.24 1.64 1.82 3.02 3.5 2.87 1.12-.01 2.19-.66 2.77-1.61.19-.33.4-.67.41-1.06.1-1.79.06-3.57.07-5.36.01-4.03-.01-8.05.02-12.07z\",\n color: \"#000000\"\n },\n pinterest: {\n path: \"M12 0C5.373 0 0 5.372 0 12c0 5.084 3.163 9.426 7.627 11.174-.105-.949-.2-2.405.042-3.441.218-.937 1.407-5.965 1.407-5.965s-.359-.719-.359-1.782c0-1.668.967-2.914 2.171-2.914 1.023 0 1.518.769 1.518 1.69 0 1.029-.655 2.568-.994 3.995-.283 1.194.599 2.169 1.777 2.169 2.133 0 3.772-2.249 3.772-5.495 0-2.873-2.064-4.882-5.012-4.882-3.414 0-5.418 2.561-5.418 5.207 0 1.031.397 2.138.893 2.738.098.119.112.224.083.345l-.333 1.36c-.053.22-.174.267-.402.161-1.499-.698-2.436-2.889-2.436-4.649 0-3.785 2.75-7.262 7.929-7.262 4.163 0 7.398 2.967 7.398 6.931 0 4.136-2.607 7.464-6.227 7.464-1.216 0-2.359-.631-2.75-1.378l-.748 2.853c-.271 1.043-1.002 2.35-1.492 3.146C9.57 23.812 10.763 24 12 24c6.627 0 12-5.373 12-12 0-6.628-5.373-12-12-12z\",\n color: \"#BD081C\"\n },\n email: {\n path: \"M1.5 8.67v8.58a3 3 0 003 3h15a3 3 0 003-3V8.67l-8.928 5.493a3 3 0 01-3.144 0L1.5 8.67z M22.5 6.908V6.75a3 3 0 00-3-3h-15a3 3 0 00-3 3v.158l9.714 5.978a1.5 1.5 0 001.572 0L22.5 6.908z\",\n color: \"#6B7280\"\n },\n whatsapp: {\n path: \"M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z\",\n color: \"#25D366\"\n },\n telegram: {\n path: \"M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z\",\n color: \"#26A5E4\"\n },\n discord: {\n path: \"M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189z\",\n color: \"#5865F2\"\n },\n snapchat: {\n path: \"M12.017 0C5.396 0 .029 5.367.029 11.987c0 5.079 3.158 9.417 7.618 11.162-.105-.949-.199-2.403.041-3.439.219-.937 1.406-5.957 1.406-5.957s-.359-.72-.359-1.781c0-1.668.967-2.914 2.171-2.914 1.023 0 1.518.769 1.518 1.69 0 1.029-.655 2.568-.994 3.995-.283 1.194.599 2.169 1.777 2.169 2.133 0 3.772-2.249 3.772-5.495 0-2.873-2.064-4.882-5.012-4.882-3.414 0-5.418 2.561-5.418 5.207 0 1.031.397 2.138.893 2.738a.36.36 0 01.083.345l-.333 1.36c-.053.22-.174.267-.402.161-1.499-.698-2.436-2.889-2.436-4.649 0-3.785 2.75-7.262 7.929-7.262 4.163 0 7.398 2.967 7.398 6.931 0 4.136-2.607 7.464-6.227 7.464-1.216 0-2.359-.631-2.75-1.378l-.748 2.853c-.271 1.043-1.002 2.35-1.492 3.146 1.124.347 2.317.535 3.554.535 6.627 0 12.017-5.373 12.017-12.001C24.034 5.367 18.644 0 12.017 0z\",\n color: \"#FFFC00\"\n },\n reddit: {\n path: \"M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25c0 .687.561 1.248 1.25 1.248.687 0 1.248-.561 1.248-1.249 0-.688-.561-1.249-1.249-1.249zm5.5 0c-.687 0-1.248.561-1.248 1.25 0 .687.561 1.248 1.249 1.248.688 0 1.249-.561 1.249-1.249 0-.687-.562-1.249-1.25-1.249zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z\",\n color: \"#FF4500\"\n },\n github: {\n path: \"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\",\n color: \"#181717\"\n },\n dribbble: {\n path: \"M12 24C5.385 24 0 18.615 0 12S5.385 0 12 0s12 5.385 12 12-5.385 12-12 12zm10.12-10.358c-.35-.11-3.17-.953-6.384-.438 1.34 3.684 1.887 6.684 1.992 7.308 2.3-1.555 3.936-4.02 4.392-6.87zm-6.115 7.808c-.153-.9-.75-4.032-2.19-7.77l-.066.02c-5.79 2.015-7.86 6.025-8.04 6.4 1.73 1.358 3.92 2.166 6.29 2.166 1.42 0 2.77-.29 4-.814zm-11.62-2.58c.232-.4 3.045-5.055 8.332-6.765.135-.045.27-.084.405-.12-.26-.585-.54-1.167-.832-1.74C7.17 11.775 2.206 11.71 1.756 11.7l-.004.312c0 2.633.998 5.037 2.634 6.855zm-2.42-8.955c.46.008 4.683.026 9.477-1.248-1.698-3.018-3.53-5.558-3.8-5.928-2.868 1.35-5.01 3.99-5.676 7.17zM9.6 2.052c.282.38 2.145 2.914 3.822 6 3.645-1.365 5.19-3.44 5.373-3.702-1.81-1.61-4.19-2.586-6.795-2.586-.825 0-1.63.1-2.4.285zm10.335 3.483c-.218.29-1.935 2.493-5.724 4.04.24.49.47.985.68 1.486.08.18.15.36.22.53 3.41-.43 6.8.26 7.14.33-.02-2.42-.88-4.64-2.31-6.38z\",\n color: \"#EA4C89\"\n },\n behance: {\n path: \"M22 7h-7V5h7v2zm1.726 10c-.442 1.297-2.029 3-5.101 3-3.074 0-5.564-1.729-5.564-5.675 0-3.91 2.325-5.92 5.466-5.92 3.082 0 4.964 1.782 5.375 4.426.078.506.109 1.188.095 2.14H15.97c.13 3.211 3.483 3.312 4.588 2.029h3.168zm-7.686-4h4.965c-.105-1.547-1.136-2.219-2.477-2.219-1.466 0-2.277.768-2.488 2.219zm-9.574 6.988H0V5.021h6.953c5.476.081 5.58 5.444 2.72 6.906 3.461 1.26 3.577 8.061-3.207 8.061zM3 11h3.584c2.508 0 2.906-3-.312-3H3v3zm3.391 3H3v3.016h3.341c3.055 0 2.868-3.016.05-3.016z\",\n color: \"#1769FF\"\n }\n};\nfunction generateSocialIconDataUri(platform, style, size) {\n const iconData = SOCIAL_ICONS[platform];\n const path = iconData?.path ?? \"\";\n const brandColor = iconData?.color ?? \"#6B7280\";\n if (path === \"\") {\n return \"\";\n }\n const isOutlined = style === \"outlined\";\n const iconColor = isOutlined ? brandColor : \"#ffffff\";\n let bgShape;\n switch (style) {\n case \"circle\":\n bgShape = `<circle cx=\"12\" cy=\"12\" r=\"12\" fill=\"${brandColor}\"/>`;\n break;\n case \"rounded\":\n bgShape = `<rect width=\"24\" height=\"24\" rx=\"6\" fill=\"${brandColor}\"/>`;\n break;\n case \"square\":\n bgShape = `<rect width=\"24\" height=\"24\" rx=\"0\" fill=\"${brandColor}\"/>`;\n break;\n case \"outlined\":\n bgShape = `<rect width=\"22\" height=\"22\" x=\"1\" y=\"1\" rx=\"3\" fill=\"transparent\" stroke=\"${brandColor}\" stroke-width=\"2\"/>`;\n break;\n default:\n bgShape = `<rect width=\"24\" height=\"24\" rx=\"3\" fill=\"${brandColor}\"/>`;\n break;\n }\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" width=\"${size}\" height=\"${size}\">` + bgShape + `<g transform=\"translate(4.8, 4.8) scale(0.6)\"><path d=\"${path}\" fill=\"${iconColor}\"/></g></svg>`;\n return \"data:image/svg+xml;base64,\" + btoa(svg);\n}\n\n// src/renderers/social.ts\nfunction renderSocialIcons(block, _context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n const icons = block.icons;\n if (icons.length === 0) {\n return \"\";\n }\n const padding = toPaddingString(block.styles.padding);\n const bgColor = block.styles.backgroundColor ? ` container-background-color=\"${block.styles.backgroundColor}\"` : \"\";\n const visibilityAttr = getCssClassAttr(block);\n const align = block.align;\n const iconSize = block.iconSize;\n const iconStyle = block.iconStyle;\n const spacing = block.spacing;\n let iconSizePx;\n switch (iconSize) {\n case \"small\":\n iconSizePx = 24;\n break;\n case \"large\":\n iconSizePx = 48;\n break;\n default:\n iconSizePx = 32;\n break;\n }\n let borderRadius;\n switch (iconStyle) {\n case \"circle\":\n borderRadius = \"50%\";\n break;\n case \"rounded\":\n borderRadius = \"8px\";\n break;\n case \"square\":\n borderRadius = \"0\";\n break;\n default:\n borderRadius = \"4px\";\n break;\n }\n const iconCount = icons.length;\n const socialElements = icons.map((icon, index) => {\n const platform = icon.platform;\n const url = escapeAttr(icon.url);\n const iconSrc = generateSocialIconDataUri(platform, iconStyle, iconSizePx);\n const rightPad = index === iconCount - 1 ? 0 : spacing;\n return `<mj-social-element src=\"${iconSrc}\" href=\"${url}\" icon-size=\"${iconSizePx}px\" padding=\"0 ${rightPad}px 0 0\" border-radius=\"${borderRadius}\" background-color=\"transparent\"></mj-social-element>`;\n });\n const socialContent = socialElements.join(\"\\n\");\n return `<mj-social\n mode=\"horizontal\"\n align=\"${align}\"\n icon-padding=\"0\"\n padding=\"${padding}\"${bgColor}${visibilityAttr}\n>\n${socialContent}\n</mj-social>`;\n}\n\n// src/renderers/menu.ts\nfunction renderMenu(block, context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n if (block.items.length === 0) {\n return \"\";\n }\n const padding = toPaddingString(block.styles.padding);\n const bgColor = bgAttr(block.styles.backgroundColor, \"container\");\n const visibilityAttr = getCssClassAttr(block);\n const fontFamilyAttr = renderFontFamilyAttr3(block.fontFamily, context);\n const align = block.textAlign;\n const fontSize = block.fontSize;\n const color = block.color;\n const content = renderMenuItems(block);\n return `<mj-text\n font-size=\"${fontSize}px\"\n color=\"${color}\"\n align=\"${align}\"\n line-height=\"1.5\"\n padding=\"${padding}\"${bgColor}${fontFamilyAttr}${visibilityAttr}\n>${content}</mj-text>`;\n}\nfunction renderMenuItems(block) {\n const items = block.items;\n const separator = escapeHtml(block.separator);\n const separatorColor = escapeCssValue(block.separatorColor);\n const spacing = block.spacing;\n const linkColor = block.linkColor ?? block.color;\n const parts = [];\n const itemCount = items.length;\n for (let index = 0; index < itemCount; index++) {\n parts.push(renderMenuItem(items[index], linkColor));\n if (index < itemCount - 1) {\n parts.push(\n `<span style=\"color: ${separatorColor}; padding: 0 ${spacing}px;\">${separator}</span>`\n );\n }\n }\n return parts.join(\"\");\n}\nfunction renderMenuItem(item, linkColor) {\n const text = escapeHtml(item.text);\n const url = escapeAttr(item.url);\n const color = escapeCssValue(item.color ?? linkColor);\n const target = item.openInNewTab ? ' target=\"_blank\" rel=\"noopener\"' : \"\";\n const styles = [`color: ${color}`, \"text-decoration: none\"];\n if (item.bold) {\n styles.push(\"font-weight: bold\");\n }\n if (item.underline) {\n styles.push(\"text-decoration: underline\");\n }\n const styleAttr = styles.join(\"; \");\n return `<a href=\"${url}\" style=\"${styleAttr}\"${target}>${text}</a>`;\n}\nfunction renderFontFamilyAttr3(fontFamily, context) {\n if (!fontFamily) {\n return \"\";\n }\n const resolved = context.resolveFontFamily(fontFamily);\n return ` font-family=\"${resolved}\"`;\n}\n\n// src/renderers/table.ts\nfunction renderTable(block, context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n if (block.rows.length === 0) {\n return \"\";\n }\n const padding = toPaddingString(block.styles.padding);\n const bgColor = bgAttr(block.styles.backgroundColor, \"container\");\n const visibilityAttr = getCssClassAttr(block);\n const fontFamilyAttr = renderFontFamilyAttr4(block.fontFamily, context);\n const fontSize = block.fontSize;\n const color = block.color;\n const align = block.textAlign;\n const tableHtml = renderTableElement(block);\n return `<mj-text\n font-size=\"${fontSize}px\"\n color=\"${color}\"\n align=\"${align}\"\n line-height=\"1.5\"\n padding=\"${padding}\"${bgColor}${fontFamilyAttr}${visibilityAttr}\n>${tableHtml}</mj-text>`;\n}\nfunction renderTableElement(block) {\n const borderColor = escapeCssValue(block.borderColor);\n const borderWidth = block.borderWidth;\n const tableStyle = \"width: 100%; border-collapse: collapse;\";\n let rowsHtml = \"\";\n for (let index = 0; index < block.rows.length; index++) {\n const row = block.rows[index];\n const isHeader = block.hasHeaderRow && index === 0;\n rowsHtml += renderRow(row, block, isHeader, borderColor, borderWidth);\n }\n return `<table style=\"${tableStyle}\">${rowsHtml}</table>`;\n}\nfunction renderRow(row, block, isHeader, borderColor, borderWidth) {\n let cellsHtml = \"\";\n for (const cell of row.cells) {\n cellsHtml += renderCell(cell, block, isHeader, borderColor, borderWidth);\n }\n return `<tr>${cellsHtml}</tr>`;\n}\nfunction renderCell(cell, block, isHeader, borderColor, borderWidth) {\n const cellPadding = block.cellPadding;\n const styles = [\n `border: ${borderWidth}px solid ${borderColor}`,\n `padding: ${cellPadding}px`\n ];\n if (isHeader) {\n styles.push(\"font-weight: bold\");\n if (block.headerBackgroundColor) {\n styles.push(\n `background-color: ${escapeCssValue(block.headerBackgroundColor)}`\n );\n }\n }\n const styleAttr = styles.join(\"; \");\n const content = convertMergeTagsToValues(cell.content);\n const tag = isHeader ? \"th\" : \"td\";\n return `<${tag} style=\"${styleAttr}\">${content}</${tag}>`;\n}\nfunction renderFontFamilyAttr4(fontFamily, context) {\n if (!fontFamily) {\n return \"\";\n }\n const resolved = context.resolveFontFamily(fontFamily);\n return ` font-family=\"${resolved}\"`;\n}\n\n// src/renderers/custom.ts\nfunction renderCustom(block, context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n const fromContext = context.customBlockHtml.get(block.id);\n const content = fromContext ?? block.renderedHtml;\n if (!content || content === \"\") {\n return \"\";\n }\n const visibilityAttr = getCssClassAttr(block);\n const bgColor = bgAttr(block.styles?.backgroundColor, \"container\");\n return `<mj-text${bgColor}${visibilityAttr}>\n${content}\n</mj-text>`;\n}\n\n// src/renderers/section.ts\nimport { isSection } from \"@templatical/types\";\n\n// src/columns.ts\nfunction getWidthPercentages(layout) {\n switch (layout) {\n case \"2\":\n return [\"50%\", \"50%\"];\n case \"3\":\n return [\"33.33%\", \"33.33%\", \"33.34%\"];\n case \"1-2\":\n return [\"33.33%\", \"66.67%\"];\n case \"2-1\":\n return [\"66.67%\", \"33.33%\"];\n default:\n return [\"100%\"];\n }\n}\nfunction getWidthPixels(layout, containerWidth) {\n switch (layout) {\n case \"2\":\n return [containerWidth * 0.5, containerWidth * 0.5];\n case \"3\":\n return [containerWidth / 3, containerWidth / 3, containerWidth / 3];\n case \"1-2\":\n return [containerWidth / 3, containerWidth * 2 / 3];\n case \"2-1\":\n return [containerWidth * 2 / 3, containerWidth / 3];\n default:\n return [containerWidth];\n }\n}\n\n// src/renderers/section.ts\nfunction renderSection(block, context, renderBlock2) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n const columnsLayout = block.columns;\n const columnWidths = getWidthPercentages(columnsLayout);\n const columnWidthsPx = getWidthPixels(columnsLayout, context.containerWidth);\n const padding = toPaddingString(block.styles.padding);\n const bgColor = bgAttr(block.styles.backgroundColor, \"native\");\n const visibilityAttr = getCssClassAttr(block);\n const children = block.children;\n const columnsContent = [];\n for (let index = 0; index < children.length; index++) {\n const column = children[index];\n const width = columnWidths[index] ?? \"100%\";\n const columnWidth = Math.floor(\n columnWidthsPx[index] ?? context.containerWidth\n );\n const filteredColumn = filterHtmlBlocks(\n column,\n context.allowHtmlBlocks\n ).filter((child) => !isSection(child));\n const columnContext = context.withContainerWidth(columnWidth);\n const columnBlocks = filteredColumn.map((child) => renderBlock2(child, columnContext)).filter((value) => value !== \"\").join(\"\\n\");\n const content = columnBlocks === \"\" ? \"<mj-text>&nbsp;</mj-text>\" : columnBlocks;\n columnsContent.push(`<mj-column width=\"${width}\">\n${content}\n</mj-column>`);\n }\n const columns = columnsContent.join(\"\\n\");\n return `<mj-section${bgColor} padding=\"${padding}\"${visibilityAttr}>\n${columns}\n</mj-section>`;\n}\nfunction filterHtmlBlocks(blocks, allowHtmlBlocks) {\n if (allowHtmlBlocks) {\n return blocks;\n }\n return blocks.filter((block) => block.type !== \"html\");\n}\n\n// src/renderers/video.ts\nfunction getVideoThumbnail(url, customThumbnail) {\n if (customThumbnail) {\n return customThumbnail;\n }\n if (!url) {\n return null;\n }\n const youtubePatterns = [\n /(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/|youtube\\.com\\/embed\\/)([a-zA-Z0-9_-]{11})/,\n /youtube\\.com\\/shorts\\/([a-zA-Z0-9_-]{11})/\n ];\n for (const pattern of youtubePatterns) {\n const match = url.match(pattern);\n if (match) {\n return `https://img.youtube.com/vi/${match[1]}/maxresdefault.jpg`;\n }\n }\n const vimeoMatch = url.match(/vimeo\\.com\\/(?:video\\/)?(\\d+)/);\n if (vimeoMatch) {\n return `https://vumbnail.com/${vimeoMatch[1]}.jpg`;\n }\n return null;\n}\nfunction renderVideo(block, context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n const thumbnailUrl = getVideoThumbnail(block.url, block.thumbnailUrl);\n if (!thumbnailUrl) {\n return \"\";\n }\n const padding = toPaddingString(block.styles.padding);\n const bgColor = bgAttr(block.styles.backgroundColor, \"container\");\n const width = block.width === \"full\" ? context.containerWidth + \"px\" : block.width + \"px\";\n const visibilityAttr = getCssClassAttr(block);\n const src = escapeAttr(thumbnailUrl);\n const alt = escapeAttr(block.alt);\n const align = block.align;\n const href = escapeAttr(block.url);\n return `<mj-image\n src=\"${src}\"\n alt=\"${alt}\"\n width=\"${width}\"\n align=\"${align}\"\n padding=\"${padding}\"\n href=\"${href}\"\n target=\"_blank\"\n rel=\"noopener\"${bgColor}${visibilityAttr}\n/>`;\n}\n\n// src/renderers/index.ts\nfunction renderBlock(block, context) {\n if (isSection2(block)) {\n return renderSection(block, context, renderBlock);\n }\n if (isTitle(block)) {\n return renderTitle(block, context);\n }\n if (isParagraph(block)) {\n return renderParagraph(block, context);\n }\n if (isImage(block)) {\n return renderImage(block, context);\n }\n if (isButton(block)) {\n return renderButton(block, context);\n }\n if (isDivider(block)) {\n return renderDivider(block, context);\n }\n if (isSpacer(block)) {\n return renderSpacer(block, context);\n }\n if (isHtml(block)) {\n return renderHtml(block, context);\n }\n if (isSocialIcons(block)) {\n return renderSocialIcons(block, context);\n }\n if (isMenu(block)) {\n return renderMenu(block, context);\n }\n if (isTable(block)) {\n return renderTable(block, context);\n }\n if (isVideo(block)) {\n return renderVideo(block, context);\n }\n if (isCustomBlock(block)) {\n return renderCustom(block, context);\n }\n return \"\";\n}\n\n// src/index.ts\nasync function renderToMjml(content, options) {\n const customFonts = options?.customFonts ?? [];\n const defaultFallbackFont = options?.defaultFallbackFont ?? \"Arial, sans-serif\";\n const allowHtmlBlocks = options?.allowHtmlBlocks ?? true;\n const customBlockHtml = await resolveCustomBlocks(\n content,\n options?.renderCustomBlock\n );\n const renderContext = new RenderContext(\n content.settings.width,\n customFonts,\n defaultFallbackFont,\n allowHtmlBlocks,\n customBlockHtml\n );\n const blocks = filterHtmlBlocks2(content.blocks, allowHtmlBlocks);\n const fontFamily = renderContext.resolveFontFamily(\n content.settings.fontFamily\n );\n const backgroundColor = content.settings.backgroundColor;\n const bodyContent = blocks.map((block) => renderTopLevelBlock(block, renderContext)).filter((value) => value !== \"\").join(\"\\n\");\n const fontDeclarations = generateFontDeclarations(customFonts);\n const previewTag = generatePreviewTag(content.settings.preheaderText);\n return `<mjml>\n <mj-head>${previewTag}\n <mj-attributes>\n <mj-all font-family=\"${fontFamily}\" />\n <mj-text font-size=\"14px\" />\n <mj-section padding=\"0\" />\n <mj-column padding=\"0\" />\n <mj-image fluid-on-mobile=\"true\" />\n </mj-attributes>${fontDeclarations}\n <mj-style>\n a { color: inherit; text-decoration: none; }\n @media only screen and (max-width: 480px) {\n .tpl-hide-mobile { display: none !important; mso-hide: all !important; }\n }\n @media only screen and (min-width: 481px) and (max-width: 768px) {\n .tpl-hide-tablet { display: none !important; mso-hide: all !important; }\n }\n @media only screen and (min-width: 769px) {\n .tpl-hide-desktop { display: none !important; mso-hide: all !important; }\n }\n </mj-style>\n </mj-head>\n <mj-body width=\"${renderContext.containerWidth}px\" background-color=\"${backgroundColor}\">\n${bodyContent}\n </mj-body>\n</mjml>`;\n}\nfunction renderTopLevelBlock(block, context) {\n if (isSection3(block)) {\n const rendered = renderBlock(block, context);\n return wrapWithDisplayCondition(block, rendered);\n }\n const content = renderBlock(block, context);\n const wrapped = wrapInSection(content);\n return wrapWithDisplayCondition(block, wrapped);\n}\nfunction wrapWithDisplayCondition(block, rendered) {\n if (rendered === \"\") {\n return \"\";\n }\n const displayCondition = block.displayCondition;\n if (!displayCondition) {\n return rendered;\n }\n return `<mj-raw>${displayCondition.before}</mj-raw>\n` + rendered + `\n<mj-raw>${displayCondition.after}</mj-raw>`;\n}\nfunction wrapInSection(content) {\n if (content === \"\") {\n return \"\";\n }\n return `<mj-section>\n <mj-column>\n${content}\n </mj-column>\n</mj-section>`;\n}\nfunction generatePreviewTag(preheaderText) {\n if (!preheaderText) {\n return \"\";\n }\n const trimmed = preheaderText.trim();\n if (trimmed === \"\") {\n return \"\";\n }\n const escaped = escapeHtml(trimmed);\n return `\n <mj-preview>${escaped}</mj-preview>`;\n}\nfunction generateFontDeclarations(customFonts) {\n if (customFonts.length === 0) {\n return \"\";\n }\n return customFonts.map(\n (font) => `\n <mj-font name=\"${escapeAttr(font.name)}\" href=\"${escapeAttr(font.url)}\" />`\n ).join(\"\");\n}\nfunction filterHtmlBlocks2(blocks, allowHtmlBlocks) {\n if (allowHtmlBlocks) {\n return blocks;\n }\n return blocks.filter((block) => block.type !== \"html\");\n}\nasync function resolveCustomBlocks(content, renderCustomBlock) {\n const result = /* @__PURE__ */ new Map();\n if (!renderCustomBlock) {\n return result;\n }\n const customBlocks = [];\n collectCustomBlocks(content.blocks, customBlocks);\n if (customBlocks.length === 0) {\n return result;\n }\n const rendered = await Promise.all(\n customBlocks.map((block) => renderCustomBlock(block))\n );\n for (let index = 0; index < customBlocks.length; index++) {\n result.set(customBlocks[index].id, rendered[index]);\n }\n return result;\n}\nfunction collectCustomBlocks(blocks, out) {\n for (const block of blocks) {\n if (isCustomBlock2(block)) {\n out.push(block);\n continue;\n }\n if (isSection3(block)) {\n for (const column of block.children) {\n collectCustomBlocks(column, out);\n }\n }\n }\n}\nexport {\n RenderContext,\n SOCIAL_ICONS,\n convertMergeTagsToValues,\n escapeAttr,\n escapeHtml,\n generateSocialIconDataUri,\n getCssClassAttr,\n getCssClasses,\n getWidthPercentages,\n getWidthPixels,\n isHiddenOnAll,\n renderBlock,\n renderToMjml,\n toPaddingString\n};\n//# sourceMappingURL=index.js.map"],"mappings":"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"}
1
+ {"version":3,"file":"dist-MGrg9tLo.js","names":["isSection2","isSection3","isCustomBlock2"],"sources":["../../../../renderer/dist/index.js"],"sourcesContent":["// src/index.ts\nimport { isSection as isSection3, isCustomBlock as isCustomBlock2 } from \"@templatical/types\";\n\n// src/render-context.ts\nvar BUILT_IN_FONT_FALLBACKS = {\n arial: \"Arial, sans-serif\",\n helvetica: \"Helvetica, sans-serif\",\n georgia: \"Georgia, serif\",\n \"times new roman\": \"'Times New Roman', serif\",\n verdana: \"Verdana, sans-serif\",\n \"trebuchet ms\": \"'Trebuchet MS', sans-serif\",\n \"courier new\": \"'Courier New', monospace\",\n tahoma: \"Tahoma, sans-serif\"\n};\nvar RenderContext = class _RenderContext {\n constructor(containerWidth, customFonts, defaultFallbackFont, allowHtmlBlocks, customBlockHtml = /* @__PURE__ */ new Map()) {\n this.containerWidth = containerWidth;\n this.customFonts = customFonts;\n this.defaultFallbackFont = defaultFallbackFont;\n this.allowHtmlBlocks = allowHtmlBlocks;\n this.customBlockHtml = customBlockHtml;\n }\n containerWidth;\n customFonts;\n defaultFallbackFont;\n allowHtmlBlocks;\n customBlockHtml;\n /**\n * Create a new context with a different container width.\n * Used when rendering columns with narrower widths.\n */\n withContainerWidth(width) {\n return new _RenderContext(\n width,\n this.customFonts,\n this.defaultFallbackFont,\n this.allowHtmlBlocks,\n this.customBlockHtml\n );\n }\n /**\n * Resolve a font family name to include custom font fallbacks.\n * If the font matches a custom font, returns `'FontName', fallback`.\n * Otherwise returns the original font family string.\n */\n resolveFontFamily(fontFamily) {\n for (const customFont of this.customFonts) {\n if (customFont.name.toLowerCase() === fontFamily.toLowerCase()) {\n const fallback = customFont.fallback ?? this.defaultFallbackFont;\n return `'${customFont.name}', ${fallback}`;\n }\n }\n const builtIn = BUILT_IN_FONT_FALLBACKS[fontFamily.toLowerCase()];\n if (builtIn) {\n return builtIn;\n }\n return fontFamily;\n }\n};\n\n// src/renderers/index.ts\nimport {\n isSection as isSection2,\n isTitle,\n isParagraph,\n isImage,\n isButton,\n isDivider,\n isSpacer,\n isHtml,\n isSocialIcons,\n isMenu,\n isTable,\n isVideo,\n isCustomBlock\n} from \"@templatical/types\";\n\n// src/renderers/title.ts\nimport { HEADING_LEVEL_FONT_SIZE } from \"@templatical/types\";\n\n// src/escape.ts\nvar HTML_ENTITIES = {\n \"&\": \"&amp;\",\n \"<\": \"&lt;\",\n \">\": \"&gt;\",\n '\"': \"&quot;\",\n \"'\": \"&#039;\"\n};\nvar HTML_ENTITY_REGEX = /[&<>\"']/g;\nfunction escapeHtml(text) {\n if (text === \"\") {\n return \"\";\n }\n return text.replace(HTML_ENTITY_REGEX, (char) => HTML_ENTITIES[char] ?? char);\n}\nfunction escapeAttr(text) {\n if (text === \"\") {\n return \"\";\n }\n return text.replace(HTML_ENTITY_REGEX, (char) => HTML_ENTITIES[char] ?? char);\n}\nfunction escapeCssValue(text) {\n if (text === \"\") {\n return \"\";\n }\n return escapeAttr(text).replace(/[;{}\\r\\n]/g, \"\");\n}\nfunction convertMergeTagsToValues(html) {\n if (html === \"\") {\n return \"\";\n }\n let result = html.replace(\n /<span[^>]*\\bdata-merge-tag=\"([^\"]*)\"[^>]*>.*?<\\/span>/gs,\n \"$1\"\n );\n result = result.replace(\n /<span[^>]*\\bdata-logic-merge-tag=\"([^\"]*)\"[^>]*>.*?<\\/span>/gs,\n \"$1\"\n );\n return result;\n}\n\n// src/padding.ts\nfunction toPaddingString(padding) {\n return `${padding.top}px ${padding.right}px ${padding.bottom}px ${padding.left}px`;\n}\n\n// src/utils.ts\nfunction bgAttr(backgroundColor, placement) {\n if (!backgroundColor) {\n return \"\";\n }\n const name = placement === \"native\" ? \"background-color\" : \"container-background-color\";\n return ` ${name}=\"${backgroundColor}\"`;\n}\n\n// src/visibility.ts\nfunction isHiddenOnAll(block) {\n const visibility = block.visibility;\n if (!visibility) {\n return false;\n }\n return !visibility.desktop && !visibility.tablet && !visibility.mobile;\n}\nfunction getCssClassAttr(block) {\n const classes = getCssClasses(block);\n if (classes === \"\") {\n return \"\";\n }\n return ` css-class=\"${classes}\"`;\n}\nfunction getCssClasses(block) {\n const visibility = block.visibility;\n if (!visibility) {\n return \"\";\n }\n const classes = [];\n if (!visibility.desktop) {\n classes.push(\"tpl-hide-desktop\");\n }\n if (!visibility.tablet) {\n classes.push(\"tpl-hide-tablet\");\n }\n if (!visibility.mobile) {\n classes.push(\"tpl-hide-mobile\");\n }\n return classes.join(\" \");\n}\n\n// src/renderers/title.ts\nfunction renderTitle(block, context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n const padding = toPaddingString(block.styles.padding);\n const bgColor = bgAttr(block.styles.backgroundColor, \"container\");\n const content = unwrapParagraph(convertMergeTagsToValues(block.content));\n const fontSize = HEADING_LEVEL_FONT_SIZE[block.level] ?? HEADING_LEVEL_FONT_SIZE[2];\n const color = block.color;\n const align = block.textAlign;\n const fontFamilyAttr = renderFontFamilyAttr(block.fontFamily, context);\n const visibilityAttr = getCssClassAttr(block);\n const safeLevel = HEADING_LEVEL_FONT_SIZE[block.level] ? block.level : 2;\n const tag = `h${safeLevel}`;\n return `<mj-text\n font-size=\"${fontSize}px\"\n color=\"${color}\"\n align=\"${align}\"\n line-height=\"1.3\"\n padding=\"${padding}\"${bgColor}${fontFamilyAttr}${visibilityAttr}\n><${tag} style=\"margin:0;font-size:inherit;color:inherit;line-height:inherit\">${content}</${tag}></mj-text>`;\n}\nfunction unwrapParagraph(html) {\n const match = html.match(/^\\s*<p\\b[^>]*>([\\s\\S]*)<\\/p>\\s*$/);\n if (!match) return html;\n if (/<\\/p>\\s*<p\\b/i.test(match[1])) return html;\n return match[1];\n}\nfunction renderFontFamilyAttr(fontFamily, context) {\n if (!fontFamily) {\n return \"\";\n }\n const resolved = context.resolveFontFamily(fontFamily);\n return ` font-family=\"${resolved}\"`;\n}\n\n// src/renderers/paragraph.ts\nfunction renderParagraph(block, _context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n const stripped = block.content.replace(/<\\/?p[^>]*>/gi, \"\").trim();\n if (stripped === \"\") {\n return \"\";\n }\n const padding = toPaddingString(block.styles.padding);\n const bgColor = bgAttr(block.styles.backgroundColor, \"container\");\n const content = convertMergeTagsToValues(block.content);\n const visibilityAttr = getCssClassAttr(block);\n return `<mj-text\n line-height=\"1.5\"\n padding=\"${padding}\"${bgColor}${visibilityAttr}\n>${content}</mj-text>`;\n}\n\n// src/renderers/image.ts\nfunction renderImage(block, context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n if (block.src === \"\") {\n return \"\";\n }\n const padding = toPaddingString(block.styles.padding);\n const bgColor = bgAttr(block.styles.backgroundColor, \"container\");\n const width = block.width === \"full\" ? context.containerWidth + \"px\" : block.width + \"px\";\n const visibilityAttr = getCssClassAttr(block);\n let linkAttr = \"\";\n if (block.linkUrl) {\n linkAttr = ` href=\"${escapeAttr(block.linkUrl)}\"`;\n if (block.linkOpenInNewTab) {\n linkAttr += ' target=\"_blank\" rel=\"noopener\"';\n }\n }\n const src = escapeAttr(block.src);\n const alt = escapeAttr(block.alt);\n const align = block.align;\n return `<mj-image\n src=\"${src}\"\n alt=\"${alt}\"\n width=\"${width}\"\n align=\"${align}\"\n padding=\"${padding}\"${bgColor}${linkAttr}${visibilityAttr}\n/>`;\n}\n\n// src/renderers/button.ts\nfunction renderButton(block, context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n const padding = toPaddingString(block.styles.padding);\n const bgColor = bgAttr(block.styles.backgroundColor, \"container\");\n const buttonPadding = toPaddingString(block.buttonPadding);\n const href = block.url === \"\" ? \"\" : escapeAttr(block.url);\n const hrefAttr = href === \"\" ? \"\" : ` href=\"${href}\"`;\n const backgroundColor = escapeAttr(block.backgroundColor);\n const textColor = escapeAttr(block.textColor);\n const fontSize = block.fontSize;\n const borderRadius = block.borderRadius;\n const text = escapeHtml(block.text);\n const targetAttr = block.openInNewTab ? ' target=\"_blank\" rel=\"noopener\"' : \"\";\n const fontFamilyAttr = renderFontFamilyAttr2(block.fontFamily, context);\n const visibilityAttr = getCssClassAttr(block);\n return `<mj-button${hrefAttr}${targetAttr}\n background-color=\"${backgroundColor}\"\n color=\"${textColor}\"\n font-size=\"${fontSize}px\"\n font-weight=\"bold\"\n border-radius=\"${borderRadius}px\"\n inner-padding=\"${buttonPadding}\"\n padding=\"${padding}\"${bgColor}${fontFamilyAttr}${visibilityAttr}\n>${text}</mj-button>`;\n}\nfunction renderFontFamilyAttr2(fontFamily, context) {\n if (!fontFamily) {\n return \"\";\n }\n const resolved = context.resolveFontFamily(fontFamily);\n return ` font-family=\"${resolved}\"`;\n}\n\n// src/renderers/divider.ts\nfunction renderDivider(block, _context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n const padding = toPaddingString(block.styles.padding);\n const bgColor = block.styles.backgroundColor ? ` container-background-color=\"${block.styles.backgroundColor}\"` : \"\";\n const width = block.width === \"full\" ? \"100%\" : block.width + \"px\";\n const thickness = block.thickness;\n const lineStyle = block.lineStyle;\n const color = block.color;\n const visibilityAttr = getCssClassAttr(block);\n return `<mj-divider\n border-width=\"${thickness}px\"\n border-style=\"${lineStyle}\"\n border-color=\"${color}\"\n width=\"${width}\"\n padding=\"${padding}\"${bgColor}${visibilityAttr}\n/>`;\n}\n\n// src/renderers/spacer.ts\nfunction renderSpacer(block, _context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n const height = block.height;\n const bgColor = block.styles.backgroundColor ? ` container-background-color=\"${block.styles.backgroundColor}\"` : \"\";\n const visibilityAttr = getCssClassAttr(block);\n return `<mj-spacer height=\"${height}px\" padding=\"0\"${bgColor}${visibilityAttr} />`;\n}\n\n// src/renderers/html.ts\nfunction renderHtml(block, context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n if (!context.allowHtmlBlocks) {\n return \"\";\n }\n const content = block.content;\n if (content === \"\") {\n return \"\";\n }\n const visibilityAttr = getCssClassAttr(block);\n return `<mj-text${visibilityAttr}>\n${content}\n</mj-text>`;\n}\n\n// src/social-icons.ts\nvar SOCIAL_ICONS = {\n facebook: {\n path: \"M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z\",\n color: \"#1877F2\"\n },\n twitter: {\n path: \"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z\",\n color: \"#000000\"\n },\n instagram: {\n path: \"M12 0C8.74 0 8.333.015 7.053.072 5.775.132 4.905.333 4.14.63c-.789.306-1.459.717-2.126 1.384S.935 3.35.63 4.14C.333 4.905.131 5.775.072 7.053.012 8.333 0 8.74 0 12s.015 3.667.072 4.947c.06 1.277.261 2.148.558 2.913.306.788.717 1.459 1.384 2.126.667.666 1.336 1.079 2.126 1.384.766.296 1.636.499 2.913.558C8.333 23.988 8.74 24 12 24s3.667-.015 4.947-.072c1.277-.06 2.148-.262 2.913-.558.788-.306 1.459-.718 2.126-1.384.666-.667 1.079-1.335 1.384-2.126.296-.765.499-1.636.558-2.913.06-1.28.072-1.687.072-4.947s-.015-3.667-.072-4.947c-.06-1.277-.262-2.149-.558-2.913-.306-.789-.718-1.459-1.384-2.126C21.319 1.347 20.651.935 19.86.63c-.765-.297-1.636-.499-2.913-.558C15.667.012 15.26 0 12 0zm0 2.16c3.203 0 3.585.016 4.85.071 1.17.055 1.805.249 2.227.415.562.217.96.477 1.382.896.419.42.679.819.896 1.381.164.422.36 1.057.413 2.227.057 1.266.07 1.646.07 4.85s-.015 3.585-.074 4.85c-.061 1.17-.256 1.805-.421 2.227-.224.562-.479.96-.899 1.382-.419.419-.824.679-1.38.896-.42.164-1.065.36-2.235.413-1.274.057-1.649.07-4.859.07-3.211 0-3.586-.015-4.859-.074-1.171-.061-1.816-.256-2.236-.421-.569-.224-.96-.479-1.379-.899-.421-.419-.69-.824-.9-1.38-.165-.42-.359-1.065-.42-2.235-.045-1.26-.061-1.649-.061-4.844 0-3.196.016-3.586.061-4.861.061-1.17.255-1.814.42-2.234.21-.57.479-.96.9-1.381.419-.419.81-.689 1.379-.898.42-.166 1.051-.361 2.221-.421 1.275-.045 1.65-.06 4.859-.06l.045.03zm0 3.678c-3.405 0-6.162 2.76-6.162 6.162 0 3.405 2.76 6.162 6.162 6.162 3.405 0 6.162-2.76 6.162-6.162 0-3.405-2.76-6.162-6.162-6.162zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm7.846-10.405c0 .795-.646 1.44-1.44 1.44-.795 0-1.44-.646-1.44-1.44 0-.794.646-1.439 1.44-1.439.793-.001 1.44.645 1.44 1.439z\",\n color: \"#E4405F\"\n },\n linkedin: {\n path: \"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z\",\n color: \"#0A66C2\"\n },\n youtube: {\n path: \"M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z\",\n color: \"#FF0000\"\n },\n tiktok: {\n path: \"M12.525.02c1.31-.02 2.61-.01 3.91-.02.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.05-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.93-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.08-1.03-2.02-1.19-3.44-3.37-3.65-5.71-.02-.5-.03-1-.01-1.49.18-1.9 1.12-3.72 2.58-4.96 1.66-1.44 3.98-2.13 6.15-1.72.02 1.48-.04 2.96-.04 4.44-.99-.32-2.15-.23-3.02.37-.63.41-1.11 1.04-1.36 1.75-.21.51-.15 1.07-.14 1.61.24 1.64 1.82 3.02 3.5 2.87 1.12-.01 2.19-.66 2.77-1.61.19-.33.4-.67.41-1.06.1-1.79.06-3.57.07-5.36.01-4.03-.01-8.05.02-12.07z\",\n color: \"#000000\"\n },\n pinterest: {\n path: \"M12 0C5.373 0 0 5.372 0 12c0 5.084 3.163 9.426 7.627 11.174-.105-.949-.2-2.405.042-3.441.218-.937 1.407-5.965 1.407-5.965s-.359-.719-.359-1.782c0-1.668.967-2.914 2.171-2.914 1.023 0 1.518.769 1.518 1.69 0 1.029-.655 2.568-.994 3.995-.283 1.194.599 2.169 1.777 2.169 2.133 0 3.772-2.249 3.772-5.495 0-2.873-2.064-4.882-5.012-4.882-3.414 0-5.418 2.561-5.418 5.207 0 1.031.397 2.138.893 2.738.098.119.112.224.083.345l-.333 1.36c-.053.22-.174.267-.402.161-1.499-.698-2.436-2.889-2.436-4.649 0-3.785 2.75-7.262 7.929-7.262 4.163 0 7.398 2.967 7.398 6.931 0 4.136-2.607 7.464-6.227 7.464-1.216 0-2.359-.631-2.75-1.378l-.748 2.853c-.271 1.043-1.002 2.35-1.492 3.146C9.57 23.812 10.763 24 12 24c6.627 0 12-5.373 12-12 0-6.628-5.373-12-12-12z\",\n color: \"#BD081C\"\n },\n email: {\n path: \"M1.5 8.67v8.58a3 3 0 003 3h15a3 3 0 003-3V8.67l-8.928 5.493a3 3 0 01-3.144 0L1.5 8.67z M22.5 6.908V6.75a3 3 0 00-3-3h-15a3 3 0 00-3 3v.158l9.714 5.978a1.5 1.5 0 001.572 0L22.5 6.908z\",\n color: \"#6B7280\"\n },\n whatsapp: {\n path: \"M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z\",\n color: \"#25D366\"\n },\n telegram: {\n path: \"M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z\",\n color: \"#26A5E4\"\n },\n discord: {\n path: \"M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189z\",\n color: \"#5865F2\"\n },\n snapchat: {\n path: \"M12.017 0C5.396 0 .029 5.367.029 11.987c0 5.079 3.158 9.417 7.618 11.162-.105-.949-.199-2.403.041-3.439.219-.937 1.406-5.957 1.406-5.957s-.359-.72-.359-1.781c0-1.668.967-2.914 2.171-2.914 1.023 0 1.518.769 1.518 1.69 0 1.029-.655 2.568-.994 3.995-.283 1.194.599 2.169 1.777 2.169 2.133 0 3.772-2.249 3.772-5.495 0-2.873-2.064-4.882-5.012-4.882-3.414 0-5.418 2.561-5.418 5.207 0 1.031.397 2.138.893 2.738a.36.36 0 01.083.345l-.333 1.36c-.053.22-.174.267-.402.161-1.499-.698-2.436-2.889-2.436-4.649 0-3.785 2.75-7.262 7.929-7.262 4.163 0 7.398 2.967 7.398 6.931 0 4.136-2.607 7.464-6.227 7.464-1.216 0-2.359-.631-2.75-1.378l-.748 2.853c-.271 1.043-1.002 2.35-1.492 3.146 1.124.347 2.317.535 3.554.535 6.627 0 12.017-5.373 12.017-12.001C24.034 5.367 18.644 0 12.017 0z\",\n color: \"#FFFC00\"\n },\n reddit: {\n path: \"M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25c0 .687.561 1.248 1.25 1.248.687 0 1.248-.561 1.248-1.249 0-.688-.561-1.249-1.249-1.249zm5.5 0c-.687 0-1.248.561-1.248 1.25 0 .687.561 1.248 1.249 1.248.688 0 1.249-.561 1.249-1.249 0-.687-.562-1.249-1.25-1.249zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z\",\n color: \"#FF4500\"\n },\n github: {\n path: \"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\",\n color: \"#181717\"\n },\n dribbble: {\n path: \"M12 24C5.385 24 0 18.615 0 12S5.385 0 12 0s12 5.385 12 12-5.385 12-12 12zm10.12-10.358c-.35-.11-3.17-.953-6.384-.438 1.34 3.684 1.887 6.684 1.992 7.308 2.3-1.555 3.936-4.02 4.392-6.87zm-6.115 7.808c-.153-.9-.75-4.032-2.19-7.77l-.066.02c-5.79 2.015-7.86 6.025-8.04 6.4 1.73 1.358 3.92 2.166 6.29 2.166 1.42 0 2.77-.29 4-.814zm-11.62-2.58c.232-.4 3.045-5.055 8.332-6.765.135-.045.27-.084.405-.12-.26-.585-.54-1.167-.832-1.74C7.17 11.775 2.206 11.71 1.756 11.7l-.004.312c0 2.633.998 5.037 2.634 6.855zm-2.42-8.955c.46.008 4.683.026 9.477-1.248-1.698-3.018-3.53-5.558-3.8-5.928-2.868 1.35-5.01 3.99-5.676 7.17zM9.6 2.052c.282.38 2.145 2.914 3.822 6 3.645-1.365 5.19-3.44 5.373-3.702-1.81-1.61-4.19-2.586-6.795-2.586-.825 0-1.63.1-2.4.285zm10.335 3.483c-.218.29-1.935 2.493-5.724 4.04.24.49.47.985.68 1.486.08.18.15.36.22.53 3.41-.43 6.8.26 7.14.33-.02-2.42-.88-4.64-2.31-6.38z\",\n color: \"#EA4C89\"\n },\n behance: {\n path: \"M22 7h-7V5h7v2zm1.726 10c-.442 1.297-2.029 3-5.101 3-3.074 0-5.564-1.729-5.564-5.675 0-3.91 2.325-5.92 5.466-5.92 3.082 0 4.964 1.782 5.375 4.426.078.506.109 1.188.095 2.14H15.97c.13 3.211 3.483 3.312 4.588 2.029h3.168zm-7.686-4h4.965c-.105-1.547-1.136-2.219-2.477-2.219-1.466 0-2.277.768-2.488 2.219zm-9.574 6.988H0V5.021h6.953c5.476.081 5.58 5.444 2.72 6.906 3.461 1.26 3.577 8.061-3.207 8.061zM3 11h3.584c2.508 0 2.906-3-.312-3H3v3zm3.391 3H3v3.016h3.341c3.055 0 2.868-3.016.05-3.016z\",\n color: \"#1769FF\"\n }\n};\nfunction generateSocialIconDataUri(platform, style, size) {\n const iconData = SOCIAL_ICONS[platform];\n const path = iconData?.path ?? \"\";\n const brandColor = iconData?.color ?? \"#6B7280\";\n if (path === \"\") {\n return \"\";\n }\n const isOutlined = style === \"outlined\";\n const iconColor = isOutlined ? brandColor : \"#ffffff\";\n let bgShape;\n switch (style) {\n case \"circle\":\n bgShape = `<circle cx=\"12\" cy=\"12\" r=\"12\" fill=\"${brandColor}\"/>`;\n break;\n case \"rounded\":\n bgShape = `<rect width=\"24\" height=\"24\" rx=\"6\" fill=\"${brandColor}\"/>`;\n break;\n case \"square\":\n bgShape = `<rect width=\"24\" height=\"24\" rx=\"0\" fill=\"${brandColor}\"/>`;\n break;\n case \"outlined\":\n bgShape = `<rect width=\"22\" height=\"22\" x=\"1\" y=\"1\" rx=\"3\" fill=\"transparent\" stroke=\"${brandColor}\" stroke-width=\"2\"/>`;\n break;\n default:\n bgShape = `<rect width=\"24\" height=\"24\" rx=\"3\" fill=\"${brandColor}\"/>`;\n break;\n }\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" width=\"${size}\" height=\"${size}\">` + bgShape + `<g transform=\"translate(4.8, 4.8) scale(0.6)\"><path d=\"${path}\" fill=\"${iconColor}\"/></g></svg>`;\n return \"data:image/svg+xml;base64,\" + btoa(svg);\n}\n\n// src/renderers/social.ts\nfunction renderSocialIcons(block, _context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n const icons = block.icons;\n if (icons.length === 0) {\n return \"\";\n }\n const padding = toPaddingString(block.styles.padding);\n const bgColor = block.styles.backgroundColor ? ` container-background-color=\"${block.styles.backgroundColor}\"` : \"\";\n const visibilityAttr = getCssClassAttr(block);\n const align = block.align;\n const iconSize = block.iconSize;\n const iconStyle = block.iconStyle;\n const spacing = block.spacing;\n let iconSizePx;\n switch (iconSize) {\n case \"small\":\n iconSizePx = 24;\n break;\n case \"large\":\n iconSizePx = 48;\n break;\n default:\n iconSizePx = 32;\n break;\n }\n let borderRadius;\n switch (iconStyle) {\n case \"circle\":\n borderRadius = \"50%\";\n break;\n case \"rounded\":\n borderRadius = \"8px\";\n break;\n case \"square\":\n borderRadius = \"0\";\n break;\n default:\n borderRadius = \"4px\";\n break;\n }\n const iconCount = icons.length;\n const socialElements = icons.map((icon, index) => {\n const platform = icon.platform;\n const url = escapeAttr(icon.url);\n const iconSrc = generateSocialIconDataUri(platform, iconStyle, iconSizePx);\n const rightPad = index === iconCount - 1 ? 0 : spacing;\n return `<mj-social-element src=\"${iconSrc}\" href=\"${url}\" icon-size=\"${iconSizePx}px\" padding=\"0 ${rightPad}px 0 0\" border-radius=\"${borderRadius}\" background-color=\"transparent\"></mj-social-element>`;\n });\n const socialContent = socialElements.join(\"\\n\");\n return `<mj-social\n mode=\"horizontal\"\n align=\"${align}\"\n icon-padding=\"0\"\n padding=\"${padding}\"${bgColor}${visibilityAttr}\n>\n${socialContent}\n</mj-social>`;\n}\n\n// src/renderers/menu.ts\nfunction renderMenu(block, context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n if (block.items.length === 0) {\n return \"\";\n }\n const padding = toPaddingString(block.styles.padding);\n const bgColor = bgAttr(block.styles.backgroundColor, \"container\");\n const visibilityAttr = getCssClassAttr(block);\n const fontFamilyAttr = renderFontFamilyAttr3(block.fontFamily, context);\n const align = block.textAlign;\n const fontSize = block.fontSize;\n const color = block.color;\n const content = renderMenuItems(block);\n return `<mj-text\n font-size=\"${fontSize}px\"\n color=\"${color}\"\n align=\"${align}\"\n line-height=\"1.5\"\n padding=\"${padding}\"${bgColor}${fontFamilyAttr}${visibilityAttr}\n>${content}</mj-text>`;\n}\nfunction renderMenuItems(block) {\n const items = block.items;\n const separator = escapeHtml(block.separator);\n const separatorColor = escapeCssValue(block.separatorColor);\n const spacing = block.spacing;\n const linkColor = block.linkColor ?? block.color;\n const parts = [];\n const itemCount = items.length;\n for (let index = 0; index < itemCount; index++) {\n parts.push(renderMenuItem(items[index], linkColor));\n if (index < itemCount - 1) {\n parts.push(\n `<span style=\"color: ${separatorColor}; padding: 0 ${spacing}px;\">${separator}</span>`\n );\n }\n }\n return parts.join(\"\");\n}\nfunction renderMenuItem(item, linkColor) {\n const text = escapeHtml(item.text);\n const url = escapeAttr(item.url);\n const color = escapeCssValue(item.color ?? linkColor);\n const target = item.openInNewTab ? ' target=\"_blank\" rel=\"noopener\"' : \"\";\n const styles = [`color: ${color}`, \"text-decoration: none\"];\n if (item.bold) {\n styles.push(\"font-weight: bold\");\n }\n if (item.underline) {\n styles.push(\"text-decoration: underline\");\n }\n const styleAttr = styles.join(\"; \");\n return `<a href=\"${url}\" style=\"${styleAttr}\"${target}>${text}</a>`;\n}\nfunction renderFontFamilyAttr3(fontFamily, context) {\n if (!fontFamily) {\n return \"\";\n }\n const resolved = context.resolveFontFamily(fontFamily);\n return ` font-family=\"${resolved}\"`;\n}\n\n// src/renderers/table.ts\nfunction renderTable(block, context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n if (block.rows.length === 0) {\n return \"\";\n }\n const padding = toPaddingString(block.styles.padding);\n const bgColor = bgAttr(block.styles.backgroundColor, \"container\");\n const visibilityAttr = getCssClassAttr(block);\n const fontFamilyAttr = renderFontFamilyAttr4(block.fontFamily, context);\n const fontSize = block.fontSize;\n const color = block.color;\n const align = block.textAlign;\n const tableHtml = renderTableElement(block);\n return `<mj-text\n font-size=\"${fontSize}px\"\n color=\"${color}\"\n align=\"${align}\"\n line-height=\"1.5\"\n padding=\"${padding}\"${bgColor}${fontFamilyAttr}${visibilityAttr}\n>${tableHtml}</mj-text>`;\n}\nfunction renderTableElement(block) {\n const borderColor = escapeCssValue(block.borderColor);\n const borderWidth = block.borderWidth;\n const tableStyle = \"width: 100%; border-collapse: collapse;\";\n let rowsHtml = \"\";\n for (let index = 0; index < block.rows.length; index++) {\n const row = block.rows[index];\n const isHeader = block.hasHeaderRow && index === 0;\n rowsHtml += renderRow(row, block, isHeader, borderColor, borderWidth);\n }\n return `<table style=\"${tableStyle}\">${rowsHtml}</table>`;\n}\nfunction renderRow(row, block, isHeader, borderColor, borderWidth) {\n let cellsHtml = \"\";\n for (const cell of row.cells) {\n cellsHtml += renderCell(cell, block, isHeader, borderColor, borderWidth);\n }\n return `<tr>${cellsHtml}</tr>`;\n}\nfunction renderCell(cell, block, isHeader, borderColor, borderWidth) {\n const cellPadding = block.cellPadding;\n const styles = [\n `border: ${borderWidth}px solid ${borderColor}`,\n `padding: ${cellPadding}px`\n ];\n if (isHeader) {\n styles.push(\"font-weight: bold\");\n if (block.headerBackgroundColor) {\n styles.push(\n `background-color: ${escapeCssValue(block.headerBackgroundColor)}`\n );\n }\n }\n const styleAttr = styles.join(\"; \");\n const content = convertMergeTagsToValues(cell.content);\n const tag = isHeader ? \"th\" : \"td\";\n return `<${tag} style=\"${styleAttr}\">${content}</${tag}>`;\n}\nfunction renderFontFamilyAttr4(fontFamily, context) {\n if (!fontFamily) {\n return \"\";\n }\n const resolved = context.resolveFontFamily(fontFamily);\n return ` font-family=\"${resolved}\"`;\n}\n\n// src/renderers/custom.ts\nfunction renderCustom(block, context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n const fromContext = context.customBlockHtml.get(block.id);\n const content = fromContext ?? block.renderedHtml;\n if (!content || content === \"\") {\n return \"\";\n }\n const visibilityAttr = getCssClassAttr(block);\n const bgColor = bgAttr(block.styles?.backgroundColor, \"container\");\n return `<mj-text${bgColor}${visibilityAttr}>\n${content}\n</mj-text>`;\n}\n\n// src/renderers/section.ts\nimport { isSection } from \"@templatical/types\";\n\n// src/columns.ts\nfunction getWidthPercentages(layout) {\n switch (layout) {\n case \"2\":\n return [\"50%\", \"50%\"];\n case \"3\":\n return [\"33.33%\", \"33.33%\", \"33.34%\"];\n case \"1-2\":\n return [\"33.33%\", \"66.67%\"];\n case \"2-1\":\n return [\"66.67%\", \"33.33%\"];\n default:\n return [\"100%\"];\n }\n}\nfunction getWidthPixels(layout, containerWidth) {\n switch (layout) {\n case \"2\":\n return [containerWidth * 0.5, containerWidth * 0.5];\n case \"3\":\n return [containerWidth / 3, containerWidth / 3, containerWidth / 3];\n case \"1-2\":\n return [containerWidth / 3, containerWidth * 2 / 3];\n case \"2-1\":\n return [containerWidth * 2 / 3, containerWidth / 3];\n default:\n return [containerWidth];\n }\n}\n\n// src/renderers/section.ts\nfunction renderSection(block, context, renderBlock2) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n const columnsLayout = block.columns;\n const columnWidths = getWidthPercentages(columnsLayout);\n const columnWidthsPx = getWidthPixels(columnsLayout, context.containerWidth);\n const padding = toPaddingString(block.styles.padding);\n const bgColor = bgAttr(block.styles.backgroundColor, \"native\");\n const visibilityAttr = getCssClassAttr(block);\n const children = block.children;\n const columnsContent = [];\n for (let index = 0; index < children.length; index++) {\n const column = children[index];\n const width = columnWidths[index] ?? \"100%\";\n const columnWidth = Math.floor(\n columnWidthsPx[index] ?? context.containerWidth\n );\n const filteredColumn = filterHtmlBlocks(\n column,\n context.allowHtmlBlocks\n ).filter((child) => !isSection(child));\n const columnContext = context.withContainerWidth(columnWidth);\n const columnBlocks = filteredColumn.map((child) => renderBlock2(child, columnContext)).filter((value) => value !== \"\").join(\"\\n\");\n const content = columnBlocks === \"\" ? \"<mj-text>&nbsp;</mj-text>\" : columnBlocks;\n columnsContent.push(`<mj-column width=\"${width}\">\n${content}\n</mj-column>`);\n }\n const columns = columnsContent.join(\"\\n\");\n return `<mj-section${bgColor} padding=\"${padding}\"${visibilityAttr}>\n${columns}\n</mj-section>`;\n}\nfunction filterHtmlBlocks(blocks, allowHtmlBlocks) {\n if (allowHtmlBlocks) {\n return blocks;\n }\n return blocks.filter((block) => block.type !== \"html\");\n}\n\n// src/renderers/video.ts\nfunction getVideoThumbnail(url, customThumbnail) {\n if (customThumbnail) {\n return customThumbnail;\n }\n if (!url) {\n return null;\n }\n const youtubePatterns = [\n /(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/|youtube\\.com\\/embed\\/)([a-zA-Z0-9_-]{11})/,\n /youtube\\.com\\/shorts\\/([a-zA-Z0-9_-]{11})/\n ];\n for (const pattern of youtubePatterns) {\n const match = url.match(pattern);\n if (match) {\n return `https://img.youtube.com/vi/${match[1]}/maxresdefault.jpg`;\n }\n }\n const vimeoMatch = url.match(/vimeo\\.com\\/(?:video\\/)?(\\d+)/);\n if (vimeoMatch) {\n return `https://vumbnail.com/${vimeoMatch[1]}.jpg`;\n }\n return null;\n}\nfunction renderVideo(block, context) {\n if (isHiddenOnAll(block)) {\n return \"\";\n }\n const thumbnailUrl = getVideoThumbnail(block.url, block.thumbnailUrl);\n if (!thumbnailUrl) {\n return \"\";\n }\n const padding = toPaddingString(block.styles.padding);\n const bgColor = bgAttr(block.styles.backgroundColor, \"container\");\n const width = block.width === \"full\" ? context.containerWidth + \"px\" : block.width + \"px\";\n const visibilityAttr = getCssClassAttr(block);\n const src = escapeAttr(thumbnailUrl);\n const alt = escapeAttr(block.alt);\n const align = block.align;\n const href = escapeAttr(block.url);\n return `<mj-image\n src=\"${src}\"\n alt=\"${alt}\"\n width=\"${width}\"\n align=\"${align}\"\n padding=\"${padding}\"\n href=\"${href}\"\n target=\"_blank\"\n rel=\"noopener\"${bgColor}${visibilityAttr}\n/>`;\n}\n\n// src/renderers/index.ts\nfunction renderBlock(block, context) {\n if (isSection2(block)) {\n return renderSection(block, context, renderBlock);\n }\n if (isTitle(block)) {\n return renderTitle(block, context);\n }\n if (isParagraph(block)) {\n return renderParagraph(block, context);\n }\n if (isImage(block)) {\n return renderImage(block, context);\n }\n if (isButton(block)) {\n return renderButton(block, context);\n }\n if (isDivider(block)) {\n return renderDivider(block, context);\n }\n if (isSpacer(block)) {\n return renderSpacer(block, context);\n }\n if (isHtml(block)) {\n return renderHtml(block, context);\n }\n if (isSocialIcons(block)) {\n return renderSocialIcons(block, context);\n }\n if (isMenu(block)) {\n return renderMenu(block, context);\n }\n if (isTable(block)) {\n return renderTable(block, context);\n }\n if (isVideo(block)) {\n return renderVideo(block, context);\n }\n if (isCustomBlock(block)) {\n return renderCustom(block, context);\n }\n return \"\";\n}\n\n// src/index.ts\nasync function renderToMjml(content, options) {\n const customFonts = options?.customFonts ?? [];\n const defaultFallbackFont = options?.defaultFallbackFont ?? \"Arial, sans-serif\";\n const allowHtmlBlocks = options?.allowHtmlBlocks ?? true;\n const customBlockHtml = await resolveCustomBlocks(\n content,\n options?.renderCustomBlock\n );\n const renderContext = new RenderContext(\n content.settings.width,\n customFonts,\n defaultFallbackFont,\n allowHtmlBlocks,\n customBlockHtml\n );\n const blocks = filterHtmlBlocks2(content.blocks, allowHtmlBlocks);\n const fontFamily = renderContext.resolveFontFamily(\n content.settings.fontFamily\n );\n const backgroundColor = content.settings.backgroundColor;\n const bodyContent = blocks.map((block) => renderTopLevelBlock(block, renderContext)).filter((value) => value !== \"\").join(\"\\n\");\n const fontDeclarations = generateFontDeclarations(customFonts);\n const previewTag = generatePreviewTag(content.settings.preheaderText);\n return `<mjml>\n <mj-head>${previewTag}\n <mj-attributes>\n <mj-all font-family=\"${fontFamily}\" />\n <mj-text font-size=\"14px\" />\n <mj-section padding=\"0\" />\n <mj-column padding=\"0\" />\n <mj-image fluid-on-mobile=\"true\" />\n </mj-attributes>${fontDeclarations}\n <mj-style>\n a { color: inherit; text-decoration: none; }\n @media only screen and (max-width: 480px) {\n .tpl-hide-mobile { display: none !important; mso-hide: all !important; }\n }\n @media only screen and (min-width: 481px) and (max-width: 768px) {\n .tpl-hide-tablet { display: none !important; mso-hide: all !important; }\n }\n @media only screen and (min-width: 769px) {\n .tpl-hide-desktop { display: none !important; mso-hide: all !important; }\n }\n </mj-style>\n </mj-head>\n <mj-body width=\"${renderContext.containerWidth}px\" background-color=\"${backgroundColor}\">\n${bodyContent}\n </mj-body>\n</mjml>`;\n}\nfunction renderTopLevelBlock(block, context) {\n if (isSection3(block)) {\n const rendered = renderBlock(block, context);\n return wrapWithDisplayCondition(block, rendered);\n }\n const content = renderBlock(block, context);\n const wrapped = wrapInSection(content);\n return wrapWithDisplayCondition(block, wrapped);\n}\nfunction wrapWithDisplayCondition(block, rendered) {\n if (rendered === \"\") {\n return \"\";\n }\n const displayCondition = block.displayCondition;\n if (!displayCondition) {\n return rendered;\n }\n return `<mj-raw>${displayCondition.before}</mj-raw>\n` + rendered + `\n<mj-raw>${displayCondition.after}</mj-raw>`;\n}\nfunction wrapInSection(content) {\n if (content === \"\") {\n return \"\";\n }\n return `<mj-section>\n <mj-column>\n${content}\n </mj-column>\n</mj-section>`;\n}\nfunction generatePreviewTag(preheaderText) {\n if (!preheaderText) {\n return \"\";\n }\n const trimmed = preheaderText.trim();\n if (trimmed === \"\") {\n return \"\";\n }\n const escaped = escapeHtml(trimmed);\n return `\n <mj-preview>${escaped}</mj-preview>`;\n}\nfunction generateFontDeclarations(customFonts) {\n if (customFonts.length === 0) {\n return \"\";\n }\n return customFonts.map(\n (font) => `\n <mj-font name=\"${escapeAttr(font.name)}\" href=\"${escapeAttr(font.url)}\" />`\n ).join(\"\");\n}\nfunction filterHtmlBlocks2(blocks, allowHtmlBlocks) {\n if (allowHtmlBlocks) {\n return blocks;\n }\n return blocks.filter((block) => block.type !== \"html\");\n}\nasync function resolveCustomBlocks(content, renderCustomBlock) {\n const result = /* @__PURE__ */ new Map();\n if (!renderCustomBlock) {\n return result;\n }\n const customBlocks = [];\n collectCustomBlocks(content.blocks, customBlocks);\n if (customBlocks.length === 0) {\n return result;\n }\n const rendered = await Promise.all(\n customBlocks.map((block) => renderCustomBlock(block))\n );\n for (let index = 0; index < customBlocks.length; index++) {\n result.set(customBlocks[index].id, rendered[index]);\n }\n return result;\n}\nfunction collectCustomBlocks(blocks, out) {\n for (const block of blocks) {\n if (isCustomBlock2(block)) {\n out.push(block);\n continue;\n }\n if (isSection3(block)) {\n for (const column of block.children) {\n collectCustomBlocks(column, out);\n }\n }\n }\n}\nexport {\n RenderContext,\n SOCIAL_ICONS,\n convertMergeTagsToValues,\n escapeAttr,\n escapeHtml,\n generateSocialIconDataUri,\n getCssClassAttr,\n getCssClasses,\n getWidthPercentages,\n getWidthPixels,\n isHiddenOnAll,\n renderBlock,\n renderToMjml,\n toPaddingString\n};\n//# sourceMappingURL=index.js.map"],"mappings":"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"}