email-builder-utils 1.1.46 → 1.1.48
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/utils/blocks/button.d.ts +29 -0
- package/dist/utils/blocks/button.d.ts.map +1 -0
- package/dist/utils/blocks/button.js +130 -0
- package/dist/utils/blocks/dividers.d.ts +4 -0
- package/dist/utils/blocks/dividers.d.ts.map +1 -0
- package/dist/utils/blocks/dividers.js +72 -0
- package/dist/utils/blocks/grid.d.ts +6 -0
- package/dist/utils/blocks/grid.d.ts.map +1 -0
- package/dist/utils/blocks/grid.js +248 -0
- package/dist/utils/blocks/image.d.ts +8 -0
- package/dist/utils/blocks/image.d.ts.map +1 -0
- package/dist/utils/blocks/image.js +58 -0
- package/dist/utils/blocks/shape.d.ts +2 -0
- package/dist/utils/blocks/shape.d.ts.map +1 -0
- package/dist/utils/blocks/shape.js +256 -0
- package/dist/utils/blocks/text.d.ts +2 -0
- package/dist/utils/blocks/text.d.ts.map +1 -0
- package/dist/utils/blocks/text.js +106 -0
- package/dist/utils/blocks/video.d.ts +2 -0
- package/dist/utils/blocks/video.d.ts.map +1 -0
- package/dist/utils/blocks/video.js +151 -0
- package/dist/utils/buildStyles.d.ts +10 -0
- package/dist/utils/buildStyles.d.ts.map +1 -0
- package/dist/utils/buildStyles.js +101 -0
- package/dist/utils/common.d.ts +1 -0
- package/dist/utils/common.d.ts.map +1 -1
- package/dist/utils/common.js +10 -0
- package/dist/utils/convertJsonToHtml.d.ts.map +1 -1
- package/dist/utils/convertJsonToHtml.js +135 -74
- package/dist/utils/gradientUtils.d.ts +8 -0
- package/dist/utils/gradientUtils.d.ts.map +1 -0
- package/dist/utils/gradientUtils.js +68 -0
- package/dist/utils/jsonToHTML.d.ts +2 -29
- package/dist/utils/jsonToHTML.d.ts.map +1 -1
- package/dist/utils/jsonToHTML.js +18 -1560
- package/dist/utils/outlookSupport.d.ts +4 -207
- package/dist/utils/outlookSupport.d.ts.map +1 -1
- package/dist/utils/outlookSupport.js +86 -453
- package/package.json +1 -1
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convertShapeBlock = convertShapeBlock;
|
|
4
|
+
const common_1 = require("../common");
|
|
5
|
+
function computeArcSize(borderRadius, widthPx) {
|
|
6
|
+
if (!borderRadius)
|
|
7
|
+
return "0";
|
|
8
|
+
if (typeof borderRadius === "number")
|
|
9
|
+
return Math.min(borderRadius / widthPx, 1).toFixed(2);
|
|
10
|
+
const s = borderRadius.toString().trim();
|
|
11
|
+
if (s.endsWith("%"))
|
|
12
|
+
return Math.min((parseFloat(s.replace("%", "")) || 0) / 100, 1).toFixed(2);
|
|
13
|
+
return Math.min((parseFloat(s.replace("px", "")) || 0) / widthPx, 1).toFixed(2);
|
|
14
|
+
}
|
|
15
|
+
function buildVMLShape({ shape, widthPx, heightPx, imageUrl, backgroundColor, borderWidth, borderColor, borderRadius, text, textColor = "#000000", textSize = 14, verticalAlign = "middle", textAlign = "center", msoHasBakedText = false, }) {
|
|
16
|
+
const bw = borderWidth || 0;
|
|
17
|
+
const bc = borderColor || "transparent";
|
|
18
|
+
const borderAttrs = bw > 0 ? `strokeweight="${bw}px" strokecolor="${bc}"` : `stroked="false"`;
|
|
19
|
+
const fillColor = backgroundColor || "#2F80ED";
|
|
20
|
+
const fillMarkup = `<v:fill ${imageUrl ? `src="${imageUrl}" type="frame" aspect="atleast"` : ""} color="${fillColor}" />`;
|
|
21
|
+
let tag = "rect";
|
|
22
|
+
let extraAttr = "";
|
|
23
|
+
if (shape === "circle" || shape === "oval") {
|
|
24
|
+
tag = "oval";
|
|
25
|
+
}
|
|
26
|
+
else if (shape === "rounded") {
|
|
27
|
+
tag = "roundrect";
|
|
28
|
+
extraAttr = `arcsize="${computeArcSize(borderRadius, widthPx)}"`;
|
|
29
|
+
}
|
|
30
|
+
const vAlignMap = { top: "top", middle: "middle", bottom: "bottom" };
|
|
31
|
+
const hAlignMap = { left: "left", center: "center", right: "right", justify: "left" };
|
|
32
|
+
const vAlign = vAlignMap[verticalAlign] || "middle";
|
|
33
|
+
const hAlign = hAlignMap[textAlign] || "center";
|
|
34
|
+
const safeFontSize = Math.max(Math.round(textSize), 10);
|
|
35
|
+
const textboxMarkup = text && !msoHasBakedText
|
|
36
|
+
? `<v:textbox inset="6pt,6pt,6pt,6pt" style="mso-fit-shape-to-text:false;">
|
|
37
|
+
<div style="display:table;width:100%;height:100%;">
|
|
38
|
+
<div style="display:table-cell;vertical-align:${vAlign};text-align:${hAlign};padding:0 6px;">
|
|
39
|
+
<div style="color:${textColor};font-family:Arial, sans-serif;font-size:${safeFontSize}px;line-height:1.3;word-wrap:break-word;">
|
|
40
|
+
${text}
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</v:textbox>`
|
|
45
|
+
: `<v:textbox inset="0,0,0,0"><div style="display:none;">.</div></v:textbox>`;
|
|
46
|
+
return `
|
|
47
|
+
<v:${tag} xmlns:v="urn:schemas-microsoft-com:vml"
|
|
48
|
+
style="width:${widthPx}px;height:${heightPx}px;display:inline-block;"
|
|
49
|
+
${borderAttrs}
|
|
50
|
+
fill="true" fillcolor="${fillColor}"${extraAttr}>
|
|
51
|
+
${fillMarkup}
|
|
52
|
+
${textboxMarkup}
|
|
53
|
+
</v:${tag}>`;
|
|
54
|
+
}
|
|
55
|
+
function appendOutlookForShape(content, outerContainerWidth, innerContainerWidth, opts, visibilityClass) {
|
|
56
|
+
const widthPx = Math.round(Math.min(outerContainerWidth, innerContainerWidth));
|
|
57
|
+
const heightPx = Math.max(1, Math.round(opts.heightPx));
|
|
58
|
+
const vml = buildVMLShape({
|
|
59
|
+
shape: opts.shape, widthPx, heightPx,
|
|
60
|
+
imageUrl: opts.msoBakeImageWithText || opts.imageUrl,
|
|
61
|
+
backgroundColor: opts.shapeColor || opts.backgroundColor,
|
|
62
|
+
borderWidth: opts.borderWidth, borderColor: opts.borderColor,
|
|
63
|
+
borderRadius: opts.borderRadius, text: opts.text,
|
|
64
|
+
textColor: opts.textColor, textSize: opts.textSize,
|
|
65
|
+
verticalAlign: opts.verticalAlign, textAlign: opts.textAlign,
|
|
66
|
+
msoHasBakedText: Boolean(opts.msoBakeImageWithText),
|
|
67
|
+
});
|
|
68
|
+
const pad = opts.padding || {};
|
|
69
|
+
const align = opts.alignment || "left";
|
|
70
|
+
const valign = opts.verticalAlign || "middle";
|
|
71
|
+
const shouldHideInOutlook = visibilityClass.includes("hide-desktop");
|
|
72
|
+
if (shouldHideInOutlook) {
|
|
73
|
+
return `<!--[if !mso]><!-->
|
|
74
|
+
<table align="${align}" border="0" cellpadding="0" cellspacing="0"
|
|
75
|
+
style="width:${widthPx}px;height:${heightPx}px;border-collapse:collapse;" class="${visibilityClass}">
|
|
76
|
+
<tr>
|
|
77
|
+
<td valign="${valign}"
|
|
78
|
+
style="padding:${pad.top || 0}px ${pad.right || 0}px ${pad.bottom || 0}px ${pad.left || 0}px;">
|
|
79
|
+
${vml}
|
|
80
|
+
</td>
|
|
81
|
+
</tr>
|
|
82
|
+
</table>
|
|
83
|
+
<!--<![endif]-->`;
|
|
84
|
+
}
|
|
85
|
+
return `<!--[if mso]>
|
|
86
|
+
<table align="${align}" border="0" cellpadding="0" cellspacing="0"
|
|
87
|
+
style="width:${widthPx}px;height:${heightPx}px;border-collapse:collapse;" class="${visibilityClass}">
|
|
88
|
+
<tr>
|
|
89
|
+
<td valign="${valign}"
|
|
90
|
+
style="padding:${pad.top || 0}px ${pad.right || 0}px ${pad.bottom || 0}px ${pad.left || 0}px;">
|
|
91
|
+
${vml}
|
|
92
|
+
</td>
|
|
93
|
+
</tr>
|
|
94
|
+
</table>
|
|
95
|
+
<![endif]-->`;
|
|
96
|
+
}
|
|
97
|
+
async function convertShapeBlock(blockData) {
|
|
98
|
+
const { style, props } = blockData.data;
|
|
99
|
+
const { shape, text, imageUrl } = props;
|
|
100
|
+
const visibilityClass = (0, common_1.getVisibilityClass)(props);
|
|
101
|
+
const { width = "100", height = "150", padding = {}, backgroundColor = "#2F80ED", borderRadius, borderWidth = 0, borderStyle = "solid", borderColor = "transparent", customCss, shapeColor, alignment = "left", msoBakeImageWithText, color = "#000000", fontSize = 14, textAlign = "center", verticalAlign = "middle", } = style || {};
|
|
102
|
+
const borderRadiusMap = {
|
|
103
|
+
rectangle: "0",
|
|
104
|
+
rounded: "10px",
|
|
105
|
+
circle: "50%",
|
|
106
|
+
oval: "50%",
|
|
107
|
+
};
|
|
108
|
+
let resolvedBorderRadius = borderRadius || borderRadiusMap[shape] || "0";
|
|
109
|
+
let resolvedWidthPx = typeof width === "number"
|
|
110
|
+
? width
|
|
111
|
+
: parseInt(width.toString().replace("px", ""), 10) || 100;
|
|
112
|
+
let resolvedHeightPx = typeof height === "number"
|
|
113
|
+
? height
|
|
114
|
+
: parseInt(height.toString().replace("px", ""), 10) || 150;
|
|
115
|
+
// --- Shape-specific constraints ---
|
|
116
|
+
if (shape === "circle") {
|
|
117
|
+
const side = Math.min(resolvedWidthPx, resolvedHeightPx);
|
|
118
|
+
resolvedWidthPx = side;
|
|
119
|
+
resolvedHeightPx = side;
|
|
120
|
+
resolvedBorderRadius = "50%";
|
|
121
|
+
}
|
|
122
|
+
else if (shape === "oval") {
|
|
123
|
+
resolvedBorderRadius = "50% / 50%";
|
|
124
|
+
}
|
|
125
|
+
const finalBackgroundColor = shapeColor || backgroundColor;
|
|
126
|
+
// --- Horizontal alignment for outer container ---
|
|
127
|
+
const alignmentStyles = {
|
|
128
|
+
left: "margin-right:auto;margin-left:0;",
|
|
129
|
+
center: "margin-left:auto;margin-right:auto;",
|
|
130
|
+
right: "margin-left:auto;margin-right:0;",
|
|
131
|
+
};
|
|
132
|
+
const alignmentStyle = alignmentStyles[alignment] || "";
|
|
133
|
+
// --- Text + vertical alignment maps ---
|
|
134
|
+
const textAlignMap = {
|
|
135
|
+
left: "left",
|
|
136
|
+
center: "center",
|
|
137
|
+
right: "right",
|
|
138
|
+
justify: "justify",
|
|
139
|
+
};
|
|
140
|
+
const textAlignStyle = textAlignMap[textAlign] || "center";
|
|
141
|
+
// --- Text styling ---
|
|
142
|
+
const textSizeStyle = `font-size:${fontSize}px;line-height:1.3;word-break:break-word;overflow-wrap:break-word;color:${color};`;
|
|
143
|
+
// ============================
|
|
144
|
+
// Modern HTML (non-MSO)
|
|
145
|
+
// ============================
|
|
146
|
+
let nonMsoContent = "";
|
|
147
|
+
// --- Case 1: Image + Text ---
|
|
148
|
+
if (imageUrl && text) {
|
|
149
|
+
nonMsoContent = `
|
|
150
|
+
<div style="display:inline-block;width:${resolvedWidthPx}px;height:${resolvedHeightPx}px;
|
|
151
|
+
border:${borderWidth}px ${borderStyle} ${borderColor};
|
|
152
|
+
border-radius:${resolvedBorderRadius};
|
|
153
|
+
background-color:${finalBackgroundColor};
|
|
154
|
+
background-image:url('${imageUrl}');
|
|
155
|
+
background-position:center center;
|
|
156
|
+
background-size:cover;
|
|
157
|
+
background-repeat:no-repeat;
|
|
158
|
+
overflow:hidden;${alignmentStyle}${customCss || ""}">
|
|
159
|
+
<table border="0" cellpadding="0" cellspacing="0" width="${resolvedWidthPx}"
|
|
160
|
+
style="width:${resolvedWidthPx}px;height:${resolvedHeightPx}px;border-collapse:collapse;">
|
|
161
|
+
<tr>
|
|
162
|
+
<td align="${textAlignStyle}" valign="${verticalAlign}"
|
|
163
|
+
width="${resolvedWidthPx}" height="${resolvedHeightPx}"
|
|
164
|
+
style="padding:6px;vertical-align:${verticalAlign};text-align:${textAlignStyle};overflow:hidden;box-sizing:border-box;">
|
|
165
|
+
<div style="${textSizeStyle}text-align:${textAlignStyle};max-width:90%;overflow:hidden;">${text}</div>
|
|
166
|
+
</td>
|
|
167
|
+
</tr>
|
|
168
|
+
</table>
|
|
169
|
+
</div>`;
|
|
170
|
+
}
|
|
171
|
+
// --- Case 2: Image only ---
|
|
172
|
+
else if (imageUrl) {
|
|
173
|
+
nonMsoContent = `
|
|
174
|
+
<div style="display:inline-block;width:${resolvedWidthPx}px;height:${resolvedHeightPx}px;
|
|
175
|
+
border:${borderWidth}px ${borderStyle} ${borderColor};
|
|
176
|
+
border-radius:${resolvedBorderRadius};
|
|
177
|
+
overflow:hidden;${alignmentStyle}${customCss || ""}">
|
|
178
|
+
<img src="${imageUrl}" alt="${text || "shape image"}"
|
|
179
|
+
width="${resolvedWidthPx}" height="${resolvedHeightPx}"
|
|
180
|
+
style="width:100%;height:100%;object-fit:cover;border-radius:${resolvedBorderRadius};display:block;" />
|
|
181
|
+
</div>`;
|
|
182
|
+
}
|
|
183
|
+
// --- Case 3: Text only ---
|
|
184
|
+
else {
|
|
185
|
+
nonMsoContent = `
|
|
186
|
+
<div style="display:inline-block;width:${resolvedWidthPx}px;height:${resolvedHeightPx}px;
|
|
187
|
+
background-color:${finalBackgroundColor};
|
|
188
|
+
border:${borderWidth}px ${borderStyle} ${borderColor};
|
|
189
|
+
border-radius:${resolvedBorderRadius};
|
|
190
|
+
overflow:hidden;${alignmentStyle}${customCss || ""}">
|
|
191
|
+
<table border="0" cellpadding="0" cellspacing="0" width="${resolvedWidthPx}"
|
|
192
|
+
style="width:${resolvedWidthPx}px;height:${resolvedHeightPx}px;border-collapse:collapse;">
|
|
193
|
+
<tr>
|
|
194
|
+
<td align="${textAlignStyle}" valign="${verticalAlign}"
|
|
195
|
+
width="${resolvedWidthPx}" height="${resolvedHeightPx}"
|
|
196
|
+
style="padding:8px;vertical-align:${verticalAlign};text-align:${textAlignStyle};box-sizing:border-box;">
|
|
197
|
+
<div style="${textSizeStyle}text-align:${textAlignStyle};max-width:90%;overflow:hidden;">${text || ""}</div>
|
|
198
|
+
</td>
|
|
199
|
+
</tr>
|
|
200
|
+
</table>
|
|
201
|
+
</div>`;
|
|
202
|
+
}
|
|
203
|
+
// Outlook (VML) fallback
|
|
204
|
+
const outlookContent = appendOutlookForShape(nonMsoContent, resolvedWidthPx, resolvedWidthPx, {
|
|
205
|
+
shape,
|
|
206
|
+
imageUrl,
|
|
207
|
+
backgroundColor,
|
|
208
|
+
shapeColor,
|
|
209
|
+
borderWidth,
|
|
210
|
+
borderColor,
|
|
211
|
+
borderRadius: resolvedBorderRadius,
|
|
212
|
+
heightPx: resolvedHeightPx,
|
|
213
|
+
text,
|
|
214
|
+
textColor: color,
|
|
215
|
+
textSize: fontSize,
|
|
216
|
+
verticalAlign,
|
|
217
|
+
textAlign, // ✅ added
|
|
218
|
+
alignment,
|
|
219
|
+
padding,
|
|
220
|
+
msoBakeImageWithText,
|
|
221
|
+
}, visibilityClass);
|
|
222
|
+
const shapeBlockProps = (0, common_1.encodeBlockPropsAttr)({
|
|
223
|
+
shape: shape || 'rectangle',
|
|
224
|
+
width: resolvedWidthPx,
|
|
225
|
+
height: resolvedHeightPx,
|
|
226
|
+
shapeColor: shapeColor || '',
|
|
227
|
+
backgroundColor: backgroundColor || '',
|
|
228
|
+
borderRadius: resolvedBorderRadius,
|
|
229
|
+
borderWidth,
|
|
230
|
+
borderColor,
|
|
231
|
+
borderStyle,
|
|
232
|
+
imageUrl: imageUrl || '',
|
|
233
|
+
text: text || '',
|
|
234
|
+
color,
|
|
235
|
+
fontSize,
|
|
236
|
+
textAlign,
|
|
237
|
+
verticalAlign,
|
|
238
|
+
alignment,
|
|
239
|
+
padding,
|
|
240
|
+
customCss: customCss || '',
|
|
241
|
+
hideOnDesktop: Boolean(props.hideOnDesktop),
|
|
242
|
+
hideOnMobile: Boolean(props.hideOnMobile),
|
|
243
|
+
});
|
|
244
|
+
// Combine into table wrapper
|
|
245
|
+
return `
|
|
246
|
+
<table width="100%" style="border-collapse:collapse;table-layout:fixed;max-width:600px;" class="${visibilityClass}" data-block-type="shape" data-block-props="${shapeBlockProps}">
|
|
247
|
+
<tr>
|
|
248
|
+
<td style="padding:${padding.top || 0}px ${padding.right || 0}px ${padding.bottom || 0}px ${padding.left || 0}px;text-align:${alignment};">
|
|
249
|
+
${outlookContent}
|
|
250
|
+
<!--[if !mso]><!-->
|
|
251
|
+
${nonMsoContent}
|
|
252
|
+
<!--<![endif]-->
|
|
253
|
+
</td>
|
|
254
|
+
</tr>
|
|
255
|
+
</table>`;
|
|
256
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/utils/blocks/text.ts"],"names":[],"mappings":"AAKA,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,GAAG,EAAE,aAAa,CAAC,EAAE,MAAM,UAsItE"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convertTextBlock = convertTextBlock;
|
|
4
|
+
const buildStyles_1 = require("../buildStyles");
|
|
5
|
+
const gradientUtils_1 = require("../gradientUtils");
|
|
6
|
+
const outlookSupport_1 = require("../outlookSupport");
|
|
7
|
+
const common_1 = require("../common");
|
|
8
|
+
function convertTextBlock(blockData, cellWidthInPx) {
|
|
9
|
+
const { style, props } = blockData.data;
|
|
10
|
+
const visibilityClass = (0, common_1.getVisibilityClass)(props);
|
|
11
|
+
const { width, backgroundColor, padding, borderRadius, borderStyle, borderColor, borderWidth, textContainerBackgroundColor, textContainerPadding, fontSize, backgroundImage, whiteSpace: _whiteSpace, ...rest } = style;
|
|
12
|
+
const bgImageStr = typeof backgroundImage === 'string' ? backgroundImage : '';
|
|
13
|
+
const customCssStr = rest.customCss || '';
|
|
14
|
+
const gradientInCustomCss = !bgImageStr.includes('gradient(') && customCssStr.includes('gradient(')
|
|
15
|
+
? (customCssStr.match(/(?:linear|radial|conic)-gradient\([^)]+(?:\([^)]*\)[^)]*)*\)/)?.[0] || '')
|
|
16
|
+
: '';
|
|
17
|
+
const effectiveGradient = bgImageStr.includes('gradient(') ? bgImageStr : gradientInCustomCss;
|
|
18
|
+
const isGradient = Boolean(effectiveGradient);
|
|
19
|
+
const parsedGradient = isGradient ? (0, gradientUtils_1.parseGradient)(effectiveGradient) : null;
|
|
20
|
+
const rawBgImageUrl = !isGradient && bgImageStr
|
|
21
|
+
? bgImageStr.replace(/^url\(['"]?/, '').replace(/['"]?\)$/, '')
|
|
22
|
+
: null;
|
|
23
|
+
const hasBgImage = Boolean(rawBgImageUrl || isGradient);
|
|
24
|
+
const fallbackBgColor = textContainerBackgroundColor ||
|
|
25
|
+
parsedGradient?.fallback ||
|
|
26
|
+
(0, gradientUtils_1.extractCssFallbackColor)(customCssStr) ||
|
|
27
|
+
'#ffffff';
|
|
28
|
+
const textBoxStyle = { backgroundColor, padding, borderRadius, borderStyle, borderColor, borderWidth };
|
|
29
|
+
const convertedTextStyle = (0, buildStyles_1.buildStyles)(textBoxStyle, { perChanges: [], pxChanges: buildStyles_1.allPxAttributes });
|
|
30
|
+
const innerCustomCss = gradientInCustomCss
|
|
31
|
+
? customCssStr.replace(/background-image\s*:[^;]+;?/gi, '').trim()
|
|
32
|
+
: customCssStr;
|
|
33
|
+
const restForStyles = gradientInCustomCss ? { ...rest, customCss: innerCustomCss } : rest;
|
|
34
|
+
const styles = (0, buildStyles_1.buildStyles)({
|
|
35
|
+
padding: textContainerPadding,
|
|
36
|
+
backgroundColor: hasBgImage ? undefined : textContainerBackgroundColor,
|
|
37
|
+
...restForStyles,
|
|
38
|
+
}, { perChanges: [], pxChanges: buildStyles_1.allPxAttributes });
|
|
39
|
+
const sanitizedText = (props.text ?? "")
|
|
40
|
+
.replace(/<p(\s[^>]*)?>/gi, (_, attrs) => `<div${attrs || ""}>`)
|
|
41
|
+
.replace(/<\/p>/gi, "</div>");
|
|
42
|
+
const navigateToUrl = props.navigateToUrl || "";
|
|
43
|
+
const fontSizeStyle = fontSize != null ? `font-size:${fontSize}px;` : "";
|
|
44
|
+
const blockTextColor = rest.color;
|
|
45
|
+
const processedText = blockTextColor
|
|
46
|
+
? sanitizedText.replace(/<a(\s[^>]*)?>/gi, (match, attrs = '') => {
|
|
47
|
+
if (/style\s*=\s*["'][^"']*\bcolor\s*:/i.test(attrs))
|
|
48
|
+
return match;
|
|
49
|
+
if (/\bstyle\s*=/i.test(attrs)) {
|
|
50
|
+
return `<a${attrs.replace(/(\bstyle\s*=\s*["'])/, `$1color:${blockTextColor};`)}>`;
|
|
51
|
+
}
|
|
52
|
+
return `<a${attrs} style="color:${blockTextColor};">`;
|
|
53
|
+
})
|
|
54
|
+
: sanitizedText;
|
|
55
|
+
const colorStyle = blockTextColor ? `color:${blockTextColor};` : '';
|
|
56
|
+
const convertedTextBox = `<div style="display:block; width:100%; box-sizing:border-box; ${colorStyle}${fontSizeStyle}${convertedTextStyle}">${processedText.replaceAll(/\n/g, "<br>")}</div>`;
|
|
57
|
+
const safeCellWidth = cellWidthInPx ? Math.min(cellWidthInPx, 600) : undefined;
|
|
58
|
+
const textContent = (0, outlookSupport_1.appendOutlookSupport)(convertedTextBox, styles, hasBgImage ? '' : visibilityClass, safeCellWidth);
|
|
59
|
+
const linkColorStyle = blockTextColor ? `color:${blockTextColor};` : 'color:inherit;';
|
|
60
|
+
if (hasBgImage) {
|
|
61
|
+
const msoWidth = cellWidthInPx ? Math.min(cellWidthInPx, 600) : 600;
|
|
62
|
+
const vmlFill = isGradient
|
|
63
|
+
? (() => {
|
|
64
|
+
const vmlAngle = (0, gradientUtils_1.cssAngleToVml)(parsedGradient?.angle || 180);
|
|
65
|
+
const c1 = parsedGradient?.fallback || '#ffffff';
|
|
66
|
+
const c2 = parsedGradient?.colors[parsedGradient.colors.length - 1] || c1;
|
|
67
|
+
return `<v:fill type="gradient" color="${c1}" color2="${c2}" angle="${vmlAngle}" />`;
|
|
68
|
+
})()
|
|
69
|
+
: `<v:fill type="frame" src="${rawBgImageUrl}" color="${fallbackBgColor}" />`;
|
|
70
|
+
const bgCss = isGradient
|
|
71
|
+
? `background:${effectiveGradient};`
|
|
72
|
+
: `background-image:url('${rawBgImageUrl}'); background-position:center center; background-size:cover; background-repeat:no-repeat;`;
|
|
73
|
+
const wrappedContent = `
|
|
74
|
+
<table border="0" cellpadding="0" cellspacing="0" width="100%" role="presentation"
|
|
75
|
+
style="border-collapse:collapse;width:100%;max-width:${msoWidth}px;" class="${visibilityClass}">
|
|
76
|
+
<tr>
|
|
77
|
+
<td width="100%" bgcolor="${fallbackBgColor}" valign="top"
|
|
78
|
+
${!isGradient && rawBgImageUrl ? `background="${rawBgImageUrl}"` : ''}
|
|
79
|
+
style="width:100%;max-width:${msoWidth}px;background-color:${fallbackBgColor};${bgCss}">
|
|
80
|
+
|
|
81
|
+
<!--[if gte mso 9]>
|
|
82
|
+
<v:rect xmlns:v="urn:schemas-microsoft-com:vml"
|
|
83
|
+
fill="true" stroke="false"
|
|
84
|
+
style="width:${msoWidth}px;">
|
|
85
|
+
${vmlFill}
|
|
86
|
+
<v:textbox inset="0,0,0,0">
|
|
87
|
+
<![endif]-->
|
|
88
|
+
|
|
89
|
+
${textContent}
|
|
90
|
+
|
|
91
|
+
<!--[if gte mso 9]>
|
|
92
|
+
</v:textbox>
|
|
93
|
+
</v:rect>
|
|
94
|
+
<![endif]-->
|
|
95
|
+
|
|
96
|
+
</td>
|
|
97
|
+
</tr>
|
|
98
|
+
</table>`;
|
|
99
|
+
return navigateToUrl
|
|
100
|
+
? `<a href="${navigateToUrl}" rel="noreferrer noopener" style="${linkColorStyle}text-decoration:none;cursor:pointer;">${wrappedContent}</a>`
|
|
101
|
+
: wrappedContent;
|
|
102
|
+
}
|
|
103
|
+
return navigateToUrl
|
|
104
|
+
? `<a href="${navigateToUrl}" rel="noreferrer noopener" style="${linkColorStyle}text-decoration:none;cursor:pointer;">${textContent}</a>`
|
|
105
|
+
: textContent;
|
|
106
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"video.d.ts","sourceRoot":"","sources":["../../../src/utils/blocks/video.ts"],"names":[],"mappings":"AAUA,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,GAAG,EACd,aAAa,EAAE,MAAM,mBAiKtB"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convertVideoBlock = convertVideoBlock;
|
|
4
|
+
const buildStyles_1 = require("../buildStyles");
|
|
5
|
+
const common_1 = require("../common");
|
|
6
|
+
const FALLBACK_THUMBNAIL = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='360'%3E%3Crect width='480' height='360' fill='%23cccccc'/%3E%3C/svg%3E`;
|
|
7
|
+
const PLAY_ICON_URL = 'https://app-rsrc.getbee.io/public/resources/components/widgetBar/video-content-icon-sets/light/type-01.png';
|
|
8
|
+
const SPACER_GIF_URL = 'https://app-rsrc.getbee.io/public/resources/multiparser/video_block/video_ratio_16-9.gif';
|
|
9
|
+
async function convertVideoBlock(blockData, cellWidthInPx) {
|
|
10
|
+
const { style = {}, props = {} } = blockData.data;
|
|
11
|
+
const visibilityClass = (0, common_1.getVisibilityClass)(props);
|
|
12
|
+
const { videoUrl, youtubeVideoUrl, thumbnailUrl, altText } = props;
|
|
13
|
+
const hideOnDesktop = Boolean(props.hideOnDesktop);
|
|
14
|
+
const videoLink = youtubeVideoUrl || videoUrl || '#';
|
|
15
|
+
let resolvedThumbnail = thumbnailUrl || FALLBACK_THUMBNAIL;
|
|
16
|
+
if (youtubeVideoUrl) {
|
|
17
|
+
const youtubeId = (0, common_1.extractYouTubeId)(youtubeVideoUrl);
|
|
18
|
+
const vimeoId = (0, common_1.extractVimeoId)(youtubeVideoUrl);
|
|
19
|
+
if (youtubeId) {
|
|
20
|
+
resolvedThumbnail = `https://img.youtube.com/vi/${youtubeId}/hqdefault.jpg`;
|
|
21
|
+
}
|
|
22
|
+
else if (vimeoId) {
|
|
23
|
+
try {
|
|
24
|
+
const res = await fetch(`https://vimeo.com/api/v2/video/${vimeoId}.json`);
|
|
25
|
+
if (res.ok) {
|
|
26
|
+
const data = await res.json();
|
|
27
|
+
resolvedThumbnail = data?.[0]?.thumbnail_large || resolvedThumbnail;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch (_) { }
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Width / dimensions
|
|
34
|
+
let percentWidth = '100%';
|
|
35
|
+
if (typeof style?.width === 'string' && style.width.trim().endsWith('%')) {
|
|
36
|
+
percentWidth = style.width.trim();
|
|
37
|
+
}
|
|
38
|
+
else if (typeof style?.width === 'number') {
|
|
39
|
+
percentWidth = `${style.width}%`;
|
|
40
|
+
}
|
|
41
|
+
const paddingLeft = style?.padding?.left || 0;
|
|
42
|
+
const paddingRight = style?.padding?.right || 0;
|
|
43
|
+
const innerContainerWidth = (parseFloat(percentWidth) / 100) * (cellWidthInPx - paddingLeft - paddingRight);
|
|
44
|
+
const thumbnailW = Math.round(innerContainerWidth);
|
|
45
|
+
const thumbnailH = Math.round(thumbnailW / (16 / 9));
|
|
46
|
+
// Border
|
|
47
|
+
const borderRadius = parseInt(style?.borderRadius || 0);
|
|
48
|
+
const borderWidth = parseInt(style?.borderWidth || 0);
|
|
49
|
+
const borderColor = style?.borderColor || 'transparent';
|
|
50
|
+
const borderStyleProp = style?.borderStyle || 'solid';
|
|
51
|
+
const outerContainerStyles = (0, buildStyles_1.buildStyles)({
|
|
52
|
+
...style,
|
|
53
|
+
width: undefined,
|
|
54
|
+
borderColor: undefined,
|
|
55
|
+
borderRadius: undefined,
|
|
56
|
+
borderWidth: undefined,
|
|
57
|
+
borderStyle: undefined,
|
|
58
|
+
}, { perChanges: buildStyles_1.addPxOrPerToAttributes, pxChanges: buildStyles_1.addPxToAttributes });
|
|
59
|
+
const align = style?.textAlign || 'left';
|
|
60
|
+
const playIconW = 65;
|
|
61
|
+
const playIconH = 46;
|
|
62
|
+
// ── Industry-standard VML + background-image table approach ──────────────────
|
|
63
|
+
// Mirrors the pattern used by professional email builders (e.g. Beefree):
|
|
64
|
+
//
|
|
65
|
+
// VML (<!--[if vml]>): all Outlook / Word rendering engine versions.
|
|
66
|
+
// v:group wraps thumbnail (v:rect frame fill) + vector play button
|
|
67
|
+
// (v:oval white circle + v:shape black triangle). No external image needed.
|
|
68
|
+
//
|
|
69
|
+
// Non-VML (<!--[if !vml]>): Gmail, Apple Mail, Yahoo, Outlook.com, EML viewers.
|
|
70
|
+
// thumbnail as `background` attribute + inline background-image on <table>.
|
|
71
|
+
// 3-column layout: [25% spacer GIF] [50% play icon, centred] [25% spacer].
|
|
72
|
+
// The spacer GIF has a 4:9 aspect ratio — when it fills the 25% column its
|
|
73
|
+
// rendered height equals thumbnailWidth × 9/16, keeping the table at 16:9
|
|
74
|
+
// without any fixed `height` CSS (which is stripped by many clients).
|
|
75
|
+
// VML coordinate positions for the play button (in the v:group coord space).
|
|
76
|
+
const ovalSize = 65;
|
|
77
|
+
const ovalLeft = Math.round(thumbnailW / 2 - ovalSize / 2);
|
|
78
|
+
const ovalTop = Math.round(thumbnailH / 2 - ovalSize / 2);
|
|
79
|
+
const triW = 23;
|
|
80
|
+
const triH = 33;
|
|
81
|
+
// Triangle centre is slightly right of geometric centre for visual balance.
|
|
82
|
+
const triLeft = Math.round(thumbnailW / 2 - triW / 2 + 3);
|
|
83
|
+
const triTop = Math.round(thumbnailH / 2 - triH / 2);
|
|
84
|
+
const borderCss = borderWidth > 0
|
|
85
|
+
? `border:${borderWidth}px ${borderStyleProp} ${borderColor};`
|
|
86
|
+
: '';
|
|
87
|
+
const radiusCss = borderRadius > 0 ? `border-radius:${borderRadius}px; overflow:hidden;` : '';
|
|
88
|
+
// min-height fallback for clients that ignore the spacer GIF (e.g. some webmail).
|
|
89
|
+
const minHeight = Math.round(thumbnailW * 0.3);
|
|
90
|
+
// VML block — shown only in Outlook (Word engine supports VML, not standard HTML).
|
|
91
|
+
const outlookContent = hideOnDesktop ? '' : `<!--[if vml]>
|
|
92
|
+
<v:group xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word"
|
|
93
|
+
coordsize="${thumbnailW},${thumbnailH}" coordorigin="0,0"
|
|
94
|
+
href="${videoLink}"
|
|
95
|
+
style="width:${thumbnailW}px;height:${thumbnailH}px;">
|
|
96
|
+
<v:rect fill="t" stroked="f" style="position:absolute;width:${thumbnailW};height:${thumbnailH};">
|
|
97
|
+
<v:fill src="${resolvedThumbnail}" type="frame"/>
|
|
98
|
+
</v:rect>
|
|
99
|
+
<v:oval fill="t" strokecolor="#ffffff" strokeweight="3px"
|
|
100
|
+
style="position:absolute;left:${ovalLeft};top:${ovalTop};width:${ovalSize};height:${ovalSize}">
|
|
101
|
+
<v:fill color="#ffffff" opacity="100%" />
|
|
102
|
+
</v:oval>
|
|
103
|
+
<v:shape coordsize="24,32" path="m,l,32,24,16,xe" fillcolor="#000000" stroked="f"
|
|
104
|
+
style="position:absolute;left:${triLeft};top:${triTop};width:${triW};height:${triH};" />
|
|
105
|
+
</v:group>
|
|
106
|
+
<![endif]-->`;
|
|
107
|
+
// Non-VML block — shown in all clients except Outlook.
|
|
108
|
+
const nonMsoContent = `<!--[if !vml]><!-->
|
|
109
|
+
<a href="${videoLink}" target="_blank"
|
|
110
|
+
style="display:block; text-decoration:none; background-image:url('${resolvedThumbnail}'); background-size:cover; background-position:center; ${borderCss}${radiusCss}">
|
|
111
|
+
<table cellpadding="0" cellspacing="0" border="0" width="100%"
|
|
112
|
+
background="${resolvedThumbnail}"
|
|
113
|
+
role="presentation"
|
|
114
|
+
style="background-image:url('${resolvedThumbnail}'); background-size:cover; background-position:center center; background-repeat:no-repeat; min-height:${minHeight}px;">
|
|
115
|
+
<tr>
|
|
116
|
+
<td width="25%" style="line-height:0; font-size:0; padding:0;">
|
|
117
|
+
<img src="${SPACER_GIF_URL}" width="100%" border="0" alt=""
|
|
118
|
+
style="display:block; height:auto; opacity:0; visibility:hidden;" />
|
|
119
|
+
</td>
|
|
120
|
+
<td width="50%" align="center" valign="middle"
|
|
121
|
+
style="text-align:center; vertical-align:middle; padding:0;">
|
|
122
|
+
<img src="${PLAY_ICON_URL}" width="${playIconW}" height="${playIconH}" alt="Play"
|
|
123
|
+
style="display:block; width:${playIconW}px; height:${playIconH}px; border:0; margin:0 auto;" />
|
|
124
|
+
</td>
|
|
125
|
+
<td width="25%" style="padding:0;"> </td>
|
|
126
|
+
</tr>
|
|
127
|
+
</table>
|
|
128
|
+
</a>
|
|
129
|
+
<!--<![endif]-->`;
|
|
130
|
+
return `
|
|
131
|
+
<table width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation"
|
|
132
|
+
style="border-collapse:collapse; max-width:600px; margin:0; padding:0;"
|
|
133
|
+
class="${visibilityClass}" data-block-type="video"
|
|
134
|
+
data-video-url="${videoUrl || ''}" data-youtube-url="${youtubeVideoUrl || ''}"
|
|
135
|
+
data-thumbnail-url="${thumbnailUrl || ''}" data-alt-text="${altText || ''}"
|
|
136
|
+
data-width="${typeof style?.width === 'number' ? style.width : 100}">
|
|
137
|
+
<tr>
|
|
138
|
+
<td align="${align}" style="${outerContainerStyles}">
|
|
139
|
+
<table border="0" cellpadding="0" cellspacing="0" role="presentation"
|
|
140
|
+
align="${align}"
|
|
141
|
+
style="border-collapse:collapse; max-width:${thumbnailW}px; width:${percentWidth};">
|
|
142
|
+
<tr>
|
|
143
|
+
<td align="${align}" style="padding:0;">
|
|
144
|
+
${outlookContent}${nonMsoContent}
|
|
145
|
+
</td>
|
|
146
|
+
</tr>
|
|
147
|
+
</table>
|
|
148
|
+
</td>
|
|
149
|
+
</tr>
|
|
150
|
+
</table>`;
|
|
151
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const addPxToAttributes: string[];
|
|
2
|
+
export declare const addPxOrPerToAttributes: string[];
|
|
3
|
+
export declare const allPxAttributes: string[];
|
|
4
|
+
export declare const tableCommonStyle = "border-collapse:collapse; table-layout:fixed";
|
|
5
|
+
export declare function sanitizeFontFamily(fontFamily: string): string;
|
|
6
|
+
export declare function buildStyles(style: any, { pxChanges, perChanges }: {
|
|
7
|
+
pxChanges: string[];
|
|
8
|
+
perChanges: string[];
|
|
9
|
+
}): string;
|
|
10
|
+
//# sourceMappingURL=buildStyles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildStyles.d.ts","sourceRoot":"","sources":["../../src/utils/buildStyles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,iBAAiB,UAA8C,CAAC;AAC7E,eAAO,MAAM,sBAAsB,UAAsB,CAAC;AAC1D,eAAO,MAAM,eAAe,UAAoD,CAAC;AAEjF,eAAO,MAAM,gBAAgB,iDAAiD,CAAC;AAQ/E,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAe7D;AAED,wBAAgB,WAAW,CACzB,KAAK,EAAE,GAAG,EACV,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE;IAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,UAmEzE"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.tableCommonStyle = exports.allPxAttributes = exports.addPxOrPerToAttributes = exports.addPxToAttributes = void 0;
|
|
4
|
+
exports.sanitizeFontFamily = sanitizeFontFamily;
|
|
5
|
+
exports.buildStyles = buildStyles;
|
|
6
|
+
const fontFallback_1 = require("./fontFallback");
|
|
7
|
+
exports.addPxToAttributes = ["fontSize", "borderRadius", "borderWidth"];
|
|
8
|
+
exports.addPxOrPerToAttributes = ["width", "height"];
|
|
9
|
+
exports.allPxAttributes = [...exports.addPxToAttributes, ...exports.addPxOrPerToAttributes];
|
|
10
|
+
exports.tableCommonStyle = "border-collapse:collapse; table-layout:fixed";
|
|
11
|
+
const GENERIC_FONT_FAMILIES = new Set([
|
|
12
|
+
'serif', 'sans-serif', 'monospace', 'cursive', 'fantasy',
|
|
13
|
+
'system-ui', 'ui-serif', 'ui-sans-serif', 'ui-monospace',
|
|
14
|
+
'ui-rounded', 'emoji', 'math', 'fangsong',
|
|
15
|
+
]);
|
|
16
|
+
function sanitizeFontFamily(fontFamily) {
|
|
17
|
+
if (!fontFamily)
|
|
18
|
+
return fontFamily;
|
|
19
|
+
return fontFamily
|
|
20
|
+
.split(',')
|
|
21
|
+
.map(font => {
|
|
22
|
+
const trimmed = font.trim();
|
|
23
|
+
const unquoted = trimmed.replace(/^["']|["']$/g, '').trim();
|
|
24
|
+
if (!unquoted)
|
|
25
|
+
return '';
|
|
26
|
+
if (GENERIC_FONT_FAMILIES.has(unquoted.toLowerCase()) || !/\s/.test(unquoted)) {
|
|
27
|
+
return unquoted;
|
|
28
|
+
}
|
|
29
|
+
return `'${unquoted.replace(/'/g, "\\'")}'`;
|
|
30
|
+
})
|
|
31
|
+
.filter(Boolean)
|
|
32
|
+
.join(', ');
|
|
33
|
+
}
|
|
34
|
+
function buildStyles(style, { pxChanges, perChanges }) {
|
|
35
|
+
if (!style)
|
|
36
|
+
style = {};
|
|
37
|
+
const stylesObj = {};
|
|
38
|
+
const INVALID_KEYS = [
|
|
39
|
+
"columns", "cellWidths", "cellWidth", "childWidth",
|
|
40
|
+
"visibility", "hideOnMobile", "hideOnDesktop", "label", "alignment",
|
|
41
|
+
];
|
|
42
|
+
Object.entries(style).forEach(([key, value]) => {
|
|
43
|
+
if (key === "customCss")
|
|
44
|
+
return;
|
|
45
|
+
if (INVALID_KEYS.includes(key))
|
|
46
|
+
return;
|
|
47
|
+
if (value === undefined || value === null || value === "")
|
|
48
|
+
return;
|
|
49
|
+
if ((key === "padding" || key === "buttonPadding") && typeof value === "object") {
|
|
50
|
+
const pad = value;
|
|
51
|
+
const safePad = {
|
|
52
|
+
top: Number.isFinite(pad.top) ? pad.top : 0,
|
|
53
|
+
right: Number.isFinite(pad.right) ? pad.right : 0,
|
|
54
|
+
bottom: Number.isFinite(pad.bottom) ? pad.bottom : 0,
|
|
55
|
+
left: Number.isFinite(pad.left) ? pad.left : 0,
|
|
56
|
+
};
|
|
57
|
+
value = `${safePad.top}px ${safePad.right}px ${safePad.bottom}px ${safePad.left}px`;
|
|
58
|
+
}
|
|
59
|
+
if (key === "fontFamily" && typeof value === "string") {
|
|
60
|
+
value = sanitizeFontFamily((0, fontFallback_1.withFontFallback)(value));
|
|
61
|
+
}
|
|
62
|
+
if (key === "backgroundImage" && typeof value === "string"
|
|
63
|
+
&& !String(value).startsWith("url(")
|
|
64
|
+
&& !String(value).toLowerCase().includes("gradient(")) {
|
|
65
|
+
value = `url('${value}')`;
|
|
66
|
+
}
|
|
67
|
+
if (key === "lineHeight" && typeof value === "number") {
|
|
68
|
+
stylesObj["line-height"] = value >= 4 ? `${value}px` : String(value);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const cssKey = key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
72
|
+
if (pxChanges.includes(key)) {
|
|
73
|
+
if (typeof value === "number") {
|
|
74
|
+
stylesObj[cssKey] = `${Math.round(value * 100) / 100}px`;
|
|
75
|
+
}
|
|
76
|
+
else if (typeof value === "string" && value.includes("null")) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
stylesObj[cssKey] = value;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else if (perChanges.includes(key)) {
|
|
84
|
+
if (typeof value === "number") {
|
|
85
|
+
stylesObj[cssKey] = `${value}%`;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
stylesObj[cssKey] = value;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
stylesObj[cssKey] = value;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
const parts = Object.entries(stylesObj)
|
|
96
|
+
.filter(([, v]) => v !== undefined && v !== null && v !== '')
|
|
97
|
+
.map(([k, v]) => `${k}:${v}`);
|
|
98
|
+
if (style.customCss)
|
|
99
|
+
parts.push(style.customCss);
|
|
100
|
+
return parts.join('; ').replace(/;\s*$/, '').trim();
|
|
101
|
+
}
|
package/dist/utils/common.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/utils/common.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,KAAG,MAAM,GAAG,IAqBvD,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,KAAG,MAAM,GAAG,IAIrD,CAAC;AAGF,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE;IACzC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,UASA"}
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/utils/common.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,KAAG,MAAM,GAAG,IAqBvD,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,KAAG,MAAM,GAAG,IAIrD,CAAC;AAGF,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE;IACzC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,UASA;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAQvE"}
|