zuljaman-banner-components 1.0.6 → 1.0.8
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/components/BannerRenderer.d.ts +48 -0
- package/dist/components/BannerRenderer.d.ts.map +1 -0
- package/dist/components/BannerRenderer.js +449 -0
- package/dist/components/BannerVisor.d.ts.map +1 -1
- package/dist/components/BannerVisor.js +132 -18
- package/dist/components/index.d.ts +1 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +4 -2
- package/dist/components/shared/DraggableElement.d.ts +31 -0
- package/dist/components/shared/DraggableElement.d.ts.map +1 -0
- package/dist/components/shared/DraggableElement.js +398 -0
- package/dist/components/shared/index.d.ts +7 -0
- package/dist/components/shared/index.d.ts.map +1 -0
- package/dist/components/shared/index.js +9 -0
- package/dist/components/styles/Style1/substyleConfig.d.ts +20 -0
- package/dist/components/styles/Style1/substyleConfig.d.ts.map +1 -0
- package/dist/components/styles/Style1/substyleConfig.js +105 -0
- package/dist/components/styles/Style2/substyleConfig.d.ts +20 -0
- package/dist/components/styles/Style2/substyleConfig.d.ts.map +1 -0
- package/dist/components/styles/Style2/substyleConfig.js +133 -0
- package/dist/components/styles/Style3/substyleConfig.d.ts +20 -0
- package/dist/components/styles/Style3/substyleConfig.d.ts.map +1 -0
- package/dist/components/styles/Style3/substyleConfig.js +91 -0
- package/dist/components/styles/Style4/substyleConfig.d.ts +20 -0
- package/dist/components/styles/Style4/substyleConfig.d.ts.map +1 -0
- package/dist/components/styles/Style4/substyleConfig.js +112 -0
- package/dist/components/styles/types/substyleTypes.d.ts +68 -0
- package/dist/components/styles/types/substyleTypes.d.ts.map +1 -0
- package/dist/components/styles/types/substyleTypes.js +6 -0
- package/dist/components/styles/utils/calculations.d.ts +47 -0
- package/dist/components/styles/utils/calculations.d.ts.map +1 -0
- package/dist/components/styles/utils/calculations.js +69 -0
- package/dist/components/styles/utils/defaultsUtils.d.ts +54 -0
- package/dist/components/styles/utils/defaultsUtils.d.ts.map +1 -0
- package/dist/components/styles/utils/defaultsUtils.js +83 -0
- package/dist/components/styles/utils/fontSizeUtils.d.ts +32 -0
- package/dist/components/styles/utils/fontSizeUtils.d.ts.map +1 -0
- package/dist/components/styles/utils/fontSizeUtils.js +52 -0
- package/dist/components/styles/utils/positioningUtils.d.ts +38 -0
- package/dist/components/styles/utils/positioningUtils.d.ts.map +1 -0
- package/dist/components/styles/utils/positioningUtils.js +79 -0
- package/dist/components/styles/utils/substyleUtils.d.ts +14 -0
- package/dist/components/styles/utils/substyleUtils.d.ts.map +1 -0
- package/dist/components/styles/utils/substyleUtils.js +18 -0
- package/dist/components/styles/utils/transformUtils.d.ts +36 -0
- package/dist/components/styles/utils/transformUtils.d.ts.map +1 -0
- package/dist/components/styles/utils/transformUtils.js +53 -0
- package/dist/constants/characterLimits.d.ts +97 -0
- package/dist/constants/characterLimits.d.ts.map +1 -0
- package/dist/constants/characterLimits.js +144 -0
- package/dist/constants/defaults.d.ts +19 -0
- package/dist/constants/defaults.d.ts.map +1 -0
- package/dist/constants/defaults.js +27 -0
- package/dist/constants/index.d.ts +2 -0
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/index.js +2 -0
- package/dist/constants/styleConfigs.d.ts.map +1 -1
- package/dist/constants/styleConfigs.js +13 -7
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/styleConfig.d.ts +40 -0
- package/dist/styleConfig.d.ts.map +1 -0
- package/dist/styleConfig.js +115 -0
- package/dist/styles/shadowUtils.js +4 -4
- package/dist/types.d.ts +149 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +10 -10
- package/dist/components/Style1/BannerStyle1.d.ts +0 -19
- package/dist/components/Style1/BannerStyle1.d.ts.map +0 -1
- package/dist/components/Style1/BannerStyle1.js +0 -27
- package/dist/components/Style1/substyles/BannerSubstyle1.d.ts +0 -12
- package/dist/components/Style1/substyles/BannerSubstyle1.d.ts.map +0 -1
- package/dist/components/Style1/substyles/BannerSubstyle1.js +0 -52
- package/dist/components/Style1/substyles/BannerSubstyle2.d.ts +0 -12
- package/dist/components/Style1/substyles/BannerSubstyle2.d.ts.map +0 -1
- package/dist/components/Style1/substyles/BannerSubstyle2.js +0 -52
- package/dist/components/Style1/substyles/BannerSubstyle3.d.ts +0 -12
- package/dist/components/Style1/substyles/BannerSubstyle3.d.ts.map +0 -1
- package/dist/components/Style1/substyles/BannerSubstyle3.js +0 -61
- package/dist/components/Style1/substyles/index.d.ts +0 -7
- package/dist/components/Style1/substyles/index.d.ts.map +0 -1
- package/dist/components/Style1/substyles/index.js +0 -22
- package/dist/components/Style2/BannerStyle2.d.ts +0 -19
- package/dist/components/Style2/BannerStyle2.d.ts.map +0 -1
- package/dist/components/Style2/BannerStyle2.js +0 -32
- package/dist/components/Style2/substyles/BannerSubstyle1.d.ts +0 -12
- package/dist/components/Style2/substyles/BannerSubstyle1.d.ts.map +0 -1
- package/dist/components/Style2/substyles/BannerSubstyle1.js +0 -35
- package/dist/components/Style2/substyles/BannerSubstyle2.d.ts +0 -12
- package/dist/components/Style2/substyles/BannerSubstyle2.d.ts.map +0 -1
- package/dist/components/Style2/substyles/BannerSubstyle2.js +0 -35
- package/dist/components/Style2/substyles/BannerSubstyle3.d.ts +0 -12
- package/dist/components/Style2/substyles/BannerSubstyle3.d.ts.map +0 -1
- package/dist/components/Style2/substyles/BannerSubstyle3.js +0 -35
- package/dist/components/Style2/substyles/index.d.ts +0 -7
- package/dist/components/Style2/substyles/index.d.ts.map +0 -1
- package/dist/components/Style2/substyles/index.js +0 -22
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BannerRenderer component - Generic platform-agnostic banner renderer
|
|
3
|
+
* Unified component that handles all banner styles based on configuration
|
|
4
|
+
*/
|
|
5
|
+
import React from "react";
|
|
6
|
+
import type { ImageProps, CopyConfig } from "../types";
|
|
7
|
+
interface BannerRendererProps {
|
|
8
|
+
bannerStyle: number;
|
|
9
|
+
copies?: CopyConfig[];
|
|
10
|
+
bannerSubstyle?: number;
|
|
11
|
+
logoUrl?: string;
|
|
12
|
+
sizeMultiplier?: number;
|
|
13
|
+
logoSizeMultiplier?: number;
|
|
14
|
+
overlayIntensityMultiplier?: number;
|
|
15
|
+
shadowIntensityMultiplier?: number;
|
|
16
|
+
backgroundImageUrl?: string;
|
|
17
|
+
postType?: string;
|
|
18
|
+
ImageComponent: React.ComponentType<ImageProps>;
|
|
19
|
+
logoTranslateX?: number;
|
|
20
|
+
logoTranslateY?: number;
|
|
21
|
+
logoRotation?: number;
|
|
22
|
+
logoWidth?: number;
|
|
23
|
+
textShadowEnabled?: boolean;
|
|
24
|
+
textShadowSize?: number;
|
|
25
|
+
textShadowIntensity?: number;
|
|
26
|
+
logoShadowEnabled?: boolean;
|
|
27
|
+
logoShadowSize?: number;
|
|
28
|
+
logoShadowIntensity?: number;
|
|
29
|
+
noiseEnabled?: boolean;
|
|
30
|
+
noiseIntensity?: number;
|
|
31
|
+
fontFamily?: string;
|
|
32
|
+
draggableMode?: boolean;
|
|
33
|
+
onLogoPositionChange?: (position: {
|
|
34
|
+
x: number;
|
|
35
|
+
y: number;
|
|
36
|
+
}) => void;
|
|
37
|
+
onLogoRotationChange?: (rotation: number) => void;
|
|
38
|
+
onLogoWidthChange?: (width: number) => void;
|
|
39
|
+
onCopyPositionChange?: (copyIndex: number, position: {
|
|
40
|
+
x: number;
|
|
41
|
+
y: number;
|
|
42
|
+
}) => void;
|
|
43
|
+
onCopyRotationChange?: (copyIndex: number, rotation: number) => void;
|
|
44
|
+
onCopyWidthChange?: (copyIndex: number, width: number) => void;
|
|
45
|
+
}
|
|
46
|
+
export declare const BannerRenderer: React.FC<BannerRendererProps>;
|
|
47
|
+
export {};
|
|
48
|
+
//# sourceMappingURL=BannerRenderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BannerRenderer.d.ts","sourceRoot":"","sources":["../../src/components/BannerRenderer.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAgE,MAAM,OAAO,CAAC;AAGrF,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAUvD,UAAU,mBAAmB;IAE3B,WAAW,EAAE,MAAM,CAAC;IAGpB,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IAEtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IAGhD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAG7B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IAGxB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,oBAAoB,CAAC,EAAE,CAAC,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACpE,oBAAoB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAG5C,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACvF,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAChE;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CA4lBxD,CAAC"}
|
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* BannerRenderer component - Generic platform-agnostic banner renderer
|
|
4
|
+
* Unified component that handles all banner styles based on configuration
|
|
5
|
+
*/
|
|
6
|
+
"use client";
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
41
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
42
|
+
};
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.BannerRenderer = void 0;
|
|
45
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
46
|
+
const react_1 = __importStar(require("react"));
|
|
47
|
+
const clsx_1 = __importDefault(require("clsx"));
|
|
48
|
+
const shadowUtils_1 = require("../styles/shadowUtils");
|
|
49
|
+
const shared_1 = require("./shared");
|
|
50
|
+
const styleConfig_1 = require("../styleConfig");
|
|
51
|
+
const defaults_1 = require("../constants/defaults");
|
|
52
|
+
const substyleConfig_1 = require("./styles/Style1/substyleConfig");
|
|
53
|
+
const substyleConfig_2 = require("./styles/Style2/substyleConfig");
|
|
54
|
+
const substyleConfig_3 = require("./styles/Style3/substyleConfig");
|
|
55
|
+
const substyleConfig_4 = require("./styles/Style4/substyleConfig");
|
|
56
|
+
const positioningUtils_1 = require("./styles/utils/positioningUtils");
|
|
57
|
+
const BannerRenderer = ({ bannerStyle, copies = [], bannerSubstyle = 1, logoUrl, sizeMultiplier = 1.0, logoSizeMultiplier = 1.0, overlayIntensityMultiplier: _overlayIntensityMultiplier = 1.0, shadowIntensityMultiplier = 1.0, backgroundImageUrl, postType, ImageComponent, logoTranslateX = 0, logoTranslateY = 0, draggableMode = false, onLogoPositionChange, logoRotation = 0, onLogoRotationChange, logoWidth, onLogoWidthChange, onCopyPositionChange, onCopyRotationChange, onCopyWidthChange, textShadowEnabled, textShadowSize, textShadowIntensity, logoShadowEnabled, logoShadowSize, logoShadowIntensity, noiseEnabled, noiseIntensity = 1.0, fontFamily, }) => {
|
|
58
|
+
const [selectedElement, setSelectedElement] = (0, react_1.useState)(null);
|
|
59
|
+
// Auto-positioning state and refs
|
|
60
|
+
const [autoOffsets, setAutoOffsets] = (0, react_1.useState)({});
|
|
61
|
+
const [recalcTrigger, setRecalcTrigger] = (0, react_1.useState)(0);
|
|
62
|
+
const logoRef = (0, react_1.useRef)(null);
|
|
63
|
+
const copyRefs = (0, react_1.useRef)([]);
|
|
64
|
+
// Get substyle configuration based on bannerStyle
|
|
65
|
+
const config = (0, react_1.useMemo)(() => {
|
|
66
|
+
switch (bannerStyle) {
|
|
67
|
+
case 2:
|
|
68
|
+
return (0, substyleConfig_2.getSubstyleConfig)(bannerSubstyle);
|
|
69
|
+
case 3:
|
|
70
|
+
return (0, substyleConfig_3.getSubstyleConfig)(bannerSubstyle);
|
|
71
|
+
case 4:
|
|
72
|
+
return (0, substyleConfig_4.getSubstyleConfig)(bannerSubstyle);
|
|
73
|
+
case 1:
|
|
74
|
+
default:
|
|
75
|
+
return (0, substyleConfig_1.getSubstyleConfig)(bannerSubstyle);
|
|
76
|
+
}
|
|
77
|
+
}, [bannerStyle, bannerSubstyle]);
|
|
78
|
+
// Get style configuration
|
|
79
|
+
const styleConfig = (0, styleConfig_1.getStyleConfig)(bannerStyle);
|
|
80
|
+
// Trigger auto-positioning recalculation when style or substyle changes
|
|
81
|
+
react_1.default.useEffect(() => {
|
|
82
|
+
setRecalcTrigger(prev => prev + 1);
|
|
83
|
+
}, [bannerStyle, bannerSubstyle]);
|
|
84
|
+
// Calculate font sizes for copies based on their styleSlot and fontSize multiplier
|
|
85
|
+
const fontSizes = (0, react_1.useMemo)(() => {
|
|
86
|
+
const baseSizeRem = defaults_1.DEFAULT_BASE_FONT_SIZE_REM;
|
|
87
|
+
return {
|
|
88
|
+
fontSize_01: `${baseSizeRem * (config.fontSize.copy1 || 1.0)}rem`,
|
|
89
|
+
fontSize_02: `${baseSizeRem * (config.fontSize.copy2 || 0.65)}rem`,
|
|
90
|
+
};
|
|
91
|
+
}, [config.fontSize]);
|
|
92
|
+
// Convert font weight string to CSS value
|
|
93
|
+
const getFontWeight = (weight) => {
|
|
94
|
+
switch (weight) {
|
|
95
|
+
case 'thin': return '300';
|
|
96
|
+
case 'normal': return '400';
|
|
97
|
+
case 'bold': return '700';
|
|
98
|
+
default: return '400';
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
// Reset auto-offsets when config changes (e.g., when changing substyle)
|
|
102
|
+
(0, react_1.useEffect)(() => {
|
|
103
|
+
setAutoOffsets({});
|
|
104
|
+
}, [config]);
|
|
105
|
+
// Memoize copies without rotation to prevent auto-positioning recalc on rotation changes
|
|
106
|
+
const copiesWithoutRotation = (0, react_1.useMemo)(() => {
|
|
107
|
+
return copies.map(copy => ({
|
|
108
|
+
text: copy.text,
|
|
109
|
+
styleSlot: copy.styleSlot,
|
|
110
|
+
translateX: copy.translateX,
|
|
111
|
+
translateY: copy.translateY,
|
|
112
|
+
width: copy.width,
|
|
113
|
+
// Exclude rotation from memoization
|
|
114
|
+
}));
|
|
115
|
+
}, [copies.map(c => `${c.text}-${c.styleSlot}-${c.translateX || 0}-${c.translateY || 0}-${c.width || 'auto'}`).join(',')]);
|
|
116
|
+
// Auto-positioning calculation
|
|
117
|
+
(0, react_1.useLayoutEffect)(() => {
|
|
118
|
+
// Only calculate if auto-positioning is enabled
|
|
119
|
+
if (!config.autoPositioning || !config.autoPositioningConfig) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const { anchorElement, targetElement } = config.autoPositioningConfig;
|
|
123
|
+
console.log('🎯 AUTO-POSITION CALC:', {
|
|
124
|
+
anchorElement,
|
|
125
|
+
targetElement,
|
|
126
|
+
direction: config.autoPositioningConfig.direction,
|
|
127
|
+
gapRem: config.gapRem,
|
|
128
|
+
});
|
|
129
|
+
// Get anchor element ref
|
|
130
|
+
let anchorRef = null;
|
|
131
|
+
if (anchorElement === 'logo') {
|
|
132
|
+
anchorRef = logoRef.current;
|
|
133
|
+
console.log('📍 Logo anchor:', {
|
|
134
|
+
exists: !!anchorRef,
|
|
135
|
+
height: anchorRef === null || anchorRef === void 0 ? void 0 : anchorRef.getBoundingClientRect().height,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
else if (anchorElement === 'copy1') {
|
|
139
|
+
// Find copy with styleSlot 0 (copy1)
|
|
140
|
+
const copy1Index = copies.findIndex(c => c.styleSlot === 0);
|
|
141
|
+
if (copy1Index !== -1) {
|
|
142
|
+
anchorRef = copyRefs.current[copy1Index];
|
|
143
|
+
}
|
|
144
|
+
console.log('📍 Copy1 anchor:', {
|
|
145
|
+
exists: !!anchorRef,
|
|
146
|
+
height: anchorRef === null || anchorRef === void 0 ? void 0 : anchorRef.getBoundingClientRect().height,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
else if (anchorElement === 'copy2') {
|
|
150
|
+
// Find copy with styleSlot 1 (copy2)
|
|
151
|
+
const copy2Index = copies.findIndex(c => c.styleSlot === 1);
|
|
152
|
+
if (copy2Index !== -1) {
|
|
153
|
+
anchorRef = copyRefs.current[copy2Index];
|
|
154
|
+
}
|
|
155
|
+
console.log('📍 Copy2 anchor:', {
|
|
156
|
+
exists: !!anchorRef,
|
|
157
|
+
height: anchorRef === null || anchorRef === void 0 ? void 0 : anchorRef.getBoundingClientRect().height,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
// If anchor element doesn't exist, can't calculate
|
|
161
|
+
if (!anchorRef) {
|
|
162
|
+
console.log('❌ NO ANCHOR REF - Skipping calculation');
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
// Get target element ref
|
|
166
|
+
let targetRef = null;
|
|
167
|
+
if (targetElement === 'copy1') {
|
|
168
|
+
const copy1Index = copies.findIndex(c => c.styleSlot === 0);
|
|
169
|
+
if (copy1Index !== -1) {
|
|
170
|
+
targetRef = copyRefs.current[copy1Index];
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else if (targetElement === 'copy2') {
|
|
174
|
+
const copy2Index = copies.findIndex(c => c.styleSlot === 1);
|
|
175
|
+
if (copy2Index !== -1) {
|
|
176
|
+
targetRef = copyRefs.current[copy2Index];
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// If target element doesn't exist, can't calculate
|
|
180
|
+
if (!targetRef) {
|
|
181
|
+
console.log('❌ NO TARGET REF - Skipping calculation');
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
// Measure anchor and target heights
|
|
185
|
+
const anchorHeight = anchorRef.getBoundingClientRect().height / sizeMultiplier;
|
|
186
|
+
const targetHeight = targetRef.getBoundingClientRect().height / sizeMultiplier;
|
|
187
|
+
// Determine if anchor has centerOrigin (logo doesn't, copies do)
|
|
188
|
+
const anchorHasCenterOrigin = anchorElement !== 'logo';
|
|
189
|
+
console.log('📏 Heights:', { anchorHeight, targetHeight, anchorHasCenterOrigin });
|
|
190
|
+
// Calculate offset
|
|
191
|
+
const offset = (0, positioningUtils_1.calculateAutoPositionOffset)(config, config.autoPositioningConfig, anchorHeight, targetHeight, anchorHasCenterOrigin);
|
|
192
|
+
console.log('✨ Calculated offset:', offset);
|
|
193
|
+
// Find target styleSlot
|
|
194
|
+
let targetStyleSlot;
|
|
195
|
+
if (targetElement === 'copy1') {
|
|
196
|
+
targetStyleSlot = 0;
|
|
197
|
+
}
|
|
198
|
+
else if (targetElement === 'copy2') {
|
|
199
|
+
targetStyleSlot = 1;
|
|
200
|
+
}
|
|
201
|
+
console.log('🎪 Target styleSlot:', targetStyleSlot);
|
|
202
|
+
// Update offsets only if changed
|
|
203
|
+
if (targetStyleSlot !== undefined) {
|
|
204
|
+
setAutoOffsets(prev => {
|
|
205
|
+
// Only update if offset has changed significantly (to prevent infinite loops from floating point precision)
|
|
206
|
+
const prevOffset = prev[targetStyleSlot] || 0;
|
|
207
|
+
const EPSILON = 0.1; // 0.1px tolerance
|
|
208
|
+
console.log('🔄 Offset comparison:', { prevOffset, newOffset: offset, willUpdate: Math.abs(prevOffset - offset) > EPSILON });
|
|
209
|
+
if (Math.abs(prevOffset - offset) > EPSILON) {
|
|
210
|
+
const newOffsets = {
|
|
211
|
+
...prev,
|
|
212
|
+
[targetStyleSlot]: offset,
|
|
213
|
+
};
|
|
214
|
+
console.log('✅ UPDATING OFFSETS:', newOffsets);
|
|
215
|
+
return newOffsets;
|
|
216
|
+
}
|
|
217
|
+
console.log('⏭️ SKIPPING - no significant change');
|
|
218
|
+
return prev; // No significant change, return same object to prevent re-render
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}, [config, sizeMultiplier, recalcTrigger, copiesWithoutRotation]);
|
|
222
|
+
// Rotation snap function - snaps to 0°, 90°, 180°, 270°
|
|
223
|
+
const handleRotationSnap = react_1.default.useCallback((angle) => {
|
|
224
|
+
const snapAngles = [0, 90, 180, 270, -90, -180, -270];
|
|
225
|
+
const snapThreshold = 3; // degrees
|
|
226
|
+
// Normalize angle to -180 to 180 range
|
|
227
|
+
let normalized = angle % 360;
|
|
228
|
+
if (normalized > 180)
|
|
229
|
+
normalized -= 360;
|
|
230
|
+
if (normalized < -180)
|
|
231
|
+
normalized += 360;
|
|
232
|
+
// Check if close to any snap angle
|
|
233
|
+
for (const snapAngle of snapAngles) {
|
|
234
|
+
if (Math.abs(normalized - snapAngle) < snapThreshold) {
|
|
235
|
+
return snapAngle;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return normalized;
|
|
239
|
+
}, []);
|
|
240
|
+
// Shadow calculations using style configuration
|
|
241
|
+
const { shadowStyle, logoShadowStyle } = (0, react_1.useMemo)(() => {
|
|
242
|
+
var _a, _b;
|
|
243
|
+
// Get shadow defaults from style config (or use fallback values)
|
|
244
|
+
const textShadowConfig = ((_a = styleConfig.shadows) === null || _a === void 0 ? void 0 : _a.textShadow) || {
|
|
245
|
+
enabled: true,
|
|
246
|
+
size: 70,
|
|
247
|
+
intensity: 0.85,
|
|
248
|
+
direction: 'bottom',
|
|
249
|
+
};
|
|
250
|
+
const logoShadowConfig = ((_b = styleConfig.shadows) === null || _b === void 0 ? void 0 : _b.logoShadow) || {
|
|
251
|
+
enabled: true,
|
|
252
|
+
size: 150,
|
|
253
|
+
intensity: 0.375,
|
|
254
|
+
direction: 'top-left',
|
|
255
|
+
};
|
|
256
|
+
// Use prop overrides if provided, otherwise use config values
|
|
257
|
+
const effectiveTextShadowEnabled = textShadowEnabled !== null && textShadowEnabled !== void 0 ? textShadowEnabled : textShadowConfig.enabled;
|
|
258
|
+
const effectiveTextShadowSize = textShadowSize !== null && textShadowSize !== void 0 ? textShadowSize : textShadowConfig.size;
|
|
259
|
+
const effectiveTextShadowIntensity = textShadowIntensity !== null && textShadowIntensity !== void 0 ? textShadowIntensity : textShadowConfig.intensity;
|
|
260
|
+
const effectiveLogoShadowEnabled = logoShadowEnabled !== null && logoShadowEnabled !== void 0 ? logoShadowEnabled : logoShadowConfig.enabled;
|
|
261
|
+
const effectiveLogoShadowSize = logoShadowSize !== null && logoShadowSize !== void 0 ? logoShadowSize : logoShadowConfig.size;
|
|
262
|
+
const effectiveLogoShadowIntensity = logoShadowIntensity !== null && logoShadowIntensity !== void 0 ? logoShadowIntensity : logoShadowConfig.intensity;
|
|
263
|
+
// Generate shadow styles only if enabled
|
|
264
|
+
const shadowStyle = effectiveTextShadowEnabled
|
|
265
|
+
? (0, shadowUtils_1.createAbstractShadowStyle)({
|
|
266
|
+
direction: textShadowConfig.direction,
|
|
267
|
+
size: `${effectiveTextShadowSize}%`,
|
|
268
|
+
intensity: effectiveTextShadowIntensity * shadowIntensityMultiplier,
|
|
269
|
+
})
|
|
270
|
+
: {};
|
|
271
|
+
const logoShadowStyle = effectiveLogoShadowEnabled
|
|
272
|
+
? (0, shadowUtils_1.createAbstractShadowStyle)({
|
|
273
|
+
direction: logoShadowConfig.direction,
|
|
274
|
+
size: `${effectiveLogoShadowSize}%`,
|
|
275
|
+
intensity: effectiveLogoShadowIntensity * shadowIntensityMultiplier,
|
|
276
|
+
})
|
|
277
|
+
: {};
|
|
278
|
+
return { shadowStyle, logoShadowStyle };
|
|
279
|
+
}, [
|
|
280
|
+
styleConfig.shadows,
|
|
281
|
+
textShadowEnabled,
|
|
282
|
+
textShadowSize,
|
|
283
|
+
textShadowIntensity,
|
|
284
|
+
logoShadowEnabled,
|
|
285
|
+
logoShadowSize,
|
|
286
|
+
logoShadowIntensity,
|
|
287
|
+
shadowIntensityMultiplier,
|
|
288
|
+
]);
|
|
289
|
+
// Shared logo component
|
|
290
|
+
const logoComponent = ((0, jsx_runtime_1.jsx)(shared_1.DraggableElement, { enabled: draggableMode, position: { x: logoTranslateX, y: logoTranslateY }, rotation: logoRotation, width: logoWidth, scale: sizeMultiplier, elementId: "logo", isSelected: selectedElement === "logo", onPositionChange: onLogoPositionChange, onRotationChange: onLogoRotationChange, onWidthChange: onLogoWidthChange, onSelect: (id) => setSelectedElement(id), onDeselect: () => setSelectedElement(null), onRotationSnap: handleRotationSnap, children: (0, jsx_runtime_1.jsx)("div", { ref: logoRef, className: "relative", style: {
|
|
291
|
+
width: logoWidth ? `${logoWidth}px` : `${defaults_1.DEFAULT_LOGO_SIZE_REM * logoSizeMultiplier}rem`,
|
|
292
|
+
height: logoWidth ? `${logoWidth}px` : `${defaults_1.DEFAULT_LOGO_SIZE_REM * logoSizeMultiplier}rem`,
|
|
293
|
+
transform: !draggableMode ? `translate(${logoTranslateX}px, ${logoTranslateY}px)` : undefined,
|
|
294
|
+
}, children: logoUrl && ((0, jsx_runtime_1.jsx)(ImageComponent, { src: logoUrl, alt: "Logo", width: 256, height: 256, className: "object-contain absolute inset-0 w-full h-full", style: { objectFit: "contain", pointerEvents: "none" } })) }) }));
|
|
295
|
+
// Function to render a copy component by styleSlot
|
|
296
|
+
// Function to render a copy component with absolute positioning
|
|
297
|
+
const renderCopyComponent = (copy) => {
|
|
298
|
+
var _a, _b, _c, _d;
|
|
299
|
+
// Use styleSlot to determine config (0 = copy1, 1 = copy2)
|
|
300
|
+
const styleSlot = copy.styleSlot !== undefined ? copy.styleSlot : 0;
|
|
301
|
+
// Determine if this is a styled copy (copy1 or copy2) vs overflow copy
|
|
302
|
+
const isStyled = styleSlot === 0 || styleSlot === 1;
|
|
303
|
+
// Get copy config, with fallback for styles that don't have copy2
|
|
304
|
+
const copyConfig = styleSlot === 0
|
|
305
|
+
? config.copy1
|
|
306
|
+
: ('copy2' in config ? config.copy2 : config.copy1);
|
|
307
|
+
// Get config position and width
|
|
308
|
+
const configX = (_a = copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.x) !== null && _a !== void 0 ? _a : 0;
|
|
309
|
+
const configY = (_b = copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.y) !== null && _b !== void 0 ? _b : 0;
|
|
310
|
+
const configWidth = copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.width;
|
|
311
|
+
const autoOffset = autoOffsets[styleSlot] || 0;
|
|
312
|
+
// Get the font size multiplier from copy config (used for both font size and padding scaling)
|
|
313
|
+
const copyFontSizeMultiplier = copy.fontSize || 1.0;
|
|
314
|
+
// Calculate font size
|
|
315
|
+
// copy.fontSize is now an absolute multiplier, not relative to config
|
|
316
|
+
// Config fontSize values only set the initial copy.fontSize value
|
|
317
|
+
const effectiveFontSize = `${defaults_1.DEFAULT_BASE_FONT_SIZE_REM * copyFontSizeMultiplier}rem`;
|
|
318
|
+
// Get alignment - always prioritize copy's own align property
|
|
319
|
+
const effectiveAlign = copy.align || (isStyled && copyConfig ? copyConfig.alignment : 'center');
|
|
320
|
+
// Get font weight - use copy's fontWeight, then config default, then fallback
|
|
321
|
+
const effectiveFontWeight = copy.fontWeight || (isStyled ? (styleSlot === 0 ? (styleConfig.copy1FontWeight || 'bold') : (styleConfig.copy2FontWeight || 'normal')) : 'normal');
|
|
322
|
+
// Get font family - prioritize copy's own fontFamily, then global override, then style config
|
|
323
|
+
const effectiveCopyFontFamily = copy.fontFamily || fontFamily || styleConfig.fontFamily;
|
|
324
|
+
// Get color properties - prioritize copy's own properties, then substyle config, then defaults
|
|
325
|
+
const effectiveColor = copy.color || (isStyled && copyConfig ? copyConfig.color : undefined) || 'white';
|
|
326
|
+
const effectiveBgColor = copy.bgColor || (isStyled && copyConfig ? copyConfig.bgColor : undefined);
|
|
327
|
+
const effectiveHasBg = copy.hasBg !== undefined ? copy.hasBg : (isStyled && copyConfig ? copyConfig.hasBg : false);
|
|
328
|
+
// Get padding and scale it proportionally with font size to maintain visual consistency
|
|
329
|
+
const basePaddingX = copy.paddingX || (isStyled && copyConfig ? copyConfig.paddingX : undefined);
|
|
330
|
+
const basePaddingY = copy.paddingY || (isStyled && copyConfig ? copyConfig.paddingY : undefined);
|
|
331
|
+
const effectivePaddingX = basePaddingX
|
|
332
|
+
? `${parseFloat(basePaddingX.replace('rem', '')) * copyFontSizeMultiplier}rem`
|
|
333
|
+
: undefined;
|
|
334
|
+
const effectivePaddingY = basePaddingY
|
|
335
|
+
? `${parseFloat(basePaddingY.replace('rem', '')) * copyFontSizeMultiplier}rem`
|
|
336
|
+
: undefined;
|
|
337
|
+
const effectiveBorderRadius = copy.borderRadius || (isStyled && copyConfig ? copyConfig.borderRadius : undefined);
|
|
338
|
+
// Apply text decoration styles
|
|
339
|
+
const textDecorationStyles = [];
|
|
340
|
+
if (copy.underline)
|
|
341
|
+
textDecorationStyles.push('underline');
|
|
342
|
+
const textDecoration = textDecorationStyles.length > 0 ? textDecorationStyles.join(' ') : 'none';
|
|
343
|
+
// Apply font style
|
|
344
|
+
const fontStyle = copy.italic ? 'italic' : 'normal';
|
|
345
|
+
// Apply additional bold if textBold is true (combines with fontWeight)
|
|
346
|
+
const finalFontWeight = copy.textBold
|
|
347
|
+
? 'bold'
|
|
348
|
+
: getFontWeight(effectiveFontWeight);
|
|
349
|
+
// Text element
|
|
350
|
+
const textElement = ((0, jsx_runtime_1.jsx)("p", { style: {
|
|
351
|
+
fontSize: effectiveFontSize,
|
|
352
|
+
fontWeight: finalFontWeight,
|
|
353
|
+
fontFamily: effectiveCopyFontFamily,
|
|
354
|
+
color: effectiveColor,
|
|
355
|
+
textDecoration,
|
|
356
|
+
fontStyle,
|
|
357
|
+
}, className: (0, clsx_1.default)("whitespace-pre-wrap", `text-${effectiveAlign}`), children: copy.text }));
|
|
358
|
+
// Wrap with background if needed
|
|
359
|
+
const contentElement = effectiveHasBg ? ((0, jsx_runtime_1.jsx)("div", { style: {
|
|
360
|
+
backgroundColor: effectiveBgColor,
|
|
361
|
+
paddingLeft: effectivePaddingX,
|
|
362
|
+
paddingRight: effectivePaddingX,
|
|
363
|
+
paddingTop: effectivePaddingY,
|
|
364
|
+
paddingBottom: effectivePaddingY,
|
|
365
|
+
borderRadius: effectiveBorderRadius,
|
|
366
|
+
display: 'inline-block',
|
|
367
|
+
}, children: textElement })) : textElement;
|
|
368
|
+
// Calculate final position: config position + auto-offset + user adjustment
|
|
369
|
+
const baseX = isStyled ? configX : 0;
|
|
370
|
+
const baseY = isStyled ? (configY + autoOffset) : 0;
|
|
371
|
+
const finalX = baseX + (copy.translateX || 0);
|
|
372
|
+
const finalY = baseY + (copy.translateY || 0);
|
|
373
|
+
const finalWidth = copy.width || configWidth;
|
|
374
|
+
const finalRotation = (_c = copy.rotation) !== null && _c !== void 0 ? _c : (isStyled ? ((_d = copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.rotation) !== null && _d !== void 0 ? _d : 0) : 0);
|
|
375
|
+
console.log(`📦 DRAGGABLE POSITION (styleSlot ${styleSlot}):`, {
|
|
376
|
+
configX,
|
|
377
|
+
configY,
|
|
378
|
+
autoOffset,
|
|
379
|
+
baseX,
|
|
380
|
+
baseY,
|
|
381
|
+
'copy.translateX': copy.translateX,
|
|
382
|
+
'copy.translateY': copy.translateY,
|
|
383
|
+
finalX,
|
|
384
|
+
finalY,
|
|
385
|
+
finalWidth,
|
|
386
|
+
});
|
|
387
|
+
return ((0, jsx_runtime_1.jsx)(shared_1.DraggableElement, { enabled: draggableMode, position: { x: finalX, y: finalY }, rotation: finalRotation, width: finalWidth, scale: sizeMultiplier, elementId: `copy-${copy.id}`, isSelected: selectedElement === `copy-${copy.id}`, centerOrigin: true, onPositionChange: (pos) => {
|
|
388
|
+
// Subtract base position to get only user adjustment
|
|
389
|
+
const adjustedPos = {
|
|
390
|
+
x: pos.x - baseX,
|
|
391
|
+
y: pos.y - baseY,
|
|
392
|
+
};
|
|
393
|
+
// Find index of this copy in the copies array to call the callback
|
|
394
|
+
const copyIndex = copies.findIndex(c => c.id === copy.id);
|
|
395
|
+
if (copyIndex !== -1) {
|
|
396
|
+
onCopyPositionChange === null || onCopyPositionChange === void 0 ? void 0 : onCopyPositionChange(copyIndex, adjustedPos);
|
|
397
|
+
}
|
|
398
|
+
}, onRotationChange: (rot) => {
|
|
399
|
+
const copyIndex = copies.findIndex(c => c.id === copy.id);
|
|
400
|
+
if (copyIndex !== -1) {
|
|
401
|
+
onCopyRotationChange === null || onCopyRotationChange === void 0 ? void 0 : onCopyRotationChange(copyIndex, rot);
|
|
402
|
+
}
|
|
403
|
+
}, onWidthChange: (w) => {
|
|
404
|
+
const copyIndex = copies.findIndex(c => c.id === copy.id);
|
|
405
|
+
if (copyIndex !== -1) {
|
|
406
|
+
onCopyWidthChange === null || onCopyWidthChange === void 0 ? void 0 : onCopyWidthChange(copyIndex, w);
|
|
407
|
+
}
|
|
408
|
+
}, onSelect: (id) => setSelectedElement(id), onDeselect: () => setSelectedElement(null), onRotationSnap: handleRotationSnap, children: (0, jsx_runtime_1.jsx)("div", { ref: (el) => {
|
|
409
|
+
// Store ref by styleSlot for auto-positioning
|
|
410
|
+
if (styleSlot === 0)
|
|
411
|
+
copyRefs.current[0] = el;
|
|
412
|
+
else if (styleSlot === 1)
|
|
413
|
+
copyRefs.current[1] = el;
|
|
414
|
+
}, style: {
|
|
415
|
+
transform: !draggableMode ? `translate(${finalX}px, ${finalY}px) rotate(${finalRotation}deg)` : undefined,
|
|
416
|
+
width: '100%',
|
|
417
|
+
// Hide copy if hidden property is true
|
|
418
|
+
display: copy.hidden ? 'none' : undefined,
|
|
419
|
+
}, children: contentElement }) }, copy.id));
|
|
420
|
+
};
|
|
421
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: "w-full h-full text-white leading-[1.05]", children: (0, jsx_runtime_1.jsxs)("div", { className: (0, clsx_1.default)("inset-0 flex flex-col items-start h-full relative isolate overflow-hidden gap-4 px-20", postType === "STORY" ? "pb-32 pt-44" : "py-20"), children: [backgroundImageUrl && ((0, jsx_runtime_1.jsx)(ImageComponent, { src: backgroundImageUrl, alt: "Background", width: 1080, height: postType === "STORY" ? 1920 : 1350, className: "object-cover absolute inset-0 w-full h-full -z-10", style: { objectFit: "cover", pointerEvents: "none" } })), noiseEnabled && ((0, jsx_runtime_1.jsx)("div", { className: "absolute inset-0 pointer-events-none", style: {
|
|
422
|
+
opacity: Math.min(noiseIntensity / 2, 1), // Normalize 0-2 range to 0-1
|
|
423
|
+
mixBlendMode: 'overlay',
|
|
424
|
+
backgroundImage: `url("data:image/svg+xml,%3Csvg viewBox='0 0 400 400' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E")`,
|
|
425
|
+
zIndex: 5,
|
|
426
|
+
} })), (0, jsx_runtime_1.jsx)("div", { style: shadowStyle, className: "relative z-10", "aria-hidden": "true" }), (0, jsx_runtime_1.jsx)("div", { style: logoShadowStyle, className: "relative z-10", "aria-hidden": "true" }), (0, jsx_runtime_1.jsx)("div", { className: "absolute z-20", style: {
|
|
427
|
+
top: '50%',
|
|
428
|
+
left: '50%',
|
|
429
|
+
transform: `translate(${config.logo.x}px, ${config.logo.y}px)`,
|
|
430
|
+
}, children: logoComponent }), (0, jsx_runtime_1.jsx)("div", { className: "absolute pointer-events-none", style: {
|
|
431
|
+
top: '50%',
|
|
432
|
+
left: '50%',
|
|
433
|
+
width: 0,
|
|
434
|
+
height: 0
|
|
435
|
+
}, children: copies.map((copy) => {
|
|
436
|
+
// Get width from config for the wrapper
|
|
437
|
+
const styleSlot = copy.styleSlot !== undefined ? copy.styleSlot : 0;
|
|
438
|
+
const copyConfig = styleSlot === 0
|
|
439
|
+
? config.copy1
|
|
440
|
+
: ('copy2' in config ? config.copy2 : config.copy1);
|
|
441
|
+
const configWidth = copy.width || (copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.width);
|
|
442
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: "pointer-events-auto absolute", style: {
|
|
443
|
+
top: '50%',
|
|
444
|
+
left: '50%',
|
|
445
|
+
width: configWidth,
|
|
446
|
+
}, children: renderCopyComponent(copy) }, copy.id));
|
|
447
|
+
}) })] }) }));
|
|
448
|
+
};
|
|
449
|
+
exports.BannerRenderer = BannerRenderer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BannerVisor.d.ts","sourceRoot":"","sources":["../../src/components/BannerVisor.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,
|
|
1
|
+
{"version":3,"file":"BannerVisor.d.ts","sourceRoot":"","sources":["../../src/components/BannerVisor.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAA+C,MAAM,OAAO,CAAC;AAEpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAc,MAAM,UAAU,CAAC;AAYzE,UAAU,yBAA0B,SAAQ,gBAAgB;IAC1D,cAAc,EAAE,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;CACjD;AAUD,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAkU3D,CAAC"}
|