@react-email/editor 1.3.2 → 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{extension-TtsG0Puz.mjs → extension-M9mAMex9.mjs} +141 -13
- package/dist/extension-M9mAMex9.mjs.map +1 -0
- package/dist/{extension-W9raGSI9.cjs → extension-r1aNq37Z.cjs} +145 -11
- package/dist/extensions/index.cjs +2 -2
- package/dist/extensions/index.mjs +2 -2
- package/dist/{extensions-CG4gZ1-f.cjs → extensions-BYOlFEwI.cjs} +4 -4
- package/dist/{extensions-CQ3r7pnM.mjs → extensions-BxF4VdQD.mjs} +5 -5
- package/dist/{extensions-CQ3r7pnM.mjs.map → extensions-BxF4VdQD.mjs.map} +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +2 -2
- package/dist/plugins/index.cjs +2 -1
- package/dist/plugins/index.d.cts +22 -2
- package/dist/plugins/index.d.cts.map +1 -1
- package/dist/plugins/index.d.mts +22 -2
- package/dist/plugins/index.d.mts.map +1 -1
- package/dist/plugins/index.mjs +2 -2
- package/dist/style.css +0 -86
- package/dist/{types-B2yr4rz3.d.cts → types-8PZgYQuK.d.mts} +4 -4
- package/dist/types-8PZgYQuK.d.mts.map +1 -0
- package/dist/{types-DzqGGKXD.d.mts → types-DUTo2zJ5.d.cts} +4 -4
- package/dist/types-DUTo2zJ5.d.cts.map +1 -0
- package/dist/ui/index.cjs +1 -1
- package/dist/ui/index.d.cts +1 -1
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.mjs +1 -1
- package/dist/ui/themes/default.css +1 -89
- package/package.json +2 -2
- package/dist/extension-TtsG0Puz.mjs.map +0 -1
- package/dist/types-B2yr4rz3.d.cts.map +0 -1
- package/dist/types-DzqGGKXD.d.mts.map +0 -1
|
@@ -113,12 +113,45 @@ function injectThemeCss(styles, options = {}) {
|
|
|
113
113
|
const container = options.scopeSelector ?? ".tiptap-extended .tiptap.ProseMirror";
|
|
114
114
|
const prefix = ".node-";
|
|
115
115
|
const styleId = options.styleId ?? "tiptap-extended-theme-css";
|
|
116
|
+
const getNodeSelector = (classReference) => `${container} ${prefix}${classReference}`;
|
|
117
|
+
const getSelectors = (classReference) => {
|
|
118
|
+
switch (classReference) {
|
|
119
|
+
case "body": return [container];
|
|
120
|
+
case "reset": return [];
|
|
121
|
+
case "list": return [
|
|
122
|
+
getNodeSelector("list"),
|
|
123
|
+
getNodeSelector("bulletList"),
|
|
124
|
+
getNodeSelector("orderedList")
|
|
125
|
+
];
|
|
126
|
+
case "bulletList": return [getNodeSelector("bulletList")];
|
|
127
|
+
case "orderedList": return [getNodeSelector("orderedList")];
|
|
128
|
+
case "nestedList": return [
|
|
129
|
+
getNodeSelector("nestedList"),
|
|
130
|
+
`${container} .node-list .node-list`,
|
|
131
|
+
`${container} .node-bulletList .node-bulletList`,
|
|
132
|
+
`${container} .node-bulletList .node-orderedList`,
|
|
133
|
+
`${container} .node-orderedList .node-bulletList`,
|
|
134
|
+
`${container} .node-orderedList .node-orderedList`
|
|
135
|
+
];
|
|
136
|
+
case "listParagraph": return [`${container} .node-listItem > .node-paragraph`];
|
|
137
|
+
default: return [getNodeSelector(classReference)];
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
const resetStyles = styles.reset ?? {};
|
|
116
141
|
const css = Object.entries(styles).reduce((acc, [key, value]) => {
|
|
117
|
-
|
|
142
|
+
const classReference = key;
|
|
143
|
+
const selectors = getSelectors(classReference);
|
|
144
|
+
if (selectors.length === 0) return acc;
|
|
145
|
+
const resolvedStyles = RESET_NODE_TYPES.has(classReference) ? {
|
|
146
|
+
...resetStyles,
|
|
147
|
+
...value
|
|
148
|
+
} : value;
|
|
149
|
+
const cssString = Object.entries(resolvedStyles).reduce((acc, [prop, val]) => {
|
|
118
150
|
const normalizeProp = prop.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
119
151
|
if (val === void 0) return acc;
|
|
120
152
|
return `${acc}${normalizeProp}:${val};`;
|
|
121
|
-
}, "")
|
|
153
|
+
}, "");
|
|
154
|
+
return `${acc}${selectors.join(",")}{${cssString}}`;
|
|
122
155
|
}, "");
|
|
123
156
|
let styleTag = document.getElementById(styleId);
|
|
124
157
|
if (!styleTag) {
|
|
@@ -161,6 +194,9 @@ const PANEL_SECTION_TITLES = {
|
|
|
161
194
|
h2: "Subtitle",
|
|
162
195
|
h3: "Heading",
|
|
163
196
|
paragraph: "Paragraph",
|
|
197
|
+
list: "List",
|
|
198
|
+
"nested-list": "Nested List",
|
|
199
|
+
"list-item": "List Item",
|
|
164
200
|
link: "Link",
|
|
165
201
|
image: "Image",
|
|
166
202
|
button: "Button",
|
|
@@ -366,6 +402,27 @@ const THEME_BASIC = [
|
|
|
366
402
|
classReference: "paragraph",
|
|
367
403
|
inputs: []
|
|
368
404
|
},
|
|
405
|
+
{
|
|
406
|
+
id: "list",
|
|
407
|
+
title: "List",
|
|
408
|
+
category: "Text",
|
|
409
|
+
classReference: "list",
|
|
410
|
+
inputs: []
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
id: "nested-list",
|
|
414
|
+
title: "Nested List",
|
|
415
|
+
category: "Text",
|
|
416
|
+
classReference: "nestedList",
|
|
417
|
+
inputs: []
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
id: "list-item",
|
|
421
|
+
title: "List Item",
|
|
422
|
+
category: "Text",
|
|
423
|
+
classReference: "listItem",
|
|
424
|
+
inputs: []
|
|
425
|
+
},
|
|
369
426
|
{
|
|
370
427
|
id: "link",
|
|
371
428
|
title: "Link",
|
|
@@ -715,6 +772,27 @@ const THEME_MINIMAL = [
|
|
|
715
772
|
classReference: "paragraph",
|
|
716
773
|
inputs: []
|
|
717
774
|
},
|
|
775
|
+
{
|
|
776
|
+
id: "list",
|
|
777
|
+
title: "List",
|
|
778
|
+
category: "Text",
|
|
779
|
+
classReference: "list",
|
|
780
|
+
inputs: []
|
|
781
|
+
},
|
|
782
|
+
{
|
|
783
|
+
id: "nested-list",
|
|
784
|
+
title: "Nested List",
|
|
785
|
+
category: "Text",
|
|
786
|
+
classReference: "nestedList",
|
|
787
|
+
inputs: []
|
|
788
|
+
},
|
|
789
|
+
{
|
|
790
|
+
id: "list-item",
|
|
791
|
+
title: "List Item",
|
|
792
|
+
category: "Text",
|
|
793
|
+
classReference: "listItem",
|
|
794
|
+
inputs: []
|
|
795
|
+
},
|
|
718
796
|
{
|
|
719
797
|
id: "link",
|
|
720
798
|
title: "Link",
|
|
@@ -785,14 +863,16 @@ const RESET_BASIC = {
|
|
|
785
863
|
paddingLeft: "1.1em",
|
|
786
864
|
paddingBottom: "1em"
|
|
787
865
|
},
|
|
866
|
+
bulletList: { listStyleType: "disc" },
|
|
867
|
+
orderedList: { listStyleType: "decimal" },
|
|
788
868
|
nestedList: {
|
|
789
869
|
paddingLeft: "1.1em",
|
|
790
870
|
paddingBottom: "0"
|
|
791
871
|
},
|
|
792
872
|
listItem: {
|
|
793
873
|
marginLeft: "1em",
|
|
794
|
-
|
|
795
|
-
|
|
874
|
+
paddingBottom: "0.3em",
|
|
875
|
+
paddingTop: "0.3em"
|
|
796
876
|
},
|
|
797
877
|
listParagraph: {
|
|
798
878
|
padding: "0",
|
|
@@ -813,12 +893,24 @@ const RESET_BASIC = {
|
|
|
813
893
|
footer: { fontSize: "0.8em" },
|
|
814
894
|
hr: {
|
|
815
895
|
paddingBottom: "1em",
|
|
896
|
+
borderStyle: "solid",
|
|
816
897
|
borderWidth: "2px"
|
|
817
898
|
},
|
|
818
899
|
image: { maxWidth: "100%" },
|
|
819
900
|
button: {
|
|
820
901
|
lineHeight: "100%",
|
|
821
|
-
display: "inline-block"
|
|
902
|
+
display: "inline-block",
|
|
903
|
+
paddingTop: "0.625em",
|
|
904
|
+
paddingRight: "1.25em",
|
|
905
|
+
paddingBottom: "0.625em",
|
|
906
|
+
paddingLeft: "1.25em",
|
|
907
|
+
backgroundColor: "#000000",
|
|
908
|
+
color: "#ffffff",
|
|
909
|
+
borderRadius: "0.375em",
|
|
910
|
+
fontWeight: 500,
|
|
911
|
+
fontSize: "0.875em",
|
|
912
|
+
textDecoration: "none",
|
|
913
|
+
textAlign: "center"
|
|
822
914
|
},
|
|
823
915
|
inlineCode: {
|
|
824
916
|
paddingTop: "0.25em",
|
|
@@ -830,6 +922,13 @@ const RESET_BASIC = {
|
|
|
830
922
|
borderRadius: "4px"
|
|
831
923
|
},
|
|
832
924
|
codeBlock: {
|
|
925
|
+
background: "#f1f5f9",
|
|
926
|
+
borderRadius: "4px",
|
|
927
|
+
paddingTop: "0.75rem",
|
|
928
|
+
paddingRight: "1rem",
|
|
929
|
+
paddingBottom: "0.75rem",
|
|
930
|
+
paddingLeft: "1rem",
|
|
931
|
+
overflowX: "auto",
|
|
833
932
|
fontFamily: "monospace",
|
|
834
933
|
fontWeight: "500",
|
|
835
934
|
fontSize: ".92em"
|
|
@@ -852,9 +951,14 @@ const RESET_THEMES = {
|
|
|
852
951
|
return acc;
|
|
853
952
|
}, {}),
|
|
854
953
|
reset: RESET_BASIC.reset,
|
|
855
|
-
button:
|
|
954
|
+
button: {
|
|
955
|
+
lineHeight: RESET_BASIC.button.lineHeight,
|
|
956
|
+
display: RESET_BASIC.button.display
|
|
957
|
+
},
|
|
856
958
|
image: RESET_BASIC.image,
|
|
857
959
|
list: RESET_BASIC.list,
|
|
960
|
+
bulletList: RESET_BASIC.bulletList,
|
|
961
|
+
orderedList: RESET_BASIC.orderedList,
|
|
858
962
|
nestedList: RESET_BASIC.nestedList,
|
|
859
963
|
listItem: RESET_BASIC.listItem,
|
|
860
964
|
listParagraph: RESET_BASIC.listParagraph,
|
|
@@ -1179,6 +1283,9 @@ const PANEL_SECTION_IDS = new Set([
|
|
|
1179
1283
|
"container",
|
|
1180
1284
|
"typography",
|
|
1181
1285
|
"paragraph",
|
|
1286
|
+
"list",
|
|
1287
|
+
"nested-list",
|
|
1288
|
+
"list-item",
|
|
1182
1289
|
"link",
|
|
1183
1290
|
"image",
|
|
1184
1291
|
"button",
|
|
@@ -1192,6 +1299,9 @@ const PANEL_SECTION_IDS_BY_TITLE = {
|
|
|
1192
1299
|
container: "container",
|
|
1193
1300
|
typography: "typography",
|
|
1194
1301
|
paragraph: "paragraph",
|
|
1302
|
+
list: "list",
|
|
1303
|
+
"nested list": "nested-list",
|
|
1304
|
+
"list item": "list-item",
|
|
1195
1305
|
link: "link",
|
|
1196
1306
|
image: "image",
|
|
1197
1307
|
button: "button",
|
|
@@ -1201,6 +1311,9 @@ const PANEL_SECTION_IDS_BY_TITLE = {
|
|
|
1201
1311
|
const PANEL_SECTION_IDS_BY_CLASS_REFERENCE = {
|
|
1202
1312
|
container: "container",
|
|
1203
1313
|
paragraph: "paragraph",
|
|
1314
|
+
list: "list",
|
|
1315
|
+
nestedList: "nested-list",
|
|
1316
|
+
listItem: "list-item",
|
|
1204
1317
|
link: "link",
|
|
1205
1318
|
image: "image",
|
|
1206
1319
|
button: "button",
|
|
@@ -1278,6 +1391,9 @@ const CLASS_REFERENCE_TO_PANEL_ID = {
|
|
|
1278
1391
|
link: "link",
|
|
1279
1392
|
image: "image",
|
|
1280
1393
|
button: "button",
|
|
1394
|
+
list: "list",
|
|
1395
|
+
nestedList: "nested-list",
|
|
1396
|
+
listItem: "list-item",
|
|
1281
1397
|
codeBlock: "code-block",
|
|
1282
1398
|
inlineCode: "inline-code"
|
|
1283
1399
|
};
|
|
@@ -1381,13 +1497,21 @@ function getMergedCssJs(theme, panelStyles) {
|
|
|
1381
1497
|
return mergeCssJs(RESET_THEMES[theme], parsed);
|
|
1382
1498
|
}
|
|
1383
1499
|
/**
|
|
1384
|
-
*
|
|
1385
|
-
* (e.g.
|
|
1386
|
-
*
|
|
1500
|
+
* Node types and theme component keys that should receive the universal
|
|
1501
|
+
* `reset` CSS (e.g. `margin: 0; padding: 0`) layered underneath their own
|
|
1502
|
+
* theme styles. Shared between `getResolvedNodeStyles` (email serializer)
|
|
1503
|
+
* and `injectThemeCss` (editor preview) so both surfaces stay in sync.
|
|
1504
|
+
*
|
|
1505
|
+
* Includes both raw tiptap node names (e.g. `tableCell`) and theme
|
|
1506
|
+
* component keys (e.g. `list`) because the serializer matches against both.
|
|
1507
|
+
*
|
|
1508
|
+
* `bulletList` and `orderedList` are intentionally omitted: their elements
|
|
1509
|
+
* already carry the shared `node-list` class, so the `list` reset rule
|
|
1510
|
+
* covers them without forcing the dedicated `.node-bulletList` /
|
|
1511
|
+
* `.node-orderedList` rules to redundantly emit `margin: 0; padding: 0`.
|
|
1387
1512
|
*/
|
|
1388
1513
|
const RESET_NODE_TYPES = new Set([
|
|
1389
1514
|
"body",
|
|
1390
|
-
"bulletList",
|
|
1391
1515
|
"button",
|
|
1392
1516
|
"columns",
|
|
1393
1517
|
"div",
|
|
@@ -1398,7 +1522,6 @@ const RESET_NODE_TYPES = new Set([
|
|
|
1398
1522
|
"listItem",
|
|
1399
1523
|
"listParagraph",
|
|
1400
1524
|
"nestedList",
|
|
1401
|
-
"orderedList",
|
|
1402
1525
|
"table",
|
|
1403
1526
|
"paragraph",
|
|
1404
1527
|
"tableCell",
|
|
@@ -1406,6 +1529,11 @@ const RESET_NODE_TYPES = new Set([
|
|
|
1406
1529
|
"tableRow",
|
|
1407
1530
|
"youtube"
|
|
1408
1531
|
]);
|
|
1532
|
+
/**
|
|
1533
|
+
* Returns resolved React.CSSProperties for a node when you already have merged CssJs
|
|
1534
|
+
* (e.g. in the serializer where there is no editor). Centralizes which theme keys
|
|
1535
|
+
* apply to which node type.
|
|
1536
|
+
*/
|
|
1409
1537
|
function getResolvedNodeStyles(node, depth, mergedCssJs) {
|
|
1410
1538
|
const key = getThemeComponentKey(node.type ?? "", depth, node.attrs ?? {});
|
|
1411
1539
|
if (!key) {
|
|
@@ -1588,6 +1716,6 @@ const EmailTheming = Extension.create({
|
|
|
1588
1716
|
}
|
|
1589
1717
|
});
|
|
1590
1718
|
//#endregion
|
|
1591
|
-
export {
|
|
1719
|
+
export { getThemeBodyFontSizePx as C, getGlobalContent as E, getPanelTitle as S, GlobalContent as T, DEFAULT_INBOX_FONT_SIZE_PX as _, getResolvedNodeStyles as a, RESET_THEMES as b, setGlobalCssInjected as c, useEmailTheming as d, createTheme as f, themeStylesToPanelOverrides as g, parseCssValue as h, getMergedCssJs as i, setGlobalStyles as l, isThemeConfig as m, RESET_NODE_TYPES as n, getThemeComponentKey as o, extendTheme as p, getEmailTheming as r, setCurrentTheme as s, EmailTheming as t, stylesToCss as u, EDITOR_THEMES as v, resolveResetValue as w, SUPPORTED_CSS_PROPERTIES as x, INBOX_EMAIL_DEFAULTS as y };
|
|
1592
1720
|
|
|
1593
|
-
//# sourceMappingURL=extension-
|
|
1721
|
+
//# sourceMappingURL=extension-M9mAMex9.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension-M9mAMex9.mjs","names":[],"sources":["../src/extensions/global-content.ts","../src/plugins/email-theming/css-transforms.ts","../src/plugins/email-theming/themes.ts","../src/plugins/email-theming/normalization.ts","../src/plugins/email-theming/theme-config.ts","../src/plugins/email-theming/extension.tsx"],"sourcesContent":["import { type Editor, mergeAttributes, Node } from '@tiptap/core';\n\nconst GLOBAL_CONTENT_NODE_TYPE = 'globalContent' as const;\n\nexport interface GlobalContentOptions {\n key: string;\n data: Record<string, unknown>;\n}\n\ndeclare module '@tiptap/core' {\n interface GlobalContent<ReturnType> {\n setGlobalContent: (key: string, value: unknown) => ReturnType;\n }\n\n interface Commands<ReturnType> {\n globalContent: GlobalContent<ReturnType>;\n }\n}\n\nlet cachedGlobalPosition: number | null = null;\n\nfunction findGlobalContentPositions(doc: Editor['state']['doc']) {\n const positions: number[] = [];\n\n doc.descendants((node, position) => {\n if (node.type.name === GLOBAL_CONTENT_NODE_TYPE) {\n positions.push(position);\n }\n });\n\n return positions;\n}\n\nfunction getCachedGlobalContentPosition(doc: Editor['state']['doc']) {\n if (cachedGlobalPosition != null) {\n try {\n if (\n doc.nodeAt(cachedGlobalPosition)?.type.name === GLOBAL_CONTENT_NODE_TYPE\n ) {\n return cachedGlobalPosition;\n }\n } catch {\n cachedGlobalPosition = null;\n }\n }\n\n const positions = findGlobalContentPositions(doc);\n cachedGlobalPosition = positions[0] ?? null;\n return cachedGlobalPosition;\n}\n\nexport function getGlobalContent(key: string, editor: Editor): unknown | null {\n const position = getCachedGlobalContentPosition(editor.state.doc);\n if (cachedGlobalPosition == null) {\n return null;\n }\n return editor.state.doc.nodeAt(position)?.attrs.data[key] ?? null;\n}\n\nexport const GlobalContent = Node.create<GlobalContentOptions>({\n name: GLOBAL_CONTENT_NODE_TYPE,\n\n addOptions() {\n return {\n key: GLOBAL_CONTENT_NODE_TYPE,\n data: {},\n };\n },\n\n group: 'block',\n\n selectable: false,\n draggable: false,\n atom: true,\n\n addAttributes() {\n return {\n data: {\n default: this.options.data,\n },\n };\n },\n\n parseHTML() {\n return [{ tag: `div[data-type=\"${this.name}\"]` }];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n 'div',\n mergeAttributes(HTMLAttributes, {\n 'data-type': this.name,\n // The node needs to have a width and height, so then\n // internal TipTap extension can find the first node position\n // and calculate the correct position of the document container\n style:\n 'width: 100%; height: 1px; visibility: hidden; background-color: transparent;',\n }),\n ];\n },\n\n addCommands() {\n return {\n setGlobalContent:\n (key: string, value: unknown) =>\n ({ tr, dispatch }) => {\n const ensureGlobalPosition = () => {\n const positions = findGlobalContentPositions(tr.doc);\n\n for (let i = positions.length - 1; i > 0; i--) {\n tr.delete(positions[i], positions[i] + 1);\n }\n\n const pos = positions[0] ?? -1;\n if (pos >= 0) {\n cachedGlobalPosition = pos;\n } else {\n cachedGlobalPosition = 0;\n tr.insert(0, this.type.create());\n }\n };\n\n if (dispatch) {\n ensureGlobalPosition();\n\n if (cachedGlobalPosition == null) {\n return false;\n }\n tr.setNodeAttribute(cachedGlobalPosition, 'data', {\n ...tr.doc.nodeAt(cachedGlobalPosition)?.attrs.data,\n [key]: value,\n });\n }\n\n return true;\n },\n };\n },\n});\n","import { ensureBorderStyleFallback } from '../../utils/styles';\nimport { RESET_NODE_TYPES } from './extension';\nimport type { CssJs, KnownThemeComponents, PanelGroup } from './types';\n\nexport function transformToCssJs(\n styleArray: PanelGroup[],\n baseFontSize: number,\n): CssJs {\n const cssJS = {} as CssJs;\n\n if (!Array.isArray(styleArray)) {\n return cssJS;\n }\n\n for (const style of styleArray) {\n for (const input of style.inputs) {\n let value = input.value;\n\n // If there's a unit property, append it to the value\n if (input.unit && typeof value === 'number') {\n // if font size prop convert px unit to em to adjust size in mobile\n if (input.prop === 'fontSize') {\n value = `${value / baseFontSize}em`;\n } else {\n value = `${value}${input.unit}`;\n }\n }\n\n if (!input.classReference) {\n continue;\n }\n\n if (!cssJS[input.classReference]) {\n cssJS[input.classReference] = {};\n }\n\n // @ts-expect-error -- backward compatibility: 'h-padding' is a legacy prop not in KnownCssProperties\n if (input.prop === 'h-padding') {\n cssJS[input.classReference].paddingLeft = value;\n cssJS[input.classReference].paddingRight = value;\n\n continue;\n }\n\n // @ts-expect-error -- input.prop is KnownCssProperties but CssJs values are React.CSSProperties; dynamic assignment is intentional\n cssJS[input.classReference][input.prop] = value;\n }\n }\n\n for (const key of Object.keys(cssJS)) {\n ensureBorderStyleFallback(\n cssJS[key as keyof CssJs] as Record<string, string | number>,\n );\n }\n\n return cssJS;\n}\n\nexport function mergeCssJs(original: CssJs, newCssJs: CssJs) {\n const merged = { ...original };\n\n for (const key in newCssJs) {\n const keyType = key as keyof CssJs;\n\n if (\n Object.hasOwn(merged, key) &&\n typeof merged[keyType] === 'object' &&\n !Array.isArray(merged[keyType])\n ) {\n merged[keyType] = {\n ...merged[keyType],\n ...newCssJs[keyType],\n };\n } else {\n merged[keyType] = newCssJs[keyType];\n }\n }\n\n return merged;\n}\n\nexport function injectThemeCss(\n styles: CssJs,\n options: { styleId?: string; scopeSelector?: string } = {},\n) {\n const container =\n options.scopeSelector ?? '.tiptap-extended .tiptap.ProseMirror';\n const prefix = '.node-';\n const styleId = options.styleId ?? 'tiptap-extended-theme-css';\n const getNodeSelector = (classReference: string) =>\n `${container} ${prefix}${classReference}`;\n const getSelectors = (classReference: KnownThemeComponents) => {\n switch (classReference) {\n case 'body':\n return [container];\n case 'reset':\n return [];\n case 'list':\n return [\n getNodeSelector('list'),\n getNodeSelector('bulletList'),\n getNodeSelector('orderedList'),\n ];\n case 'bulletList':\n return [getNodeSelector('bulletList')];\n case 'orderedList':\n return [getNodeSelector('orderedList')];\n case 'nestedList':\n return [\n getNodeSelector('nestedList'),\n `${container} .node-list .node-list`,\n `${container} .node-bulletList .node-bulletList`,\n `${container} .node-bulletList .node-orderedList`,\n `${container} .node-orderedList .node-bulletList`,\n `${container} .node-orderedList .node-orderedList`,\n ];\n case 'listParagraph':\n return [`${container} .node-listItem > .node-paragraph`];\n default:\n return [getNodeSelector(classReference)];\n }\n };\n const resetStyles = styles.reset ?? {};\n\n const css = Object.entries(styles).reduce((acc, [key, value]) => {\n const classReference = key as KnownThemeComponents;\n const selectors = getSelectors(classReference);\n if (selectors.length === 0) {\n return acc;\n }\n\n const resolvedStyles = RESET_NODE_TYPES.has(classReference)\n ? { ...resetStyles, ...value }\n : value;\n\n const cssString = Object.entries(resolvedStyles).reduce(\n (acc, [prop, val]) => {\n const normalizeProp = prop.replace(/([A-Z])/g, '-$1').toLowerCase();\n\n if (val === undefined) {\n return acc;\n }\n\n return `${acc}${normalizeProp}:${val};`;\n },\n '',\n );\n\n return `${acc}${selectors.join(',')}{${cssString}}`;\n }, '');\n\n let styleTag = document.getElementById(styleId) as HTMLStyleElement;\n\n if (!styleTag) {\n styleTag = document.createElement('style');\n styleTag.textContent = css;\n styleTag.id = styleId;\n\n document.head.appendChild(styleTag);\n\n return;\n }\n\n styleTag.textContent = css;\n}\n\nexport function injectGlobalPlainCss(\n css?: string | null,\n options: { styleId?: string; scopeSelector?: string } = {},\n) {\n const styleId = options.styleId ?? 'global-editor-style';\n const container = options.scopeSelector ?? '.tiptap-extended .ProseMirror';\n let styleElement = document.getElementById(styleId);\n\n if (!css) {\n if (styleElement) {\n styleElement.textContent = '';\n }\n return;\n }\n\n if (!styleElement) {\n styleElement = document.createElement('style');\n styleElement.id = styleId;\n document.head.appendChild(styleElement);\n }\n\n // Remove CSS within @media (prefers-color-scheme: dark) blocks\n const cleanedCSS = css.replace(\n /@media\\s?\\(prefers-color-scheme:\\s?dark\\)\\s?{([\\s\\S]+?})\\s*}/g,\n '',\n );\n\n // TODO: Figure out a way to extract the body and apply the styles out of the nested .tiptap-extended\n styleElement.textContent = `${container} { ${cleanedCSS} }`;\n}\n","import type {\n EditorTheme,\n PanelGroup,\n PanelSectionId,\n ResetTheme,\n SupportedCssProperties,\n} from './types';\n\n/**\n * Single source of truth for panel section display titles.\n * Titles are resolved from here at render time via `getPanelTitle`,\n * so they never depend on what's persisted in the DB.\n */\nconst PANEL_SECTION_TITLES: Record<PanelSectionId, string> = {\n body: 'Background',\n container: 'Body',\n typography: 'Text',\n h1: 'Title',\n h2: 'Subtitle',\n h3: 'Heading',\n paragraph: 'Paragraph',\n list: 'List',\n 'nested-list': 'Nested List',\n 'list-item': 'List Item',\n link: 'Link',\n image: 'Image',\n button: 'Button',\n 'code-block': 'Code Block',\n 'inline-code': 'Inline Code',\n};\n\n/**\n * Resolves the display title for a panel group.\n * Uses the `id` lookup when available, falls back to the\n * DB-persisted `title` for backwards compatibility.\n */\nexport function getPanelTitle(group: PanelGroup): string {\n if (group.id && group.id in PANEL_SECTION_TITLES) {\n return PANEL_SECTION_TITLES[group.id];\n }\n return group.title;\n}\n\nconst THEME_BASIC: PanelGroup[] = [\n {\n id: 'body',\n title: 'Background',\n classReference: 'body',\n inputs: [\n {\n label: 'Background',\n type: 'color',\n value: '#ffffff',\n prop: 'backgroundColor',\n classReference: 'body',\n },\n {\n label: 'Padding Top',\n type: 'number',\n value: undefined,\n unit: 'px',\n prop: 'paddingTop',\n classReference: 'body',\n },\n {\n label: 'Padding Right',\n type: 'number',\n value: undefined,\n unit: 'px',\n prop: 'paddingRight',\n classReference: 'body',\n },\n {\n label: 'Padding Bottom',\n type: 'number',\n value: undefined,\n unit: 'px',\n prop: 'paddingBottom',\n classReference: 'body',\n },\n {\n label: 'Padding Left',\n type: 'number',\n value: undefined,\n unit: 'px',\n prop: 'paddingLeft',\n classReference: 'body',\n },\n ],\n },\n {\n id: 'container',\n title: 'Content',\n classReference: 'container',\n inputs: [\n {\n label: 'Align',\n type: 'select',\n value: 'left',\n options: {\n left: 'Left',\n center: 'Center',\n right: 'Right',\n },\n prop: 'align',\n classReference: 'container',\n },\n {\n label: 'Width',\n type: 'number',\n value: 600,\n unit: 'px',\n prop: 'width',\n classReference: 'container',\n },\n {\n label: 'Height',\n type: 'number',\n unit: 'px',\n prop: 'height',\n classReference: 'container',\n },\n {\n label: 'Text',\n type: 'color',\n value: '#000000',\n prop: 'color',\n classReference: 'container',\n },\n {\n label: 'Background',\n type: 'color',\n value: '#ffffff',\n prop: 'backgroundColor',\n classReference: 'container',\n },\n {\n label: 'Padding Top',\n type: 'number',\n value: 0,\n unit: 'px',\n prop: 'paddingTop',\n classReference: 'container',\n },\n {\n label: 'Padding Right',\n type: 'number',\n value: 0,\n unit: 'px',\n prop: 'paddingRight',\n classReference: 'container',\n },\n {\n label: 'Padding Bottom',\n type: 'number',\n value: 0,\n unit: 'px',\n prop: 'paddingBottom',\n classReference: 'container',\n },\n {\n label: 'Padding Left',\n type: 'number',\n value: 0,\n unit: 'px',\n prop: 'paddingLeft',\n classReference: 'container',\n },\n {\n label: 'Corner radius',\n type: 'number',\n value: 0,\n unit: 'px',\n prop: 'borderRadius',\n classReference: 'container',\n },\n {\n label: 'Border color',\n type: 'color',\n value: '#000000',\n prop: 'borderColor',\n classReference: 'container',\n },\n ],\n },\n {\n id: 'typography',\n title: 'Text',\n classReference: 'body',\n inputs: [\n {\n label: 'Font size',\n type: 'number',\n value: 14,\n unit: 'px',\n prop: 'fontSize',\n classReference: 'body',\n },\n {\n label: 'Line Height',\n type: 'number',\n value: 155,\n unit: '%',\n prop: 'lineHeight',\n classReference: 'container',\n },\n ],\n },\n {\n id: 'h1',\n title: 'Title',\n category: 'Text',\n classReference: 'h1',\n inputs: [],\n },\n {\n id: 'h2',\n title: 'Subtitle',\n category: 'Text',\n classReference: 'h2',\n inputs: [],\n },\n {\n id: 'h3',\n title: 'Heading',\n category: 'Text',\n classReference: 'h3',\n inputs: [],\n },\n {\n id: 'paragraph',\n title: 'Paragraph',\n category: 'Text',\n classReference: 'paragraph',\n inputs: [],\n },\n {\n id: 'list',\n title: 'List',\n category: 'Text',\n classReference: 'list',\n inputs: [],\n },\n {\n id: 'nested-list',\n title: 'Nested List',\n category: 'Text',\n classReference: 'nestedList',\n inputs: [],\n },\n {\n id: 'list-item',\n title: 'List Item',\n category: 'Text',\n classReference: 'listItem',\n inputs: [],\n },\n {\n id: 'link',\n title: 'Link',\n classReference: 'link',\n inputs: [\n {\n label: 'Color',\n type: 'color',\n value: '#0670DB',\n prop: 'color',\n classReference: 'link',\n },\n {\n label: 'Decoration',\n type: 'select',\n value: 'underline',\n prop: 'textDecoration',\n options: {\n underline: 'Underline',\n none: 'None',\n },\n classReference: 'link',\n },\n ],\n },\n {\n id: 'image',\n title: 'Image',\n classReference: 'image',\n inputs: [\n {\n label: 'Border radius',\n type: 'number',\n value: 8,\n unit: 'px',\n prop: 'borderRadius',\n classReference: 'image',\n },\n ],\n },\n {\n id: 'button',\n title: 'Button',\n classReference: 'button',\n inputs: [\n {\n label: 'Background',\n type: 'color',\n value: '#000000',\n prop: 'backgroundColor',\n classReference: 'button',\n },\n {\n label: 'Text color',\n type: 'color',\n value: '#ffffff',\n prop: 'color',\n classReference: 'button',\n },\n {\n label: 'Radius',\n type: 'number',\n value: 4,\n unit: 'px',\n prop: 'borderRadius',\n classReference: 'button',\n },\n {\n label: 'Padding Top',\n type: 'number',\n value: 7,\n unit: 'px',\n prop: 'paddingTop',\n classReference: 'button',\n },\n {\n label: 'Padding Right',\n type: 'number',\n value: 12,\n unit: 'px',\n prop: 'paddingRight',\n classReference: 'button',\n },\n {\n label: 'Padding Bottom',\n type: 'number',\n value: 7,\n unit: 'px',\n prop: 'paddingBottom',\n classReference: 'button',\n },\n {\n label: 'Padding Left',\n type: 'number',\n value: 12,\n unit: 'px',\n prop: 'paddingLeft',\n classReference: 'button',\n },\n ],\n },\n {\n id: 'code-block',\n title: 'Code Block',\n classReference: 'codeBlock',\n inputs: [\n {\n label: 'Border Radius',\n type: 'number',\n value: 4,\n unit: 'px',\n prop: 'borderRadius',\n classReference: 'codeBlock',\n },\n {\n label: 'Padding Top',\n type: 'number',\n value: 12,\n unit: 'px',\n prop: 'paddingTop',\n classReference: 'codeBlock',\n },\n {\n label: 'Padding Bottom',\n type: 'number',\n value: 12,\n unit: 'px',\n prop: 'paddingBottom',\n classReference: 'codeBlock',\n },\n {\n label: 'Padding Left',\n type: 'number',\n value: 16,\n unit: 'px',\n prop: 'paddingLeft',\n classReference: 'codeBlock',\n },\n {\n label: 'Padding Right',\n type: 'number',\n value: 16,\n unit: 'px',\n prop: 'paddingRight',\n classReference: 'codeBlock',\n },\n ],\n },\n {\n id: 'inline-code',\n title: 'Inline Code',\n classReference: 'inlineCode',\n inputs: [\n {\n label: 'Background',\n type: 'color',\n value: '#e5e7eb',\n prop: 'backgroundColor',\n classReference: 'inlineCode',\n },\n {\n label: 'Text color',\n type: 'color',\n value: '#1e293b',\n prop: 'color',\n classReference: 'inlineCode',\n },\n {\n label: 'Radius',\n type: 'number',\n value: 4,\n unit: 'px',\n prop: 'borderRadius',\n classReference: 'inlineCode',\n },\n ],\n },\n];\n\nconst THEME_MINIMAL: PanelGroup[] = [\n {\n id: 'body',\n title: 'Background',\n classReference: 'body',\n inputs: [\n {\n label: 'Background',\n type: 'color',\n value: '#ffffff',\n prop: 'backgroundColor',\n classReference: 'body',\n },\n {\n label: 'Padding Top',\n type: 'number',\n value: undefined,\n unit: 'px',\n prop: 'paddingTop',\n classReference: 'body',\n },\n {\n label: 'Padding Right',\n type: 'number',\n value: undefined,\n unit: 'px',\n prop: 'paddingRight',\n classReference: 'body',\n },\n {\n label: 'Padding Bottom',\n type: 'number',\n value: undefined,\n unit: 'px',\n prop: 'paddingBottom',\n classReference: 'body',\n },\n {\n label: 'Padding Left',\n type: 'number',\n value: undefined,\n unit: 'px',\n prop: 'paddingLeft',\n classReference: 'body',\n },\n ],\n },\n {\n id: 'container',\n title: 'Content',\n classReference: 'container',\n inputs: [\n {\n label: 'Align',\n type: 'select',\n value: 'left',\n options: {\n left: 'Left',\n center: 'Center',\n right: 'Right',\n },\n prop: 'align',\n classReference: 'container',\n },\n {\n label: 'Width',\n type: 'number',\n value: 600,\n unit: 'px',\n prop: 'width',\n classReference: 'container',\n },\n {\n label: 'Height',\n type: 'number',\n unit: 'px',\n prop: 'height',\n classReference: 'container',\n },\n {\n label: 'Text',\n type: 'color',\n value: '#000000',\n prop: 'color',\n classReference: 'container',\n },\n {\n label: 'Background',\n type: 'color',\n value: '#ffffff',\n prop: 'backgroundColor',\n classReference: 'container',\n },\n {\n label: 'Padding Top',\n type: 'number',\n value: 0,\n unit: 'px',\n prop: 'paddingTop',\n classReference: 'container',\n },\n {\n label: 'Padding Right',\n type: 'number',\n value: 0,\n unit: 'px',\n prop: 'paddingRight',\n classReference: 'container',\n },\n {\n label: 'Padding Bottom',\n type: 'number',\n value: 0,\n unit: 'px',\n prop: 'paddingBottom',\n classReference: 'container',\n },\n {\n label: 'Padding Left',\n type: 'number',\n value: 0,\n unit: 'px',\n prop: 'paddingLeft',\n classReference: 'container',\n },\n {\n label: 'Corner radius',\n type: 'number',\n value: 0,\n unit: 'px',\n prop: 'borderRadius',\n classReference: 'container',\n },\n {\n label: 'Border color',\n type: 'color',\n value: '#000000',\n prop: 'borderColor',\n classReference: 'container',\n },\n ],\n },\n {\n id: 'typography',\n title: 'Text',\n classReference: 'body',\n inputs: [],\n },\n {\n id: 'h1',\n title: 'Title',\n category: 'Text',\n classReference: 'h1',\n inputs: [],\n },\n {\n id: 'h2',\n title: 'Subtitle',\n category: 'Text',\n classReference: 'h2',\n inputs: [],\n },\n {\n id: 'h3',\n title: 'Heading',\n category: 'Text',\n classReference: 'h3',\n inputs: [],\n },\n {\n id: 'paragraph',\n title: 'Paragraph',\n category: 'Text',\n classReference: 'paragraph',\n inputs: [],\n },\n {\n id: 'list',\n title: 'List',\n category: 'Text',\n classReference: 'list',\n inputs: [],\n },\n {\n id: 'nested-list',\n title: 'Nested List',\n category: 'Text',\n classReference: 'nestedList',\n inputs: [],\n },\n {\n id: 'list-item',\n title: 'List Item',\n category: 'Text',\n classReference: 'listItem',\n inputs: [],\n },\n {\n id: 'link',\n title: 'Link',\n classReference: 'link',\n inputs: [],\n },\n {\n id: 'image',\n title: 'Image',\n classReference: 'image',\n inputs: [],\n },\n {\n id: 'button',\n title: 'Button',\n classReference: 'button',\n inputs: [],\n },\n {\n id: 'code-block',\n title: 'Code Block',\n classReference: 'codeBlock',\n inputs: [],\n },\n {\n id: 'inline-code',\n title: 'Inline Code',\n classReference: 'inlineCode',\n inputs: [],\n },\n];\n\nconst RESET_BASIC: ResetTheme = {\n reset: {\n margin: '0',\n padding: '0',\n },\n body: {\n fontFamily:\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif\",\n fontSize: '14px',\n minHeight: '100%',\n lineHeight: '155%',\n },\n container: {},\n h1: {\n fontSize: '2.25em',\n lineHeight: '1.44em',\n paddingTop: '0.389em',\n fontWeight: 600,\n },\n h2: {\n fontSize: '1.8em',\n lineHeight: '1.44em',\n paddingTop: '0.389em',\n fontWeight: 600,\n },\n h3: {\n fontSize: '1.4em',\n lineHeight: '1.08em',\n paddingTop: '0.389em',\n fontWeight: 600,\n },\n paragraph: {\n fontSize: '1em',\n paddingTop: '0.5em',\n paddingBottom: '0.5em',\n },\n list: {\n paddingLeft: '1.1em',\n paddingBottom: '1em',\n },\n bulletList: {\n listStyleType: 'disc',\n },\n orderedList: {\n listStyleType: 'decimal',\n },\n nestedList: {\n paddingLeft: '1.1em',\n paddingBottom: '0',\n },\n listItem: {\n marginLeft: '1em',\n paddingBottom: '0.3em',\n paddingTop: '0.3em',\n },\n listParagraph: { padding: '0', margin: '0' },\n blockquote: {\n borderLeft: '3px solid #acb3be',\n color: '#7e8a9a',\n marginLeft: 0,\n paddingLeft: '0.8em',\n fontSize: '1.1em',\n fontFamily:\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif\",\n },\n link: { color: '#0670DB', textDecoration: 'underline' },\n footer: {\n fontSize: '0.8em',\n },\n hr: {\n paddingBottom: '1em',\n borderStyle: 'solid',\n borderWidth: '2px',\n },\n image: {\n maxWidth: '100%',\n },\n button: {\n lineHeight: '100%',\n display: 'inline-block',\n paddingTop: '0.625em',\n paddingRight: '1.25em',\n paddingBottom: '0.625em',\n paddingLeft: '1.25em',\n backgroundColor: '#000000',\n color: '#ffffff',\n borderRadius: '0.375em',\n fontWeight: 500,\n fontSize: '0.875em',\n textDecoration: 'none',\n textAlign: 'center',\n },\n inlineCode: {\n paddingTop: '0.25em',\n paddingBottom: '0.25em',\n paddingLeft: '0.4em',\n paddingRight: '0.4em',\n background: '#e5e7eb',\n color: '#1e293b',\n borderRadius: '4px',\n },\n codeBlock: {\n background: '#f1f5f9',\n borderRadius: '4px',\n paddingTop: '0.75rem',\n paddingRight: '1rem',\n paddingBottom: '0.75rem',\n paddingLeft: '1rem',\n overflowX: 'auto',\n fontFamily: 'monospace',\n fontWeight: '500',\n fontSize: '.92em',\n },\n codeTag: {\n lineHeight: '130%',\n fontFamily: 'monospace',\n fontSize: '.92em',\n },\n section: {\n padding: '10px 20px 10px 20px',\n boxSizing: 'border-box' as const,\n },\n};\n\nconst RESET_MINIMAL: ResetTheme = {\n ...Object.keys(RESET_BASIC).reduce<ResetTheme>((acc, key) => {\n acc[key as keyof ResetTheme] = {};\n return acc;\n }, {} as ResetTheme),\n reset: RESET_BASIC.reset,\n button: {\n lineHeight: RESET_BASIC.button.lineHeight,\n display: RESET_BASIC.button.display,\n },\n image: RESET_BASIC.image,\n list: RESET_BASIC.list,\n bulletList: RESET_BASIC.bulletList,\n orderedList: RESET_BASIC.orderedList,\n nestedList: RESET_BASIC.nestedList,\n listItem: RESET_BASIC.listItem,\n listParagraph: RESET_BASIC.listParagraph,\n link: RESET_BASIC.link,\n};\n\nexport const RESET_THEMES: Record<EditorTheme, ResetTheme> = {\n basic: RESET_BASIC,\n minimal: RESET_MINIMAL,\n};\n\nexport function resolveResetValue(\n value: string | number | undefined,\n targetUnit: 'px' | '%',\n bodyFontSizePx: number,\n): number | undefined {\n if (value === undefined) {\n return undefined;\n }\n const str = String(value);\n const num = Number.parseFloat(str);\n if (Number.isNaN(num)) {\n return undefined;\n }\n if (str.endsWith('em')) {\n return targetUnit === 'px' ? Math.floor(num * bodyFontSizePx) : num * 100;\n }\n return num;\n}\n\nexport const EDITOR_THEMES: Record<EditorTheme, PanelGroup[]> = {\n minimal: THEME_MINIMAL,\n basic: THEME_BASIC,\n};\n\nexport function getThemeBodyFontSizePx(theme: EditorTheme): number {\n for (const group of EDITOR_THEMES[theme]) {\n if (group.classReference !== 'body') {\n continue;\n }\n for (const input of group.inputs) {\n if (input.prop === 'fontSize' && typeof input.value === 'number') {\n return input.value;\n }\n }\n }\n return 14;\n}\n\n/**\n * Use to make the preview nicer once the theme might miss some\n * important properties to make layout accurate\n */\nexport const DEFAULT_INBOX_FONT_SIZE_PX = 14;\nexport const INBOX_EMAIL_DEFAULTS: Partial<ResetTheme> = {\n body: {\n color: '#000000',\n fontFamily:\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif\",\n fontSize: `${DEFAULT_INBOX_FONT_SIZE_PX}px`,\n },\n container: {\n width: 600,\n },\n};\n\nexport const SUPPORTED_CSS_PROPERTIES: SupportedCssProperties = {\n align: {\n label: 'Align',\n type: 'select',\n options: {\n left: 'Left',\n center: 'Center',\n right: 'Right',\n },\n defaultValue: 'left',\n category: 'layout',\n },\n backgroundColor: {\n label: 'Background',\n type: 'color',\n excludeNodes: ['image', 'youtube'],\n defaultValue: '#ffffff',\n category: 'appearance',\n },\n color: {\n label: 'Text color',\n type: 'color',\n excludeNodes: ['image', 'youtube'],\n defaultValue: '#000000',\n category: 'typography',\n },\n fontSize: {\n label: 'Font size',\n type: 'number',\n unit: 'px',\n excludeNodes: ['image', 'youtube'],\n defaultValue: 14,\n category: 'typography',\n },\n fontWeight: {\n label: 'Font weight',\n type: 'select',\n options: {\n 300: 'Light',\n 400: 'Normal',\n 600: 'Semi Bold',\n 700: 'Bold',\n 800: 'Extra Bold',\n },\n excludeNodes: ['image', 'youtube'],\n defaultValue: 400,\n category: 'typography',\n },\n letterSpacing: {\n label: 'Letter spacing',\n type: 'number',\n unit: 'px',\n excludeNodes: ['image', 'youtube'],\n defaultValue: 0,\n category: 'typography',\n },\n lineHeight: {\n label: 'Line height',\n type: 'number',\n unit: '%',\n defaultValue: 155,\n category: 'typography',\n },\n textDecoration: {\n label: 'Text decoration',\n type: 'select',\n options: {\n none: 'None',\n underline: 'Underline',\n 'line-through': 'Line-through',\n },\n defaultValue: 'none',\n category: 'typography',\n },\n borderRadius: {\n label: 'Border Radius',\n type: 'number',\n unit: 'px',\n defaultValue: 8,\n category: 'appearance',\n },\n borderTopLeftRadius: {\n label: 'Border Radius (Top-Left)',\n type: 'number',\n unit: 'px',\n defaultValue: 8,\n category: 'appearance',\n },\n borderTopRightRadius: {\n label: 'Border Radius (Top-Right)',\n type: 'number',\n unit: 'px',\n defaultValue: 8,\n category: 'appearance',\n },\n borderBottomLeftRadius: {\n label: 'Border Radius (Bottom-Left)',\n type: 'number',\n unit: 'px',\n defaultValue: 8,\n category: 'appearance',\n },\n borderBottomRightRadius: {\n label: 'Border Radius (Bottom-Right)',\n type: 'number',\n unit: 'px',\n defaultValue: 8,\n category: 'appearance',\n },\n borderWidth: {\n label: 'Border Width',\n type: 'number',\n unit: 'px',\n defaultValue: 1,\n category: 'appearance',\n },\n borderTopWidth: {\n label: 'Border Top Width',\n type: 'number',\n unit: 'px',\n defaultValue: 1,\n category: 'appearance',\n },\n borderRightWidth: {\n label: 'Border Right Width',\n type: 'number',\n unit: 'px',\n defaultValue: 1,\n category: 'appearance',\n },\n borderBottomWidth: {\n label: 'Border Bottom Width',\n type: 'number',\n unit: 'px',\n defaultValue: 1,\n category: 'appearance',\n },\n borderLeftWidth: {\n label: 'Border Left Width',\n type: 'number',\n unit: 'px',\n defaultValue: 1,\n category: 'appearance',\n },\n borderStyle: {\n label: 'Border Style',\n type: 'select',\n options: {\n solid: 'Solid',\n dashed: 'Dashed',\n dotted: 'Dotted',\n },\n defaultValue: 'solid',\n category: 'appearance',\n },\n borderTopStyle: {\n label: 'Border Top Style',\n type: 'select',\n options: {\n solid: 'Solid',\n dashed: 'Dashed',\n dotted: 'Dotted',\n },\n defaultValue: 'solid',\n category: 'appearance',\n },\n borderRightStyle: {\n label: 'Border Right Style',\n type: 'select',\n options: {\n solid: 'Solid',\n dashed: 'Dashed',\n dotted: 'Dotted',\n },\n defaultValue: 'solid',\n category: 'appearance',\n },\n borderBottomStyle: {\n label: 'Border Bottom Style',\n type: 'select',\n options: {\n solid: 'Solid',\n dashed: 'Dashed',\n dotted: 'Dotted',\n },\n defaultValue: 'solid',\n category: 'appearance',\n },\n borderLeftStyle: {\n label: 'Border Left Style',\n type: 'select',\n options: {\n solid: 'Solid',\n dashed: 'Dashed',\n dotted: 'Dotted',\n },\n defaultValue: 'solid',\n category: 'appearance',\n },\n borderColor: {\n label: 'Border Color',\n type: 'color',\n defaultValue: '#000000',\n category: 'appearance',\n },\n borderTopColor: {\n label: 'Border Top Color',\n type: 'color',\n defaultValue: '#000000',\n category: 'appearance',\n },\n borderRightColor: {\n label: 'Border Right Color',\n type: 'color',\n defaultValue: '#000000',\n category: 'appearance',\n },\n borderBottomColor: {\n label: 'Border Bottom Color',\n type: 'color',\n defaultValue: '#000000',\n category: 'appearance',\n },\n borderLeftColor: {\n label: 'Border Left Color',\n type: 'color',\n defaultValue: '#000000',\n category: 'appearance',\n },\n padding: {\n label: 'Padding',\n type: 'number',\n unit: 'px',\n defaultValue: 8,\n category: 'layout',\n },\n paddingTop: {\n label: 'Padding Top',\n type: 'number',\n unit: 'px',\n defaultValue: 8,\n category: 'layout',\n },\n paddingLeft: {\n label: 'Padding Left',\n type: 'number',\n unit: 'px',\n defaultValue: 8,\n category: 'layout',\n },\n paddingBottom: {\n label: 'Padding Bottom',\n type: 'number',\n unit: 'px',\n defaultValue: 8,\n category: 'layout',\n },\n paddingRight: {\n label: 'Padding Right',\n type: 'number',\n unit: 'px',\n defaultValue: 8,\n category: 'layout',\n },\n width: {\n label: 'Width',\n type: 'number',\n unit: 'px',\n defaultValue: 600,\n category: 'layout',\n },\n height: {\n label: 'Height',\n type: 'number',\n unit: 'px',\n defaultValue: 400,\n category: 'layout',\n },\n};\n","import { EDITOR_THEMES } from './themes';\nimport type {\n EditorTheme,\n KnownThemeComponents,\n PanelGroup,\n PanelSectionId,\n} from './types';\n\nconst PANEL_SECTION_IDS = new Set<PanelSectionId>([\n 'body',\n 'container',\n 'typography',\n 'paragraph',\n 'list',\n 'nested-list',\n 'list-item',\n 'link',\n 'image',\n 'button',\n 'code-block',\n 'inline-code',\n]);\n\nconst PANEL_SECTION_IDS_BY_TITLE: Record<string, PanelSectionId> = {\n background: 'body',\n body: 'body',\n content: 'container',\n container: 'container',\n typography: 'typography',\n paragraph: 'paragraph',\n list: 'list',\n 'nested list': 'nested-list',\n 'list item': 'list-item',\n link: 'link',\n image: 'image',\n button: 'button',\n 'code block': 'code-block',\n 'inline code': 'inline-code',\n};\n\nconst PANEL_SECTION_IDS_BY_CLASS_REFERENCE: Partial<\n Record<KnownThemeComponents, PanelSectionId>\n> = {\n container: 'container',\n paragraph: 'paragraph',\n list: 'list',\n nestedList: 'nested-list',\n listItem: 'list-item',\n link: 'link',\n image: 'image',\n button: 'button',\n codeBlock: 'code-block',\n inlineCode: 'inline-code',\n};\n\nfunction isPanelSectionId(value: unknown): value is PanelSectionId {\n return (\n typeof value === 'string' && PANEL_SECTION_IDS.has(value as PanelSectionId)\n );\n}\n\nfunction normalizeTitle(title: string | undefined): string {\n return title?.trim().toLowerCase().replace(/\\s+/g, ' ') ?? '';\n}\n\nfunction resolvePanelSectionId(group: PanelGroup): PanelSectionId | null {\n if (isPanelSectionId(group.id)) {\n return group.id;\n }\n\n const normalizedTitle = normalizeTitle(group.title);\n\n if (group.classReference === 'body') {\n if (normalizedTitle === 'typography') {\n return 'typography';\n }\n\n return 'body';\n }\n\n if (\n group.classReference &&\n PANEL_SECTION_IDS_BY_CLASS_REFERENCE[group.classReference]\n ) {\n return PANEL_SECTION_IDS_BY_CLASS_REFERENCE[group.classReference] ?? null;\n }\n\n return PANEL_SECTION_IDS_BY_TITLE[normalizedTitle] ?? null;\n}\n\nfunction normalizePanelInputs(\n inputs: PanelGroup['inputs'],\n defaultInputs: PanelGroup['inputs'],\n fallbackClassReference?: KnownThemeComponents,\n): PanelGroup['inputs'] {\n if (!Array.isArray(inputs)) {\n return [];\n }\n\n return inputs.map((input) => {\n const defaultInput = defaultInputs.find(\n (candidate) => candidate.prop === input.prop,\n );\n\n return {\n ...defaultInput,\n ...input,\n classReference:\n input.classReference ??\n defaultInput?.classReference ??\n fallbackClassReference,\n };\n });\n}\n\nexport function inferThemeFromPanelStyles(\n panelStyles: PanelGroup[] | null | undefined,\n): EditorTheme | null {\n if (!Array.isArray(panelStyles) || panelStyles.length === 0) {\n return null;\n }\n\n let finalTheme: EditorTheme | null = null;\n for (const group of panelStyles) {\n if (!Array.isArray(group?.inputs)) {\n finalTheme = null;\n break;\n }\n\n if (group.inputs.length !== 0) {\n finalTheme = 'basic';\n break;\n }\n\n finalTheme = 'minimal';\n }\n\n return finalTheme;\n}\n\nexport function normalizeThemePanelStyles(\n theme: EditorTheme,\n panelStyles: PanelGroup[] | null | undefined,\n): PanelGroup[] | null {\n if (!Array.isArray(panelStyles)) {\n return null;\n }\n\n return panelStyles.map((group) => {\n const panelId = resolvePanelSectionId(group);\n\n if (!panelId) {\n return group;\n }\n\n const defaultGroup = EDITOR_THEMES[theme].find(\n (candidate) => candidate.id === panelId,\n );\n\n if (!defaultGroup) {\n return group;\n }\n\n return {\n ...group,\n id: panelId,\n title: defaultGroup.title,\n classReference: defaultGroup.classReference,\n inputs: normalizePanelInputs(\n group.inputs,\n defaultGroup.inputs,\n defaultGroup.classReference,\n ),\n };\n });\n}\n","import { SUPPORTED_CSS_PROPERTIES } from './themes';\nimport type {\n EditorTheme,\n EditorThemeInput,\n KnownCssProperties,\n PanelGroup,\n PanelSectionId,\n ThemeableComponent,\n ThemeComponentStyles,\n ThemeConfig,\n} from './types';\n\nconst CLASS_REFERENCE_TO_PANEL_ID: Record<ThemeableComponent, PanelSectionId> =\n {\n body: 'body',\n container: 'container',\n h1: 'h1',\n h2: 'h2',\n h3: 'h3',\n paragraph: 'paragraph',\n link: 'link',\n image: 'image',\n button: 'button',\n list: 'list',\n nestedList: 'nested-list',\n listItem: 'list-item',\n codeBlock: 'code-block',\n inlineCode: 'inline-code',\n };\n\nexport function parseCssValue(value: string | number): {\n value: string | number;\n unit?: 'px' | '%';\n} {\n if (typeof value === 'number') {\n return { value };\n }\n const pxMatch = /^(-?\\d+(?:\\.\\d+)?)px$/.exec(value);\n if (pxMatch) {\n return { value: Number.parseFloat(pxMatch[1]), unit: 'px' };\n }\n const percentMatch = /^(-?\\d+(?:\\.\\d+)?)%$/.exec(value);\n if (percentMatch) {\n return { value: Number.parseFloat(percentMatch[1]), unit: '%' };\n }\n return { value };\n}\n\nexport function isThemeConfig(\n theme: EditorThemeInput | undefined,\n): theme is ThemeConfig {\n return typeof theme === 'object' && theme !== null && 'styles' in theme;\n}\n\nexport function themeStylesToPanelOverrides(\n styles: ThemeComponentStyles,\n basePanels: PanelGroup[],\n): PanelGroup[] {\n const result: PanelGroup[] = basePanels.map((group) => ({\n ...group,\n inputs: group.inputs.map((input) => ({ ...input })),\n }));\n\n for (const [component, cssProps] of Object.entries(styles) as [\n ThemeableComponent,\n React.CSSProperties,\n ][]) {\n if (!cssProps) continue;\n const panelId = CLASS_REFERENCE_TO_PANEL_ID[component];\n\n const group = result.find((g) => g.id === panelId);\n if (!group) continue;\n\n for (const [cssProp, cssValue] of Object.entries(cssProps) as [\n KnownCssProperties,\n string | number,\n ][]) {\n if (cssValue === undefined) continue;\n\n const existingInput = group.inputs.find(\n (i) => i.prop === cssProp && i.classReference === component,\n );\n\n const parsed = parseCssValue(cssValue);\n\n if (existingInput) {\n existingInput.value = parsed.value;\n if (parsed.unit !== undefined) {\n existingInput.unit = parsed.unit;\n }\n } else {\n const propMeta = SUPPORTED_CSS_PROPERTIES[cssProp];\n group.inputs.push({\n label: propMeta?.label ?? cssProp,\n type: propMeta?.type ?? 'text',\n prop: cssProp,\n classReference: component,\n value: parsed.value,\n unit: parsed.unit ?? propMeta?.unit,\n options: propMeta?.options,\n });\n }\n }\n }\n\n return result;\n}\n\nexport function createTheme(styles: ThemeComponentStyles): ThemeConfig {\n return { styles };\n}\n\nexport function extendTheme(\n base: EditorTheme,\n overrides: ThemeComponentStyles,\n): ThemeConfig {\n return { extends: base, styles: overrides };\n}\n","import type { Editor, JSONContent } from '@tiptap/core';\nimport { Extension } from '@tiptap/core';\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\nimport { useEditorState } from '@tiptap/react';\nimport type * as React from 'react';\nimport { Body, Head, Html, Preview } from 'react-email';\nimport type { SerializerPlugin } from '../../core/serializer/serializer-plugin';\nimport { getGlobalContent } from '../../extensions/global-content';\nimport {\n injectGlobalPlainCss,\n injectThemeCss,\n mergeCssJs,\n transformToCssJs,\n} from './css-transforms';\nimport {\n inferThemeFromPanelStyles,\n normalizeThemePanelStyles,\n} from './normalization';\nimport { isThemeConfig, themeStylesToPanelOverrides } from './theme-config';\nimport {\n DEFAULT_INBOX_FONT_SIZE_PX,\n EDITOR_THEMES,\n RESET_THEMES,\n} from './themes';\nimport type {\n CssJs,\n EditorTheme,\n EditorThemeInput,\n KnownThemeComponents,\n PanelGroup,\n} from './types';\n\n/**\n * Maps a document node (type + attrs) to the theme component key used for style lookup.\n * Centralizes all node-type → theme-component knowledge.\n */\nexport function getThemeComponentKey(\n nodeType: string,\n depth: number,\n attrs: Record<string, unknown> = {},\n): KnownThemeComponents | null {\n switch (nodeType) {\n case 'paragraph':\n if (depth > 0) {\n return 'listParagraph';\n }\n return 'paragraph';\n case 'heading': {\n const level = attrs.level as number | undefined;\n return `h${level ?? 1}` as KnownThemeComponents;\n }\n case 'blockquote':\n return 'blockquote';\n case 'button':\n return 'button';\n case 'container':\n return 'container';\n case 'section':\n return 'section';\n case 'footer':\n return 'footer';\n case 'image':\n return 'image';\n case 'youtube':\n case 'twitter':\n return 'image';\n case 'orderedList':\n case 'bulletList':\n if (depth > 0) {\n return 'nestedList';\n }\n return 'list';\n case 'listItem':\n return 'listItem';\n case 'codeBlock':\n return 'codeBlock';\n case 'code':\n return 'inlineCode';\n case 'link':\n return 'link';\n case 'horizontalRule':\n return 'hr';\n default:\n return null;\n }\n}\n\n/**\n * Returns merged theme styles (reset + panel styles) for the given editor.\n * Use when you have editor access and need the full CssJs map.\n */\nexport function getMergedCssJs(\n theme: EditorTheme,\n panelStyles: PanelGroup[] | undefined,\n): CssJs {\n const panels: PanelGroup[] =\n normalizeThemePanelStyles(theme, panelStyles) ?? EDITOR_THEMES[theme];\n const parsed = transformToCssJs(panels, DEFAULT_INBOX_FONT_SIZE_PX);\n const merged = mergeCssJs(RESET_THEMES[theme], parsed);\n\n return merged;\n}\n\n/**\n * Node types and theme component keys that should receive the universal\n * `reset` CSS (e.g. `margin: 0; padding: 0`) layered underneath their own\n * theme styles. Shared between `getResolvedNodeStyles` (email serializer)\n * and `injectThemeCss` (editor preview) so both surfaces stay in sync.\n *\n * Includes both raw tiptap node names (e.g. `tableCell`) and theme\n * component keys (e.g. `list`) because the serializer matches against both.\n *\n * `bulletList` and `orderedList` are intentionally omitted: their elements\n * already carry the shared `node-list` class, so the `list` reset rule\n * covers them without forcing the dedicated `.node-bulletList` /\n * `.node-orderedList` rules to redundantly emit `margin: 0; padding: 0`.\n */\nexport const RESET_NODE_TYPES = new Set<string>([\n 'body',\n 'button',\n 'columns',\n 'div',\n 'h1',\n 'h2',\n 'h3',\n 'list',\n 'listItem',\n 'listParagraph',\n 'nestedList',\n 'table',\n 'paragraph',\n 'tableCell',\n 'tableHeader',\n 'tableRow',\n 'youtube',\n]);\n\n/**\n * Returns resolved React.CSSProperties for a node when you already have merged CssJs\n * (e.g. in the serializer where there is no editor). Centralizes which theme keys\n * apply to which node type.\n */\nexport function getResolvedNodeStyles(\n node: JSONContent,\n depth: number,\n mergedCssJs: CssJs,\n): React.CSSProperties {\n const key = getThemeComponentKey(node.type ?? '', depth, node.attrs ?? {});\n if (!key) {\n if (RESET_NODE_TYPES.has(node.type ?? '')) {\n return mergedCssJs.reset ?? {};\n }\n return {};\n }\n const component = mergedCssJs[key] ?? {};\n const shouldReset =\n RESET_NODE_TYPES.has(key) || RESET_NODE_TYPES.has(node.type ?? '');\n if (shouldReset) {\n const reset = mergedCssJs.reset ?? {};\n return { ...reset, ...component };\n }\n return { ...component };\n}\n\nexport function stylesToCss(\n styles: PanelGroup[],\n theme: EditorTheme,\n): Record<KnownThemeComponents, React.CSSProperties> {\n const parsed = transformToCssJs(\n normalizeThemePanelStyles(theme, styles) ?? EDITOR_THEMES[theme],\n DEFAULT_INBOX_FONT_SIZE_PX,\n );\n return mergeCssJs(RESET_THEMES[theme], parsed);\n}\n\nfunction resolveThemeConfig(config: EditorThemeInput): {\n baseTheme: EditorTheme;\n panels: PanelGroup[] | undefined;\n} {\n if (!isThemeConfig(config)) {\n return { baseTheme: config, panels: undefined };\n }\n const baseTheme: EditorTheme = config.extends ?? 'minimal';\n const basePanels = EDITOR_THEMES[baseTheme];\n const panels = themeStylesToPanelOverrides(config.styles, basePanels);\n return { baseTheme, panels };\n}\n\nexport function getEmailTheming(editor: Editor) {\n const theme = getEmailTheme(editor);\n const normalizedStyles =\n normalizeThemePanelStyles(theme, getEmailStyles(editor)) ??\n EDITOR_THEMES[theme];\n\n return {\n styles: normalizedStyles,\n theme,\n css: getEmailCss(editor),\n };\n}\n\nexport function useEmailTheming(editor: Editor | null) {\n return useEditorState({\n editor,\n selector({ editor: ed }) {\n if (!ed) {\n return null;\n }\n return getEmailTheming(ed);\n },\n });\n}\n\nfunction getEmailStyles(editor: Editor) {\n return getGlobalContent('styles', editor) as PanelGroup[] | null;\n}\n\n/**\n * Sets the global panel styles on the editor document.\n * Persists into the `GlobalContent` node under the `'styles'` key.\n */\nexport function setGlobalStyles(editor: Editor, styles: PanelGroup[]): boolean {\n return editor.commands.setGlobalContent('styles', styles);\n}\n\n/**\n * Sets the current email theme on the editor document.\n * Persists into the `GlobalContent` node under the `'theme'` key.\n */\nexport function setCurrentTheme(editor: Editor, theme: EditorTheme): boolean {\n return editor.commands.setGlobalContent('theme', theme);\n}\n\n/**\n * Sets the global CSS string injected into the email `<head>`.\n * Persists into the `GlobalContent` node under the `'css'` key.\n */\nexport function setGlobalCssInjected(editor: Editor, css: string): boolean {\n return editor.commands.setGlobalContent('css', css);\n}\n\nfunction getEmailTheme(editor: Editor): EditorTheme {\n const extensionOptions = (\n editor.extensionManager.extensions.find(\n (extension) => extension.name === 'theming',\n ) as { options?: { theme?: EditorThemeInput } }\n )?.options?.theme;\n\n if (isThemeConfig(extensionOptions)) {\n return extensionOptions.extends ?? 'minimal';\n }\n\n if (extensionOptions === 'basic' || extensionOptions === 'minimal') {\n return extensionOptions;\n }\n\n const globalTheme = getGlobalContent('theme', editor) as EditorTheme | null;\n if (globalTheme === 'basic' || globalTheme === 'minimal') {\n return globalTheme;\n }\n\n const inferredTheme = inferThemeFromPanelStyles(getEmailStyles(editor));\n if (inferredTheme) {\n return inferredTheme;\n }\n\n return 'basic';\n}\n\nfunction getEmailCss(editor: Editor) {\n return getGlobalContent('css', editor) as string | null;\n}\n\nexport const EmailTheming = Extension.create<{\n theme?: EditorThemeInput;\n serializerPlugin: SerializerPlugin;\n}>({\n name: 'theming',\n\n addOptions() {\n return {\n theme: undefined as EditorThemeInput | undefined,\n serializerPlugin: {\n getNodeStyles(node, depth, editor): React.CSSProperties {\n const theming = getEmailTheming(editor);\n\n return getResolvedNodeStyles(\n node,\n depth,\n getMergedCssJs(theming.theme, theming.styles),\n );\n },\n BaseTemplate({ previewText, children, editor }) {\n const { css: globalCss, styles, theme } = getEmailTheming(editor);\n const mergedStyles = getMergedCssJs(theme, styles);\n\n return (\n <Html>\n <Head>\n <meta content=\"width=device-width\" name=\"viewport\" />\n <meta content=\"IE=edge\" httpEquiv=\"X-UA-Compatible\" />\n <meta name=\"x-apple-disable-message-reformatting\" />\n <meta\n content=\"telephone=no,address=no,email=no,date=no,url=no\"\n name=\"format-detection\"\n />\n\n {globalCss && <style>{globalCss}</style>}\n </Head>\n {previewText && previewText !== '' && (\n <Preview>{previewText}</Preview>\n )}\n\n <Body style={mergedStyles.body}>{children}</Body>\n </Html>\n );\n },\n } satisfies SerializerPlugin,\n };\n },\n\n addProseMirrorPlugins() {\n const { editor } = this;\n const scopeId = `tiptap-theme-${Math.random().toString(36).slice(2, 10)}`;\n const scopeAttribute = 'data-editor-theme-scope';\n const scopeSelector = `.tiptap.ProseMirror[${scopeAttribute}=\"${scopeId}\"]`;\n const themeStyleId = `${scopeId}-theme`;\n const globalStyleId = `${scopeId}-global`;\n\n return [\n new Plugin({\n key: new PluginKey('themingStyleInjector'),\n view(view) {\n let prevStyles: PanelGroup[] | null = null;\n let prevTheme: EditorTheme | null = null;\n let prevCss: string | null = null;\n let seededFromConfig = false;\n\n view.dom.setAttribute(scopeAttribute, scopeId);\n\n const sync = () => {\n if (!seededFromConfig) {\n seededFromConfig = true;\n const extensionTheme = (\n editor.extensionManager.extensions.find(\n (ext) => ext.name === 'theming',\n ) as { options?: { theme?: EditorThemeInput } }\n )?.options?.theme;\n\n if (isThemeConfig(extensionTheme)) {\n const { baseTheme, panels } =\n resolveThemeConfig(extensionTheme);\n if (panels && !getGlobalContent('styles', editor)) {\n editor.commands.setGlobalContent('styles', panels);\n }\n if (!getGlobalContent('theme', editor)) {\n editor.commands.setGlobalContent('theme', baseTheme);\n }\n }\n }\n\n const theme = getEmailTheme(editor);\n const styles = getEmailStyles(editor);\n const resolvedStyles = styles ?? EDITOR_THEMES[theme];\n const css = getEmailCss(editor);\n\n if (styles !== prevStyles || theme !== prevTheme) {\n prevStyles = styles as PanelGroup[] | null;\n prevTheme = theme;\n const mergedCssJs = getMergedCssJs(theme, resolvedStyles);\n injectThemeCss(mergedCssJs, {\n scopeSelector,\n styleId: themeStyleId,\n });\n }\n\n if (css !== prevCss) {\n prevCss = css;\n injectGlobalPlainCss(css, {\n scopeSelector,\n styleId: globalStyleId,\n });\n }\n };\n\n sync();\n\n return {\n update: sync,\n destroy() {\n document.getElementById(themeStyleId)?.remove();\n document.getElementById(globalStyleId)?.remove();\n view.dom.removeAttribute(scopeAttribute);\n },\n };\n },\n }),\n ];\n },\n});\n"],"mappings":"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AM;IACN,OAAO;IACP,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,gBAAgB;IACjB;GACF;EACF;CACD;EACE,IAAI;EACJ,OAAO;EACP,gBAAgB;EAChB,QAAQ,CACN;GACE,OAAO;GACP,MAAM;GACN,OAAO;GACP,MAAM;GACN,MAAM;GACN,gBAAgB;GACjB,EACD;GACE,OAAO;GACP,MAAM;GACN,OAAO;GACP,MAAM;GACN,MAAM;GACN,gBAAgB;GACjB,CACF;EACF;CACD;EACE,IAAI;EACJ,OAAO;EACP,UAAU;EACV,gBAAgB;EAChB,QAAQ,EAAE;EACX;CACD;EACE,IAAI;EACJ,OAAO;EACP,UAAU;EACV,gBAAgB;EAChB,QAAQ,EAAE;EACX;CACD;EACE,IAAI;EACJ,OAAO;EACP,UAAU;EACV,gBAAgB;EAChB,QAAQ,EAAE;EACX;CACD;EACE,IAAI;EACJ,OAAO;EACP,UAAU;EACV,gBAAgB;EAChB,QAAQ,EAAE;EACX;CACD;EACE,IAAI;EACJ,OAAO;EACP,UAAU;EACV,gBAAgB;EAChB,QAAQ,EAAE;EACX;CACD;EACE,IAAI;EACJ,OAAO;EACP,UAAU;EACV,gBAAgB;EAChB,QAAQ,EAAE;EACX;CACD;EACE,IAAI;EACJ,OAAO;EACP,UAAU;EACV,gBAAgB;EAChB,QAAQ,EAAE;EACX;CACD;EACE,IAAI;EACJ,OAAO;EACP,gBAAgB;EAChB,QAAQ,CACN;GACE,OAAO;GACP,MAAM;GACN,OAAO;GACP,MAAM;GACN,gBAAgB;GACjB,EACD;GACE,OAAO;GACP,MAAM;GACN,OAAO;GACP,MAAM;GACN,SAAS;IACP,WAAW;IACX,MAAM;IACP;GACD,gBAAgB;GACjB,CACF;EACF;CACD;EACE,IAAI;EACJ,OAAO;EACP,gBAAgB;EAChB,QAAQ,CACN;GACE,OAAO;GACP,MAAM;GACN,OAAO;GACP,MAAM;GACN,MAAM;GACN,gBAAgB;GACjB,CACF;EACF;CACD;EACE,IAAI;EACJ,OAAO;EACP,gBAAgB;EAChB,QAAQ;GACN;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACF;EACF;CACD;EACE,IAAI;EACJ,OAAO;EACP,gBAAgB;EAChB,QAAQ;GACN;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACF;EACF;CACD;EACE,IAAI;EACJ,OAAO;EACP,gBAAgB;EAChB,QAAQ;GACN;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACF;EACF;CACF;AAED,MAAM,gBAA8B;CAClC;EACE,IAAI;EACJ,OAAO;EACP,gBAAgB;EAChB,QAAQ;GACN;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO,KAAA;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO,KAAA;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO,KAAA;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO,KAAA;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACF;EACF;CACD;EACE,IAAI;EACJ,OAAO;EACP,gBAAgB;EAChB,QAAQ;GACN;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,SAAS;KACP,MAAM;KACN,QAAQ;KACR,OAAO;KACR;IACD,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,gBAAgB;IACjB;GACD;IACE,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,g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AAc,CAAC,SAAS,UAAU;EAClC,cAAc;EACd,UAAU;EACX;CACD,OAAO;EACL,OAAO;EACP,MAAM;EACN,cAAc,CAAC,SAAS,UAAU;EAClC,cAAc;EACd,UAAU;EACX;CACD,UAAU;EACR,OAAO;EACP,MAAM;EACN,MAAM;EACN,cAAc,CAAC,SAAS,UAAU;EAClC,cAAc;EACd,UAAU;EACX;CACD,YAAY;EACV,OAAO;EACP,MAAM;EACN,SAAS;GACP,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACN;EACD,cAAc,CAAC,SAAS,UAAU;EAClC,cAAc;EACd,UAAU;EACX;CACD,eAAe;EACb,OAAO;EACP,MAAM;EACN,MAAM;EACN,cAAc,CAAC,SAAS,UAAU;EAClC,cAAc;EACd,UAAU;EACX;CACD,YAAY;EACV,OAAO;EACP,MAAM;EACN,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,gBAAgB;EACd,OAAO;EACP,MAAM;EACN,SAAS;GACP,MAAM;GACN,WAAW;GACX,gBAAgB;GACjB;EACD,cAAc;EACd,UAAU;EACX;CACD,cAAc;EACZ,OAAO;EACP,MAAM;EACN,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,qBAAqB;EACnB,OAAO;EACP,MAAM;EACN,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,sBAAsB;EACpB,OAAO;EACP,MAAM;EACN,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,wBAAwB;EACtB,OAAO;EACP,MAAM;EACN,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,yBAAyB;EACvB,OAAO;EACP,MAAM;EACN,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,aAAa;EACX,OAAO;EACP,MAAM;EACN,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,gBAAgB;EACd,OAAO;EACP,MAAM;EACN,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,kBAAkB;EAChB,OAAO;EACP,MAAM;EACN,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,mBAAmB;EACjB,OAAO;EACP,MAAM;EACN,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,iBAAiB;EACf,OAAO;EACP,MAAM;EACN,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,aAAa;EACX,OAAO;EACP,MAAM;EACN,SAAS;GACP,OAAO;GACP,QAAQ;GACR,QAAQ;GACT;EACD,cAAc;EACd,UAAU;EACX;CACD,gBAAgB;EACd,OAAO;EACP,MAAM;EACN,SAAS;GACP,OAAO;GACP,QAAQ;GACR,QAAQ;GACT;EACD,cAAc;EACd,UAAU;EACX;CACD,kBAAkB;EAChB,OAAO;EACP,MAAM;EACN,SAAS;GACP,OAAO;GACP,QAAQ;GACR,QAAQ;GACT;EACD,cAAc;EACd,UAAU;EACX;CACD,mBAAmB;EACjB,OAAO;EACP,MAAM;EACN,SAAS;GACP,OAAO;GACP,QAAQ;GACR,QAAQ;GACT;EACD,cAAc;EACd,UAAU;EACX;CACD,iBAAiB;EACf,OAAO;EACP,MAAM;EACN,SAAS;GACP,OAAO;GACP,QAAQ;GACR,QAAQ;GACT;EACD,cAAc;EACd,UAAU;EACX;CACD,aAAa;EACX,OAAO;EACP,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,gBAAgB;EACd,OAAO;EACP,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,kBAAkB;EAChB,OAAO;EACP,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,mBAAmB;EACjB,OAAO;EACP,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,iBAAiB;EACf,OAAO;EACP,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,SAAS;EACP,OAAO;EACP,MAAM;EACN,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,YAAY;EACV,OAAO;EACP,MAAM;EACN,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,aAAa;EACX,OAAO;EACP,MAAM;EACN,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,eAAe;EACb,OAAO;EACP,MAAM;EACN,MAAM;EACN,cAAc;EACd,UAAU;EACX;CACD,cAAc;EACZ,OAAO;EACP,MAAM;EACN,MAAM;EACN,cAAc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"}
|