@rocketium/auto-adapt 2.0.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,930 +1 @@
1
- 'use strict';
2
-
3
- // src/constants.ts
4
- var FALLBACK_AUTO_FIT_SIZES = [1, Infinity];
5
- var THRESHOLD_FOR_NOT_SKEWING = 90;
6
- var ASPECT_RATIO_WEIGHT = 0.9;
7
- var SCALE_DISTANCE_WEIGHT = 0.1;
8
- var MIN_MATCH_PERCENTAGE = 20;
9
- var MAX_MATCH_PERCENTAGE = 100;
10
- var DEFAULT_BORDER_PROPERTIES = {
11
- stroke: "rgba(0, 0, 0, 1)",
12
- strokeWidth: 0,
13
- strokeDashArray: [0, 0]
14
- };
15
-
16
- // src/utils/sizeMatching.ts
17
- var getNormalizedSizeValue = (sizeValue) => {
18
- switch (sizeValue) {
19
- case "square":
20
- return "720x720";
21
- case "landscape":
22
- return "1280x720";
23
- case "portrait":
24
- return "720x1280";
25
- default:
26
- return sizeValue;
27
- }
28
- };
29
- var getEuclideanDistanceBetweenPoints = ({
30
- x1,
31
- y1,
32
- x2,
33
- y2
34
- }) => {
35
- const widthDifference = x2 - x1;
36
- const heightDifference = y2 - y1;
37
- return Math.sqrt(widthDifference * widthDifference + heightDifference * heightDifference);
38
- };
39
- var getEuclideanDistanceBetweenSizes = ({ size1, size2 }) => {
40
- const firstSize = getNormalizedSizeValue(size1);
41
- const secondSize = getNormalizedSizeValue(size2);
42
- const [firstSizeWidth, firstSizeHeight] = firstSize.split("x").map(Number);
43
- const [secondSizeWidth, secondSizeHeight] = secondSize.split("x").map(Number);
44
- return getEuclideanDistanceBetweenPoints({
45
- x1: firstSizeWidth ?? 0,
46
- y1: firstSizeHeight ?? 0,
47
- x2: secondSizeWidth ?? 0,
48
- y2: secondSizeHeight ?? 0
49
- });
50
- };
51
- var computeSizeMatchScores = (sizes, adaptSize) => {
52
- const [adaptWidth, adaptHeight] = getNormalizedSizeValue(adaptSize).split("x").map(Number);
53
- const adaptRatio = adaptWidth / adaptHeight;
54
- const sizeDistanceMap = /* @__PURE__ */ new Map();
55
- for (const size of sizes) {
56
- const ratio = size.width / size.height;
57
- if (isNaN(ratio) || isNaN(adaptRatio)) continue;
58
- const aspectRatioDistance = Math.abs(adaptRatio - ratio);
59
- const euclideanDistance = getEuclideanDistanceBetweenPoints({
60
- x1: adaptWidth,
61
- y1: adaptHeight,
62
- x2: size.width,
63
- y2: size.height
64
- });
65
- sizeDistanceMap.set(size.key, { aspectRatioDistance, euclideanDistance });
66
- }
67
- const maxAspectRatioDistance = Math.max(...Array.from(sizeDistanceMap.values()).map((v) => v.aspectRatioDistance));
68
- const maxEuclideanDistance = Math.max(...Array.from(sizeDistanceMap.values()).map((v) => v.euclideanDistance));
69
- const scored = [];
70
- for (const size of sizes) {
71
- const distances = sizeDistanceMap.get(size.key);
72
- if (!distances) {
73
- scored.push({ ...size, matchPercentage: MIN_MATCH_PERCENTAGE });
74
- continue;
75
- }
76
- const normalizedAspectRatio = maxAspectRatioDistance === 0 ? 1 : 1 - distances.aspectRatioDistance / maxAspectRatioDistance;
77
- const normalizedEuclidean = maxEuclideanDistance === 0 ? 1 : 1 - distances.euclideanDistance / maxEuclideanDistance;
78
- const rawScore = normalizedAspectRatio * ASPECT_RATIO_WEIGHT + normalizedEuclidean * SCALE_DISTANCE_WEIGHT;
79
- const matchPercentage = Math.round(
80
- Math.max(MIN_MATCH_PERCENTAGE, Math.min(MAX_MATCH_PERCENTAGE, rawScore * 100))
81
- );
82
- scored.push({ ...size, matchPercentage });
83
- }
84
- scored.sort((a, b) => b.matchPercentage - a.matchPercentage);
85
- return scored;
86
- };
87
- var findClosestSizeWithMatches = ({
88
- availableSizes,
89
- adaptSize
90
- }) => {
91
- const sizeInputs = availableSizes.map((s) => {
92
- const normalized = getNormalizedSizeValue(s);
93
- const [width, height] = normalized.split("x").map(Number);
94
- return { key: s, width, height };
95
- });
96
- const scored = computeSizeMatchScores(sizeInputs, adaptSize);
97
- const [adaptWidth, adaptHeight] = getNormalizedSizeValue(adaptSize).split("x").map(Number);
98
- const adaptRatio = adaptWidth / adaptHeight;
99
- let closestSize = availableSizes[0];
100
- let minAspectRatioDistance = Number.MAX_VALUE;
101
- let minEuclideanDistance = Number.MAX_VALUE;
102
- for (const input of sizeInputs) {
103
- const ratio = input.width / input.height;
104
- if (isNaN(ratio) || isNaN(adaptRatio)) continue;
105
- const aspectRatioDistance = Math.abs(adaptRatio - ratio);
106
- const euclideanDistance = getEuclideanDistanceBetweenPoints({
107
- x1: adaptWidth,
108
- y1: adaptHeight,
109
- x2: input.width,
110
- y2: input.height
111
- });
112
- if (aspectRatioDistance < minAspectRatioDistance || aspectRatioDistance === minAspectRatioDistance && euclideanDistance < minEuclideanDistance) {
113
- minAspectRatioDistance = aspectRatioDistance;
114
- minEuclideanDistance = euclideanDistance;
115
- closestSize = input.key;
116
- }
117
- }
118
- return {
119
- closestSize,
120
- sortedMatches: scored.reduce(
121
- (acc, { key, matchPercentage }) => {
122
- acc[key] = matchPercentage;
123
- return acc;
124
- },
125
- {}
126
- )
127
- };
128
- };
129
- var findClosestSizeObjectsWithMatches = ({
130
- availableSizes,
131
- adaptSize
132
- }) => {
133
- if (Object.keys(availableSizes).length === 0) {
134
- return [];
135
- }
136
- const sizeInputs = Object.entries(availableSizes).map(([key, sizeObj]) => ({
137
- key,
138
- width: sizeObj.width,
139
- height: sizeObj.height
140
- }));
141
- const scored = computeSizeMatchScores(sizeInputs, adaptSize);
142
- return scored.map((s) => ({
143
- _id: s.key,
144
- ...availableSizes[s.key],
145
- matchPercentage: s.matchPercentage
146
- }));
147
- };
148
- var findBestReferenceSize = (availableSizes, targetSize) => {
149
- const sizeKeys = Object.keys(availableSizes);
150
- if (sizeKeys.length === 1) {
151
- return sizeKeys[0];
152
- }
153
- try {
154
- const sortedMatches = findClosestSizeObjectsWithMatches({
155
- availableSizes,
156
- adaptSize: targetSize
157
- });
158
- return sortedMatches[0]?._id || sizeKeys[0];
159
- } catch (error) {
160
- console.warn("Error finding closest size, using first available:", error);
161
- return sizeKeys[0];
162
- }
163
- };
164
-
165
- // src/utils/typeGuards.ts
166
- var isTextJSON = (object) => {
167
- return object.dataType === "TEXT";
168
- };
169
- var isImageJSON = (object) => {
170
- return object.dataType === "IMAGE";
171
- };
172
- var isShapeJSON = (object) => {
173
- return object.dataType === "SHAPE";
174
- };
175
- var isSVGContainerJSON = (object) => {
176
- return object?.type === "svg-container" && object?.dataType === "SHAPE";
177
- };
178
- var isRoundedRectJSON = (object) => {
179
- return object?.type === "rounded-rect" && object?.dataType === "SHAPE";
180
- };
181
- var isGroupJSON = (object) => {
182
- return object?.dataType === "GROUP";
183
- };
184
- var isCreativeBoxJSON = (object) => {
185
- return object?.dataType === "CREATIVE_BOX";
186
- };
187
- var isAudioJSON = (object) => {
188
- return object?.dataType === "AUDIO";
189
- };
190
-
191
- // src/utils/scaling.ts
192
- var num = (obj, key, fallback = 0) => {
193
- if (key in obj) {
194
- const val = obj[key];
195
- return typeof val === "number" ? val : fallback;
196
- }
197
- return fallback;
198
- };
199
- var getAreaPercentageOfElementOnCanvasJSON = ({
200
- element,
201
- canvasDimensions
202
- }) => {
203
- const canvasWidth = typeof canvasDimensions.width === "number" ? canvasDimensions.width : 0;
204
- const canvasHeight = typeof canvasDimensions.height === "number" ? canvasDimensions.height : 0;
205
- const elementWidth = ("width" in element ? element.width : 1) * ("scaleX" in element ? element.scaleX : 1);
206
- const elementHeight = ("height" in element ? element.height : 1) * ("scaleY" in element ? element.scaleY ?? 1 : 1);
207
- const elementTop = "top" in element ? element.top : 0;
208
- const elementLeft = "left" in element ? element.left : 0;
209
- const elementRight = elementLeft + elementWidth;
210
- const elementBottom = elementTop + elementHeight;
211
- const canvasArea = canvasWidth * canvasHeight;
212
- if (canvasArea === 0) {
213
- return 0;
214
- }
215
- const intersectionWidth = Math.min(elementRight, canvasWidth) - Math.max(elementLeft, 0);
216
- const intersectionHeight = Math.min(elementBottom, canvasHeight) - Math.max(elementTop, 0);
217
- const intersectionArea = Math.max(intersectionWidth, 0) * Math.max(intersectionHeight, 0);
218
- return Math.round(intersectionArea / canvasArea * 100);
219
- };
220
- var checkIfElementShouldBeSkewed = ({
221
- areaPercentage,
222
- referenceLengths,
223
- type
224
- }) => {
225
- if (type === "GROUP") return false;
226
- if (areaPercentage > THRESHOLD_FOR_NOT_SKEWING) return true;
227
- const spansFullWidth = Math.floor(referenceLengths.left) <= 0 && Math.floor(referenceLengths.width) >= referenceLengths.canvasWidth;
228
- const spansFullHeight = Math.floor(referenceLengths.top) <= 0 && Math.floor(referenceLengths.height) >= referenceLengths.canvasHeight;
229
- return spansFullWidth || spansFullHeight;
230
- };
231
- var scaleCornerRadius = (cornerRadius, scalingRatio) => {
232
- return {
233
- tl: (cornerRadius?.tl || 0) * scalingRatio,
234
- tr: (cornerRadius?.tr || 0) * scalingRatio,
235
- bl: (cornerRadius?.bl || 0) * scalingRatio,
236
- br: (cornerRadius?.br || 0) * scalingRatio
237
- };
238
- };
239
- var scalePadding = (padding, scalingRatio) => {
240
- const p = padding ?? { top: 0, right: 0, bottom: 0, left: 0 };
241
- return {
242
- ...p,
243
- top: p.top ? p.top * scalingRatio : 0,
244
- right: p.right ? p.right * scalingRatio : 0,
245
- bottom: p.bottom ? p.bottom * scalingRatio : 0,
246
- left: p.left ? p.left * scalingRatio : 0
247
- };
248
- };
249
- var getScaledBorderJSON = ({
250
- object,
251
- scalingRatio
252
- }) => {
253
- if (isCreativeBoxJSON(object) || isGroupJSON(object) || isAudioJSON(object)) {
254
- return {};
255
- }
256
- if (!("border" in object) || !object?.border) return {};
257
- const border = object.border;
258
- if (!border.strokeWidth) return {};
259
- return {
260
- border: {
261
- ...DEFAULT_BORDER_PROPERTIES,
262
- ...border,
263
- strokeWidth: border.strokeWidth * scalingRatio
264
- }
265
- };
266
- };
267
- var adaptWordStyleFontSizes = ({
268
- wordStyle,
269
- scalingRatio
270
- }) => {
271
- if (!wordStyle || wordStyle.length === 0) {
272
- return wordStyle;
273
- }
274
- return wordStyle.map((style) => {
275
- if (!style.data?.styles?.fontSize) {
276
- return style;
277
- }
278
- const currentFontSizeUnit = style.data.styles.fontSizeUnit ?? "%";
279
- const adaptedFontSize = currentFontSizeUnit === "px" ? Math.round(style.data.styles.fontSize * scalingRatio) : style.data.styles.fontSize;
280
- return {
281
- ...style,
282
- data: {
283
- ...style.data,
284
- styles: {
285
- ...style.data.styles,
286
- fontSize: adaptedFontSize,
287
- fontSizeUnit: currentFontSizeUnit
288
- }
289
- }
290
- };
291
- });
292
- };
293
- var scaleAutoFitSizes = (autoFitSizes, scalingRatio, fallbackHeight) => {
294
- if (autoFitSizes && autoFitSizes.length === 2) {
295
- return autoFitSizes.map((size) => Math.ceil((size ?? fallbackHeight) * scalingRatio));
296
- }
297
- return [...FALLBACK_AUTO_FIT_SIZES];
298
- };
299
- var getValuesWithoutSkewingJSON = ({
300
- closestSize,
301
- adaptSize,
302
- object
303
- }) => {
304
- const referenceSize = getNormalizedSizeValue(closestSize);
305
- const [referenceWidth, referenceHeight] = referenceSize.split("x").map(Number);
306
- const [adaptWidth, adaptHeight] = adaptSize.split("x").map(Number);
307
- const top = num(object, "top");
308
- const left = num(object, "left");
309
- const scaleX = num(object, "scaleX", 1);
310
- const scaleY = num(object, "scaleY", 1);
311
- const width = num(object, "width", 1) * scaleX;
312
- const height = num(object, "height", 1) * scaleY;
313
- const widthScaleFactor = adaptWidth / referenceWidth;
314
- const heightScaleFactor = adaptHeight / referenceHeight;
315
- const scaleFactor = Math.min(widthScaleFactor, heightScaleFactor);
316
- const elementWidthInNewSize = Math.ceil(width * scaleFactor);
317
- const elementHeightInNewSize = Math.ceil(height * scaleFactor);
318
- const distanceFromRight = Math.abs(left + width - referenceWidth);
319
- const distanceFromBottom = Math.abs(top + height - referenceHeight);
320
- const distanceFromLeft = Math.abs(left);
321
- const distanceFromTop = Math.abs(top);
322
- const ALIGNMENT_THRESHOLD = 1;
323
- if (distanceFromRight < ALIGNMENT_THRESHOLD || distanceFromLeft < ALIGNMENT_THRESHOLD || distanceFromBottom < ALIGNMENT_THRESHOLD || distanceFromTop < ALIGNMENT_THRESHOLD) {
324
- let elementLeftInNewSize;
325
- let elementTopInNewSize;
326
- if (distanceFromRight < ALIGNMENT_THRESHOLD) {
327
- elementLeftInNewSize = adaptWidth - elementWidthInNewSize;
328
- } else if (distanceFromLeft < ALIGNMENT_THRESHOLD) {
329
- elementLeftInNewSize = 0;
330
- } else {
331
- const elementLeftPercentage = left / referenceWidth;
332
- elementLeftInNewSize = Math.ceil(elementLeftPercentage * adaptWidth);
333
- }
334
- if (distanceFromBottom < ALIGNMENT_THRESHOLD) {
335
- elementTopInNewSize = adaptHeight - elementHeightInNewSize;
336
- } else if (distanceFromTop < ALIGNMENT_THRESHOLD) {
337
- elementTopInNewSize = 0;
338
- } else {
339
- const elementTopPercentage = top / referenceHeight;
340
- elementTopInNewSize = Math.ceil(elementTopPercentage * adaptHeight);
341
- }
342
- return {
343
- left: elementLeftInNewSize,
344
- top: elementTopInNewSize,
345
- width: elementWidthInNewSize / scaleX,
346
- height: elementHeightInNewSize / scaleY
347
- };
348
- }
349
- const elementCenterX = left + width / 2;
350
- const elementCenterY = top + height / 2;
351
- const elementRight = left + width;
352
- const elementBottom = top + height;
353
- const canvasCenterX = referenceWidth / 2;
354
- const canvasCenterY = referenceHeight / 2;
355
- const leftArea = Math.max(0, Math.min(elementRight, canvasCenterX) - Math.max(left, 0)) * Math.max(0, Math.min(elementBottom, referenceHeight) - Math.max(top, 0));
356
- const rightArea = Math.max(0, Math.min(elementRight, referenceWidth) - Math.max(left, canvasCenterX)) * Math.max(0, Math.min(elementBottom, referenceHeight) - Math.max(top, 0));
357
- const totalArea = leftArea + rightArea;
358
- const CENTER_THRESHOLD = 0.05;
359
- const isHorizontallyCentered = Math.abs(leftArea - rightArea) / totalArea < CENTER_THRESHOLD;
360
- if (isHorizontallyCentered) {
361
- const centerXPercentage = elementCenterX / referenceWidth;
362
- const centerYPercentage = elementCenterY / referenceHeight;
363
- const newCenterX = centerXPercentage * adaptWidth;
364
- const newCenterY = centerYPercentage * adaptHeight;
365
- return {
366
- left: newCenterX - elementWidthInNewSize / 2,
367
- top: newCenterY - elementHeightInNewSize / 2,
368
- width: elementWidthInNewSize,
369
- height: elementHeightInNewSize
370
- };
371
- }
372
- const isInRightHalf = elementCenterX > canvasCenterX;
373
- const isInBottomHalf = elementCenterY > canvasCenterY;
374
- const referenceX = isInRightHalf ? elementRight / referenceWidth : left / referenceWidth;
375
- const referenceY = isInBottomHalf ? elementBottom / referenceHeight : top / referenceHeight;
376
- const newX = referenceX * adaptWidth;
377
- const newY = referenceY * adaptHeight;
378
- return {
379
- left: isInRightHalf ? newX - elementWidthInNewSize : newX,
380
- top: isInBottomHalf ? newY - elementHeightInNewSize : newY,
381
- width: elementWidthInNewSize,
382
- height: elementHeightInNewSize
383
- };
384
- };
385
- var adaptTextNoSkew = (object, values, scalingRatio, closestHeight) => {
386
- return {
387
- ...object,
388
- left: values.left,
389
- top: values.top,
390
- width: values.width,
391
- height: values.height,
392
- wordSpacing: object.wordSpacing ? object.wordSpacing * scalingRatio : 0,
393
- padding: scalePadding(object.padding, scalingRatio),
394
- cornerRadius: scaleCornerRadius(object.cornerRadius, scalingRatio),
395
- ...getScaledBorderJSON({ object, scalingRatio }),
396
- autoFitSizes: scaleAutoFitSizes(object.autoFitSizes, scalingRatio, closestHeight),
397
- fontSize: object.fontSize * scalingRatio,
398
- wordStyle: adaptWordStyleFontSizes({ wordStyle: object.wordStyle || [], scalingRatio })
399
- };
400
- };
401
- var adaptImageNoSkew = (object, values, scalingRatio, widthRatio, heightRatio) => {
402
- return {
403
- ...object,
404
- left: values.left,
405
- top: values.top,
406
- width: values.width,
407
- height: values.height,
408
- imageScale: (object.imageScale ?? 1) * scalingRatio,
409
- imageLeft: (object.imageLeft ?? 0) * widthRatio,
410
- imageTop: (object.imageTop ?? 0) * heightRatio,
411
- cornerRadius: scaleCornerRadius(object.cornerRadius, scalingRatio),
412
- ...getScaledBorderJSON({ object, scalingRatio })
413
- };
414
- };
415
- var adaptSvgNoSkew = (object, values, scalingRatio, widthRatio, heightRatio) => {
416
- return {
417
- ...object,
418
- left: values.left,
419
- top: values.top,
420
- width: values.width,
421
- height: values.height,
422
- imageScale: (object.imageScale ?? 1) * scalingRatio,
423
- imageLeft: (object.imageLeft ?? 0) * widthRatio,
424
- imageTop: (object.imageTop ?? 0) * heightRatio,
425
- ...getScaledBorderJSON({ object, scalingRatio })
426
- };
427
- };
428
- var adaptRoundedRectNoSkew = (object, values, scalingRatio) => {
429
- return {
430
- ...object,
431
- left: values.left,
432
- top: values.top,
433
- width: values.width,
434
- height: values.height,
435
- cornerRadius: scaleCornerRadius(object.cornerRadius, scalingRatio),
436
- ...getScaledBorderJSON({ object, scalingRatio })
437
- };
438
- };
439
- var adaptShapeNoSkew = (object, values, scalingRatio) => {
440
- return {
441
- ...object,
442
- left: values.left,
443
- top: values.top,
444
- scaleX: (object.scaleX ?? 1) * scalingRatio,
445
- scaleY: (object.scaleY ?? 1) * scalingRatio,
446
- ...getScaledBorderJSON({ object, scalingRatio })
447
- };
448
- };
449
- var adaptTextSkew = (object, widthRatio, heightRatio, scalingRatio, closestHeight) => {
450
- return {
451
- ...object,
452
- left: object.left * widthRatio,
453
- top: object.top * heightRatio,
454
- width: object.width * widthRatio,
455
- height: object.height * heightRatio,
456
- autoFitSizes: scaleAutoFitSizes(object.autoFitSizes, scalingRatio, closestHeight),
457
- cornerRadius: scaleCornerRadius(object.cornerRadius, scalingRatio),
458
- fontSize: object.fontSize * scalingRatio,
459
- wordStyle: adaptWordStyleFontSizes({ wordStyle: object.wordStyle || [], scalingRatio })
460
- };
461
- };
462
- var adaptImageSkew = (object, widthRatio, heightRatio, scalingRatio) => {
463
- return {
464
- ...object,
465
- left: object.left * widthRatio,
466
- top: object.top * heightRatio,
467
- width: object.width * widthRatio,
468
- height: object.height * heightRatio,
469
- imageScale: (object.imageScale ?? 1) * scalingRatio,
470
- imageLeft: (object.imageLeft ?? 0) * widthRatio,
471
- imageTop: (object.imageTop ?? 0) * heightRatio,
472
- cornerRadius: scaleCornerRadius(object.cornerRadius, scalingRatio)
473
- };
474
- };
475
- var adaptSvgSkew = (object, widthRatio, heightRatio, scalingRatio) => {
476
- return {
477
- ...object,
478
- left: object.left * widthRatio,
479
- top: object.top * heightRatio,
480
- width: object.width * widthRatio,
481
- height: object.height * heightRatio,
482
- imageScale: (object.imageScale ?? 1) * scalingRatio,
483
- imageLeft: (object.imageLeft ?? 0) * widthRatio,
484
- imageTop: (object.imageTop ?? 0) * heightRatio,
485
- ...getScaledBorderJSON({ object, scalingRatio })
486
- };
487
- };
488
- var adaptRoundedRectSkew = (object, widthRatio, heightRatio, scalingRatio) => {
489
- return {
490
- ...object,
491
- left: object.left * widthRatio,
492
- top: object.top * heightRatio,
493
- width: object.width * widthRatio,
494
- height: object.height * heightRatio,
495
- cornerRadius: scaleCornerRadius(object.cornerRadius, scalingRatio),
496
- ...getScaledBorderJSON({ object, scalingRatio })
497
- };
498
- };
499
- var adaptShapeSkew = (object, widthRatio, heightRatio, scalingRatio) => {
500
- return {
501
- ...object,
502
- left: object.left * widthRatio,
503
- top: object.top * heightRatio,
504
- scaleX: (object.scaleX ?? 1) * widthRatio,
505
- scaleY: (object.scaleY ?? 1) * heightRatio,
506
- ...getScaledBorderJSON({ object, scalingRatio })
507
- };
508
- };
509
- var adaptGroupChildText = (groupObject, scalingRatio, closestHeight, parentObject) => {
510
- return {
511
- ...groupObject,
512
- left: groupObject.left * scalingRatio,
513
- top: groupObject.top * scalingRatio,
514
- width: groupObject.width * scalingRatio,
515
- height: groupObject.height * scalingRatio,
516
- wordSpacing: groupObject.wordSpacing ? groupObject.wordSpacing * scalingRatio : 0,
517
- padding: scalePadding(groupObject.padding, scalingRatio),
518
- cornerRadius: scaleCornerRadius(groupObject.cornerRadius, scalingRatio),
519
- ...getScaledBorderJSON({ object: parentObject, scalingRatio }),
520
- autoFitSizes: scaleAutoFitSizes(groupObject.autoFitSizes, scalingRatio, closestHeight),
521
- fontSize: groupObject.fontSize * scalingRatio,
522
- wordStyle: adaptWordStyleFontSizes({ wordStyle: groupObject.wordStyle || [], scalingRatio })
523
- };
524
- };
525
- var adaptGroupChildImage = (groupObject, scalingRatio, parentObject) => {
526
- return {
527
- ...groupObject,
528
- left: groupObject.left * scalingRatio,
529
- top: groupObject.top * scalingRatio,
530
- width: groupObject.width * scalingRatio,
531
- height: groupObject.height * scalingRatio,
532
- imageScale: (groupObject.imageScale ?? 1) * scalingRatio,
533
- imageLeft: (groupObject.imageLeft ?? 0) * scalingRatio,
534
- imageTop: (groupObject.imageTop ?? 0) * scalingRatio,
535
- cornerRadius: scaleCornerRadius(groupObject.cornerRadius, scalingRatio),
536
- ...getScaledBorderJSON({ object: parentObject, scalingRatio })
537
- };
538
- };
539
- var adaptGroupChildSvg = (svgContainer, scalingRatio, parentObject) => {
540
- return {
541
- ...svgContainer,
542
- left: svgContainer.left * scalingRatio,
543
- top: svgContainer.top * scalingRatio,
544
- width: svgContainer.width * scalingRatio,
545
- height: svgContainer.height * scalingRatio,
546
- imageScale: (svgContainer.imageScale ?? 1) * scalingRatio,
547
- imageLeft: (svgContainer.imageLeft ?? 0) * scalingRatio,
548
- imageTop: (svgContainer.imageTop ?? 0) * scalingRatio,
549
- ...getScaledBorderJSON({ object: parentObject, scalingRatio })
550
- };
551
- };
552
- var adaptGroupChildRoundedRect = (roundedRectObject, scalingRatio, parentObject) => {
553
- return {
554
- ...roundedRectObject,
555
- left: roundedRectObject.left * scalingRatio,
556
- top: roundedRectObject.top * scalingRatio,
557
- width: roundedRectObject.width * scalingRatio,
558
- height: roundedRectObject.height * scalingRatio,
559
- cornerRadius: scaleCornerRadius(roundedRectObject.cornerRadius, scalingRatio),
560
- ...getScaledBorderJSON({ object: parentObject, scalingRatio })
561
- };
562
- };
563
- var adaptGroupChildShape = (groupObject, scalingRatio, parentObject) => {
564
- return {
565
- ...groupObject,
566
- left: num(groupObject, "left") * scalingRatio,
567
- top: num(groupObject, "top") * scalingRatio,
568
- scaleX: num(groupObject, "scaleX", 1) * scalingRatio,
569
- scaleY: num(groupObject, "scaleY", 1) * scalingRatio,
570
- ...getScaledBorderJSON({ object: parentObject, scalingRatio })
571
- };
572
- };
573
-
574
- // src/adapter.ts
575
- var getAdaptedObjectsJSON = ({
576
- adaptSize,
577
- objects,
578
- closestSize
579
- }) => {
580
- const [adaptWidth, adaptHeight] = adaptSize.split("x").map(Number);
581
- const [closestWidth, closestHeight] = closestSize.split("x").map(Number);
582
- const widthRatio = adaptWidth / closestWidth;
583
- const heightRatio = adaptHeight / closestHeight;
584
- const scalingRatio = Math.min(widthRatio, heightRatio);
585
- const newObjects = {};
586
- for (const objectId of Object.keys(objects)) {
587
- const object = objects[objectId];
588
- if (object.dataType === "CREATIVE_BOX") {
589
- newObjects[objectId] = {
590
- ...object,
591
- height: adaptHeight,
592
- width: adaptWidth
593
- };
594
- continue;
595
- }
596
- if (object.dataType === "AUDIO") {
597
- newObjects[objectId] = object;
598
- continue;
599
- }
600
- getAreaPercentageOfElementOnCanvasJSON({
601
- element: object,
602
- canvasDimensions: { width: closestWidth, height: closestHeight }
603
- });
604
- const areaPercentage = getAreaPercentageOfElementOnCanvasJSON({
605
- element: object,
606
- canvasDimensions: { width: closestWidth, height: closestHeight }
607
- });
608
- const shouldSkew = checkIfElementShouldBeSkewed({
609
- areaPercentage,
610
- referenceLengths: {
611
- left: object.left ?? 0,
612
- top: object.top ?? 0,
613
- width: object.width ?? 1,
614
- height: object.height ?? 1,
615
- canvasWidth: closestWidth,
616
- canvasHeight: closestHeight
617
- },
618
- type: object.dataType
619
- });
620
- if (!shouldSkew) {
621
- const values = getValuesWithoutSkewingJSON({ closestSize, adaptSize, object });
622
- if (values.left === 0 && values.height === 0 && values.top === 0 && values.width === 0) {
623
- throw new Error("Invalid values");
624
- }
625
- if ("groupPath" in object && object.groupPath) {
626
- continue;
627
- }
628
- if (isTextJSON(object)) {
629
- newObjects[objectId] = adaptTextNoSkew(object, values, scalingRatio, closestHeight);
630
- continue;
631
- }
632
- if (isImageJSON(object)) {
633
- newObjects[objectId] = adaptImageNoSkew(object, values, scalingRatio, widthRatio, heightRatio);
634
- continue;
635
- }
636
- if (isShapeJSON(object)) {
637
- if (isSVGContainerJSON(object)) {
638
- newObjects[objectId] = adaptSvgNoSkew(object, values, scalingRatio, widthRatio, heightRatio);
639
- continue;
640
- }
641
- if (isRoundedRectJSON(object)) {
642
- newObjects[objectId] = adaptRoundedRectNoSkew(object, values, scalingRatio);
643
- continue;
644
- }
645
- newObjects[objectId] = adaptShapeNoSkew(object, values, scalingRatio);
646
- continue;
647
- }
648
- if (isGroupJSON(object)) {
649
- newObjects[objectId] = {
650
- ...object,
651
- left: values.left,
652
- top: values.top,
653
- width: values.width,
654
- height: values.height
655
- };
656
- for (const groupObjectId of object.objects) {
657
- const groupObject = objects[groupObjectId];
658
- if (!groupObject) continue;
659
- if (isTextJSON(groupObject)) {
660
- newObjects[groupObjectId] = adaptGroupChildText(
661
- groupObject,
662
- scalingRatio,
663
- closestHeight,
664
- object
665
- );
666
- continue;
667
- }
668
- if (isImageJSON(groupObject)) {
669
- newObjects[groupObjectId] = adaptGroupChildImage(groupObject, scalingRatio, object);
670
- continue;
671
- }
672
- if (isShapeJSON(groupObject)) {
673
- if (isSVGContainerJSON(groupObject)) {
674
- newObjects[groupObjectId] = adaptGroupChildSvg(groupObject, scalingRatio, object);
675
- continue;
676
- }
677
- if (isRoundedRectJSON(groupObject)) {
678
- newObjects[groupObjectId] = adaptGroupChildRoundedRect(
679
- groupObject,
680
- scalingRatio,
681
- object
682
- );
683
- continue;
684
- }
685
- newObjects[groupObjectId] = adaptGroupChildShape(groupObject, scalingRatio, object);
686
- continue;
687
- }
688
- }
689
- continue;
690
- }
691
- }
692
- if (isTextJSON(object)) {
693
- newObjects[objectId] = adaptTextSkew(object, widthRatio, heightRatio, scalingRatio, closestHeight);
694
- continue;
695
- }
696
- if (isImageJSON(object)) {
697
- newObjects[objectId] = adaptImageSkew(object, widthRatio, heightRatio, scalingRatio);
698
- continue;
699
- }
700
- if (isShapeJSON(object)) {
701
- if (isSVGContainerJSON(object)) {
702
- newObjects[objectId] = adaptSvgSkew(object, widthRatio, heightRatio, scalingRatio);
703
- continue;
704
- }
705
- if (isRoundedRectJSON(object)) {
706
- newObjects[objectId] = adaptRoundedRectSkew(object, widthRatio, heightRatio, scalingRatio);
707
- continue;
708
- }
709
- newObjects[objectId] = adaptShapeSkew(object, widthRatio, heightRatio, scalingRatio);
710
- continue;
711
- }
712
- newObjects[objectId] = {
713
- ...object,
714
- left: num(object, "left") * widthRatio,
715
- top: num(object, "top") * heightRatio,
716
- width: num(object, "width", 1) * widthRatio,
717
- height: num(object, "height", 1) * heightRatio,
718
- ...getScaledBorderJSON({ object, scalingRatio })
719
- };
720
- }
721
- return newObjects;
722
- };
723
- var resolveObjectsForSize = (objects, sizeId) => {
724
- const resolved = {};
725
- for (const [id, obj] of Object.entries(objects)) {
726
- const sizeOverrides = obj.overrides?.[sizeId] || {};
727
- const { overrides: _overrides, zIndex: _zIndex, ...base } = obj;
728
- resolved[id] = { ...base, ...sizeOverrides };
729
- }
730
- return resolved;
731
- };
732
- var applyAdaptedAsOverrides = (originalObjects, adaptedObjects, newSizeId) => {
733
- const result = JSON.parse(JSON.stringify(originalObjects));
734
- for (const [layerId, adapted] of Object.entries(adaptedObjects)) {
735
- if (!result[layerId]) continue;
736
- const existingOverrides = result[layerId].overrides || {};
737
- result[layerId].overrides = {
738
- ...existingOverrides,
739
- [newSizeId]: {
740
- ...adapted,
741
- zIndex: result[layerId].overrides?.[newSizeId]?.zIndex ?? result[layerId].zIndex ?? 0
742
- }
743
- };
744
- }
745
- return result;
746
- };
747
- var buildNewCapsule = ({
748
- originalCapsule,
749
- updatedObjects,
750
- sizeId,
751
- referenceCreativeId,
752
- sizeToGenerate,
753
- sizeName,
754
- sizeCategory,
755
- videoLength
756
- }) => {
757
- const [widthOfNewSize, heightOfNewSize] = sizeToGenerate.split("x").map(Number);
758
- const canvasData = JSON.parse(JSON.stringify(originalCapsule.canvasData));
759
- canvasData.variant.objects = updatedObjects;
760
- canvasData.variant.sizes[sizeId] = {
761
- width: widthOfNewSize,
762
- height: heightOfNewSize,
763
- id: sizeId,
764
- displayName: sizeName || sizeToGenerate,
765
- rulers: [],
766
- ...videoLength !== void 0 && { videoLength }
767
- };
768
- const creativesOrder = originalCapsule.creativesOrder;
769
- const finalCreativesOrder = creativesOrder && creativesOrder.length > 0 ? [...creativesOrder, sizeId] : [referenceCreativeId, sizeId];
770
- const newSizeData = {
771
- name: sizeName || sizeToGenerate,
772
- width: widthOfNewSize,
773
- height: heightOfNewSize,
774
- active: true,
775
- thumbnail: "",
776
- creativeUrl: "",
777
- ...sizeCategory && { category: sizeCategory }
778
- };
779
- return {
780
- ...originalCapsule,
781
- canvasData,
782
- savedCustomDimensions: {
783
- ...originalCapsule.savedCustomDimensions,
784
- [sizeId]: newSizeData
785
- },
786
- newAddedSizes: {
787
- ...originalCapsule.newAddedSizes,
788
- [sizeId]: newSizeData
789
- },
790
- creativesOrder: finalCreativesOrder
791
- };
792
- };
793
- var generateBaseLayoutForSize = ({
794
- originalCapsule,
795
- capsuleId,
796
- creativeId,
797
- sizeId,
798
- sizeToGenerate,
799
- sizeName,
800
- sizeCategory
801
- }) => {
802
- const availableSizes = originalCapsule.canvasData.variant?.sizes;
803
- if (!availableSizes || Object.keys(availableSizes).length === 0) {
804
- throw new Error(`No sizes available in capsule: ${capsuleId}`);
805
- }
806
- let referenceCreativeId;
807
- if (creativeId && availableSizes[creativeId]) {
808
- referenceCreativeId = creativeId;
809
- console.log(`[BaseLayoutAdapter] Using provided reference size: ${referenceCreativeId}`);
810
- } else {
811
- referenceCreativeId = findBestReferenceSize(availableSizes, sizeToGenerate);
812
- console.log(
813
- `[BaseLayoutAdapter] Found best reference size: ${referenceCreativeId} for target: ${sizeToGenerate}`
814
- );
815
- if (creativeId && !availableSizes[creativeId]) {
816
- console.warn(
817
- `[BaseLayoutAdapter] Provided creativeId ${creativeId} not found, using ${referenceCreativeId}`
818
- );
819
- }
820
- }
821
- const currentSize = availableSizes[referenceCreativeId];
822
- const closestSize = `${currentSize.width}x${currentSize.height}`;
823
- const variantObjects = originalCapsule.canvasData.variant.objects;
824
- const resolvedObjects = resolveObjectsForSize(variantObjects, referenceCreativeId);
825
- const adaptedObjects = getAdaptedObjectsJSON({
826
- adaptSize: sizeToGenerate,
827
- objects: resolvedObjects,
828
- closestSize
829
- });
830
- const updatedObjects = applyAdaptedAsOverrides(variantObjects, adaptedObjects, sizeId);
831
- return buildNewCapsule({
832
- originalCapsule,
833
- updatedObjects,
834
- sizeId,
835
- referenceCreativeId,
836
- sizeToGenerate,
837
- sizeName,
838
- sizeCategory,
839
- videoLength: currentSize?.videoLength
840
- });
841
- };
842
-
843
- // src/types/canvas.ts
844
- var CANVAS_EDITOR_ELEMENT = {
845
- TEXT: "TEXT",
846
- SHAPE: "SHAPE",
847
- IMAGE: "IMAGE",
848
- GROUP: "GROUP",
849
- CREATIVE_BOX: "CREATIVE_BOX",
850
- VIDEO: "VIDEO",
851
- AUDIO: "AUDIO",
852
- CANVAS_MASK: "CANVAS_MASK"
853
- };
854
- var CreativeElementCategory = /* @__PURE__ */ ((CreativeElementCategory2) => {
855
- CreativeElementCategory2["HERO_IMAGE"] = "HERO_IMAGE";
856
- CreativeElementCategory2["PRODUCT_IMAGE"] = "PRODUCT_IMAGE";
857
- CreativeElementCategory2["BACKGROUND"] = "BACKGROUND";
858
- CreativeElementCategory2["LOGO"] = "LOGO";
859
- CreativeElementCategory2["ICON"] = "ICON";
860
- CreativeElementCategory2["HEADLINE"] = "HEADLINE";
861
- CreativeElementCategory2["SUBHEADLINE"] = "SUBHEADLINE";
862
- CreativeElementCategory2["BODY_COPY"] = "BODY_COPY";
863
- CreativeElementCategory2["PRICE"] = "PRICE";
864
- CreativeElementCategory2["CTA"] = "CTA";
865
- CreativeElementCategory2["TERMS_CONDITIONS"] = "TERMS_CONDITIONS";
866
- CreativeElementCategory2["REVIEWS_TESTIMONIALS"] = "REVIEWS_TESTIMONIALS";
867
- CreativeElementCategory2["WARRANTY_INFO"] = "WARRANTY_INFO";
868
- CreativeElementCategory2["BADGE"] = "BADGE";
869
- CreativeElementCategory2["NEW_PRODUCT_LABEL"] = "NEW_PRODUCT_LABEL";
870
- CreativeElementCategory2["OTHER"] = "OTHER";
871
- return CreativeElementCategory2;
872
- })(CreativeElementCategory || {});
873
- var WORD_STYLE_TYPE = /* @__PURE__ */ ((WORD_STYLE_TYPE2) => {
874
- WORD_STYLE_TYPE2["WORD_STYLE"] = "WORD_STYLE";
875
- WORD_STYLE_TYPE2["MISSING_GLYPH"] = "MISSING_GLYPH";
876
- WORD_STYLE_TYPE2["VARIABLES"] = "VARIABLES";
877
- return WORD_STYLE_TYPE2;
878
- })(WORD_STYLE_TYPE || {});
879
- var TextAnimationType = /* @__PURE__ */ ((TextAnimationType2) => {
880
- TextAnimationType2["CHARACTER"] = "character";
881
- TextAnimationType2["WORD"] = "word";
882
- TextAnimationType2["LINE"] = "line";
883
- return TextAnimationType2;
884
- })(TextAnimationType || {});
885
- var AnimationSpecialCase = /* @__PURE__ */ ((AnimationSpecialCase2) => {
886
- AnimationSpecialCase2["TYPING_EFFECT"] = "typing-effect";
887
- AnimationSpecialCase2["NONE"] = "none";
888
- return AnimationSpecialCase2;
889
- })(AnimationSpecialCase || {});
890
-
891
- // src/types/capsule.ts
892
- var RULER_AXIS = {
893
- X: "x",
894
- Y: "y"
895
- };
896
-
897
- exports.AnimationSpecialCase = AnimationSpecialCase;
898
- exports.CANVAS_EDITOR_ELEMENT = CANVAS_EDITOR_ELEMENT;
899
- exports.CreativeElementCategory = CreativeElementCategory;
900
- exports.RULER_AXIS = RULER_AXIS;
901
- exports.TextAnimationType = TextAnimationType;
902
- exports.WORD_STYLE_TYPE = WORD_STYLE_TYPE;
903
- exports.adaptWordStyleFontSizes = adaptWordStyleFontSizes;
904
- exports.applyAdaptedAsOverrides = applyAdaptedAsOverrides;
905
- exports.buildNewCapsule = buildNewCapsule;
906
- exports.checkIfElementShouldBeSkewed = checkIfElementShouldBeSkewed;
907
- exports.findBestReferenceSize = findBestReferenceSize;
908
- exports.findClosestSizeObjectsWithMatches = findClosestSizeObjectsWithMatches;
909
- exports.findClosestSizeWithMatches = findClosestSizeWithMatches;
910
- exports.generateBaseLayoutForSize = generateBaseLayoutForSize;
911
- exports.getAdaptedObjectsJSON = getAdaptedObjectsJSON;
912
- exports.getAreaPercentageOfElementOnCanvasJSON = getAreaPercentageOfElementOnCanvasJSON;
913
- exports.getEuclideanDistanceBetweenSizes = getEuclideanDistanceBetweenSizes;
914
- exports.getNormalizedSizeValue = getNormalizedSizeValue;
915
- exports.getScaledBorderJSON = getScaledBorderJSON;
916
- exports.getValuesWithoutSkewingJSON = getValuesWithoutSkewingJSON;
917
- exports.isAudioJSON = isAudioJSON;
918
- exports.isCreativeBoxJSON = isCreativeBoxJSON;
919
- exports.isGroupJSON = isGroupJSON;
920
- exports.isImageJSON = isImageJSON;
921
- exports.isRoundedRectJSON = isRoundedRectJSON;
922
- exports.isSVGContainerJSON = isSVGContainerJSON;
923
- exports.isShapeJSON = isShapeJSON;
924
- exports.isTextJSON = isTextJSON;
925
- exports.resolveObjectsForSize = resolveObjectsForSize;
926
- exports.scaleAutoFitSizes = scaleAutoFitSizes;
927
- exports.scaleCornerRadius = scaleCornerRadius;
928
- exports.scalePadding = scalePadding;
929
- //# sourceMappingURL=index.js.map
930
- //# sourceMappingURL=index.js.map
1
+ 'use strict';var se=[1,1/0],de=90,me=.9,le=.1,W=20,pe=100,ue={stroke:"rgba(0, 0, 0, 1)",strokeWidth:0,strokeDashArray:[0,0]};var y=e=>{switch(e){case "square":return "720x720";case "landscape":return "1280x720";case "portrait":return "720x1280";default:return e}},Y=({x1:e,y1:t,x2:n,y2:r})=>{let a=n-e,d=r-t;return Math.sqrt(a*a+d*d)},Xe=({size1:e,size2:t})=>{let n=y(e),r=y(t),[a,d]=n.split("x").map(Number),[u,l]=r.split("x").map(Number);return Y({x1:a??0,y1:d??0,x2:u??0,y2:l??0})},ce=(e,t)=>{let[n,r]=y(t).split("x").map(Number),a=n/r,d=new Map;for(let o of e){let s=o.width/o.height;if(isNaN(s)||isNaN(a))continue;let p=Math.abs(a-s),i=Y({x1:n,y1:r,x2:o.width,y2:o.height});d.set(o.key,{aspectRatioDistance:p,euclideanDistance:i});}let u=Math.max(...Array.from(d.values()).map(o=>o.aspectRatioDistance)),l=Math.max(...Array.from(d.values()).map(o=>o.euclideanDistance)),m=[];for(let o of e){let s=d.get(o.key);if(!s){m.push({...o,matchPercentage:W});continue}let p=u===0?1:1-s.aspectRatioDistance/u,i=l===0?1:1-s.euclideanDistance/l,S=p*me+i*le,E=Math.round(Math.max(W,Math.min(pe,S*100)));m.push({...o,matchPercentage:E});}return m.sort((o,s)=>s.matchPercentage-o.matchPercentage),m},He=({availableSizes:e,adaptSize:t})=>{let n=e.map(s=>{let p=y(s),[i,S]=p.split("x").map(Number);return {key:s,width:i,height:S}}),r=ce(n,t),[a,d]=y(t).split("x").map(Number),u=a/d,l=e[0],m=Number.MAX_VALUE,o=Number.MAX_VALUE;for(let s of n){let p=s.width/s.height;if(isNaN(p)||isNaN(u))continue;let i=Math.abs(u-p),S=Y({x1:a,y1:d,x2:s.width,y2:s.height});(i<m||i===m&&S<o)&&(m=i,o=S,l=s.key);}return {closestSize:l,sortedMatches:r.reduce((s,{key:p,matchPercentage:i})=>(s[p]=i,s),{})}},Se=({availableSizes:e,adaptSize:t})=>{if(Object.keys(e).length===0)return [];let n=Object.entries(e).map(([a,d])=>({key:a,width:d.width,height:d.height}));return ce(n,t).map(a=>({_id:a.key,...e[a.key],matchPercentage:a.matchPercentage}))},X=(e,t)=>{let n=Object.keys(e);if(n.length===1)return n[0];try{return Se({availableSizes:e,adaptSize:t})[0]?._id||n[0]}catch(r){return console.warn("Error finding closest size, using first available:",r),n[0]}};var R=e=>e.dataType==="TEXT",J=e=>e.dataType==="IMAGE",v=e=>e.dataType==="SHAPE",A=e=>e?.type==="svg-container"&&e?.dataType==="SHAPE",I=e=>e?.type==="rounded-rect"&&e?.dataType==="SHAPE",w=e=>e?.dataType==="GROUP",z=e=>e?.dataType==="CREATIVE_BOX",H=e=>e?.dataType==="VIDEO",P=e=>e?.dataType==="AUDIO";var O=(e,t,n=0)=>{if(t in e){let r=e[t];return typeof r=="number"?r:n}return n},M=({element:e,canvasDimensions:t})=>{let n=typeof t.width=="number"?t.width:0,r=typeof t.height=="number"?t.height:0,a=("width"in e?e.width:1)*("scaleX"in e?e.scaleX:1),d=("height"in e?e.height:1)*("scaleY"in e?e.scaleY??1:1),u="top"in e?e.top:0,l="left"in e?e.left:0,m=l+a,o=u+d,s=n*r;if(s===0)return 0;let p=Math.min(m,n)-Math.max(l,0),i=Math.min(o,r)-Math.max(u,0),S=Math.max(p,0)*Math.max(i,0);return Math.round(S/s*100)},V=({areaPercentage:e,referenceLengths:t,type:n})=>{if(n==="GROUP")return false;if(e>de)return true;let r=Math.floor(t.left)<=0&&Math.floor(t.width)>=t.canvasWidth,a=Math.floor(t.top)<=0&&Math.floor(t.height)>=t.canvasHeight;return r||a},b=(e,t)=>({tl:(e?.tl||0)*t,tr:(e?.tr||0)*t,bl:(e?.bl||0)*t,br:(e?.br||0)*t}),U=(e,t)=>{let n=e??{top:0,right:0,bottom:0,left:0};return {...n,top:n.top?n.top*t:0,right:n.right?n.right*t:0,bottom:n.bottom?n.bottom*t:0,left:n.left?n.left*t:0}},h=({object:e,scalingRatio:t})=>{if(z(e)||w(e)||P(e))return {};if(!("border"in e)||!e?.border)return {};let n=e.border;return n.strokeWidth?{border:{...ue,...n,strokeWidth:n.strokeWidth*t}}:{}},k=({wordStyle:e,scalingRatio:t})=>!e||e.length===0?e:e.map(n=>{if(!n.data?.styles?.fontSize)return n;let r=n.data.styles.fontSizeUnit??"%",a=r==="px"?Math.round(n.data.styles.fontSize*t):n.data.styles.fontSize;return {...n,data:{...n.data,styles:{...n.data.styles,fontSize:a,fontSizeUnit:r}}}}),D=(e,t,n)=>e&&e.length===2?e.map(r=>Math.ceil((r??n)*t)):[...se],K=({closestSize:e,adaptSize:t,object:n})=>{let r=y(e),[a,d]=r.split("x").map(Number),[u,l]=t.split("x").map(Number),m=O(n,"top"),o=O(n,"left"),s=O(n,"scaleX",1),p=O(n,"scaleY",1),i=O(n,"width",1)*s,S=O(n,"height",1)*p,E=u/a,f=l/d,c=Math.min(E,f),g=Math.ceil(i*c),x=Math.ceil(S*c),$=Math.abs(o+i-a),q=Math.abs(m+S-d),Z=Math.abs(o),Q=Math.abs(m),N=1;if($<N||Z<N||q<N||Q<N){let T,C;if($<N)T=u-g;else if(Z<N)T=0;else {let L=o/a;T=Math.ceil(L*u);}if(q<N)C=l-x;else if(Q<N)C=0;else {let L=m/d;C=Math.ceil(L*l);}return {left:T,top:C,width:g/s,height:x/p}}let j=o+i/2,ee=m+S/2,F=o+i,G=m+S,B=a/2,Fe=d/2,te=Math.max(0,Math.min(F,B)-Math.max(o,0))*Math.max(0,Math.min(G,d)-Math.max(m,0)),ne=Math.max(0,Math.min(F,a)-Math.max(o,B))*Math.max(0,Math.min(G,d)-Math.max(m,0)),Ge=te+ne;if(Math.abs(te-ne)/Ge<.05){let T=j/a,C=ee/d,L=T*u,Ye=C*l;return {left:L-g/2,top:Ye-x/2,width:g,height:x}}let re=j>B,ie=ee>Fe,Be=re?F/a:o/a,We=ie?G/d:m/d,ae=Be*u,oe=We*l;return {left:re?ae-g:ae,top:ie?oe-x:oe,width:g,height:x}},ge=(e,t,n,r)=>({...e,left:t.left,top:t.top,width:t.width,height:t.height,wordSpacing:e.wordSpacing?e.wordSpacing*n:0,padding:U(e.padding,n),cornerRadius:b(e.cornerRadius,n),...h({object:e,scalingRatio:n}),autoFitSizes:D(e.autoFitSizes,n,r),fontSize:e.fontSize*n,wordStyle:k({wordStyle:e.wordStyle||[],scalingRatio:n})}),he=(e,t,n,r,a)=>({...e,left:t.left,top:t.top,width:t.width,height:t.height,imageScale:(e.imageScale??1)*n,imageLeft:(e.imageLeft??0)*r,imageTop:(e.imageTop??0)*a,cornerRadius:b(e.cornerRadius,n),...h({object:e,scalingRatio:n})}),fe=(e,t,n,r,a)=>({...e,left:t.left,top:t.top,width:t.width,height:t.height,imageScale:(e.imageScale??1)*n,imageLeft:(e.imageLeft??0)*r,imageTop:(e.imageTop??0)*a,...h({object:e,scalingRatio:n})}),Oe=(e,t,n)=>({...e,left:t.left,top:t.top,width:t.width,height:t.height,cornerRadius:b(e.cornerRadius,n),...h({object:e,scalingRatio:n})}),be=(e,t,n)=>({...e,left:t.left,top:t.top,scaleX:(e.scaleX??1)*n,scaleY:(e.scaleY??1)*n,...h({object:e,scalingRatio:n})}),Ne=(e,t,n,r,a)=>({...e,left:e.left*t,top:e.top*n,width:e.width*t,height:e.height*n,autoFitSizes:D(e.autoFitSizes,r,a),cornerRadius:b(e.cornerRadius,r),...h({object:e,scalingRatio:r}),fontSize:e.fontSize*r,wordStyle:k({wordStyle:e.wordStyle||[],scalingRatio:r})}),ye=(e,t,n,r)=>({...e,left:e.left*t,top:e.top*n,width:e.width*t,height:e.height*n,imageScale:(e.imageScale??1)*r,imageLeft:(e.imageLeft??0)*t,imageTop:(e.imageTop??0)*n,cornerRadius:b(e.cornerRadius,r),...h({object:e,scalingRatio:r})}),Ee=(e,t,n,r)=>({...e,left:e.left*t,top:e.top*n,width:e.width*t,height:e.height*n,imageScale:(e.imageScale??1)*r,imageLeft:(e.imageLeft??0)*t,imageTop:(e.imageTop??0)*n,...h({object:e,scalingRatio:r})}),xe=(e,t,n,r)=>({...e,left:e.left*t,top:e.top*n,width:e.width*t,height:e.height*n,cornerRadius:b(e.cornerRadius,r),...h({object:e,scalingRatio:r})}),Te=(e,t,n,r)=>({...e,left:e.left*t,top:e.top*n,scaleX:(e.scaleX??1)*t,scaleY:(e.scaleY??1)*n,...h({object:e,scalingRatio:r})}),Ce=(e,t,n)=>({...e,left:e.left*t,top:e.top*t,width:e.width*t,height:e.height*t,wordSpacing:e.wordSpacing?e.wordSpacing*t:0,padding:U(e.padding,t),cornerRadius:b(e.cornerRadius,t),...h({object:e,scalingRatio:t}),autoFitSizes:D(e.autoFitSizes,t,n),fontSize:e.fontSize*t,wordStyle:k({wordStyle:e.wordStyle||[],scalingRatio:t})}),Re=(e,t)=>({...e,left:e.left*t,top:e.top*t,width:e.width*t,height:e.height*t,imageScale:(e.imageScale??1)*t,imageLeft:(e.imageLeft??0)*t,imageTop:(e.imageTop??0)*t,cornerRadius:b(e.cornerRadius,t),...h({object:e,scalingRatio:t})}),Je=(e,t)=>({...e,left:e.left*t,top:e.top*t,width:e.width*t,height:e.height*t,imageScale:(e.imageScale??1)*t,imageLeft:(e.imageLeft??0)*t,imageTop:(e.imageTop??0)*t,...h({object:e,scalingRatio:t})}),ve=(e,t)=>({...e,left:e.left*t,top:e.top*t,width:e.width*t,height:e.height*t,cornerRadius:b(e.cornerRadius,t),...h({object:e,scalingRatio:t})}),Ae=(e,t)=>({...e,left:O(e,"left")*t,top:O(e,"top")*t,scaleX:O(e,"scaleX",1)*t,scaleY:O(e,"scaleY",1)*t,...h({object:e,scalingRatio:t})});var Ie=({adaptSize:e,objects:t,closestSize:n})=>{let[r,a]=e.split("x").map(Number),[d,u]=n.split("x").map(Number),l=r/d,m=a/u,o=Math.min(l,m),s={};for(let p of Object.keys(t)){let i=t[p];if(i.dataType==="CREATIVE_BOX"){s[p]={...i,height:a,width:r};continue}if(i.dataType==="AUDIO"){s[p]=i;continue}M({element:i,canvasDimensions:{width:d,height:u}});let S=M({element:i,canvasDimensions:{width:d,height:u}});if(!V({areaPercentage:S,referenceLengths:{left:i.left??0,top:i.top??0,width:i.width??1,height:i.height??1,canvasWidth:d,canvasHeight:u},type:i.dataType})){let f=K({closestSize:n,adaptSize:e,object:i});if(f.left===0&&f.height===0&&f.top===0&&f.width===0)throw new Error("Invalid values");if("groupPath"in i&&i.groupPath)continue;if(R(i)){s[p]=ge(i,f,o,u);continue}if(J(i)){s[p]=he(i,f,o,l,m);continue}if(v(i)){if(A(i)){s[p]=fe(i,f,o,l,m);continue}if(I(i)){s[p]=Oe(i,f,o);continue}s[p]=be(i,f,o);continue}if(w(i)){s[p]={...i,left:f.left,top:f.top,width:f.width,height:f.height};for(let c of i.objects){let g=t[c];if(g){if(R(g)){s[c]=Ce(g,o,u);continue}if(J(g)){s[c]=Re(g,o);continue}if(v(g)){if(A(g)){s[c]=Je(g,o);continue}if(I(g)){s[c]=ve(g,o);continue}s[c]=Ae(g,o);continue}}}continue}}if(R(i)){s[p]=Ne(i,l,m,o,u);continue}if(J(i)){s[p]=ye(i,l,m,o);continue}if(v(i)){if(A(i)){s[p]=Ee(i,l,m,o);continue}if(I(i)){s[p]=xe(i,l,m,o);continue}s[p]=Te(i,l,m,o);continue}s[p]={...i,left:O(i,"left")*l,top:O(i,"top")*m,width:O(i,"width",1)*l,height:O(i,"height",1)*m,...h({object:i,scalingRatio:o})};}return s},we=(e,t)=>{let n={};for(let[r,a]of Object.entries(e)){let d=a.overrides?.[t]||{},{overrides:u,zIndex:l,...m}=a;n[r]={...m,...d};}return n},ze=(e,t,n)=>{let r=JSON.parse(JSON.stringify(e));for(let[a,d]of Object.entries(t)){if(!r[a])continue;let u=r[a].overrides||{};r[a].overrides={...u,[n]:{...d,zIndex:r[a].overrides?.[n]?.zIndex??r[a].zIndex??0}};}return r},_=["left","top","width","height","angle","visible"],Ve=["fontSize","autoFitSizes","padding","wordSpacing"],Ue=["imageScale","imageLeft","imageTop","objectFit","imageOriginX","imageOriginY"],Ke=["imageScale","imageLeft","imageTop","scaleX","scaleY","objectFit","imageOriginX","imageOriginY"],$e=["left","top","angle","visible","scaleX","scaleY"],qe=e=>z(e)||P(e)?[]:R(e)?[..._,...Ve]:J(e)||H(e)?[..._,...Ue]:v(e)?A(e)?[..._,...Ke]:I(e)?_:$e:(w(e),_),Pe=(e,t)=>{if(z(e)||P(e))return e;let n=qe(e),r={...e},a=t;for(let d of n)a[d]!==void 0&&(r[d]=a[d]);return r},Ze=(e,t)=>{let n={};for(let[r,a]of Object.entries(e))t[r]?n[r]=Pe(a,t[r]):n[r]=a;return n},_e=({originalCapsule:e,updatedObjects:t,sizeId:n,referenceCreativeId:r,sizeToGenerate:a,sizeName:d,sizeCategory:u,videoLength:l})=>{let[m,o]=a.split("x").map(Number),s=JSON.parse(JSON.stringify(e.canvasData));s.variant.objects=t,s.variant.sizes[n]={width:m,height:o,id:n,displayName:d||a,rulers:[],...l!==void 0&&{videoLength:l}};let p=e.creativesOrder,i=p&&p.length>0?[...p,n]:[r,n],S={name:d||a,width:m,height:o,active:true,thumbnail:"",creativeUrl:"",...u&&{category:u}};return {...e,canvasData:s,savedCustomDimensions:{...e.savedCustomDimensions,[n]:S},newAddedSizes:{...e.newAddedSizes,[n]:S},creativesOrder:i}},Qe=({originalCapsule:e,capsuleId:t,creativeId:n,sizeId:r,sizeToGenerate:a,sizeName:d,sizeCategory:u})=>{let l=e.canvasData.variant?.sizes;if(!l||Object.keys(l).length===0)throw new Error(`No sizes available in capsule: ${t}`);let m;n&&l[n]?(m=n,console.log(`[BaseLayoutAdapter] Using provided reference size: ${m}`)):(m=X(l,a),console.log(`[BaseLayoutAdapter] Found best reference size: ${m} for target: ${a}`),n&&!l[n]&&console.warn(`[BaseLayoutAdapter] Provided creativeId ${n} not found, using ${m}`));let o=l[m],s=`${o.width}x${o.height}`,p=e.canvasData.variant.objects,i=we(p,m),S=Ie({adaptSize:a,objects:i,closestSize:s}),E=ze(p,S,r);return _e({originalCapsule:e,updatedObjects:E,sizeId:r,referenceCreativeId:m,sizeToGenerate:a,sizeName:d,sizeCategory:u,videoLength:o?.videoLength})};var je={TEXT:"TEXT",SHAPE:"SHAPE",IMAGE:"IMAGE",GROUP:"GROUP",CREATIVE_BOX:"CREATIVE_BOX",VIDEO:"VIDEO",AUDIO:"AUDIO",CANVAS_MASK:"CANVAS_MASK"},Le=(c=>(c.HERO_IMAGE="HERO_IMAGE",c.PRODUCT_IMAGE="PRODUCT_IMAGE",c.BACKGROUND="BACKGROUND",c.LOGO="LOGO",c.ICON="ICON",c.HEADLINE="HEADLINE",c.SUBHEADLINE="SUBHEADLINE",c.BODY_COPY="BODY_COPY",c.PRICE="PRICE",c.CTA="CTA",c.TERMS_CONDITIONS="TERMS_CONDITIONS",c.REVIEWS_TESTIMONIALS="REVIEWS_TESTIMONIALS",c.WARRANTY_INFO="WARRANTY_INFO",c.BADGE="BADGE",c.NEW_PRODUCT_LABEL="NEW_PRODUCT_LABEL",c.OTHER="OTHER",c))(Le||{}),Me=(r=>(r.WORD_STYLE="WORD_STYLE",r.MISSING_GLYPH="MISSING_GLYPH",r.VARIABLES="VARIABLES",r))(Me||{}),ke=(r=>(r.CHARACTER="character",r.WORD="word",r.LINE="line",r))(ke||{}),De=(n=>(n.TYPING_EFFECT="typing-effect",n.NONE="none",n))(De||{});var et={X:"x",Y:"y"};exports.AnimationSpecialCase=De;exports.CANVAS_EDITOR_ELEMENT=je;exports.CreativeElementCategory=Le;exports.RULER_AXIS=et;exports.TextAnimationType=ke;exports.WORD_STYLE_TYPE=Me;exports.adaptWordStyleFontSizes=k;exports.applyAdaptedAsOverrides=ze;exports.buildNewCapsule=_e;exports.checkIfElementShouldBeSkewed=V;exports.findBestReferenceSize=X;exports.findClosestSizeObjectsWithMatches=Se;exports.findClosestSizeWithMatches=He;exports.generateBaseLayoutForSize=Qe;exports.getAdaptedObjectsJSON=Ie;exports.getAreaPercentageOfElementOnCanvasJSON=M;exports.getEuclideanDistanceBetweenSizes=Xe;exports.getNormalizedSizeValue=y;exports.getScaledBorderJSON=h;exports.getValuesWithoutSkewingJSON=K;exports.isAudioJSON=P;exports.isCreativeBoxJSON=z;exports.isGroupJSON=w;exports.isImageJSON=J;exports.isRoundedRectJSON=I;exports.isSVGContainerJSON=A;exports.isShapeJSON=v;exports.isTextJSON=R;exports.isVideoJSON=H;exports.mergeLayoutFromReference=Pe;exports.mergeLayoutFromReferenceObjects=Ze;exports.resolveObjectsForSize=we;exports.scaleAutoFitSizes=D;exports.scaleCornerRadius=b;exports.scalePadding=U;