@maizzle/framework 6.0.0-rc.16 → 6.0.0-rc.18

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 (460) hide show
  1. package/bin/maizzle.mjs +1 -1
  2. package/dist/build.d.ts +20 -0
  3. package/dist/build.d.ts.map +1 -0
  4. package/dist/{build.mjs → build.js} +14 -10
  5. package/dist/build.js.map +1 -0
  6. package/dist/components/Body.vue +10 -0
  7. package/dist/components/Button.vue +70 -11
  8. package/dist/components/Column.vue +10 -0
  9. package/dist/components/Container.vue +29 -1
  10. package/dist/components/Html.vue +10 -0
  11. package/dist/components/Layout.vue +27 -12
  12. package/dist/components/MarkdownLayout.vue +39 -0
  13. package/dist/components/Overlap.vue +10 -0
  14. package/dist/components/Preheader.vue +3 -8
  15. package/dist/components/Row.vue +13 -2
  16. package/dist/components/Section.vue +10 -0
  17. package/dist/components/Tailwind.vue +43 -0
  18. package/dist/components/{utils.d.mts → utils.d.ts} +1 -1
  19. package/dist/components/utils.d.ts.map +1 -0
  20. package/dist/components/{utils.mjs → utils.js} +1 -1
  21. package/dist/components/utils.js.map +1 -0
  22. package/dist/composables/{defineConfig.d.mts → defineConfig.d.ts} +2 -2
  23. package/dist/composables/defineConfig.d.ts.map +1 -0
  24. package/dist/composables/{defineConfig.mjs → defineConfig.js} +3 -3
  25. package/dist/composables/defineConfig.js.map +1 -0
  26. package/dist/composables/{renderContext.d.mts → renderContext.d.ts} +11 -5
  27. package/dist/composables/renderContext.d.ts.map +1 -0
  28. package/dist/composables/{renderContext.mjs → renderContext.js} +1 -1
  29. package/dist/composables/renderContext.js.map +1 -0
  30. package/dist/composables/useBaseUrl.d.ts +19 -0
  31. package/dist/composables/useBaseUrl.d.ts.map +1 -0
  32. package/dist/composables/useBaseUrl.js +27 -0
  33. package/dist/composables/useBaseUrl.js.map +1 -0
  34. package/dist/composables/{useConfig.d.mts → useConfig.d.ts} +2 -2
  35. package/dist/composables/useConfig.d.ts.map +1 -0
  36. package/dist/composables/{useConfig.mjs → useConfig.js} +1 -1
  37. package/dist/composables/useConfig.js.map +1 -0
  38. package/dist/composables/{useDoctype.d.mts → useDoctype.d.ts} +1 -1
  39. package/dist/composables/useDoctype.d.ts.map +1 -0
  40. package/dist/composables/{useDoctype.mjs → useDoctype.js} +2 -2
  41. package/dist/composables/useDoctype.js.map +1 -0
  42. package/dist/composables/{useEvent.d.mts → useEvent.d.ts} +2 -2
  43. package/dist/composables/useEvent.d.ts.map +1 -0
  44. package/dist/composables/{useEvent.mjs → useEvent.js} +2 -2
  45. package/dist/composables/useEvent.js.map +1 -0
  46. package/dist/composables/{useFont.d.mts → useFont.d.ts} +1 -1
  47. package/dist/composables/useFont.d.ts.map +1 -0
  48. package/dist/composables/{useFont.mjs → useFont.js} +2 -2
  49. package/dist/composables/useFont.js.map +1 -0
  50. package/dist/composables/{useOutlookFallback.d.mts → useOutlookFallback.d.ts} +1 -1
  51. package/dist/composables/useOutlookFallback.d.ts.map +1 -0
  52. package/dist/composables/{useOutlookFallback.mjs → useOutlookFallback.js} +1 -1
  53. package/dist/composables/useOutlookFallback.js.map +1 -0
  54. package/dist/composables/{usePlaintext.d.mts → usePlaintext.d.ts} +1 -1
  55. package/dist/composables/usePlaintext.d.ts.map +1 -0
  56. package/dist/composables/{usePlaintext.mjs → usePlaintext.js} +2 -2
  57. package/dist/composables/usePlaintext.js.map +1 -0
  58. package/dist/composables/{usePreheader.d.mts → usePreheader.d.ts} +1 -1
  59. package/dist/composables/usePreheader.d.ts.map +1 -0
  60. package/dist/composables/{usePreheader.mjs → usePreheader.js} +2 -2
  61. package/dist/composables/usePreheader.js.map +1 -0
  62. package/dist/composables/useTransformers.d.ts +34 -0
  63. package/dist/composables/useTransformers.d.ts.map +1 -0
  64. package/dist/composables/useTransformers.js +49 -0
  65. package/dist/composables/useTransformers.js.map +1 -0
  66. package/dist/composables/useUrlQuery.d.ts +19 -0
  67. package/dist/composables/useUrlQuery.d.ts.map +1 -0
  68. package/dist/composables/useUrlQuery.js +27 -0
  69. package/dist/composables/useUrlQuery.js.map +1 -0
  70. package/dist/config/{defaults.d.mts → defaults.d.ts} +2 -2
  71. package/dist/config/defaults.d.ts.map +1 -0
  72. package/dist/config/{defaults.mjs → defaults.js} +8 -2
  73. package/dist/config/defaults.js.map +1 -0
  74. package/dist/config/{index.d.mts → index.d.ts} +4 -4
  75. package/dist/config/index.d.ts.map +1 -0
  76. package/dist/config/{index.mjs → index.js} +3 -3
  77. package/dist/config/index.js.map +1 -0
  78. package/dist/events/{index.d.mts → index.d.ts} +10 -4
  79. package/dist/events/index.d.ts.map +1 -0
  80. package/dist/events/{index.mjs → index.js} +20 -4
  81. package/dist/events/index.js.map +1 -0
  82. package/dist/index.d.ts +37 -0
  83. package/dist/index.js +37 -0
  84. package/dist/{plaintext.d.mts → plaintext.d.ts} +1 -1
  85. package/dist/plaintext.d.ts.map +1 -0
  86. package/dist/{plaintext.mjs → plaintext.js} +1 -1
  87. package/dist/plaintext.js.map +1 -0
  88. package/dist/{plugin.d.mts → plugin.d.ts} +2 -2
  89. package/dist/plugin.d.ts.map +1 -0
  90. package/dist/{plugin.mjs → plugin.js} +5 -5
  91. package/dist/plugin.js.map +1 -0
  92. package/dist/plugins/postcss/{mergeMediaQueries.d.mts → mergeMediaQueries.d.ts} +2 -2
  93. package/dist/plugins/postcss/mergeMediaQueries.d.ts.map +1 -0
  94. package/dist/plugins/postcss/{mergeMediaQueries.mjs → mergeMediaQueries.js} +1 -1
  95. package/dist/plugins/postcss/mergeMediaQueries.js.map +1 -0
  96. package/dist/plugins/postcss/{pruneVars.d.mts → pruneVars.d.ts} +1 -1
  97. package/dist/plugins/postcss/pruneVars.d.ts.map +1 -0
  98. package/dist/plugins/postcss/{pruneVars.mjs → pruneVars.js} +1 -1
  99. package/dist/plugins/postcss/pruneVars.js.map +1 -0
  100. package/dist/plugins/postcss/{quoteFontFamilies.d.mts → quoteFontFamilies.d.ts} +1 -1
  101. package/dist/plugins/postcss/quoteFontFamilies.d.ts.map +1 -0
  102. package/dist/plugins/postcss/{quoteFontFamilies.mjs → quoteFontFamilies.js} +1 -1
  103. package/dist/plugins/postcss/quoteFontFamilies.js.map +1 -0
  104. package/dist/plugins/postcss/{removeDeclarations.d.mts → removeDeclarations.d.ts} +1 -1
  105. package/dist/plugins/postcss/removeDeclarations.d.ts.map +1 -0
  106. package/dist/plugins/postcss/{removeDeclarations.mjs → removeDeclarations.js} +1 -1
  107. package/dist/plugins/postcss/removeDeclarations.js.map +1 -0
  108. package/dist/plugins/postcss/resolveMaizzleImports.d.ts +16 -0
  109. package/dist/plugins/postcss/resolveMaizzleImports.d.ts.map +1 -0
  110. package/dist/plugins/postcss/resolveMaizzleImports.js +40 -0
  111. package/dist/plugins/postcss/resolveMaizzleImports.js.map +1 -0
  112. package/dist/plugins/postcss/{resolveProps.d.mts → resolveProps.d.ts} +1 -1
  113. package/dist/plugins/postcss/resolveProps.d.ts.map +1 -0
  114. package/dist/plugins/postcss/{resolveProps.mjs → resolveProps.js} +1 -1
  115. package/dist/plugins/postcss/resolveProps.js.map +1 -0
  116. package/dist/plugins/postcss/{tailwindCleanup.d.mts → tailwindCleanup.d.ts} +2 -2
  117. package/dist/plugins/postcss/tailwindCleanup.d.ts.map +1 -0
  118. package/dist/plugins/postcss/{tailwindCleanup.mjs → tailwindCleanup.js} +1 -1
  119. package/dist/plugins/postcss/tailwindCleanup.js.map +1 -0
  120. package/dist/{prepare.d.mts → prepare.d.ts} +1 -1
  121. package/dist/prepare.d.ts.map +1 -0
  122. package/dist/{prepare.mjs → prepare.js} +4 -4
  123. package/dist/prepare.js.map +1 -0
  124. package/dist/render/{createRenderer.d.mts → createRenderer.d.ts} +4 -3
  125. package/dist/render/createRenderer.d.ts.map +1 -0
  126. package/dist/render/{createRenderer.mjs → createRenderer.js} +21 -12
  127. package/dist/render/createRenderer.js.map +1 -0
  128. package/dist/render/index.d.ts +18 -0
  129. package/dist/render/index.d.ts.map +1 -0
  130. package/dist/render/index.js +45 -0
  131. package/dist/render/index.js.map +1 -0
  132. package/dist/render/{injectFonts.d.mts → injectFonts.d.ts} +2 -2
  133. package/dist/render/injectFonts.d.ts.map +1 -0
  134. package/dist/render/{injectFonts.mjs → injectFonts.js} +2 -2
  135. package/dist/render/injectFonts.js.map +1 -0
  136. package/dist/render/plugins/{codeBlockExtract.d.mts → codeBlockExtract.d.ts} +1 -1
  137. package/dist/render/plugins/codeBlockExtract.d.ts.map +1 -0
  138. package/dist/render/plugins/{codeBlockExtract.mjs → codeBlockExtract.js} +1 -1
  139. package/dist/render/plugins/codeBlockExtract.js.map +1 -0
  140. package/dist/render/plugins/{markdownExtract.d.mts → markdownExtract.d.ts} +1 -1
  141. package/dist/render/plugins/markdownExtract.d.ts.map +1 -0
  142. package/dist/render/plugins/{markdownExtract.mjs → markdownExtract.js} +1 -1
  143. package/dist/render/plugins/markdownExtract.js.map +1 -0
  144. package/dist/render/plugins/{rawExtract.d.mts → rawExtract.d.ts} +1 -1
  145. package/dist/render/plugins/rawExtract.d.ts.map +1 -0
  146. package/dist/render/plugins/{rawExtract.mjs → rawExtract.js} +1 -1
  147. package/dist/render/plugins/rawExtract.js.map +1 -0
  148. package/dist/render/plugins/{rowSourceLocation.d.mts → rowSourceLocation.d.ts} +1 -1
  149. package/dist/render/plugins/rowSourceLocation.d.ts.map +1 -0
  150. package/dist/render/plugins/{rowSourceLocation.mjs → rowSourceLocation.js} +1 -1
  151. package/dist/render/plugins/rowSourceLocation.js.map +1 -0
  152. package/dist/{serve.d.mts → serve.d.ts} +2 -2
  153. package/dist/serve.d.ts.map +1 -0
  154. package/dist/{serve.mjs → serve.js} +23 -14
  155. package/dist/serve.js.map +1 -0
  156. package/dist/server/{compatibility.d.mts → compatibility.d.ts} +2 -2
  157. package/dist/server/compatibility.d.ts.map +1 -0
  158. package/dist/server/{compatibility.mjs → compatibility.js} +4 -4
  159. package/dist/server/compatibility.js.map +1 -0
  160. package/dist/server/{email.d.mts → email.d.ts} +2 -2
  161. package/dist/server/email.d.ts.map +1 -0
  162. package/dist/server/{email.mjs → email.js} +1 -1
  163. package/dist/server/email.js.map +1 -0
  164. package/dist/server/{linter.d.mts → linter.d.ts} +2 -2
  165. package/dist/server/linter.d.ts.map +1 -0
  166. package/dist/server/{linter.mjs → linter.js} +2 -2
  167. package/dist/server/linter.js.map +1 -0
  168. package/dist/server/{sfc-utils.d.mts → sfc-utils.d.ts} +1 -1
  169. package/dist/server/sfc-utils.d.ts.map +1 -0
  170. package/dist/server/{sfc-utils.mjs → sfc-utils.js} +1 -1
  171. package/dist/server/sfc-utils.js.map +1 -0
  172. package/dist/server/ui/App.vue +18 -0
  173. package/dist/server/ui/components/ui/command/Command.vue +4 -1
  174. package/dist/server/ui/pages/Preview.vue +78 -19
  175. package/dist/transformers/{addAttributes.d.mts → addAttributes.d.ts} +2 -2
  176. package/dist/transformers/addAttributes.d.ts.map +1 -0
  177. package/dist/transformers/{addAttributes.mjs → addAttributes.js} +3 -3
  178. package/dist/transformers/addAttributes.js.map +1 -0
  179. package/dist/transformers/{attributeToStyle.d.mts → attributeToStyle.d.ts} +2 -2
  180. package/dist/transformers/attributeToStyle.d.ts.map +1 -0
  181. package/dist/transformers/{attributeToStyle.mjs → attributeToStyle.js} +3 -3
  182. package/dist/transformers/attributeToStyle.js.map +1 -0
  183. package/dist/transformers/{base.d.mts → base.d.ts} +2 -2
  184. package/dist/transformers/base.d.ts.map +1 -0
  185. package/dist/transformers/{base.mjs → base.js} +6 -6
  186. package/dist/transformers/base.js.map +1 -0
  187. package/dist/transformers/{columnWidth.d.mts → columnWidth.d.ts} +1 -1
  188. package/dist/transformers/columnWidth.d.ts.map +1 -0
  189. package/dist/transformers/{columnWidth.mjs → columnWidth.js} +3 -3
  190. package/dist/transformers/columnWidth.js.map +1 -0
  191. package/dist/transformers/{entities.d.mts → entities.d.ts} +2 -2
  192. package/dist/transformers/entities.d.ts.map +1 -0
  193. package/dist/transformers/{entities.mjs → entities.js} +3 -3
  194. package/dist/transformers/entities.js.map +1 -0
  195. package/dist/transformers/filters/{defaults.d.mts → defaults.d.ts} +1 -1
  196. package/dist/transformers/filters/defaults.d.ts.map +1 -0
  197. package/dist/transformers/filters/{defaults.mjs → defaults.js} +1 -1
  198. package/dist/transformers/filters/defaults.js.map +1 -0
  199. package/dist/transformers/filters/{index.d.mts → index.d.ts} +2 -2
  200. package/dist/transformers/filters/index.d.ts.map +1 -0
  201. package/dist/transformers/filters/{index.mjs → index.js} +5 -5
  202. package/dist/transformers/filters/index.js.map +1 -0
  203. package/dist/transformers/{format.d.mts → format.d.ts} +2 -2
  204. package/dist/transformers/format.d.ts.map +1 -0
  205. package/dist/transformers/{format.mjs → format.js} +1 -1
  206. package/dist/transformers/format.js.map +1 -0
  207. package/dist/transformers/{index.d.mts → index.d.ts} +4 -3
  208. package/dist/transformers/index.d.ts.map +1 -0
  209. package/dist/transformers/index.js +113 -0
  210. package/dist/transformers/index.js.map +1 -0
  211. package/dist/transformers/{inlineCSS.d.mts → inlineCSS.d.ts} +2 -2
  212. package/dist/transformers/inlineCSS.d.ts.map +1 -0
  213. package/dist/transformers/{inlineCSS.mjs → inlineCSS.js} +12 -6
  214. package/dist/transformers/inlineCSS.js.map +1 -0
  215. package/dist/transformers/{inlineLink.d.mts → inlineLink.d.ts} +1 -1
  216. package/dist/transformers/inlineLink.d.ts.map +1 -0
  217. package/dist/transformers/{inlineLink.mjs → inlineLink.js} +3 -3
  218. package/dist/transformers/inlineLink.js.map +1 -0
  219. package/dist/transformers/{minify.d.mts → minify.d.ts} +2 -2
  220. package/dist/transformers/minify.d.ts.map +1 -0
  221. package/dist/transformers/{minify.mjs → minify.js} +1 -1
  222. package/dist/transformers/minify.js.map +1 -0
  223. package/dist/transformers/msoPlaceholders.d.ts +28 -0
  224. package/dist/transformers/msoPlaceholders.d.ts.map +1 -0
  225. package/dist/transformers/msoPlaceholders.js +89 -0
  226. package/dist/transformers/msoPlaceholders.js.map +1 -0
  227. package/dist/transformers/{purgeCSS.d.mts → purgeCSS.d.ts} +2 -2
  228. package/dist/transformers/purgeCSS.d.ts.map +1 -0
  229. package/dist/transformers/{purgeCSS.mjs → purgeCSS.js} +49 -7
  230. package/dist/transformers/purgeCSS.js.map +1 -0
  231. package/dist/transformers/{removeAttributes.d.mts → removeAttributes.d.ts} +2 -2
  232. package/dist/transformers/removeAttributes.d.ts.map +1 -0
  233. package/dist/transformers/{removeAttributes.mjs → removeAttributes.js} +3 -3
  234. package/dist/transformers/removeAttributes.js.map +1 -0
  235. package/dist/transformers/{replaceStrings.d.mts → replaceStrings.d.ts} +2 -2
  236. package/dist/transformers/replaceStrings.d.ts.map +1 -0
  237. package/dist/transformers/{replaceStrings.mjs → replaceStrings.js} +1 -1
  238. package/dist/transformers/replaceStrings.js.map +1 -0
  239. package/dist/transformers/{safeClassNames.d.mts → safeClassNames.d.ts} +2 -2
  240. package/dist/transformers/safeClassNames.d.ts.map +1 -0
  241. package/dist/transformers/{safeClassNames.mjs → safeClassNames.js} +3 -3
  242. package/dist/transformers/safeClassNames.js.map +1 -0
  243. package/dist/transformers/{shorthandCSS.d.mts → shorthandCSS.d.ts} +2 -2
  244. package/dist/transformers/shorthandCSS.d.ts.map +1 -0
  245. package/dist/transformers/{shorthandCSS.mjs → shorthandCSS.js} +3 -3
  246. package/dist/transformers/shorthandCSS.js.map +1 -0
  247. package/dist/transformers/{sixHex.d.mts → sixHex.d.ts} +2 -2
  248. package/dist/transformers/sixHex.d.ts.map +1 -0
  249. package/dist/transformers/{sixHex.mjs → sixHex.js} +3 -3
  250. package/dist/transformers/sixHex.js.map +1 -0
  251. package/dist/transformers/tailwindComponent.d.ts +16 -0
  252. package/dist/transformers/tailwindComponent.d.ts.map +1 -0
  253. package/dist/transformers/tailwindComponent.js +93 -0
  254. package/dist/transformers/tailwindComponent.js.map +1 -0
  255. package/dist/transformers/{tailwindcss.d.mts → tailwindcss.d.ts} +2 -2
  256. package/dist/transformers/tailwindcss.d.ts.map +1 -0
  257. package/dist/transformers/{tailwindcss.mjs → tailwindcss.js} +6 -58
  258. package/dist/transformers/tailwindcss.js.map +1 -0
  259. package/dist/transformers/{urlQuery.d.mts → urlQuery.d.ts} +2 -2
  260. package/dist/transformers/urlQuery.d.ts.map +1 -0
  261. package/dist/transformers/{urlQuery.mjs → urlQuery.js} +2 -2
  262. package/dist/transformers/urlQuery.js.map +1 -0
  263. package/dist/types/{config.d.mts → config.d.ts} +45 -4
  264. package/dist/types/config.d.ts.map +1 -0
  265. package/dist/types/{index.d.mts → index.d.ts} +2 -2
  266. package/dist/utils/ast/index.d.ts +4 -0
  267. package/dist/utils/ast/index.js +5 -0
  268. package/dist/utils/ast/{parser.d.mts → parser.d.ts} +1 -1
  269. package/dist/utils/ast/parser.d.ts.map +1 -0
  270. package/dist/utils/ast/{parser.mjs → parser.js} +1 -1
  271. package/dist/utils/ast/parser.js.map +1 -0
  272. package/dist/utils/ast/{serializer.d.mts → serializer.d.ts} +1 -1
  273. package/dist/utils/ast/serializer.d.ts.map +1 -0
  274. package/dist/utils/ast/{serializer.mjs → serializer.js} +2 -2
  275. package/dist/utils/ast/serializer.js.map +1 -0
  276. package/dist/utils/ast/{walker.d.mts → walker.d.ts} +1 -1
  277. package/dist/utils/ast/walker.d.ts.map +1 -0
  278. package/dist/utils/ast/{walker.mjs → walker.js} +1 -1
  279. package/dist/utils/ast/walker.js.map +1 -0
  280. package/dist/utils/compileTailwindCss.d.ts +16 -0
  281. package/dist/utils/compileTailwindCss.d.ts.map +1 -0
  282. package/dist/utils/compileTailwindCss.js +55 -0
  283. package/dist/utils/compileTailwindCss.js.map +1 -0
  284. package/dist/utils/{decodeStyleEntities.d.mts → decodeStyleEntities.d.ts} +1 -1
  285. package/dist/utils/decodeStyleEntities.d.ts.map +1 -0
  286. package/dist/utils/{decodeStyleEntities.mjs → decodeStyleEntities.js} +1 -1
  287. package/dist/utils/decodeStyleEntities.js.map +1 -0
  288. package/dist/utils/{detect.d.mts → detect.d.ts} +1 -1
  289. package/dist/utils/detect.d.ts.map +1 -0
  290. package/dist/utils/{detect.mjs → detect.js} +1 -1
  291. package/dist/utils/detect.js.map +1 -0
  292. package/dist/utils/{url.d.mts → url.d.ts} +1 -1
  293. package/dist/utils/url.d.ts.map +1 -0
  294. package/dist/utils/{url.mjs → url.js} +1 -1
  295. package/dist/utils/url.js.map +1 -0
  296. package/node_modules/@clack/core/CHANGELOG.md +8 -0
  297. package/node_modules/@clack/core/dist/index.d.mts +18 -4
  298. package/node_modules/@clack/core/dist/index.mjs +16 -10
  299. package/node_modules/@clack/core/dist/index.mjs.map +1 -1
  300. package/node_modules/@clack/core/package.json +5 -2
  301. package/node_modules/@clack/prompts/CHANGELOG.md +15 -0
  302. package/node_modules/@clack/prompts/README.md +107 -2
  303. package/node_modules/@clack/prompts/dist/index.d.mts +16 -11
  304. package/node_modules/@clack/prompts/dist/index.mjs +114 -107
  305. package/node_modules/@clack/prompts/dist/index.mjs.map +1 -1
  306. package/node_modules/@clack/prompts/package.json +7 -4
  307. package/node_modules/fast-string-truncated-width/dist/index.js +36 -96
  308. package/node_modules/fast-string-truncated-width/dist/types.d.ts +0 -3
  309. package/node_modules/fast-string-truncated-width/dist/utils.d.ts +3 -3
  310. package/node_modules/fast-string-truncated-width/dist/utils.js +14 -9
  311. package/node_modules/fast-string-truncated-width/package.json +1 -1
  312. package/node_modules/fast-string-truncated-width/readme.md +2 -3
  313. package/node_modules/fast-string-width/package.json +2 -2
  314. package/node_modules/fast-string-width/readme.md +0 -3
  315. package/node_modules/fast-wrap-ansi/lib/main.js +4 -1
  316. package/node_modules/fast-wrap-ansi/lib/main.js.map +1 -1
  317. package/node_modules/fast-wrap-ansi/package.json +2 -2
  318. package/node_modules/tinyexec/README.md +1 -1
  319. package/node_modules/tinyexec/dist/main.d.mts +6 -6
  320. package/node_modules/tinyexec/dist/main.mjs +126 -134
  321. package/node_modules/tinyexec/package.json +9 -9
  322. package/package.json +15 -8
  323. package/dist/build.d.mts +0 -19
  324. package/dist/build.d.mts.map +0 -1
  325. package/dist/build.mjs.map +0 -1
  326. package/dist/components/utils.d.mts.map +0 -1
  327. package/dist/components/utils.mjs.map +0 -1
  328. package/dist/composables/defineConfig.d.mts.map +0 -1
  329. package/dist/composables/defineConfig.mjs.map +0 -1
  330. package/dist/composables/renderContext.d.mts.map +0 -1
  331. package/dist/composables/renderContext.mjs.map +0 -1
  332. package/dist/composables/useConfig.d.mts.map +0 -1
  333. package/dist/composables/useConfig.mjs.map +0 -1
  334. package/dist/composables/useDoctype.d.mts.map +0 -1
  335. package/dist/composables/useDoctype.mjs.map +0 -1
  336. package/dist/composables/useEvent.d.mts.map +0 -1
  337. package/dist/composables/useEvent.mjs.map +0 -1
  338. package/dist/composables/useFont.d.mts.map +0 -1
  339. package/dist/composables/useFont.mjs.map +0 -1
  340. package/dist/composables/useOutlookFallback.d.mts.map +0 -1
  341. package/dist/composables/useOutlookFallback.mjs.map +0 -1
  342. package/dist/composables/usePlaintext.d.mts.map +0 -1
  343. package/dist/composables/usePlaintext.mjs.map +0 -1
  344. package/dist/composables/usePreheader.d.mts.map +0 -1
  345. package/dist/composables/usePreheader.mjs.map +0 -1
  346. package/dist/config/defaults.d.mts.map +0 -1
  347. package/dist/config/defaults.mjs.map +0 -1
  348. package/dist/config/index.d.mts.map +0 -1
  349. package/dist/config/index.mjs.map +0 -1
  350. package/dist/events/index.d.mts.map +0 -1
  351. package/dist/events/index.mjs.map +0 -1
  352. package/dist/index.d.mts +0 -34
  353. package/dist/index.mjs +0 -34
  354. package/dist/plaintext.d.mts.map +0 -1
  355. package/dist/plaintext.mjs.map +0 -1
  356. package/dist/plugin.d.mts.map +0 -1
  357. package/dist/plugin.mjs.map +0 -1
  358. package/dist/plugins/postcss/mergeMediaQueries.d.mts.map +0 -1
  359. package/dist/plugins/postcss/mergeMediaQueries.mjs.map +0 -1
  360. package/dist/plugins/postcss/pruneVars.d.mts.map +0 -1
  361. package/dist/plugins/postcss/pruneVars.mjs.map +0 -1
  362. package/dist/plugins/postcss/quoteFontFamilies.d.mts.map +0 -1
  363. package/dist/plugins/postcss/quoteFontFamilies.mjs.map +0 -1
  364. package/dist/plugins/postcss/removeDeclarations.d.mts.map +0 -1
  365. package/dist/plugins/postcss/removeDeclarations.mjs.map +0 -1
  366. package/dist/plugins/postcss/resolveProps.d.mts.map +0 -1
  367. package/dist/plugins/postcss/resolveProps.mjs.map +0 -1
  368. package/dist/plugins/postcss/tailwindCleanup.d.mts.map +0 -1
  369. package/dist/plugins/postcss/tailwindCleanup.mjs.map +0 -1
  370. package/dist/prepare.d.mts.map +0 -1
  371. package/dist/prepare.mjs.map +0 -1
  372. package/dist/render/createRenderer.d.mts.map +0 -1
  373. package/dist/render/createRenderer.mjs.map +0 -1
  374. package/dist/render/index.d.mts +0 -26
  375. package/dist/render/index.d.mts.map +0 -1
  376. package/dist/render/index.mjs +0 -46
  377. package/dist/render/index.mjs.map +0 -1
  378. package/dist/render/injectFonts.d.mts.map +0 -1
  379. package/dist/render/injectFonts.mjs.map +0 -1
  380. package/dist/render/plugins/codeBlockExtract.d.mts.map +0 -1
  381. package/dist/render/plugins/codeBlockExtract.mjs.map +0 -1
  382. package/dist/render/plugins/markdownExtract.d.mts.map +0 -1
  383. package/dist/render/plugins/markdownExtract.mjs.map +0 -1
  384. package/dist/render/plugins/rawExtract.d.mts.map +0 -1
  385. package/dist/render/plugins/rawExtract.mjs.map +0 -1
  386. package/dist/render/plugins/rowSourceLocation.d.mts.map +0 -1
  387. package/dist/render/plugins/rowSourceLocation.mjs.map +0 -1
  388. package/dist/serve.d.mts.map +0 -1
  389. package/dist/serve.mjs.map +0 -1
  390. package/dist/server/compatibility.d.mts.map +0 -1
  391. package/dist/server/compatibility.mjs.map +0 -1
  392. package/dist/server/email.d.mts.map +0 -1
  393. package/dist/server/email.mjs.map +0 -1
  394. package/dist/server/linter.d.mts.map +0 -1
  395. package/dist/server/linter.mjs.map +0 -1
  396. package/dist/server/sfc-utils.d.mts.map +0 -1
  397. package/dist/server/sfc-utils.mjs.map +0 -1
  398. package/dist/transformers/addAttributes.d.mts.map +0 -1
  399. package/dist/transformers/addAttributes.mjs.map +0 -1
  400. package/dist/transformers/attributeToStyle.d.mts.map +0 -1
  401. package/dist/transformers/attributeToStyle.mjs.map +0 -1
  402. package/dist/transformers/base.d.mts.map +0 -1
  403. package/dist/transformers/base.mjs.map +0 -1
  404. package/dist/transformers/columnWidth.d.mts.map +0 -1
  405. package/dist/transformers/columnWidth.mjs.map +0 -1
  406. package/dist/transformers/entities.d.mts.map +0 -1
  407. package/dist/transformers/entities.mjs.map +0 -1
  408. package/dist/transformers/filters/defaults.d.mts.map +0 -1
  409. package/dist/transformers/filters/defaults.mjs.map +0 -1
  410. package/dist/transformers/filters/index.d.mts.map +0 -1
  411. package/dist/transformers/filters/index.mjs.map +0 -1
  412. package/dist/transformers/format.d.mts.map +0 -1
  413. package/dist/transformers/format.mjs.map +0 -1
  414. package/dist/transformers/index.d.mts.map +0 -1
  415. package/dist/transformers/index.mjs +0 -85
  416. package/dist/transformers/index.mjs.map +0 -1
  417. package/dist/transformers/inlineCSS.d.mts.map +0 -1
  418. package/dist/transformers/inlineCSS.mjs.map +0 -1
  419. package/dist/transformers/inlineLink.d.mts.map +0 -1
  420. package/dist/transformers/inlineLink.mjs.map +0 -1
  421. package/dist/transformers/minify.d.mts.map +0 -1
  422. package/dist/transformers/minify.mjs.map +0 -1
  423. package/dist/transformers/msoWidthFromClass.d.mts +0 -19
  424. package/dist/transformers/msoWidthFromClass.d.mts.map +0 -1
  425. package/dist/transformers/msoWidthFromClass.mjs +0 -61
  426. package/dist/transformers/msoWidthFromClass.mjs.map +0 -1
  427. package/dist/transformers/purgeCSS.d.mts.map +0 -1
  428. package/dist/transformers/purgeCSS.mjs.map +0 -1
  429. package/dist/transformers/removeAttributes.d.mts.map +0 -1
  430. package/dist/transformers/removeAttributes.mjs.map +0 -1
  431. package/dist/transformers/replaceStrings.d.mts.map +0 -1
  432. package/dist/transformers/replaceStrings.mjs.map +0 -1
  433. package/dist/transformers/safeClassNames.d.mts.map +0 -1
  434. package/dist/transformers/safeClassNames.mjs.map +0 -1
  435. package/dist/transformers/shorthandCSS.d.mts.map +0 -1
  436. package/dist/transformers/shorthandCSS.mjs.map +0 -1
  437. package/dist/transformers/sixHex.d.mts.map +0 -1
  438. package/dist/transformers/sixHex.mjs.map +0 -1
  439. package/dist/transformers/tailwindcss.d.mts.map +0 -1
  440. package/dist/transformers/tailwindcss.mjs.map +0 -1
  441. package/dist/transformers/urlQuery.d.mts.map +0 -1
  442. package/dist/transformers/urlQuery.mjs.map +0 -1
  443. package/dist/types/config.d.mts.map +0 -1
  444. package/dist/utils/ast/index.d.mts +0 -4
  445. package/dist/utils/ast/index.mjs +0 -5
  446. package/dist/utils/ast/parser.d.mts.map +0 -1
  447. package/dist/utils/ast/parser.mjs.map +0 -1
  448. package/dist/utils/ast/serializer.d.mts.map +0 -1
  449. package/dist/utils/ast/serializer.mjs.map +0 -1
  450. package/dist/utils/ast/walker.d.mts.map +0 -1
  451. package/dist/utils/ast/walker.mjs.map +0 -1
  452. package/dist/utils/decodeStyleEntities.d.mts.map +0 -1
  453. package/dist/utils/decodeStyleEntities.mjs.map +0 -1
  454. package/dist/utils/detect.d.mts.map +0 -1
  455. package/dist/utils/detect.mjs.map +0 -1
  456. package/dist/utils/url.d.mts.map +0 -1
  457. package/dist/utils/url.mjs.map +0 -1
  458. /package/dist/components/{Divider.vue → Hr.vue} +0 -0
  459. /package/dist/types/{config.mjs → config.js} +0 -0
  460. /package/dist/types/{index.mjs → index.js} +0 -0
@@ -1,85 +0,0 @@
1
- import { parse } from "../utils/ast/parser.mjs";
2
- import { serialize } from "../utils/ast/serializer.mjs";
3
- import "../utils/ast/index.mjs";
4
- import { inlineLink } from "./inlineLink.mjs";
5
- import { tailwindcss } from "./tailwindcss.mjs";
6
- import { safeClassNames } from "./safeClassNames.mjs";
7
- import { attributeToStyle } from "./attributeToStyle.mjs";
8
- import { inlineCSS } from "./inlineCSS.mjs";
9
- import { msoWidthFromClass } from "./msoWidthFromClass.mjs";
10
- import { columnWidth } from "./columnWidth.mjs";
11
- import { removeAttributes } from "./removeAttributes.mjs";
12
- import { shorthandCSS } from "./shorthandCSS.mjs";
13
- import { sixHex } from "./sixHex.mjs";
14
- import { addAttributes } from "./addAttributes.mjs";
15
- import { filters } from "./filters/index.mjs";
16
- import { base } from "./base.mjs";
17
- import { entities } from "./entities.mjs";
18
- import { urlQuery } from "./urlQuery.mjs";
19
- import { purgeCSS } from "./purgeCSS.mjs";
20
- import { replaceStrings } from "./replaceStrings.mjs";
21
- import { format } from "./format.mjs";
22
- import { minify } from "./minify.mjs";
23
-
24
- //#region src/transformers/index.ts
25
- /**
26
- * Run all Maizzle transformers on the rendered HTML.
27
- *
28
- * The HTML is parsed into a DOM once at the start and passed through all
29
- * DOM-based transformers as a shared `ChildNode[]`. After all DOM transformers
30
- * complete, the DOM is serialized back to a string exactly once.
31
- *
32
- * String-only transformers (those that rely on external tools that require a
33
- * raw HTML string) then run on the serialized output.
34
- *
35
- * Transformers run in a specific order:
36
- * 0. Inline link stylesheets — replace `<link rel="stylesheet">` with `<style>` tags
37
- * 1. Tailwind CSS — compile CSS, lower syntax, optimize (cleanup + merge media queries)
38
- * 2. Safe class names
39
- * 3. Attribute to style
40
- * 4. CSS inliner
41
- * 5. Remove attributes
42
- * 6. Shorthand CSS
43
- * 7. Six-digit HEX
44
- * 8. Add attributes
45
- * 9. Filters
46
- * 10. Base URL
47
- * 11. URL query
48
- * 12. Purge CSS (serializes/parses internally around email-comb)
49
- * 13. Entities
50
- * + Vue-generated comments stripped here (on serialized string)
51
- * 14. Replace strings
52
- * 15. Prettify
53
- * 16. Minify
54
- */
55
- async function runTransformers(html, config, filePath, doctype) {
56
- html = html.replaceAll("<!--[-->", "").replaceAll("<!--]-->", "").replaceAll("<!--teleport start anchor-->", "").replaceAll("<!--teleport anchor-->", "").replaceAll("<!--teleport start-->", "").replaceAll("<!--teleport end-->", "");
57
- let dom = parse(html);
58
- dom = await inlineLink(dom, filePath);
59
- dom = await tailwindcss(dom, config, filePath);
60
- dom = safeClassNames(dom, config.css);
61
- dom = attributeToStyle(dom, config.css);
62
- dom = inlineCSS(dom, config.css);
63
- dom = msoWidthFromClass(dom);
64
- dom = columnWidth(dom);
65
- dom = removeAttributes(dom, config.html?.attributes);
66
- dom = shorthandCSS(dom, config.css);
67
- dom = sixHex(dom, config.css);
68
- dom = addAttributes(dom, config.html?.attributes);
69
- dom = filters(dom, config.filters);
70
- dom = base(dom, config.url);
71
- dom = urlQuery(dom, config.url);
72
- dom = purgeCSS(dom, config.css);
73
- dom = entities(dom, config.html?.decodeEntities);
74
- const isXhtml = doctype ? /xhtml/i.test(doctype) : false;
75
- let result = serialize(dom, { selfClosingTags: isXhtml });
76
- result = replaceStrings(result, config);
77
- result = await format(result, config);
78
- result = minify(result, config);
79
- if (!isXhtml) result = result.replace(/ \/>/g, ">");
80
- return result;
81
- }
82
-
83
- //#endregion
84
- export { runTransformers };
85
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/transformers/index.ts"],"sourcesContent":["import { parse, serialize } from '../utils/ast/index.ts'\nimport { inlineLink } from './inlineLink.ts'\nimport { tailwindcss } from './tailwindcss.ts'\nimport { safeClassNames } from './safeClassNames.ts'\nimport { attributeToStyle } from './attributeToStyle.ts'\nimport { inlineCSS } from './inlineCSS.ts'\nimport { msoWidthFromClass } from './msoWidthFromClass.ts'\nimport { columnWidth } from './columnWidth.ts'\nimport { removeAttributes } from './removeAttributes.ts'\nimport { shorthandCSS } from './shorthandCSS.ts'\nimport { sixHex } from './sixHex.ts'\nimport { addAttributes } from './addAttributes.ts'\nimport { filters } from './filters/index.ts'\nimport { base } from './base.ts'\nimport { entities } from './entities.ts'\nimport { urlQuery } from './urlQuery.ts'\nimport { purgeCSS } from './purgeCSS.ts'\nimport { replaceStrings } from './replaceStrings.ts'\nimport { format } from './format.ts'\nimport { minify } from './minify.ts'\nimport type { MaizzleConfig } from '../types/config.ts'\n\n/**\n * Run all Maizzle transformers on the rendered HTML.\n *\n * The HTML is parsed into a DOM once at the start and passed through all\n * DOM-based transformers as a shared `ChildNode[]`. After all DOM transformers\n * complete, the DOM is serialized back to a string exactly once.\n *\n * String-only transformers (those that rely on external tools that require a\n * raw HTML string) then run on the serialized output.\n *\n * Transformers run in a specific order:\n * 0. Inline link stylesheets — replace `<link rel=\"stylesheet\">` with `<style>` tags\n * 1. Tailwind CSS — compile CSS, lower syntax, optimize (cleanup + merge media queries)\n * 2. Safe class names\n * 3. Attribute to style\n * 4. CSS inliner\n * 5. Remove attributes\n * 6. Shorthand CSS\n * 7. Six-digit HEX\n * 8. Add attributes\n * 9. Filters\n * 10. Base URL\n * 11. URL query\n * 12. Purge CSS (serializes/parses internally around email-comb)\n * 13. Entities\n * + Vue-generated comments stripped here (on serialized string)\n * 14. Replace strings\n * 15. Prettify\n * 16. Minify\n */\nexport async function runTransformers(\n html: string,\n config: MaizzleConfig,\n filePath?: string,\n doctype?: string,\n): Promise<string> {\n // Strip Vue SSR fragment markers before parsing. They contain `-->`, which\n // prematurely terminates conditional comments like `<!--[if mso]>...<![endif]-->`\n // when htmlparser2 reads them, swallowing real markup into comment data.\n html = html\n .replaceAll('<!--[-->', '')\n .replaceAll('<!--]-->', '')\n .replaceAll('<!--teleport start anchor-->', '')\n .replaceAll('<!--teleport anchor-->', '')\n .replaceAll('<!--teleport start-->', '')\n .replaceAll('<!--teleport end-->', '')\n\n // Parse once — all DOM transformers share this array\n let dom = parse(html)\n\n // 0. Inline <link> stylesheets\n dom = await inlineLink(dom, filePath)\n\n // 1. Tailwind CSS — always runs first\n dom = await tailwindcss(dom, config, filePath)\n\n // 2. Safe class names\n dom = safeClassNames(dom, config.css)\n\n // 3. Attribute to style\n dom = attributeToStyle(dom, config.css)\n\n // 4. CSS inliner (serializes/parses internally around juice)\n dom = inlineCSS(dom, config.css)\n\n // 4.5. Resolve MSO width placeholders from inlined max-width/width\n dom = msoWidthFromClass(dom)\n\n // 4.6. Resolve Column min-width placeholders from nearest sized ancestor\n dom = columnWidth(dom)\n\n // 5. Remove attributes\n dom = removeAttributes(dom, config.html?.attributes)\n\n // 6. Shorthand CSS\n dom = shorthandCSS(dom, config.css)\n\n // 7. Six-digit HEX\n dom = sixHex(dom, config.css)\n\n // 8. Add attributes\n dom = addAttributes(dom, config.html?.attributes)\n\n // 9. Filters\n dom = filters(dom, config.filters)\n\n // 10. Base URL (serializes/parses internally for VML/MSO regex passes)\n dom = base(dom, config.url)\n\n // 11. URL query\n dom = urlQuery(dom, config.url)\n\n // 12. Purge CSS (serializes/parses internally around email-comb)\n dom = purgeCSS(dom, config.css)\n\n // 13. Entities\n dom = entities(dom, config.html?.decodeEntities)\n\n // Serialize once — remaining transformers operate on the HTML string\n const isXhtml = doctype ? /xhtml/i.test(doctype) : false\n let result = serialize(dom, { selfClosingTags: isXhtml })\n\n // 14. Replace strings\n result = replaceStrings(result, config)\n\n // 15. Format\n result = await format(result, config)\n\n // 16. Minify\n result = minify(result, config)\n\n // Strip self-closing slashes for HTML5 doctypes\n if (!isXhtml) {\n result = result.replace(/ \\/>/g, '>')\n }\n\n return result\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDA,eAAsB,gBACpB,MACA,QACA,UACA,SACiB;AAIjB,QAAO,KACJ,WAAW,YAAY,GAAG,CAC1B,WAAW,YAAY,GAAG,CAC1B,WAAW,gCAAgC,GAAG,CAC9C,WAAW,0BAA0B,GAAG,CACxC,WAAW,yBAAyB,GAAG,CACvC,WAAW,uBAAuB,GAAG;CAGxC,IAAI,MAAM,MAAM,KAAK;AAGrB,OAAM,MAAM,WAAW,KAAK,SAAS;AAGrC,OAAM,MAAM,YAAY,KAAK,QAAQ,SAAS;AAG9C,OAAM,eAAe,KAAK,OAAO,IAAI;AAGrC,OAAM,iBAAiB,KAAK,OAAO,IAAI;AAGvC,OAAM,UAAU,KAAK,OAAO,IAAI;AAGhC,OAAM,kBAAkB,IAAI;AAG5B,OAAM,YAAY,IAAI;AAGtB,OAAM,iBAAiB,KAAK,OAAO,MAAM,WAAW;AAGpD,OAAM,aAAa,KAAK,OAAO,IAAI;AAGnC,OAAM,OAAO,KAAK,OAAO,IAAI;AAG7B,OAAM,cAAc,KAAK,OAAO,MAAM,WAAW;AAGjD,OAAM,QAAQ,KAAK,OAAO,QAAQ;AAGlC,OAAM,KAAK,KAAK,OAAO,IAAI;AAG3B,OAAM,SAAS,KAAK,OAAO,IAAI;AAG/B,OAAM,SAAS,KAAK,OAAO,IAAI;AAG/B,OAAM,SAAS,KAAK,OAAO,MAAM,eAAe;CAGhD,MAAM,UAAU,UAAU,SAAS,KAAK,QAAQ,GAAG;CACnD,IAAI,SAAS,UAAU,KAAK,EAAE,iBAAiB,SAAS,CAAC;AAGzD,UAAS,eAAe,QAAQ,OAAO;AAGvC,UAAS,MAAM,OAAO,QAAQ,OAAO;AAGrC,UAAS,OAAO,QAAQ,OAAO;AAG/B,KAAI,CAAC,QACH,UAAS,OAAO,QAAQ,SAAS,IAAI;AAGvC,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"inlineCSS.d.mts","names":[],"sources":["../../src/transformers/inlineCSS.ts"],"mappings":";;;;;;AAeA;;;;;;;iBAAgB,SAAA,CAAU,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,SAAA,GAAiB,SAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"inlineCSS.mjs","names":[],"sources":["../../src/transformers/inlineCSS.ts"],"sourcesContent":["import juice from 'juice'\nimport { walk, parse, serialize } from '../utils/ast/index.ts'\nimport type { ChildNode, Element } from 'domhandler'\nimport type { Options as JuiceOptions } from 'juice'\nimport type { CssConfig } from '../types/config.ts'\n\n/**\n * Inline CSS transformer.\n *\n * Inlines CSS from `<style>` tags into inline style attributes on HTML elements.\n * This is important for email client compatibility (especially Outlook on Windows).\n *\n * Enabled when `css.inline` is set to `true` or an object with options.\n * All Juice options are supported and passed through directly.\n */\nexport function inlineCSS(dom: ChildNode[], config: CssConfig = {}): ChildNode[] {\n const inline = config.inline\n\n // Disabled when inline is falsy or not an object/truthy\n if (!inline) {\n return dom\n }\n\n // Build options from config\n const options = typeof inline === 'object' ? inline : {}\n\n // Separate Maizzle-specific options from Juice options\n const {\n preferUnitlessValues = true,\n safelist,\n customCSS = '',\n styleToAttribute,\n excludedProperties,\n widthElements,\n heightElements,\n codeBlocks,\n ...juicePassthrough\n } = options\n\n // Configure Juice static properties\n juice.styleToAttribute = styleToAttribute ?? {}\n juice.excludedProperties = ['--tw-shadow', ...(excludedProperties ?? [])]\n juice.widthElements = (widthElements ?? ['img', 'video']).map(i => i.toUpperCase()) as unknown as HTMLElement[]\n juice.heightElements = (heightElements ?? ['img', 'video']).map(i => i.toUpperCase()) as unknown as HTMLElement[]\n\n // Add custom code blocks\n if (codeBlocks && typeof codeBlocks === 'object') {\n Object.entries(codeBlocks).forEach(([key, value]) => {\n if (value.start && value.end) {\n juice.codeBlocks[key] = value\n }\n })\n }\n\n // Handle style tags with embed attributes.\n // We add a marker attribute that persists through the pipeline,\n // then restore data-embed from it after Juice runs.\n walk(dom, (node) => {\n const el = node as Element\n if (el.name === 'style' && el.attribs) {\n // Sync data-embed ↔ embed. Use `in` so presence-only attrs\n // (<style embed> → attribs.embed === '') still count.\n if ('embed' in el.attribs && !('data-embed' in el.attribs)) {\n el.attribs['data-embed'] = ''\n }\n if ('data-embed' in el.attribs && !('embed' in el.attribs)) {\n el.attribs.embed = ''\n }\n\n // Add marker that persists through the pipeline\n if ('data-embed' in el.attribs) {\n el.attribs['data-maizzle-embed'] = ''\n }\n }\n })\n\n // Serialize for juice (juice requires a string)\n const serialized = serialize(dom)\n\n let inlinedHtml: string\n\n try {\n const juiceOptions: JuiceOptions = {\n removeStyleTags: juicePassthrough.removeStyleTags ?? false,\n removeInlinedSelectors: juicePassthrough.removeInlinedSelectors ?? true,\n applyWidthAttributes: juicePassthrough.applyWidthAttributes ?? true,\n applyHeightAttributes: juicePassthrough.applyHeightAttributes ?? true,\n preservedSelectors: safelist ?? [],\n ...customCSS ? { extraCss: customCSS } : {},\n inlineDuplicateProperties: juicePassthrough.inlineDuplicateProperties ?? true,\n ...juicePassthrough,\n }\n\n inlinedHtml = juice(serialized, juiceOptions)\n } catch {\n // If Juice fails, return the dom unchanged\n return dom\n }\n\n // Post-process for preferUnitlessValues\n const result = parse(inlinedHtml)\n\n walk(result, (node) => {\n const el = node as Element\n if (el.attribs?.style) {\n // Normalize style formatting: ensure spaces after : and ;\n let style = el.attribs.style\n .replace(/:\\s*/g, ': ')\n .replace(/;\\s*/g, '; ')\n .trimEnd()\n\n // Ensure trailing semicolon\n if (!style.endsWith(';')) {\n style += ';'\n }\n\n if (preferUnitlessValues) {\n style = style.replace(\n /\\b0(px|rem|em|%|vh|vw|vmin|vmax|in|cm|mm|pt|pc|ex|ch)\\b/g,\n '0'\n )\n }\n\n el.attribs.style = style\n }\n })\n\n // Restore data-embed from our marker, then remove the marker.\n // The purge step will handle final data-embed/embed removal.\n walk(result, (node) => {\n const el = node as Element\n if (el.name === 'style' && el.attribs && 'data-maizzle-embed' in el.attribs) {\n el.attribs['data-embed'] = ''\n el.attribs.embed = ''\n delete el.attribs['data-maizzle-embed']\n }\n })\n\n return result\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,SAAgB,UAAU,KAAkB,SAAoB,EAAE,EAAe;CAC/E,MAAM,SAAS,OAAO;AAGtB,KAAI,CAAC,OACH,QAAO;CAOT,MAAM,EACJ,uBAAuB,MACvB,UACA,YAAY,IACZ,kBACA,oBACA,eACA,gBACA,YACA,GAAG,qBAZW,OAAO,WAAW,WAAW,SAAS,EAAE;AAgBxD,OAAM,mBAAmB,oBAAoB,EAAE;AAC/C,OAAM,qBAAqB,CAAC,eAAe,GAAI,sBAAsB,EAAE,CAAE;AACzE,OAAM,iBAAiB,iBAAiB,CAAC,OAAO,QAAQ,EAAE,KAAI,MAAK,EAAE,aAAa,CAAC;AACnF,OAAM,kBAAkB,kBAAkB,CAAC,OAAO,QAAQ,EAAE,KAAI,MAAK,EAAE,aAAa,CAAC;AAGrF,KAAI,cAAc,OAAO,eAAe,SACtC,QAAO,QAAQ,WAAW,CAAC,SAAS,CAAC,KAAK,WAAW;AACnD,MAAI,MAAM,SAAS,MAAM,IACvB,OAAM,WAAW,OAAO;GAE1B;AAMJ,MAAK,MAAM,SAAS;EAClB,MAAM,KAAK;AACX,MAAI,GAAG,SAAS,WAAW,GAAG,SAAS;AAGrC,OAAI,WAAW,GAAG,WAAW,EAAE,gBAAgB,GAAG,SAChD,IAAG,QAAQ,gBAAgB;AAE7B,OAAI,gBAAgB,GAAG,WAAW,EAAE,WAAW,GAAG,SAChD,IAAG,QAAQ,QAAQ;AAIrB,OAAI,gBAAgB,GAAG,QACrB,IAAG,QAAQ,wBAAwB;;GAGvC;CAGF,MAAM,aAAa,UAAU,IAAI;CAEjC,IAAI;AAEJ,KAAI;AAYF,gBAAc,MAAM,YAXe;GACjC,iBAAiB,iBAAiB,mBAAmB;GACrD,wBAAwB,iBAAiB,0BAA0B;GACnE,sBAAsB,iBAAiB,wBAAwB;GAC/D,uBAAuB,iBAAiB,yBAAyB;GACjE,oBAAoB,YAAY,EAAE;GAClC,GAAG,YAAY,EAAE,UAAU,WAAW,GAAG,EAAE;GAC3C,2BAA2B,iBAAiB,6BAA6B;GACzE,GAAG;GACJ,CAE4C;SACvC;AAEN,SAAO;;CAIT,MAAM,SAAS,MAAM,YAAY;AAEjC,MAAK,SAAS,SAAS;EACrB,MAAM,KAAK;AACX,MAAI,GAAG,SAAS,OAAO;GAErB,IAAI,QAAQ,GAAG,QAAQ,MACpB,QAAQ,SAAS,KAAK,CACtB,QAAQ,SAAS,KAAK,CACtB,SAAS;AAGZ,OAAI,CAAC,MAAM,SAAS,IAAI,CACtB,UAAS;AAGX,OAAI,qBACF,SAAQ,MAAM,QACZ,4DACA,IACD;AAGH,MAAG,QAAQ,QAAQ;;GAErB;AAIF,MAAK,SAAS,SAAS;EACrB,MAAM,KAAK;AACX,MAAI,GAAG,SAAS,WAAW,GAAG,WAAW,wBAAwB,GAAG,SAAS;AAC3E,MAAG,QAAQ,gBAAgB;AAC3B,MAAG,QAAQ,QAAQ;AACnB,UAAO,GAAG,QAAQ;;GAEpB;AAEF,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"inlineLink.d.mts","names":[],"sources":["../../src/transformers/inlineLink.ts"],"mappings":";;;;;AAYA;;;;;iBAAsB,UAAA,CAAW,GAAA,EAAK,SAAA,IAAa,QAAA,YAAoB,OAAA,CAAQ,SAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"inlineLink.mjs","names":[],"sources":["../../src/transformers/inlineLink.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport { resolve, dirname } from 'node:path'\nimport type { ChildNode, Element } from 'domhandler'\nimport { walk } from '../utils/ast/index.ts'\n\n/**\n * Inline `<link rel=\"stylesheet\">` tags as `<style>` tags.\n *\n * - Local file paths are always inlined (resolved relative to the template)\n * - Remote URLs (http/https) are only inlined if the `inline` attribute is present\n * - Runs before the tailwindcss transformer so CSS is compiled normally\n */\nexport async function inlineLink(dom: ChildNode[], filePath?: string): Promise<ChildNode[]> {\n const links: { node: Element; parent: ChildNode; index: number }[] = []\n\n walk(dom, (node) => {\n if ((node as Element).name !== 'link') return\n\n const el = node as Element\n const attrs = el.attribs || {}\n\n if (attrs.rel !== 'stylesheet' || !attrs.href) return\n\n const parent = el.parent as ChildNode\n\n if (parent && 'children' in parent) {\n const index = (parent.children as ChildNode[]).indexOf(el)\n if (index !== -1) {\n links.push({ node: el, parent, index })\n }\n } else {\n // Top-level node\n const index = dom.indexOf(el)\n if (index !== -1) {\n links.push({ node: el, parent: null as any, index })\n }\n }\n })\n\n for (const { node, parent, index } of links) {\n const href = node.attribs.href\n const isRemote = href.startsWith('http://') || href.startsWith('https://')\n\n let css: string | undefined\n\n if (isRemote) {\n if (!('inline' in node.attribs)) continue\n\n try {\n const response = await fetch(href)\n css = await response.text()\n } catch {\n continue\n }\n } else {\n if (!filePath) continue\n\n try {\n const absolutePath = resolve(dirname(filePath), href)\n css = readFileSync(absolutePath, 'utf8')\n } catch {\n continue\n }\n }\n\n const styleNode = {\n type: 'tag',\n name: 'style',\n attribs: {},\n children: [{\n type: 'text',\n data: css,\n parent: null as any,\n }],\n parent: parent || null,\n } as any\n\n // Set parent reference on the text child\n styleNode.children[0].parent = styleNode\n\n const siblings = parent && 'children' in parent\n ? parent.children as ChildNode[]\n : dom\n\n siblings.splice(index, 1, styleNode)\n }\n\n return dom\n}\n"],"mappings":";;;;;;;;;;;;;AAYA,eAAsB,WAAW,KAAkB,UAAyC;CAC1F,MAAM,QAA+D,EAAE;AAEvE,MAAK,MAAM,SAAS;AAClB,MAAK,KAAiB,SAAS,OAAQ;EAEvC,MAAM,KAAK;EACX,MAAM,QAAQ,GAAG,WAAW,EAAE;AAE9B,MAAI,MAAM,QAAQ,gBAAgB,CAAC,MAAM,KAAM;EAE/C,MAAM,SAAS,GAAG;AAElB,MAAI,UAAU,cAAc,QAAQ;GAClC,MAAM,QAAS,OAAO,SAAyB,QAAQ,GAAG;AAC1D,OAAI,UAAU,GACZ,OAAM,KAAK;IAAE,MAAM;IAAI;IAAQ;IAAO,CAAC;SAEpC;GAEL,MAAM,QAAQ,IAAI,QAAQ,GAAG;AAC7B,OAAI,UAAU,GACZ,OAAM,KAAK;IAAE,MAAM;IAAI,QAAQ;IAAa;IAAO,CAAC;;GAGxD;AAEF,MAAK,MAAM,EAAE,MAAM,QAAQ,WAAW,OAAO;EAC3C,MAAM,OAAO,KAAK,QAAQ;EAC1B,MAAM,WAAW,KAAK,WAAW,UAAU,IAAI,KAAK,WAAW,WAAW;EAE1E,IAAI;AAEJ,MAAI,UAAU;AACZ,OAAI,EAAE,YAAY,KAAK,SAAU;AAEjC,OAAI;AAEF,UAAM,OADW,MAAM,MAAM,KAAK,EACb,MAAM;WACrB;AACN;;SAEG;AACL,OAAI,CAAC,SAAU;AAEf,OAAI;AAEF,UAAM,aADe,QAAQ,QAAQ,SAAS,EAAE,KAAK,EACpB,OAAO;WAClC;AACN;;;EAIJ,MAAM,YAAY;GAChB,MAAM;GACN,MAAM;GACN,SAAS,EAAE;GACX,UAAU,CAAC;IACT,MAAM;IACN,MAAM;IACN,QAAQ;IACT,CAAC;GACF,QAAQ,UAAU;GACnB;AAGD,YAAU,SAAS,GAAG,SAAS;AAM/B,GAJiB,UAAU,cAAc,SACrC,OAAO,WACP,KAEK,OAAO,OAAO,GAAG,UAAU;;AAGtC,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"minify.d.mts","names":[],"sources":["../../src/transformers/minify.ts"],"mappings":";;;;;AAmBA;;;;;;;;iBAAgB,MAAA,CAAO,IAAA,UAAc,MAAA,GAAQ,aAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"minify.mjs","names":["merge"],"sources":["../../src/transformers/minify.ts"],"sourcesContent":["import { crush } from 'html-crush'\nimport { defu as merge } from 'defu'\nimport type { Opts } from 'html-crush'\nimport type { MaizzleConfig } from '../types/config.ts'\n\nconst DEFAULT_OPTIONS = {\n removeLineBreaks: true,\n}\n\n/**\n * Minify transformer.\n *\n * Minifies HTML using the `html-crush` package.\n * Enabled by setting `minify: true` (or passing options object).\n * User options are merged on top of the defaults.\n *\n * The only Maizzle default that differs from html-crush's own defaults\n * is `removeLineBreaks: true`.\n */\nexport function minify(html: string, config: MaizzleConfig = {}): string {\n const option = config.html?.minify\n\n if (!option) return html\n\n const userOptions = typeof option === 'object' ? option : {}\n const options = merge(userOptions, DEFAULT_OPTIONS) as Partial<Opts>\n\n return crush(html, options).result\n}\n"],"mappings":";;;;AAKA,MAAM,kBAAkB,EACtB,kBAAkB,MACnB;;;;;;;;;;;AAYD,SAAgB,OAAO,MAAc,SAAwB,EAAE,EAAU;CACvE,MAAM,SAAS,OAAO,MAAM;AAE5B,KAAI,CAAC,OAAQ,QAAO;AAKpB,QAAO,MAAM,MAFGA,KADI,OAAO,WAAW,WAAW,SAAS,EAAE,EACzB,gBAAgB,CAExB,CAAC"}
@@ -1,19 +0,0 @@
1
- import { ChildNode } from "domhandler";
2
-
3
- //#region src/transformers/msoWidthFromClass.d.ts
4
- /**
5
- * Resolve `__MAIZZLE_MSOW_{id}__` placeholders inside MSO conditional
6
- * comments by reading the inlined `max-width` (or `width`) of the
7
- * paired element marked with `data-maizzle-msow-id`.
8
- *
9
- * Used by `<Container>` and `<Section>` to derive Outlook's table width
10
- * from the resolved Tailwind class or inline style on the inner div,
11
- * after CSS inlining.
12
- *
13
- * Falls back to the value of `data-maizzle-msow-fallback` (default
14
- * `600px`) when the value can't be parsed.
15
- */
16
- declare function msoWidthFromClass(dom: ChildNode[]): ChildNode[];
17
- //#endregion
18
- export { msoWidthFromClass };
19
- //# sourceMappingURL=msoWidthFromClass.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"msoWidthFromClass.d.mts","names":[],"sources":["../../src/transformers/msoWidthFromClass.ts"],"mappings":";;;;;AAkCA;;;;;;;;;;iBAAgB,iBAAA,CAAkB,GAAA,EAAK,SAAA,KAAc,SAAA"}
@@ -1,61 +0,0 @@
1
- import { walk } from "../utils/ast/walker.mjs";
2
- import "../utils/ast/index.mjs";
3
-
4
- //#region src/transformers/msoWidthFromClass.ts
5
- const RE_MAX_WIDTH = /(?:^|;\s*)max-width:\s*([^;]+)/i;
6
- const RE_WIDTH = /(?:^|;\s*)width:\s*([^;]+)/i;
7
- const RE_PERCENT = /^[\d.]+%$/;
8
- function resolveWidth(value) {
9
- const trimmed = value.trim();
10
- if (RE_PERCENT.test(trimmed)) return trimmed;
11
- const m = trimmed.match(/^([\d.]+)(px|rem|em|pt)?$/i);
12
- if (!m) return null;
13
- const n = parseFloat(m[1]);
14
- switch ((m[2] || "px").toLowerCase()) {
15
- case "px": return `${Math.round(n)}px`;
16
- case "rem":
17
- case "em": return `${Math.round(n * 16)}px`;
18
- case "pt": return `${Math.round(n * 1.333)}px`;
19
- default: return null;
20
- }
21
- }
22
- /**
23
- * Resolve `__MAIZZLE_MSOW_{id}__` placeholders inside MSO conditional
24
- * comments by reading the inlined `max-width` (or `width`) of the
25
- * paired element marked with `data-maizzle-msow-id`.
26
- *
27
- * Used by `<Container>` and `<Section>` to derive Outlook's table width
28
- * from the resolved Tailwind class or inline style on the inner div,
29
- * after CSS inlining.
30
- *
31
- * Falls back to the value of `data-maizzle-msow-fallback` (default
32
- * `600px`) when the value can't be parsed.
33
- */
34
- function msoWidthFromClass(dom) {
35
- const widths = /* @__PURE__ */ new Map();
36
- walk(dom, (node) => {
37
- const el = node;
38
- const id = el.attribs?.["data-maizzle-msow-id"];
39
- if (!id) return;
40
- delete el.attribs["data-maizzle-msow-id"];
41
- const fallback = el.attribs["data-maizzle-msow-fallback"] ?? "600px";
42
- delete el.attribs["data-maizzle-msow-fallback"];
43
- const style = el.attribs.style ?? "";
44
- const raw = style.match(RE_MAX_WIDTH)?.[1] ?? style.match(RE_WIDTH)?.[1];
45
- const resolved = raw ? resolveWidth(raw) : null;
46
- widths.set(id, resolved ?? fallback);
47
- });
48
- if (widths.size === 0) return dom;
49
- walk(dom, (node) => {
50
- if (node.type !== "comment") return;
51
- let data = node.data;
52
- if (!data.includes("__MAIZZLE_MSOW_")) return;
53
- for (const [id, px] of widths) data = data.replaceAll(`__MAIZZLE_MSOW_${id}__`, px);
54
- node.data = data;
55
- });
56
- return dom;
57
- }
58
-
59
- //#endregion
60
- export { msoWidthFromClass };
61
- //# sourceMappingURL=msoWidthFromClass.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"msoWidthFromClass.mjs","names":[],"sources":["../../src/transformers/msoWidthFromClass.ts"],"sourcesContent":["import { walk } from '../utils/ast/index.ts'\nimport type { ChildNode, Element } from 'domhandler'\n\nconst RE_MAX_WIDTH = /(?:^|;\\s*)max-width:\\s*([^;]+)/i\nconst RE_WIDTH = /(?:^|;\\s*)width:\\s*([^;]+)/i\nconst RE_PERCENT = /^[\\d.]+%$/\n\nfunction resolveWidth(value: string): string | null {\n const trimmed = value.trim()\n if (RE_PERCENT.test(trimmed)) return trimmed\n const m = trimmed.match(/^([\\d.]+)(px|rem|em|pt)?$/i)\n if (!m) return null\n const n = parseFloat(m[1])\n switch ((m[2] || 'px').toLowerCase()) {\n case 'px': return `${Math.round(n)}px`\n case 'rem':\n case 'em': return `${Math.round(n * 16)}px`\n case 'pt': return `${Math.round(n * 1.333)}px`\n default: return null\n }\n}\n\n/**\n * Resolve `__MAIZZLE_MSOW_{id}__` placeholders inside MSO conditional\n * comments by reading the inlined `max-width` (or `width`) of the\n * paired element marked with `data-maizzle-msow-id`.\n *\n * Used by `<Container>` and `<Section>` to derive Outlook's table width\n * from the resolved Tailwind class or inline style on the inner div,\n * after CSS inlining.\n *\n * Falls back to the value of `data-maizzle-msow-fallback` (default\n * `600px`) when the value can't be parsed.\n */\nexport function msoWidthFromClass(dom: ChildNode[]): ChildNode[] {\n const widths = new Map<string, string>()\n\n walk(dom, (node) => {\n const el = node as Element\n const id = el.attribs?.['data-maizzle-msow-id']\n if (!id) return\n delete el.attribs['data-maizzle-msow-id']\n\n const fallback = el.attribs['data-maizzle-msow-fallback'] ?? '600px'\n delete el.attribs['data-maizzle-msow-fallback']\n\n const style = el.attribs.style ?? ''\n const raw = style.match(RE_MAX_WIDTH)?.[1] ?? style.match(RE_WIDTH)?.[1]\n const resolved = raw ? resolveWidth(raw) : null\n widths.set(id, resolved ?? fallback)\n })\n\n if (widths.size === 0) return dom\n\n walk(dom, (node) => {\n if (node.type !== 'comment') return\n let data = (node as any).data as string\n if (!data.includes('__MAIZZLE_MSOW_')) return\n for (const [id, px] of widths) {\n data = data.replaceAll(`__MAIZZLE_MSOW_${id}__`, px)\n }\n ;(node as any).data = data\n })\n\n return dom\n}\n"],"mappings":";;;;AAGA,MAAM,eAAe;AACrB,MAAM,WAAW;AACjB,MAAM,aAAa;AAEnB,SAAS,aAAa,OAA8B;CAClD,MAAM,UAAU,MAAM,MAAM;AAC5B,KAAI,WAAW,KAAK,QAAQ,CAAE,QAAO;CACrC,MAAM,IAAI,QAAQ,MAAM,6BAA6B;AACrD,KAAI,CAAC,EAAG,QAAO;CACf,MAAM,IAAI,WAAW,EAAE,GAAG;AAC1B,UAAS,EAAE,MAAM,MAAM,aAAa,EAApC;EACE,KAAK,KAAM,QAAO,GAAG,KAAK,MAAM,EAAE,CAAC;EACnC,KAAK;EACL,KAAK,KAAM,QAAO,GAAG,KAAK,MAAM,IAAI,GAAG,CAAC;EACxC,KAAK,KAAM,QAAO,GAAG,KAAK,MAAM,IAAI,MAAM,CAAC;EAC3C,QAAS,QAAO;;;;;;;;;;;;;;;AAgBpB,SAAgB,kBAAkB,KAA+B;CAC/D,MAAM,yBAAS,IAAI,KAAqB;AAExC,MAAK,MAAM,SAAS;EAClB,MAAM,KAAK;EACX,MAAM,KAAK,GAAG,UAAU;AACxB,MAAI,CAAC,GAAI;AACT,SAAO,GAAG,QAAQ;EAElB,MAAM,WAAW,GAAG,QAAQ,iCAAiC;AAC7D,SAAO,GAAG,QAAQ;EAElB,MAAM,QAAQ,GAAG,QAAQ,SAAS;EAClC,MAAM,MAAM,MAAM,MAAM,aAAa,GAAG,MAAM,MAAM,MAAM,SAAS,GAAG;EACtE,MAAM,WAAW,MAAM,aAAa,IAAI,GAAG;AAC3C,SAAO,IAAI,IAAI,YAAY,SAAS;GACpC;AAEF,KAAI,OAAO,SAAS,EAAG,QAAO;AAE9B,MAAK,MAAM,SAAS;AAClB,MAAI,KAAK,SAAS,UAAW;EAC7B,IAAI,OAAQ,KAAa;AACzB,MAAI,CAAC,KAAK,SAAS,kBAAkB,CAAE;AACvC,OAAK,MAAM,CAAC,IAAI,OAAO,OACrB,QAAO,KAAK,WAAW,kBAAkB,GAAG,KAAK,GAAG;AAErD,EAAC,KAAa,OAAO;GACtB;AAEF,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"purgeCSS.d.mts","names":[],"sources":["../../src/transformers/purgeCSS.ts"],"mappings":";;;;;;AAkDA;;;;;;;;;;;;;iBAAgB,QAAA,CAAS,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,SAAA,GAAiB,SAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"purgeCSS.mjs","names":["merge"],"sources":["../../src/transformers/purgeCSS.ts"],"sourcesContent":["import { comb } from 'email-comb'\nimport { defu as merge } from 'defu'\nimport postcss from 'postcss'\nimport safeParser from 'postcss-safe-parser'\nimport { selectAll } from 'css-select'\nimport type { ChildNode, Element } from 'domhandler'\nimport { parse, serialize, walk } from '../utils/ast/index.ts'\nimport type { CssConfig } from '../types/config.ts'\n\nconst DEFAULT_SAFELIST: string[] = [\n '*body*', // Gmail\n '.gmail*', // Gmail\n '.apple*', // Apple Mail\n '.ios*', // Mail on iOS\n '.ox-*', // Open-Xchange\n '.outlook*', // Outlook.com\n '[data-ogs*', // Outlook.com\n '.bloop_container', // Airmail\n '.Singleton', // Apple Mail 10\n '.unused', // Notes 8\n '.moz-text-html', // Thunderbird\n '.mail-detail-content', // Comcast, Libero webmail\n '*edo*', // Edison (all)\n '#*', // Freenet uses #msgBody\n '.lang*', // Fenced code blocks\n]\n\nconst DEFAULT_OPTIONS = {\n backend: [\n { heads: '{{', tails: '}}' },\n { heads: '{%', tails: '%}' },\n ],\n whitelist: [...DEFAULT_SAFELIST],\n}\n\n/**\n * Remove unused CSS transformer.\n *\n * Uses `email-comb` to strip CSS selectors and corresponding class/id\n * references that are not matched anywhere in the HTML body.\n *\n * Enable by setting `css.purge: true` (or passing options).\n * The user-supplied options are merged on top of the defaults, so\n * `safelist` values are **appended** to the built-in safelist rather\n * than replacing it.\n *\n * Accepts `ChildNode[]` as input, serializes internally before passing\n * to email-comb (which requires a raw HTML string), then parses the\n * result back to `ChildNode[]` so it fits in the DOM pipeline.\n */\nexport function purgeCSS(dom: ChildNode[], config: CssConfig = {}): ChildNode[] {\n const option = config.purge\n\n if (!option) return dom\n\n const userOptions = typeof option === 'object' ? option : {}\n\n // Merge user options on top of defaults.\n // defu merges objects deeply; for arrays it appends user values.\n // We want the user safelist appended to the default safelist,\n // so we build whitelist manually.\n const userSafelist = Array.isArray((userOptions as any).safelist)\n ? (userOptions as any).safelist as string[]\n : []\n\n const { safelist: _discard, ...restUserOptions } = userOptions as any\n\n const options = merge(\n { ...restUserOptions, whitelist: [...DEFAULT_SAFELIST, ...userSafelist] },\n DEFAULT_OPTIONS,\n )\n\n // Deep purge first: DOM-aware selector removal using PostCSS + css-select.\n // Runs before email-comb so that email-comb can clean up orphaned classes\n // in HTML attributes left behind by removed CSS rules.\n const safelist = [...DEFAULT_SAFELIST, ...userSafelist]\n dom = deepPurge(dom, safelist)\n\n const { result } = comb(serialize(dom), options)\n\n let purgedDom = parse(result)\n\n // Clean up data-embed/embed attributes — no longer needed after purging\n walk(purgedDom, (node) => {\n const el = node as Element\n if (el.name === 'style' && el.attribs) {\n delete el.attribs['data-embed']\n delete el.attribs.embed\n }\n })\n\n return purgedDom\n}\n\n/**\n * Deep purge: uses PostCSS to parse CSS in non-embedded style tags,\n * then checks each selector against the DOM with css-select.\n * Removes rules where no selector matches any element.\n */\nfunction isSafelisted(selector: string, safelist: string[]): boolean {\n return safelist.some((pattern) => {\n if (pattern.startsWith('*') && pattern.endsWith('*')) {\n return selector.includes(pattern.slice(1, -1))\n }\n if (pattern.endsWith('*')) {\n return selector.startsWith(pattern.slice(0, -1))\n }\n if (pattern.startsWith('*')) {\n return selector.endsWith(pattern.slice(1))\n }\n return selector === pattern\n })\n}\n\nfunction deepPurge(dom: ChildNode[], safelist: string[]): ChildNode[] {\n walk(dom, (node) => {\n const el = node as Element\n\n if (el.name !== 'style' || !el.attribs) return\n if ('data-embed' in el.attribs || 'embed' in el.attribs) return\n\n const textNode = el.children?.find((c: any) => c.type === 'text') as any\n if (!textNode?.data?.trim()) return\n\n const root = postcss.parse(textNode.data, { parser: safeParser })\n\n root.walkRules((rule) => {\n // Skip rules inside @media or other at-rules — those may target\n // states we can't match statically (hover, responsive, etc.)\n if (rule.parent?.type === 'atrule') return\n\n const selectors = rule.selectors ?? [rule.selector]\n const matched = selectors.filter((sel) => {\n // Keep safelisted selectors\n if (isSafelisted(sel, safelist)) return true\n\n // Skip pseudo-classes/elements that can't be matched statically.\n // Functional pseudos like :not(), :is(), :where(), :has() are\n // matchable by css-select, so we only skip dynamic/state ones.\n if (/::[\\w-]/.test(sel)) return true\n if (/(?<!:):(?!not\\b|is\\b|where\\b|has\\b)[\\w-]/.test(sel.replace(/\\\\./g, ''))) return true\n\n try {\n return selectAll(sel, dom).length > 0\n } catch {\n // If css-select can't parse the selector, keep it\n return true\n }\n })\n\n if (matched.length === 0) {\n rule.remove()\n } else if (matched.length < selectors.length) {\n rule.selectors = matched\n }\n })\n\n // Remove empty at-rules\n root.walkAtRules((atRule) => {\n if (atRule.nodes?.length === 0) {\n atRule.remove()\n }\n })\n\n const purgedCss = root.toString()\n\n if (purgedCss.trim()) {\n textNode.data = purgedCss\n } else {\n // Remove the style tag entirely if empty\n const parent = el.parent\n if (parent && 'children' in parent) {\n const idx = parent.children.indexOf(el as any)\n if (idx !== -1) parent.children.splice(idx, 1)\n }\n }\n })\n\n return dom\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"removeAttributes.d.mts","names":[],"sources":["../../src/transformers/removeAttributes.ts"],"mappings":";;;;;;AAkCA;;;;;;;;;;;;;;;;;;;;;iBAAgB,gBAAA,CAAiB,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,gBAAA,GAAwB,SAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"removeAttributes.mjs","names":[],"sources":["../../src/transformers/removeAttributes.ts"],"sourcesContent":["import type { ChildNode, Element } from 'domhandler'\nimport { walk } from '../utils/ast/index.ts'\nimport type { AttributesConfig } from '../types/config.ts'\n\ninterface RemoveAttributeConfig {\n name: string\n value?: string | RegExp | boolean\n}\n\ntype RemoveAttributeOption = string | RemoveAttributeConfig\n\n/**\n * Remove attributes transformer.\n *\n * Removes specified HTML attributes from elements.\n *\n * By default, removes empty `style` and `class` attributes.\n *\n * Supports:\n * - String: removes attribute when empty (boolean or empty string)\n * - Object with name and value: removes when attribute matches exactly\n * - Object with name and RegExp value: removes when attribute value matches regex\n *\n * Configured via `remove` array:\n * ```js\n * {\n * remove: [\n * 'data-src', // Remove empty data-src attributes\n * { name: 'id', value: 'test' }, // Remove id=\"test\" exactly\n * { name: 'data-id', value: /\\d/ } // Remove data-id when value contains digits\n * ]\n * }\n * ```\n */\nexport function removeAttributes(dom: ChildNode[], config: AttributesConfig = {}): ChildNode[] {\n const removeOptions = config.remove\n\n // Always remove empty style and class attributes by default\n const alwaysRemove: RemoveAttributeOption[] = ['style', 'class']\n\n // Parse user options\n let userOptions: RemoveAttributeOption[] = []\n if (Array.isArray(removeOptions)) {\n userOptions = removeOptions as RemoveAttributeOption[]\n }\n\n // Combine default and user options\n const attributesToRemove: RemoveAttributeOption[] = [...alwaysRemove, ...userOptions]\n\n if (attributesToRemove.length === 0) {\n return dom\n }\n\n walk(dom, (node) => {\n const el = node as Element\n if (!el.attribs) return\n\n for (const attr of attributesToRemove) {\n let attrName: string\n let attrValue: string | RegExp | boolean | undefined\n\n if (typeof attr === 'string') {\n attrName = attr\n attrValue = true // Remove when value is empty (boolean true or empty string)\n } else {\n attrName = attr.name\n attrValue = attr.value\n }\n\n const currentValue = el.attribs[attrName]\n\n // Skip if attribute doesn't exist\n if (currentValue === undefined) continue\n\n let shouldRemove = false\n\n if (typeof attrValue === 'boolean') {\n // Remove if value is empty (boolean true is treated as no-value attribute)\n shouldRemove = currentValue === '' || (currentValue as unknown) === true\n } else if (typeof attrValue === 'string') {\n // Remove if value matches exactly\n shouldRemove = currentValue === attrValue\n } else if (attrValue instanceof RegExp) {\n // Remove if value matches regex\n shouldRemove = attrValue.test(currentValue)\n } else {\n // Default: remove if empty\n shouldRemove = currentValue === ''\n }\n\n if (shouldRemove) {\n delete el.attribs[attrName]\n }\n }\n })\n\n return dom\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,SAAgB,iBAAiB,KAAkB,SAA2B,EAAE,EAAe;CAC7F,MAAM,gBAAgB,OAAO;CAG7B,MAAM,eAAwC,CAAC,SAAS,QAAQ;CAGhE,IAAI,cAAuC,EAAE;AAC7C,KAAI,MAAM,QAAQ,cAAc,CAC9B,eAAc;CAIhB,MAAM,qBAA8C,CAAC,GAAG,cAAc,GAAG,YAAY;AAErF,KAAI,mBAAmB,WAAW,EAChC,QAAO;AAGT,MAAK,MAAM,SAAS;EAClB,MAAM,KAAK;AACX,MAAI,CAAC,GAAG,QAAS;AAEjB,OAAK,MAAM,QAAQ,oBAAoB;GACrC,IAAI;GACJ,IAAI;AAEJ,OAAI,OAAO,SAAS,UAAU;AAC5B,eAAW;AACX,gBAAY;UACP;AACL,eAAW,KAAK;AAChB,gBAAY,KAAK;;GAGnB,MAAM,eAAe,GAAG,QAAQ;AAGhC,OAAI,iBAAiB,OAAW;GAEhC,IAAI,eAAe;AAEnB,OAAI,OAAO,cAAc,UAEvB,gBAAe,iBAAiB,MAAO,iBAA6B;YAC3D,OAAO,cAAc,SAE9B,gBAAe,iBAAiB;YACvB,qBAAqB,OAE9B,gBAAe,UAAU,KAAK,aAAa;OAG3C,gBAAe,iBAAiB;AAGlC,OAAI,aACF,QAAO,GAAG,QAAQ;;GAGtB;AAEF,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"replaceStrings.d.mts","names":[],"sources":["../../src/transformers/replaceStrings.ts"],"mappings":";;;;;AAWA;;;;;;;iBAAgB,cAAA,CAAe,IAAA,UAAc,MAAA,GAAQ,aAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"replaceStrings.mjs","names":[],"sources":["../../src/transformers/replaceStrings.ts"],"sourcesContent":["import type { MaizzleConfig } from '../types/config.ts'\n\n/**\n * Replace strings transformer.\n *\n * Replaces strings in the HTML using the key-value pairs defined in\n * `config.replaceStrings`. Each key is treated as a regular expression\n * pattern (case-insensitive, global), and the value is the replacement.\n *\n * Character classes must be escaped in keys, e.g. `\\\\s` for `\\s`.\n */\nexport function replaceStrings(html: string, config: MaizzleConfig = {}): string {\n const replacements = config.replaceStrings\n\n if (!replacements || Object.keys(replacements).length === 0) return html\n\n return Object.entries(replacements).reduce(\n (result, [pattern, replacement]) => result.replace(new RegExp(pattern, 'gi'), replacement),\n html,\n )\n}\n"],"mappings":";;;;;;;;;;AAWA,SAAgB,eAAe,MAAc,SAAwB,EAAE,EAAU;CAC/E,MAAM,eAAe,OAAO;AAE5B,KAAI,CAAC,gBAAgB,OAAO,KAAK,aAAa,CAAC,WAAW,EAAG,QAAO;AAEpE,QAAO,OAAO,QAAQ,aAAa,CAAC,QACjC,QAAQ,CAAC,SAAS,iBAAiB,OAAO,QAAQ,IAAI,OAAO,SAAS,KAAK,EAAE,YAAY,EAC1F,KACD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"safeClassNames.d.mts","names":[],"sources":["../../src/transformers/safeClassNames.ts"],"mappings":";;;;;;AAsGA;;;;;;;;;;;;iBAAgB,cAAA,CAAe,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,SAAA,GAAiB,SAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"safeClassNames.mjs","names":[],"sources":["../../src/transformers/safeClassNames.ts"],"sourcesContent":["import postcss from 'postcss'\nimport safeParser from 'postcss-safe-parser'\nimport type { ChildNode, Element } from 'domhandler'\nimport { walk } from '../utils/ast/index.ts'\nimport type { CssConfig } from '../types/config.ts'\n\nconst DEFAULT_REPLACEMENTS: Record<string, string> = {\n ':': '-',\n '/': '-',\n '%': 'pc',\n '.': '_',\n ',': '_',\n '#': '_',\n '[': '',\n ']': '',\n '(': '',\n ')': '',\n '{': '',\n '}': '',\n '!': '-i',\n '&': 'and-',\n '<': 'lt-',\n '=': 'eq-',\n '>': 'gt-',\n '|': 'or-',\n '@': 'at-',\n '?': 'q-',\n '\\\\': '-',\n '\"': '-',\n \"'\": '-',\n '*': '-',\n '+': '-',\n ';': '-',\n '^': '-',\n '`': '-',\n '~': '-',\n '$': '-',\n}\n\nfunction escapeForRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\n/**\n * Replace escaped special characters in CSS selectors.\n *\n * Tailwind generates selectors like `.sm\\:text-base`. This function\n * replaces the `\\:` with `-` (or whatever the configured replacement is)\n * so the selector becomes `.sm-text-base`, which is safe for email clients.\n */\nfunction processCssSelectors(css: string, replacements: Record<string, string>): string {\n // Matches \\<char> in CSS selectors — e.g. \\: \\/ \\. \\[ etc.\n const selectorRegex = new RegExp(\n `\\\\\\\\(${Object.keys(replacements).map(escapeForRegex).join('|')})`,\n 'g',\n )\n\n return postcss([\n (root: postcss.Root) => {\n root.walkRules((rule: postcss.Rule) => {\n rule.selector = rule.selector\n .replace(selectorRegex, (_matched, char) => replacements[char] ?? _matched)\n // Handle CSS unicode escape for comma (\\2c → _)\n .replaceAll('\\\\2c ', '_')\n })\n },\n ]).process(css, { parser: safeParser }).css\n}\n\n/**\n * Replace unsafe special characters in a class attribute value.\n *\n * Splits on whitespace and replaces each char from the replacements map\n * in each class token individually.\n */\nfunction processClassAttr(classStr: string, replacements: Record<string, string>): string {\n return classStr\n .split(/\\s+/)\n .filter(Boolean)\n .map((cls) => {\n for (const [from, to] of Object.entries(replacements)) {\n cls = cls.split(from).join(to)\n }\n return cls\n })\n .join(' ')\n}\n\n/**\n * Safe class names transformer.\n *\n * Replaces unsafe characters (`:`, `/`, `[`, `]`, etc.) in:\n * - CSS selectors inside `<style>` tags\n * - HTML `class` attributes\n *\n * This makes Tailwind utility classes like `sm:text-base` safe for\n * email clients that cannot handle escaped characters in class names.\n *\n * Enabled by default. Disable by setting `css.safe` to `false`.\n * Customize replacements by passing a `Record<string, string>` — user\n * values are merged on top of the defaults.\n */\nexport function safeClassNames(dom: ChildNode[], config: CssConfig = {}): ChildNode[] {\n const option = config.safe ?? true\n\n if (!option) return dom\n\n const replacements: Record<string, string> =\n option && typeof option === 'object'\n ? { ...DEFAULT_REPLACEMENTS, ...option }\n : DEFAULT_REPLACEMENTS\n\n walk(dom, (node) => {\n const el = node as Element\n\n // Process CSS selectors inside <style> tags\n if (el.name === 'style' && el.children?.length) {\n const text = el.children.find((c) => c.type === 'text') as any\n if (text?.data?.trim()) {\n text.data = processCssSelectors(text.data, replacements)\n }\n }\n\n // Replace special chars in class attributes\n if ('attribs' in el && el.attribs?.class) {\n el.attribs.class = processClassAttr(el.attribs.class, replacements)\n }\n })\n\n return dom\n}\n"],"mappings":";;;;;;AAMA,MAAM,uBAA+C;CACnD,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,MAAM;CACN,MAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACN;AAED,SAAS,eAAe,GAAmB;AACzC,QAAO,EAAE,QAAQ,uBAAuB,OAAO;;;;;;;;;AAUjD,SAAS,oBAAoB,KAAa,cAA8C;CAEtF,MAAM,gBAAgB,IAAI,OACxB,QAAQ,OAAO,KAAK,aAAa,CAAC,IAAI,eAAe,CAAC,KAAK,IAAI,CAAC,IAChE,IACD;AAED,QAAO,QAAQ,EACZ,SAAuB;AACtB,OAAK,WAAW,SAAuB;AACrC,QAAK,WAAW,KAAK,SAClB,QAAQ,gBAAgB,UAAU,SAAS,aAAa,SAAS,SAAS,CAE1E,WAAW,SAAS,IAAI;IAC3B;GAEL,CAAC,CAAC,QAAQ,KAAK,EAAE,QAAQ,YAAY,CAAC,CAAC;;;;;;;;AAS1C,SAAS,iBAAiB,UAAkB,cAA8C;AACxF,QAAO,SACJ,MAAM,MAAM,CACZ,OAAO,QAAQ,CACf,KAAK,QAAQ;AACZ,OAAK,MAAM,CAAC,MAAM,OAAO,OAAO,QAAQ,aAAa,CACnD,OAAM,IAAI,MAAM,KAAK,CAAC,KAAK,GAAG;AAEhC,SAAO;GACP,CACD,KAAK,IAAI;;;;;;;;;;;;;;;;AAiBd,SAAgB,eAAe,KAAkB,SAAoB,EAAE,EAAe;CACpF,MAAM,SAAS,OAAO,QAAQ;AAE9B,KAAI,CAAC,OAAQ,QAAO;CAEpB,MAAM,eACJ,UAAU,OAAO,WAAW,WACxB;EAAE,GAAG;EAAsB,GAAG;EAAQ,GACtC;AAEN,MAAK,MAAM,SAAS;EAClB,MAAM,KAAK;AAGX,MAAI,GAAG,SAAS,WAAW,GAAG,UAAU,QAAQ;GAC9C,MAAM,OAAO,GAAG,SAAS,MAAM,MAAM,EAAE,SAAS,OAAO;AACvD,OAAI,MAAM,MAAM,MAAM,CACpB,MAAK,OAAO,oBAAoB,KAAK,MAAM,aAAa;;AAK5D,MAAI,aAAa,MAAM,GAAG,SAAS,MACjC,IAAG,QAAQ,QAAQ,iBAAiB,GAAG,QAAQ,OAAO,aAAa;GAErE;AAEF,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"shorthandCSS.d.mts","names":[],"sources":["../../src/transformers/shorthandCSS.ts"],"mappings":";;;;;;AA2BA;;;;;;;;;;;;;;iBAAgB,YAAA,CAAa,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,SAAA,GAAiB,SAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"shorthandCSS.mjs","names":[],"sources":["../../src/transformers/shorthandCSS.ts"],"sourcesContent":["import postcss from 'postcss'\nimport safeParser from 'postcss-safe-parser'\nimport mergeLonghand from 'postcss-merge-longhand'\nimport type { ChildNode, Element } from 'domhandler'\nimport { walk } from '../utils/ast/index.ts'\nimport type { CssConfig } from '../types/config.ts'\n\ninterface ShorthandCssOptions {\n tags?: string[]\n}\n\n/**\n * Shorthand CSS transformer.\n *\n * Rewrites longhand CSS inside `style` attributes with shorthand syntax.\n * Works with margin, padding, and border when all sides are specified.\n *\n * For example:\n * `margin-left: 2px; margin-right: 2px; margin-top: 4px; margin-bottom: 4px`\n * becomes:\n * `margin: 4px 2px`\n *\n * Enabled via `css.shorthand`:\n * - `true`: enable for all tags\n * - `{ tags: ['td', 'div'] }`: enable only for specified tags\n * - `false` or omitted: disabled\n */\nexport function shorthandCSS(dom: ChildNode[], config: CssConfig = {}): ChildNode[] {\n const option = config.shorthand\n\n // Disabled by default\n if (!option) {\n return dom\n }\n\n // Parse options\n const options: ShorthandCssOptions = typeof option === 'object' ? option : {}\n const allowedTags = options.tags ?? []\n const hasTagFilter = allowedTags.length > 0\n\n walk(dom, (node) => {\n const el = node as Element\n\n // Skip if no attribs or no style\n if (!el.attribs?.style) {\n return\n }\n\n // Skip if tag filter is active and this tag is not allowed\n if (hasTagFilter && !allowedTags.includes(el.name)) {\n return\n }\n\n const styleValue = el.attribs.style\n\n try {\n // Process the style with postcss-merge-longhand\n // Wrap in a dummy selector since postcss needs a rule\n const { css } = postcss()\n .use(mergeLonghand)\n .process(`div { ${styleValue} }`, { parser: safeParser })\n\n // Extract the content between the braces\n const match = css.match(/div\\s*\\{\\s*([^}]+)\\s*\\}/)\n if (match && match[1]) {\n const newStyle = match[1].trim()\n if (newStyle !== styleValue) {\n el.attribs.style = newStyle\n }\n }\n } catch {\n // If processing fails, keep the original style\n }\n })\n\n return dom\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA2BA,SAAgB,aAAa,KAAkB,SAAoB,EAAE,EAAe;CAClF,MAAM,SAAS,OAAO;AAGtB,KAAI,CAAC,OACH,QAAO;CAKT,MAAM,eAD+B,OAAO,WAAW,WAAW,SAAS,EAAE,EACjD,QAAQ,EAAE;CACtC,MAAM,eAAe,YAAY,SAAS;AAE1C,MAAK,MAAM,SAAS;EAClB,MAAM,KAAK;AAGX,MAAI,CAAC,GAAG,SAAS,MACf;AAIF,MAAI,gBAAgB,CAAC,YAAY,SAAS,GAAG,KAAK,CAChD;EAGF,MAAM,aAAa,GAAG,QAAQ;AAE9B,MAAI;GAGF,MAAM,EAAE,QAAQ,SAAS,CACtB,IAAI,cAAc,CAClB,QAAQ,SAAS,WAAW,KAAK,EAAE,QAAQ,YAAY,CAAC;GAG3D,MAAM,QAAQ,IAAI,MAAM,0BAA0B;AAClD,OAAI,SAAS,MAAM,IAAI;IACrB,MAAM,WAAW,MAAM,GAAG,MAAM;AAChC,QAAI,aAAa,WACf,IAAG,QAAQ,QAAQ;;UAGjB;GAGR;AAEF,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"sixHex.d.mts","names":[],"sources":["../../src/transformers/sixHex.ts"],"mappings":";;;;;;AAeA;;;;;;iBAAgB,MAAA,CAAO,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,SAAA,GAAiB,SAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"sixHex.mjs","names":[],"sources":["../../src/transformers/sixHex.ts"],"sourcesContent":["import { conv } from 'color-shorthand-hex-to-six-digit'\nimport type { ChildNode, Element } from 'domhandler'\nimport { walk } from '../utils/ast/index.ts'\nimport type { CssConfig } from '../types/config.ts'\n\nconst targets = new Set(['bgcolor', 'color'])\n\n/**\n * Six-digit HEX transformer.\n *\n * Converts 3-digit HEX color codes to 6-digit in `bgcolor` and `color`\n * attributes, for better email client compatibility.\n *\n * Enabled by default via `css.sixHex`.\n */\nexport function sixHex(dom: ChildNode[], config: CssConfig = {}): ChildNode[] {\n if (config.sixHex === false) {\n return dom\n }\n\n walk(dom, (node) => {\n const el = node as Element\n\n if (!el.attribs) {\n return\n }\n\n for (const attr of targets) {\n const value = el.attribs[attr]\n\n if (value) {\n el.attribs[attr] = conv(value)\n }\n }\n })\n\n return dom\n}\n"],"mappings":";;;;;AAKA,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,QAAQ,CAAC;;;;;;;;;AAU7C,SAAgB,OAAO,KAAkB,SAAoB,EAAE,EAAe;AAC5E,KAAI,OAAO,WAAW,MACpB,QAAO;AAGT,MAAK,MAAM,SAAS;EAClB,MAAM,KAAK;AAEX,MAAI,CAAC,GAAG,QACN;AAGF,OAAK,MAAM,QAAQ,SAAS;GAC1B,MAAM,QAAQ,GAAG,QAAQ;AAEzB,OAAI,MACF,IAAG,QAAQ,QAAQ,KAAK,MAAM;;GAGlC;AAEF,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"tailwindcss.d.mts","names":[],"sources":["../../src/transformers/tailwindcss.ts"],"mappings":";;;;;;AAqIA;;;;;;;;;;;;;;iBAAsB,WAAA,CAAY,GAAA,EAAK,SAAA,IAAa,MAAA,EAAQ,aAAA,EAAe,QAAA,YAAoB,OAAA,CAAQ,SAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"tailwindcss.mjs","names":["resolveProps","pruneVars"],"sources":["../../src/transformers/tailwindcss.ts"],"sourcesContent":["import postcss from 'postcss'\nimport tailwindcssPostcss from '@tailwindcss/postcss'\nimport postcssCalc from 'postcss-calc'\nimport resolveProps from '../plugins/postcss/resolveProps.ts'\nimport pruneVars from '../plugins/postcss/pruneVars.ts'\nimport safeParser from 'postcss-safe-parser'\nimport { transform } from 'lightningcss'\nimport { resolve, dirname, relative } from 'node:path'\nimport type { ChildNode, Element } from 'domhandler'\nimport { walk } from '../utils/ast/index.ts'\nimport { tailwindCleanup } from '../plugins/postcss/tailwindCleanup.ts'\nimport { mergeMediaQueries } from '../plugins/postcss/mergeMediaQueries.ts'\nimport { quoteFontFamilies } from '../plugins/postcss/quoteFontFamilies.ts'\nimport { decodeStyleEntities } from '../utils/decodeStyleEntities.ts'\nimport type { MaizzleConfig } from '../types/config.ts'\n\nfunction createProcessor(config: MaizzleConfig) {\n return postcss([\n tailwindcssPostcss({\n base: config.css?.base,\n transformAssetUrls: false,\n optimize: false, // we run Lightning CSS manually\n }),\n resolveProps(),\n postcssCalc({}),\n pruneVars(),\n ])\n}\n\n/**\n * Check if CSS content uses Tailwind features that require source scanning.\n *\n * Only CSS that imports Tailwind (or @maizzle/tailwindcss) needs @source\n * directives. Plain CSS without Tailwind imports doesn't need scanning\n * and would pass through @source directives unconsumed.\n */\nfunction usesTailwind(css: string): boolean {\n return /((@import|@reference)\\s+[\"'](tailwindcss|@maizzle\\/tailwindcss)|@tailwind\\s)/.test(css)\n}\n\n/**\n * Lower modern CSS syntax using lightningcss.\n *\n * Targets IE 1 to maximize syntax lowering — converts modern features\n * like nesting, oklch(), color-mix(), @property, etc. into simple CSS\n * that email clients can understand.\n */\nfunction lowerSyntax(css: string): string {\n const result = transform({\n filename: 'email.css',\n code: Buffer.from(css),\n minify: false,\n targets: {\n ie: 4 << 5,\n },\n })\n\n return result.code.toString()\n}\n\n/**\n * Run cleanup and media query merging on the compiled CSS.\n *\n * Removes unwanted selectors (:host, :lang) and at-rules (@layer, @property),\n * then sorts and merges media queries.\n */\nasync function optimizeCss(css: string, config: MaizzleConfig): Promise<string> {\n const plugins: postcss.Plugin[] = [...tailwindCleanup(config), quoteFontFamilies()]\n\n const mediaPlugin = mergeMediaQueries(config)\n if (mediaPlugin) plugins.push(mediaPlugin)\n\n const result = await postcss(plugins).process(css, { from: undefined })\n\n return result.css\n}\n\n/**\n * Build @source directives for Tailwind CSS scanning.\n *\n * Configures two types of sources:\n * 1. Exclusions for output dir and user-configured paths\n * 2. Inline source with all class attribute values from the rendered DOM,\n * capturing classes from all components (built-in + user), dynamic\n * expressions, and the template itself — Tailwind's scanner handles\n * the actual class extraction from these raw values\n */\nfunction buildSourceDirectives(dom: ChildNode[], config: MaizzleConfig, fromDir: string): string {\n const directives: string[] = []\n\n // Exclude output dir and user-configured paths\n const excludePaths = [\n resolve(config.output?.path ?? 'dist'),\n ...(config.css?.exclude ?? []).map(p => resolve(p)),\n ]\n\n for (const p of excludePaths) {\n directives.push(`@source not \"${relative(fromDir, resolve(p))}\";`)\n }\n\n // Inline source: collect all class attribute values from the rendered DOM.\n // After Vue SSR, the DOM contains every class from every component\n // (built-in framework components, user components, dynamic bindings).\n // We pass these raw values to Tailwind's scanner via @source inline().\n const classes: string[] = []\n walk(dom, (n) => {\n const cls = (n as Element).attribs?.class\n if (cls) classes.push(cls)\n })\n\n if (classes.length) {\n directives.push(`@source inline(\"${classes.join(' ')}\");`)\n }\n\n return directives.join('\\n')\n}\n\n/**\n * Tailwind CSS transformer.\n *\n * Compiles CSS inside <style> tags in the DOM using\n * @tailwindcss/postcss, then lowers modern CSS syntax with lightningcss.\n *\n * Configures Tailwind sources to scan:\n * - Rendered class attributes (via `@source inline`) for all classes from all components\n * - User project files (via Tailwind's auto-detection from base/from path)\n *\n * User `@source` and `@source not directives` in style tags are preserved.\n * Source directives are only added to style tags that import Tailwind.\n *\n * Runs as the first transformer in the pipeline so that subsequent\n * transformers (inliner, purge, etc.) work with fully compiled CSS.\n */\nexport async function tailwindcss(dom: ChildNode[], config: MaizzleConfig, filePath?: string): Promise<ChildNode[]> {\n const styleTags: { node: Element; cssContent: string }[] = []\n\n walk(dom, (node) => {\n if ((node as Element).name !== 'style') return\n\n const el = node as Element\n const attrs = el.attribs || {}\n\n // `raw` opts out of compilation entirely (marker is consumed here).\n // `embed`/`data-embed` only signal \"preserve tag after inlining\" — they\n // still need to go through compile so Tailwind/@apply resolves.\n if ('raw' in attrs) {\n delete el.attribs.raw\n return\n }\n\n // Get text content from children and decode HTML entities\n const rawContent = el.children\n .filter(child => child.type === 'text')\n .map(child => (child as any).data)\n .join('')\n\n if (!rawContent.trim()) return\n\n styleTags.push({ node: el, cssContent: decodeStyleEntities(rawContent) })\n })\n\n if (!styleTags.length) return dom\n\n const fromPath = filePath ?? resolve(process.cwd(), 'template.vue')\n const fromDir = dirname(fromPath)\n\n // Only compute source directives if at least one style tag uses Tailwind\n const hasTailwindStyles = styleTags.some(({ cssContent }) => usesTailwind(cssContent))\n const sourceDirectives = hasTailwindStyles\n ? buildSourceDirectives(dom, config, fromDir)\n : ''\n\n // Create processor once — reused for all style tags in this template\n const processor = createProcessor(config)\n\n for (let i = 0; i < styleTags.length; i++) {\n const { node, cssContent } = styleTags[i]\n\n // Only add source directives to style tags that import Tailwind —\n // plain CSS doesn't need them and @tailwindcss/postcss would leave\n // the directives unconsumed in the output\n const fullCss = usesTailwind(cssContent)\n ? `${cssContent}\\n${sourceDirectives}`\n : cssContent\n\n try {\n const result = await processor.process(\n fullCss,\n {\n from: `${fromPath}?style=${i}`,\n parser: safeParser,\n }\n )\n\n const lowered = lowerSyntax(result.css)\n const optimized = await optimizeCss(lowered, config)\n\n // Replace the style tag's children with the compiled CSS\n node.children = [{\n type: 'text',\n data: optimized,\n parent: node,\n } as any]\n } catch {\n // If CSS processing fails, still replace with decoded content\n // so HTML entities don't break the CSS\n node.children = [{\n type: 'text',\n data: cssContent,\n parent: node,\n } as any]\n }\n }\n\n return dom\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"urlQuery.d.mts","names":[],"sources":["../../src/transformers/urlQuery.ts"],"mappings":";;;;;;AA0CA;;;;;;;;;;;;;;iBAAgB,QAAA,CAAS,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,SAAA,GAAiB,SAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"urlQuery.mjs","names":[],"sources":["../../src/transformers/urlQuery.ts"],"sourcesContent":["import queryString from 'query-string'\nimport { selectAll } from 'css-select'\nimport type { ChildNode, Element } from 'domhandler'\nimport { isAbsoluteUrl } from '../utils/url.ts'\nimport type { UrlConfig, UrlQueryOptions } from '../types/config.ts'\n\nconst DEFAULT_ATTRIBUTES = ['src', 'href', 'poster', 'srcset', 'background']\nconst DEFAULT_TAGS = ['a']\n\n/**\n * Append query parameters to a URL string using query-string.\n */\nfunction appendParams(\n url: string,\n params: Record<string, unknown>,\n qsOptions: queryString.StringifyOptions,\n strict: boolean,\n): string {\n if (strict && !isAbsoluteUrl(url)) return url\n\n return queryString.stringifyUrl(\n { url, query: params as queryString.StringifiableRecord },\n qsOptions,\n )\n}\n\n/**\n * URL query transformer.\n *\n * Appends query parameters to URLs found in specified attributes of\n * specified HTML tags.\n *\n * Reads config from the `config.url` object in `MaizzleConfig` (pass\n * `config.url` directly when calling as a standalone transformer).\n * The `_options` key inside `query` controls behaviour:\n * - `tags` — CSS selectors for elements to process. Default: `['a']`\n * - `attributes` — attribute names to process. Default: `['src', 'href', 'poster', 'srcset', 'background']`\n * - `strict` — only append to absolute URLs. Default: `true`\n * - `qs` — options forwarded to query-string. Default: `{ encode: false }`\n *\n * All non-`_options` keys inside `query` are treated as URL parameters to append.\n */\nexport function urlQuery(dom: ChildNode[], config: UrlConfig = {}): ChildNode[] {\n const queryConfig = config.query\n\n if (!queryConfig || Object.keys(queryConfig).length === 0) return dom\n\n const { _options, ...params } = queryConfig as Record<string, unknown>\n const options = (_options ?? {}) as UrlQueryOptions\n\n if (Object.keys(params).length === 0) return dom\n\n const tags = options.tags ?? DEFAULT_TAGS\n const attributes = options.attributes ?? DEFAULT_ATTRIBUTES\n const strict = options.strict ?? true\n const qsOptions: queryString.StringifyOptions = { encode: false, ...((options.qs ?? {}) as queryString.StringifyOptions) }\n\n // Use css-select to find all elements matching any of the tag selectors\n const selector = tags.join(', ')\n const elements = selectAll(selector, dom) as Element[]\n\n for (const el of elements) {\n for (const attr of attributes) {\n const value = el.attribs[attr]\n if (!value) continue\n\n const updated = appendParams(value, params, qsOptions, strict)\n if (updated !== value) {\n el.attribs[attr] = updated\n }\n }\n }\n\n return dom\n}\n"],"mappings":";;;;;AAMA,MAAM,qBAAqB;CAAC;CAAO;CAAQ;CAAU;CAAU;CAAa;AAC5E,MAAM,eAAe,CAAC,IAAI;;;;AAK1B,SAAS,aACP,KACA,QACA,WACA,QACQ;AACR,KAAI,UAAU,CAAC,cAAc,IAAI,CAAE,QAAO;AAE1C,QAAO,YAAY,aACjB;EAAE;EAAK,OAAO;EAA2C,EACzD,UACD;;;;;;;;;;;;;;;;;;AAmBH,SAAgB,SAAS,KAAkB,SAAoB,EAAE,EAAe;CAC9E,MAAM,cAAc,OAAO;AAE3B,KAAI,CAAC,eAAe,OAAO,KAAK,YAAY,CAAC,WAAW,EAAG,QAAO;CAElE,MAAM,EAAE,UAAU,GAAG,WAAW;CAChC,MAAM,UAAW,YAAY,EAAE;AAE/B,KAAI,OAAO,KAAK,OAAO,CAAC,WAAW,EAAG,QAAO;CAE7C,MAAM,OAAO,QAAQ,QAAQ;CAC7B,MAAM,aAAa,QAAQ,cAAc;CACzC,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,YAA0C;EAAE,QAAQ;EAAO,GAAK,QAAQ,MAAM,EAAE;EAAoC;CAI1H,MAAM,WAAW,UADA,KAAK,KAAK,KAAK,EACK,IAAI;AAEzC,MAAK,MAAM,MAAM,SACf,MAAK,MAAM,QAAQ,YAAY;EAC7B,MAAM,QAAQ,GAAG,QAAQ;AACzB,MAAI,CAAC,MAAO;EAEZ,MAAM,UAAU,aAAa,OAAO,QAAQ,WAAW,OAAO;AAC9D,MAAI,YAAY,MACd,IAAG,QAAQ,QAAQ;;AAKzB,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.d.mts","names":[],"sources":["../../src/types/config.ts"],"mappings":"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"}
@@ -1,4 +0,0 @@
1
- import { parse } from "./parser.mjs";
2
- import { walk } from "./walker.mjs";
3
- import { serialize } from "./serializer.mjs";
4
- export { parse, serialize, walk };
@@ -1,5 +0,0 @@
1
- import { parse } from "./parser.mjs";
2
- import { walk } from "./walker.mjs";
3
- import { serialize } from "./serializer.mjs";
4
-
5
- export { parse, serialize, walk };
@@ -1 +0,0 @@
1
- {"version":3,"file":"parser.d.mts","names":[],"sources":["../../../src/utils/ast/parser.ts"],"mappings":";;;iBAIgB,KAAA,CAAM,IAAA,UAAc,OAAA,GAAS,iBAAA,GAAyB,SAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"parser.mjs","names":[],"sources":["../../../src/utils/ast/parser.ts"],"sourcesContent":["import { Parser } from 'htmlparser2'\nimport { DomHandler } from 'domhandler'\nimport type { ChildNode, DomHandlerOptions } from 'domhandler'\n\nexport function parse(html: string, options: DomHandlerOptions = {}): ChildNode[] {\n const handler = new DomHandler()\n const parser = new Parser(handler, options)\n parser.write(html)\n parser.end()\n return handler.dom\n}\n"],"mappings":";;;;AAIA,SAAgB,MAAM,MAAc,UAA6B,EAAE,EAAe;CAChF,MAAM,UAAU,IAAI,YAAY;CAChC,MAAM,SAAS,IAAI,OAAO,SAAS,QAAQ;AAC3C,QAAO,MAAM,KAAK;AAClB,QAAO,KAAK;AACZ,QAAO,QAAQ"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"serializer.d.mts","names":[],"sources":["../../../src/utils/ast/serializer.ts"],"mappings":";;;;iBA6BgB,SAAA,CAAU,GAAA,EAAK,SAAA,IAAa,OAAA,GAAU,oBAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"serializer.mjs","names":[],"sources":["../../../src/utils/ast/serializer.ts"],"sourcesContent":["import render from 'dom-serializer'\nimport type { ChildNode } from 'domhandler'\nimport type { DomSerializerOptions } from 'dom-serializer'\nimport { walk } from './walker.ts'\n\n/**\n * Re-encode < and > as entities in text nodes inside <code> elements.\n *\n * The DOM parser decodes entities like &#x3C; into raw < in text nodes.\n * With encodeEntities: false the serializer outputs them as-is, which\n * creates broken HTML (e.g. </a> inside a code block closes the real tag).\n *\n * We selectively fix this for <code> contents only, so the rest of the\n * document (where encodeEntities: false is needed) is unaffected.\n */\nfunction encodeCodeTextNodes(dom: ChildNode[]): void {\n walk(dom, (node) => {\n const el = node as import('domhandler').Element\n if (el.name !== 'code') return\n\n walk(el.children ?? [], (child) => {\n if (child.type === 'text') {\n const text = child as import('domhandler').Text\n text.data = text.data.replace(/</g, '&lt;').replace(/>/g, '&gt;')\n }\n })\n })\n}\n\nexport function serialize(dom: ChildNode[], options?: DomSerializerOptions): string {\n encodeCodeTextNodes(dom)\n return render(dom, { encodeEntities: false, ...options })\n}\n"],"mappings":";;;;;;;;;;;;;;AAeA,SAAS,oBAAoB,KAAwB;AACnD,MAAK,MAAM,SAAS;EAClB,MAAM,KAAK;AACX,MAAI,GAAG,SAAS,OAAQ;AAExB,OAAK,GAAG,YAAY,EAAE,GAAG,UAAU;AACjC,OAAI,MAAM,SAAS,QAAQ;IACzB,MAAM,OAAO;AACb,SAAK,OAAO,KAAK,KAAK,QAAQ,MAAM,OAAO,CAAC,QAAQ,MAAM,OAAO;;IAEnE;GACF;;AAGJ,SAAgB,UAAU,KAAkB,SAAwC;AAClF,qBAAoB,IAAI;AACxB,QAAO,OAAO,KAAK;EAAE,gBAAgB;EAAO,GAAG;EAAS,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"walker.d.mts","names":[],"sources":["../../../src/utils/ast/walker.ts"],"mappings":";;;iBAEgB,IAAA,CAAK,GAAA,EAAK,SAAA,IAAa,QAAA,GAAW,IAAA,EAAM,SAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"walker.mjs","names":[],"sources":["../../../src/utils/ast/walker.ts"],"sourcesContent":["import type { ChildNode } from 'domhandler'\n\nexport function walk(ast: ChildNode[], callback: (node: ChildNode) => void): void {\n function traverse(node: ChildNode) {\n callback(node)\n\n if ('children' in node && node.children && node.children.length > 0) {\n for (const child of node.children) {\n traverse(child)\n }\n }\n }\n\n for (const node of ast) {\n traverse(node)\n }\n}\n"],"mappings":";AAEA,SAAgB,KAAK,KAAkB,UAA2C;CAChF,SAAS,SAAS,MAAiB;AACjC,WAAS,KAAK;AAEd,MAAI,cAAc,QAAQ,KAAK,YAAY,KAAK,SAAS,SAAS,EAChE,MAAK,MAAM,SAAS,KAAK,SACvB,UAAS,MAAM;;AAKrB,MAAK,MAAM,QAAQ,IACjB,UAAS,KAAK"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"decodeStyleEntities.d.mts","names":[],"sources":["../../src/utils/decodeStyleEntities.ts"],"mappings":";;AAUA;;;;;;;;;iBAAgB,mBAAA,CAAoB,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"decodeStyleEntities.mjs","names":[],"sources":["../../src/utils/decodeStyleEntities.ts"],"sourcesContent":["/**\n * Decode HTML entities that Vue SSR encodes inside `<style>` tags.\n *\n * Vue's `renderToString` HTML-encodes quotes and angle brackets within\n * style elements in templates, breaking CSS like\n * `@import \"tailwindcss\"` → `@import &quot;tailwindcss&quot;`.\n *\n * `&amp;` is decoded last so previously-decoded entities are not\n * re-processed.\n */\nexport function decodeStyleEntities(s: string): string {\n return s\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .replace(/&apos;/g, \"'\")\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&amp;/g, '&')\n}\n"],"mappings":";;;;;;;;;;;AAUA,SAAgB,oBAAoB,GAAmB;AACrD,QAAO,EACJ,QAAQ,WAAW,KAAI,CACvB,QAAQ,UAAU,IAAI,CACtB,QAAQ,WAAW,IAAI,CACvB,QAAQ,SAAS,IAAI,CACrB,QAAQ,SAAS,IAAI,CACrB,QAAQ,UAAU,IAAI"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"detect.d.mts","names":[],"sources":["../../src/utils/detect.ts"],"mappings":";iBAGgB,SAAA,CAAU,GAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"detect.mjs","names":[],"sources":["../../src/utils/detect.ts"],"sourcesContent":["import { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\nexport function isLaravel(cwd: string = process.cwd()): boolean {\n return existsSync(resolve(cwd, 'artisan'))\n}\n"],"mappings":";;;;AAGA,SAAgB,UAAU,MAAc,QAAQ,KAAK,EAAW;AAC9D,QAAO,WAAW,QAAQ,KAAK,UAAU,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"url.d.mts","names":[],"sources":["../../src/utils/url.ts"],"mappings":";cAEa,WAAA,EAAa,MAAA;AAAA,cAcb,aAAA;AAAA,iBAEG,aAAA,CAAc,GAAA;AAAA,iBAMd,aAAA,CAAc,MAAA,UAAgB,OAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"url.mjs","names":[],"sources":["../../src/utils/url.ts"],"sourcesContent":["import isUrl from 'is-url-superb'\n\nexport const defaultTags: Record<string, string[]> = {\n a: ['href'],\n img: ['src', 'srcset'],\n video: ['src', 'poster'],\n source: ['src', 'srcset'],\n link: ['href'],\n script: ['src'],\n object: ['data'],\n embed: ['src'],\n iframe: ['src'],\n 'v:image': ['src'],\n 'v:fill': ['src'],\n}\n\nexport const urlAttributes = [...new Set(Object.values(defaultTags).flat())]\n\nexport function isAbsoluteUrl(url: string): boolean {\n if (!url) return true\n\n return url.startsWith('//') || url.startsWith('#') || url.startsWith('?') || isUrl(url)\n}\n\nexport function processSrcset(srcset: string, baseUrl: string): string {\n return srcset.split(',').map(entry => {\n const parts = entry.trim().split(/\\s+/)\n\n if (parts[0] && !isAbsoluteUrl(parts[0])) {\n parts[0] = baseUrl + parts[0]\n }\n\n return parts.join(' ')\n }).join(', ')\n}\n"],"mappings":";;;AAEA,MAAa,cAAwC;CACnD,GAAG,CAAC,OAAO;CACX,KAAK,CAAC,OAAO,SAAS;CACtB,OAAO,CAAC,OAAO,SAAS;CACxB,QAAQ,CAAC,OAAO,SAAS;CACzB,MAAM,CAAC,OAAO;CACd,QAAQ,CAAC,MAAM;CACf,QAAQ,CAAC,OAAO;CAChB,OAAO,CAAC,MAAM;CACd,QAAQ,CAAC,MAAM;CACf,WAAW,CAAC,MAAM;CAClB,UAAU,CAAC,MAAM;CAClB;AAED,MAAa,gBAAgB,CAAC,GAAG,IAAI,IAAI,OAAO,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;AAE5E,SAAgB,cAAc,KAAsB;AAClD,KAAI,CAAC,IAAK,QAAO;AAEjB,QAAO,IAAI,WAAW,KAAK,IAAI,IAAI,WAAW,IAAI,IAAI,IAAI,WAAW,IAAI,IAAI,MAAM,IAAI;;AAGzF,SAAgB,cAAc,QAAgB,SAAyB;AACrE,QAAO,OAAO,MAAM,IAAI,CAAC,KAAI,UAAS;EACpC,MAAM,QAAQ,MAAM,MAAM,CAAC,MAAM,MAAM;AAEvC,MAAI,MAAM,MAAM,CAAC,cAAc,MAAM,GAAG,CACtC,OAAM,KAAK,UAAU,MAAM;AAG7B,SAAO,MAAM,KAAK,IAAI;GACtB,CAAC,KAAK,KAAK"}
File without changes
File without changes
File without changes