(function () { function escapeHtml(value) { return String(value === undefined || value === null ? '' : value) .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } function valueOrDefault(value, fallback) { return value === undefined || value === null || value === '' ? fallback : value; } function clamp(value, min, max) { return Math.max(min, Math.min(max, value)); } function getRegionName(card) { return String(card.querySelector('[name="region_name[]"]').value || '').trim(); } function syncRegionIdentity(card, value) { var next = String(value || '').trim(); card.querySelector('[name="region_name[]"]').value = next; card.querySelector('[name="region_key[]"]').value = next; card.querySelector('[name="region_label[]"]').value = next; } function readCard(card) { var name = getRegionName(card); return { region_key: name, label: name, region_type: card.querySelector('[name="region_type[]"]').value, font_family: card.querySelector('[name="font_family[]"]').value, x: Number(card.querySelector('[name="region_x[]"]').value || 0), y: Number(card.querySelector('[name="region_y[]"]').value || 0), width: Number(card.querySelector('[name="region_width[]"]').value || 0), height: Number(card.querySelector('[name="region_height[]"]').value || 0), z_index: Number(card.querySelector('[name="region_z[]"]').value || 0) }; } function writeCard(card, values) { if (values.region_name !== undefined) { syncRegionIdentity(card, values.region_name); } else if (values.region_key !== undefined) { syncRegionIdentity(card, values.region_key); } else if (values.label !== undefined) { syncRegionIdentity(card, values.label); } if (values.region_type !== undefined) { card.querySelector('[name="region_type[]"]').value = values.region_type; } if (values.font_family !== undefined) { card.querySelector('[name="font_family[]"]').value = values.font_family; } if (values.x !== undefined) { card.querySelector('[name="region_x[]"]').value = Math.round(values.x); } if (values.y !== undefined) { card.querySelector('[name="region_y[]"]').value = Math.round(values.y); } if (values.width !== undefined) { card.querySelector('[name="region_width[]"]').value = Math.round(values.width); } if (values.height !== undefined) { card.querySelector('[name="region_height[]"]').value = Math.round(values.height); } if (values.z_index !== undefined) { card.querySelector('[name="region_z[]"]').value = Math.round(values.z_index); } } function clampRegion(region, size, minSize) { var bounds = size || { width: 1920, height: 1080 }; var minimum = minSize || 12; var x = clamp(region.x, 0, bounds.width - minimum); var y = clamp(region.y, 0, bounds.height - minimum); var width = Math.max(minimum, region.width); var height = Math.max(minimum, region.height); if (x + width > bounds.width) { width = bounds.width - x; } if (y + height > bounds.height) { height = bounds.height - y; } return { x: Math.round(x), y: Math.round(y), width: Math.round(Math.max(minimum, width)), height: Math.round(Math.max(minimum, height)) }; } function getOverlayRect(overlay) { return overlay.getBoundingClientRect(); } function toCanvasPoint(event, overlay, size) { var rect = getOverlayRect(overlay); var canvasSize = size || { width: 1920, height: 1080 }; var x = clamp(event.clientX - rect.left, 0, rect.width); var y = clamp(event.clientY - rect.top, 0, rect.height); return { x: Math.round((x / Math.max(rect.width, 1)) * canvasSize.width), y: Math.round((y / Math.max(rect.height, 1)) * canvasSize.height) }; } function canvasRectToPixels(region, overlay, size) { var rect = getOverlayRect(overlay); var canvasSize = size || { width: 1920, height: 1080 }; return { left: (region.x / canvasSize.width) * rect.width, top: (region.y / canvasSize.height) * rect.height, width: (region.width / canvasSize.width) * rect.width, height: (region.height / canvasSize.height) * rect.height }; } window.templateDesignerUtils = { escapeHtml: escapeHtml, valueOrDefault: valueOrDefault, clamp: clamp, getRegionName: getRegionName, syncRegionIdentity: syncRegionIdentity, readCard: readCard, writeCard: writeCard, clampRegion: clampRegion, getOverlayRect: getOverlayRect, toCanvasPoint: toCanvasPoint, canvasRectToPixels: canvasRectToPixels }; }());