(function (window, document) {
    'use strict';

    function cloneDeep(value) {
        return JSON.parse(JSON.stringify(value));
    }

    function clamp(value, min, max) {
        return Math.min(max, Math.max(min, value));
    }

    function formatNumber(value, decimals) {
        var number = Number(value || 0);
        if (!window.isFinite(number)) {
            number = 0;
        }
        return number.toLocaleString(undefined, {
            minimumFractionDigits: decimals,
            maximumFractionDigits: decimals
        });
    }

    function humanBytes(bytes) {
        var size = Number(bytes || 0);
        var units = ['B', 'KB', 'MB', 'GB'];
        var index = 0;

        while (size >= 1024 && index < units.length - 1) {
            size /= 1024;
            index += 1;
        }

        return formatNumber(size, size >= 100 ? 0 : 1) + ' ' + units[index];
    }


    function escapeHtml(value) {
        return String(value == null ? '' : value)
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#039;');
    }

    function getFileExtension(type, fileName) {
        if (type === 'image/jpeg') {
            return 'jpg';
        }
        if (type === 'image/png') {
            return 'png';
        }
        if (type === 'image/webp') {
            return 'webp';
        }
        var parts = String(fileName || '').split('.');
        return parts.length > 1 ? parts.pop().toLowerCase() : 'png';
    }

    function supportsImageType(type) {
        try {
            var canvas = document.createElement('canvas');
            return canvas.toDataURL(type).indexOf('data:' + type) === 0;
        } catch (error) {
            return false;
        }
    }

    function createPngCompressionCanvas(canvas, quality) {
        var normalizedQuality = clamp(Number(quality || 1), 0.6, 1);
        var exportCanvas = document.createElement('canvas');
        var exportContext;
        var imageData;
        var data;
        var levels;
        var step;
        var index;

        if (normalizedQuality >= 0.995) {
            return canvas;
        }

        exportCanvas.width = canvas.width;
        exportCanvas.height = canvas.height;
        exportContext = exportCanvas.getContext('2d');

        if (!exportContext) {
            return canvas;
        }

        exportContext.drawImage(canvas, 0, 0);

        try {
            imageData = exportContext.getImageData(0, 0, exportCanvas.width, exportCanvas.height);
            data = imageData.data;
            levels = Math.max(8, Math.min(256, Math.round(12 + (normalizedQuality * 116))));
            step = 255 / Math.max(1, levels - 1);

            for (index = 0; index < data.length; index += 4) {
                data[index] = Math.round(data[index] / step) * step;
                data[index + 1] = Math.round(data[index + 1] / step) * step;
                data[index + 2] = Math.round(data[index + 2] / step) * step;
                if (data[index + 3] < 255) {
                    data[index + 3] = Math.round(data[index + 3] / step) * step;
                }
            }

            exportContext.putImageData(imageData, 0, 0);
        } catch (error) {
            return canvas;
        }

        return exportCanvas;
    }

    function getPngPaletteSize(quality) {
        var normalizedQuality = clamp(Number(quality || 1), 0.6, 1);

        if (normalizedQuality >= 0.97) {
            return 256;
        }
        if (normalizedQuality >= 0.93) {
            return 192;
        }
        if (normalizedQuality >= 0.88) {
            return 160;
        }
        if (normalizedQuality >= 0.82) {
            return 128;
        }
        if (normalizedQuality >= 0.74) {
            return 96;
        }
        if (normalizedQuality >= 0.66) {
            return 64;
        }
        if (normalizedQuality >= 0.56) {
            return 48;
        }
        if (normalizedQuality >= 0.48) {
            return 32;
        }

        return 16;
    }

    function bufferToArrayBuffer(buffer) {
        if (buffer instanceof ArrayBuffer) {
            return buffer;
        }
        if (ArrayBuffer.isView(buffer)) {
            return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
        }
        return null;
    }

    function encodePngQuantized(canvas, quality) {
        return new Promise(function (resolve) {
            var upng = window.UPNG;
            var context;
            var imageData;
            var encoded;
            var arrayBuffer;
            var paletteSize;

            if (!upng || typeof upng.encode !== 'function') {
                resolve(null);
                return;
            }

            context = canvas.getContext('2d');
            if (!context) {
                resolve(null);
                return;
            }

            try {
                imageData = context.getImageData(0, 0, canvas.width, canvas.height);
                paletteSize = getPngPaletteSize(quality);
                encoded = upng.encode([imageData.data.buffer], canvas.width, canvas.height, paletteSize);
                arrayBuffer = bufferToArrayBuffer(encoded);

                if (!arrayBuffer) {
                    resolve(null);
                    return;
                }

                resolve(new Blob([arrayBuffer], { type: 'image/png' }));
            } catch (error) {
                resolve(null);
            }
        });
    }

    function canvasToBlob(canvas, type, quality) {
        return new Promise(function (resolve) {
            var exportCanvas = canvas;
            var exportContext;

            if (type === 'image/jpeg') {
                exportCanvas = document.createElement('canvas');
                exportCanvas.width = canvas.width;
                exportCanvas.height = canvas.height;
                exportContext = exportCanvas.getContext('2d');

                if (!exportContext) {
                    resolve(null);
                    return;
                }

                exportContext.fillStyle = '#ffffff';
                exportContext.fillRect(0, 0, exportCanvas.width, exportCanvas.height);
                exportContext.drawImage(canvas, 0, 0);
            } else if (type === 'image/png') {
                encodePngQuantized(canvas, quality).then(function (pngBlob) {
                    if (pngBlob && pngBlob.size) {
                        resolve(pngBlob);
                        return;
                    }

                    exportCanvas = createPngCompressionCanvas(canvas, quality);
                    exportCanvas.toBlob(function (blob) {
                        if (!blob) {
                            resolve(null);
                            return;
                        }
                        resolve(blob);
                    }, type, undefined);
                });
                return;
            }

            exportCanvas.toBlob(function (blob) {
                if (!blob) {
                    resolve(null);
                    return;
                }

                if (type !== 'image/png' && blob.type !== type) {
                    resolve(null);
                    return;
                }

                resolve(blob);
            }, type, type === 'image/png' ? undefined : quality);
        });
    }

    function detectTransparency(canvas) {
        var width = Math.max(1, Math.min(48, canvas.width || 1));
        var height = Math.max(1, Math.min(48, canvas.height || 1));
        var sampleCanvas = document.createElement('canvas');
        var sampleContext;
        var imageData;
        var data;
        var index;

        sampleCanvas.width = width;
        sampleCanvas.height = height;
        sampleContext = sampleCanvas.getContext('2d');

        if (!sampleContext) {
            return false;
        }

        sampleContext.drawImage(canvas, 0, 0, width, height);
        imageData = sampleContext.getImageData(0, 0, width, height);
        data = imageData.data;

        for (index = 3; index < data.length; index += 4) {
            if (data[index] < 250) {
                return true;
            }
        }

        return false;
    }

    function isLossyType(type) {
        return type === 'image/jpeg' || type === 'image/webp';
    }

    var runtimeScriptPromises = window.noesiaSwaImageToolsRuntimeScriptPromises || (window.noesiaSwaImageToolsRuntimeScriptPromises = {});

    function ensureTrailingSlash(value) {
        var stringValue = String(value || '');

        return stringValue && stringValue.slice(-1) !== '/' ? stringValue + '/' : stringValue;
    }

    function getConverterVendorBase(root) {
        var panel = root ? root.querySelector('[data-image-converter-panel]') : null;

        return panel ? ensureTrailingSlash(panel.getAttribute('data-image-converter-vendor-base') || '') : '';
    }

    function getAssetsBaseFromVendorBase(vendorBase) {
        var normalizedVendorBase = ensureTrailingSlash(vendorBase);

        return normalizedVendorBase.replace(/vendor\/?$/, '');
    }

    function loadRuntimeScriptOnce(key, src, attributes) {
        var normalizedKey = String(key || '').trim();
        var normalizedSrc = String(src || '').trim();
        var attrs = attributes && typeof attributes === 'object' ? attributes : {};

        if (!normalizedKey || !normalizedSrc) {
            return Promise.reject(new Error('Missing runtime script source.'));
        }

        if (runtimeScriptPromises[normalizedKey]) {
            return runtimeScriptPromises[normalizedKey];
        }

        runtimeScriptPromises[normalizedKey] = new Promise(function (resolve, reject) {
            var existing = document.querySelector('script[data-noesia-swa-runtime-script="' + normalizedKey + '"]');
            var script = existing || document.createElement('script');

            function cleanupFailure(error) {
                delete runtimeScriptPromises[normalizedKey];
                reject(error);
            }

            if (existing) {
                if (existing.getAttribute('data-noesia-swa-runtime-loaded') === '1') {
                    resolve();
                    return;
                }

                existing.addEventListener('load', function onExistingLoad() {
                    existing.removeEventListener('load', onExistingLoad);
                    resolve();
                }, { once: true });
                existing.addEventListener('error', function onExistingError() {
                    existing.removeEventListener('error', onExistingError);
                    cleanupFailure(new Error('Unable to load runtime script: ' + normalizedSrc));
                }, { once: true });
                return;
            }

            script.src = normalizedSrc;
            script.async = false;
            script.setAttribute('data-noesia-swa-runtime-script', normalizedKey);

            Object.keys(attrs).forEach(function (name) {
                var value = attrs[name];

                if (value === false || value == null) {
                    return;
                }

                if (value === true) {
                    script.setAttribute(name, name);
                    return;
                }

                script.setAttribute(name, String(value));
            });

            script.onload = function () {
                script.setAttribute('data-noesia-swa-runtime-loaded', '1');
                resolve();
            };
            script.onerror = function () {
                cleanupFailure(new Error('Unable to load runtime script: ' + normalizedSrc));
            };

            (document.body || document.head || document.documentElement).appendChild(script);
        });

        return runtimeScriptPromises[normalizedKey];
    }

    function ensureToolsRuntime(root) {
        var vendorBase = getConverterVendorBase(root);

        if (!vendorBase) {
            return Promise.resolve();
        }

        return loadRuntimeScriptOnce('noesia-swa-image-tools-upng', vendorBase + 'UPNG.js');
    }

    function ensureConverterRuntime(root) {
        var vendorBase = getConverterVendorBase(root);
        var assetsBase = getAssetsBaseFromVendorBase(vendorBase);
        var converterConfig;
        var steps;

        if (!vendorBase || !assetsBase) {
            return Promise.reject(new Error('The Image Tools converter assets could not be resolved.'));
        }

        converterConfig = window.noesiaSwaImageToolsConverterConfig || {};
        window.noesiaSwaImageToolsConverterConfig = Object.assign({}, converterConfig, {
            vendorBaseUrl: vendorBase,
            pdfWorkerSrc: vendorBase + 'pdf.worker.min.js',
            independentEncoderJs: vendorBase + 'noesia-independent-encoders.js',
            independentEncoderModule: vendorBase + 'noesia-independent-encoders.mjs'
        });

        steps = [
            function () { return loadRuntimeScriptOnce('noesia-swa-image-tools-jszip', vendorBase + 'jszip.min.js'); },
            function () { return loadRuntimeScriptOnce('noesia-swa-image-tools-pdf', vendorBase + 'noesia-pdfjs-bridge.js'); },
            function () { return loadRuntimeScriptOnce('noesia-swa-image-tools-heic2any', vendorBase + 'heic2any.min.js'); },
            function () { return loadRuntimeScriptOnce('noesia-swa-image-tools-xlsx', vendorBase + 'xlsx.full.min.js'); },
            function () { return loadRuntimeScriptOnce('noesia-swa-image-tools-jspdf', vendorBase + 'jspdf.umd.min.js'); },
            function () { return loadRuntimeScriptOnce('noesia-swa-image-tools-dompurify', vendorBase + 'purify.min.js'); },
            function () { return loadRuntimeScriptOnce('noesia-swa-image-tools-wmfjs', vendorBase + 'WMFJS.bundle.min.js'); },
            function () { return loadRuntimeScriptOnce('noesia-swa-image-tools-emfjs', vendorBase + 'EMFJS.bundle.min.js'); },
            function () { return loadRuntimeScriptOnce('noesia-swa-image-tools-rtfjs', vendorBase + 'RTFJS.bundle.min.js'); },
            function () { return loadRuntimeScriptOnce('noesia-swa-image-tools-pako', vendorBase + 'pako.min.js'); },
            function () { return loadRuntimeScriptOnce('noesia-swa-image-tools-utif', vendorBase + 'UTIF.js'); },
            function () { return loadRuntimeScriptOnce('noesia-swa-image-tools-gifuct', vendorBase + 'gifuct-noesia.bundle.js'); },
            function () { return loadRuntimeScriptOnce('noesia-swa-image-tools-upng', vendorBase + 'UPNG.js'); },
            function () { return loadRuntimeScriptOnce('noesia-swa-image-tools-independent-encoders', vendorBase + 'noesia-independent-encoders.js', { type: 'module' }); },
            function () {
                return loadRuntimeScriptOnce('noesia-swa-image-tools-converter', assetsBase + 'js/universal-local-converter.js').then(function () {
                    if (window.NoesiaSwaIndependentEncodersReady && typeof window.NoesiaSwaIndependentEncodersReady.then === 'function') {
                        return window.NoesiaSwaIndependentEncodersReady.catch(function () {
                            return null;
                        });
                    }

                    return null;
                });
            }
        ];

        return steps.reduce(function (promise, step) {
            return promise.then(step);
        }, Promise.resolve());
    }

    function bootstrap() {
        var root = document.querySelector('[data-image-tools-root]');
        if (!root || root.getAttribute('data-image-tools-booted') === '1') {
            return;
        }

        root.setAttribute('data-image-tools-booted', '1');
        root._imageToolsToolsRuntimePromise = ensureToolsRuntime(root);

        var globalData = window.noesiaSwaAdminData || {};
        var i18n = globalData.i18n || {};

        function t(key, fallback) {
            return Object.prototype.hasOwnProperty.call(i18n, key) ? i18n[key] : fallback;
        }

        function setText(node, value) {
            if (node) {
                node.textContent = value;
            }
        }




        root._imageToolsConverterInit = function () {
            var converterPanel = root.querySelector('[data-image-converter-panel]');

            if (!converterPanel) {
                return Promise.resolve();
            }

            if (root._imageToolsConverterPromise) {
                return root._imageToolsConverterPromise;
            }

            root._imageToolsConverterPromise = ensureConverterRuntime(root).then(function () {
                if (!window.NoesiaSwaUniversalLocalConverter || typeof window.NoesiaSwaUniversalLocalConverter.bootstrap !== 'function') {
                    throw new Error('The local converter runtime is not available on this admin screen.');
                }
                window.NoesiaSwaUniversalLocalConverter.bootstrap(converterPanel, {
                    i18n: i18n
                });
            }).catch(function (error) {
                root._imageToolsConverterPromise = null;
                throw error;
            });

            return root._imageToolsConverterPromise;
        };

        initShellCollapse();
        initTabs();
        initTools();
        initDesign();

        function initShellCollapse() {
            var storageKey = 'noesia_swa_image_tools_shell_collapsed_v1';
            var toggle = root.querySelector('[data-image-tools-shell-toggle]');
            var collapsed = false;
            if (!toggle) {
                return;
            }
            try {
                collapsed = window.localStorage.getItem(storageKey) === '1';
            } catch (error) {
                collapsed = false;
            }
            function syncShell() {
                root.classList.toggle('is-shell-collapsed', collapsed);
                toggle.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
            }
            syncShell();
            toggle.addEventListener('click', function () {
                collapsed = !collapsed;
                syncShell();
                try {
                    window.localStorage.setItem(storageKey, collapsed ? '1' : '0');
                } catch (error) {
                    // Ignore storage errors.
                }
            });
        }

        function initTabs() {
            var tabButtons = root.querySelectorAll('[data-image-tools-tab-toggle]');
            var tabPanels = root.querySelectorAll('[data-image-tools-panel]');

            function setTab(tab) {
                root.setAttribute('data-image-tools-tab', tab);
                tabButtons.forEach(function (button) {
                    var active = button.getAttribute('data-image-tools-tab-toggle') === tab;
                    button.classList.toggle('is-active', active);
                    button.setAttribute('aria-selected', active ? 'true' : 'false');
                });
                tabPanels.forEach(function (panel) {
                    var active = panel.getAttribute('data-image-tools-panel') === tab;
                    panel.hidden = !active;
                    panel.classList.toggle('is-active', active);
                });

                if (tab === 'design' && typeof root._imageToolsDesignRefresh === 'function') {
                    window.requestAnimationFrame(root._imageToolsDesignRefresh);
                }

                if (tab === 'converter' && typeof root._imageToolsConverterInit === 'function') {
                    root._imageToolsConverterInit();
                }
            }

            tabButtons.forEach(function (button) {
                button.addEventListener('click', function () {
                    setTab(button.getAttribute('data-image-tools-tab-toggle'));
                });
            });

            setTab(root.getAttribute('data-image-tools-tab') || 'tools');
        }

        function initTools() {
            var input = root.querySelector('[data-image-tools-input]');
            var dropzone = root.querySelector('[data-image-tools-dropzone]');
            var dropCopyNode = root.querySelector('[data-image-tools-dropcopy]');
            var queueNode = root.querySelector('[data-image-tools-queue]');
            var statusNode = root.querySelector('[data-image-tools-status]');
            var template = root.querySelector('[data-image-tools-card-template]');
            var formatSelect = root.querySelector('[data-image-tools-format]');
            var qualityInput = root.querySelector('[data-image-tools-quality]');
            var qualityReadout = root.querySelector('[data-image-tools-quality-readout]');
            var widthInput = root.querySelector('[data-image-tools-width]');
            var heightInput = root.querySelector('[data-image-tools-height]');
            var smartModeCheckbox = root.querySelector('[data-image-tools-smart-mode]');
            var autoProcessCheckbox = root.querySelector('[data-image-tools-auto]');
            var downloadAfterCheckbox = root.querySelector('[data-image-tools-download-after]');
            var presetButtons = root.querySelectorAll('[data-image-tools-preset]');
            var viewButtons = root.querySelectorAll('[data-image-tools-view-toggle]');
            var statFiles = root.querySelector('[data-image-tools-stat-files]');
            var statReady = root.querySelector('[data-image-tools-stat-ready]');
            var statSavings = root.querySelector('[data-image-tools-stat-savings]');
            var browseButton = root.querySelector('[data-image-tools-action="browse"]');
            var reprocessButton = root.querySelector('[data-image-tools-action="reprocess"]');
            var downloadAllButton = root.querySelector('[data-image-tools-action="download-all"]');
            var clearButton = root.querySelector('[data-image-tools-action="clear"]');
            var items = [];
            var itemCounter = 0;
            var maxQueueItems = 20;

            if (!queueNode || !template) {
                return;
            }

            function getSettings() {
                var format = formatSelect ? formatSelect.value : 'keep';
                var quality = parseFloat(qualityInput ? qualityInput.value : '0.94');
                var maxWidthValue = widthInput ? String(widthInput.value || '').trim() : '';
                var maxHeightValue = heightInput ? String(heightInput.value || '').trim() : '';
                var maxWidth = maxWidthValue ? Math.max(1, parseInt(maxWidthValue, 10) || 0) : null;
                var maxHeight = maxHeightValue ? Math.max(1, parseInt(maxHeightValue, 10) || 0) : null;

                return {
                    format: format,
                    quality: clamp(quality || 0.94, 0.6, 1),
                    maxWidth: maxWidth,
                    maxHeight: maxHeight,
                    smartMode: !!(smartModeCheckbox && smartModeCheckbox.checked)
                };
            }

            function updateQualityReadout() {
                var normalizedQuality;
                var paletteSize;

                if (!qualityInput || !qualityReadout) {
                    return;
                }

                normalizedQuality = clamp(parseFloat(qualityInput.value || '0.94') || 0.94, 0.6, 1);
                if (formatSelect && formatSelect.value === 'image/png') {
                    paletteSize = getPngPaletteSize(normalizedQuality);
                    qualityReadout.textContent = 'PNG ' + paletteSize + ' colors';
                } else {
                    qualityReadout.textContent = Math.round(normalizedQuality * 100) + '%';
                }
            }

            function updateQualityControls() {
                if (qualityInput) {
                    qualityInput.disabled = false;
                }
                presetButtons.forEach(function (button) {
                    button.disabled = false;
                    button.classList.remove('is-disabled');
                });
                updateQualityReadout();
            }

            function cleanupItem(item) {
                if (!item) {
                    return;
                }
                if (item.originalUrl) {
                    URL.revokeObjectURL(item.originalUrl);
                }
                if (item.outputUrl && item.outputUrl !== item.originalUrl) {
                    URL.revokeObjectURL(item.outputUrl);
                }
            }

            function buildMetaLine(blob, dimensions, suffix) {
                var parts = [];
                if (blob && blob.size) {
                    parts.push(humanBytes(blob.size));
                }
                if (dimensions && dimensions.width && dimensions.height) {
                    parts.push(dimensions.width + '×' + dimensions.height);
                }
                if (suffix) {
                    parts.push(suffix);
                }
                return parts.join(' • ');
            }

            function updateStats() {
                var readyItems = items.filter(function (item) {
                    return !!item.outputBlob && !item.error;
                });
                var savings = 0;

                readyItems.forEach(function (item) {
                    if (item.file && item.outputBlob && item.file.size > 0) {
                        savings += Math.max(0, 100 - ((item.outputBlob.size / item.file.size) * 100));
                    }
                });

                setText(statFiles, String(items.length));
                setText(statReady, String(readyItems.length));
                setText(statSavings, readyItems.length ? (formatNumber(savings / readyItems.length, 1) + '%') : '0%');
            }

            function buildEmptyState() {
                queueNode.innerHTML = '<div class="noesia-swa-image-tools__empty"><span class="dashicons dashicons-format-image" aria-hidden="true"></span><strong>' + t('image_tools_empty', 'Add one or more images to begin.') + '</strong><p>' + t('image_tools_browser_only', 'Local browser mode. Files stay on this device.') + '</p></div>';
            }

            function renderItem(item) {
                if (!item.node || !item.file) {
                    return;
                }

                var statusNodeLocal = item.node.querySelector('[data-card-status]');
                var savingNode = item.node.querySelector('[data-card-saving]');
                var downloadNode = item.node.querySelector('[data-card-download]');
                var originalNode = item.node.querySelector('[data-card-original]');
                var outputNode = item.node.querySelector('[data-card-output]');
                var originalMetaNode = item.node.querySelector('[data-card-original-meta]');
                var outputMetaNode = item.node.querySelector('[data-card-output-meta]');
                var originalLineNode = item.node.querySelector('[data-card-original-line]');
                var outputLineNode = item.node.querySelector('[data-card-output-line]');
                var filenameNode = item.node.querySelector('.noesia-swa-image-tools__filename');

                if (filenameNode) {
                    filenameNode.textContent = item.file.name;
                }
                if (originalNode && item.originalUrl) {
                    originalNode.src = item.originalUrl;
                }
                if (outputNode) {
                    outputNode.src = item.outputUrl || item.originalUrl;
                }

                var originalMeta = humanBytes(item.file.size) + (item.originalDimensions ? (' • ' + item.originalDimensions.width + '×' + item.originalDimensions.height) : '');
                var outputMeta = item.outputBlob ? buildMetaLine(item.outputBlob, item.outputDimensions, item.outputBlob.type.replace('image/', '').toUpperCase()) : (item.error ? item.error : t('image_tools_processing', 'Processing…'));

                if (originalMetaNode) {
                    originalMetaNode.textContent = originalMeta;
                }
                if (outputMetaNode) {
                    outputMetaNode.textContent = outputMeta;
                }
                if (originalLineNode) {
                    originalLineNode.textContent = originalMeta;
                }
                if (outputLineNode) {
                    outputLineNode.textContent = outputMeta;
                }
                if (statusNodeLocal) {
                    statusNodeLocal.textContent = item.error ? item.error : item.statusLabel;
                    statusNodeLocal.className = 'noesia-swa-image-tools__badge';
                    if (item.error) {
                        statusNodeLocal.classList.add('is-error');
                    } else if (item.outputBlob) {
                        statusNodeLocal.classList.add('is-ready');
                    }
                }
                if (savingNode) {
                    if (item.outputBlob && item.file.size > 0) {
                        savingNode.textContent = formatNumber(Math.max(0, 100 - ((item.outputBlob.size / item.file.size) * 100)), 1) + '%';
                    } else {
                        savingNode.textContent = '0%';
                    }
                }
                if (downloadNode) {
                    if (item.outputBlob && item.outputUrl) {
                        downloadNode.hidden = false;
                        downloadNode.href = item.outputUrl;
                        downloadNode.download = item.downloadName;
                    } else {
                        downloadNode.hidden = true;
                        downloadNode.removeAttribute('href');
                    }
                }
            }

            function setQueueView(view) {
                var nextView = view === 'list' ? 'list' : 'cards';
                root.setAttribute('data-image-tools-view', nextView);

                viewButtons.forEach(function (button) {
                    var buttonView = button.getAttribute('data-image-tools-view-toggle');
                    button.classList.toggle('is-active', buttonView === nextView);
                    button.setAttribute('aria-pressed', buttonView === nextView ? 'true' : 'false');
                });
            }

            function renderQueue() {
                if (!items.length) {
                    buildEmptyState();
                    updateStats();
                    return;
                }

                queueNode.innerHTML = '';

                items.forEach(function (item) {
                    if (!item.node) {
                        var fragment = template.content.cloneNode(true);
                        var card = fragment.querySelector('.noesia-swa-image-tools__card');
                        item.node = card;

                        card.querySelector('[data-card-action="remove"]').addEventListener('click', function () {
                            cleanupItem(item);
                            items = items.filter(function (candidate) {
                                return candidate.id !== item.id;
                            });
                            renderQueue();
                            setText(statusNode, items.length ? t('image_tools_browser_only', 'Local browser mode. Files stay on this device.') : t('image_tools_empty', 'Add one or more images to begin.'));
                        });

                        card.querySelector('[data-card-action="process"]').addEventListener('click', function () {
                            processItem(item);
                        });
                    }

                    renderItem(item);
                    queueNode.appendChild(item.node);
                });

                updateStats();
            }

            function triggerDownload(item) {
                if (!item.outputUrl || !item.outputBlob) {
                    return;
                }
                var anchor = document.createElement('a');
                anchor.href = item.outputUrl;
                anchor.download = item.downloadName;
                document.body.appendChild(anchor);
                anchor.click();
                anchor.remove();
            }

            function cloneOriginalAsOutput(item) {
                if (!item || !item.file || !item.originalUrl) {
                    return;
                }

                if (item.outputUrl && item.outputUrl !== item.originalUrl) {
                    URL.revokeObjectURL(item.outputUrl);
                }

                item.outputBlob = item.file;
                item.outputUrl = item.originalUrl;
                item.outputDimensions = item.originalDimensions ? {
                    width: item.originalDimensions.width,
                    height: item.originalDimensions.height
                } : null;
                item.downloadName = item.file.name;
            }

            function getCandidateTypes(item, settings, hasAlpha) {
                var originalType = String((item.file && item.file.type) || 'image/png');
                var candidates = [];
                var explicitFormat = settings && settings.format && settings.format !== 'keep';

                if (explicitFormat) {
                    return [settings.format];
                }

                if (!settings.smartMode) {
                    if (originalType === 'image/png' && settings.quality < 0.995) {
                        if (hasAlpha) {
                            candidates.push('image/webp');
                            candidates.push('image/png');
                            candidates.push('image/jpeg');
                        } else {
                            candidates.push('image/webp');
                            candidates.push('image/jpeg');
                            candidates.push('image/png');
                        }
                    } else {
                        candidates.push(originalType);
                    }
                } else if (hasAlpha) {
                    candidates.push('image/webp');
                    candidates.push('image/png');
                } else if (originalType === 'image/jpeg') {
                    candidates.push('image/webp');
                    candidates.push('image/jpeg');
                } else if (originalType === 'image/webp') {
                    candidates.push('image/webp');
                    candidates.push('image/jpeg');
                    candidates.push('image/png');
                } else {
                    candidates.push('image/webp');
                    candidates.push('image/jpeg');
                    candidates.push('image/png');
                }

                return candidates.filter(function (type, index, all) {
                    if (type === 'image/webp' && !supportsImageType('image/webp')) {
                        return false;
                    }
                    if (settings.smartMode && hasAlpha && type === 'image/jpeg') {
                        return false;
                    }
                    return all.indexOf(type) === index;
                });
            }

            function shouldKeepOriginalResult(item, blob, width, height, targetType, settings) {
                if (!item || !item.file || !blob) {
                    return false;
                }
                if (settings.format && settings.format !== 'keep') {
                    return false;
                }

                var originalType = String(item.file.type || '');
                var sameType = originalType === String(targetType || '');
                var originalWidth = item.originalDimensions ? Number(item.originalDimensions.width || 0) : 0;
                var originalHeight = item.originalDimensions ? Number(item.originalDimensions.height || 0) : 0;
                var sameDimensions = originalWidth === Number(width || 0) && originalHeight === Number(height || 0);
                var noResizeRequested = !settings.maxWidth && !settings.maxHeight;
                var savingsRatio = item.file.size > 0 ? (1 - (blob.size / item.file.size)) : 0;
                var manualLossyPng = !settings.smartMode && settings.format === 'keep' && originalType === 'image/png' && settings.quality < 0.995;

                if (manualLossyPng && !sameType) {
                    return blob.size >= item.file.size && sameDimensions;
                }
                if (blob.size >= item.file.size && sameDimensions) {
                    return true;
                }
                if (sameDimensions && savingsRatio < 0.03) {
                    return true;
                }
                if (sameType && sameDimensions && savingsRatio < 0.02) {
                    return true;
                }
                if (originalType === 'image/png' && sameType && noResizeRequested && sameDimensions && blob.size >= (item.file.size * 0.95)) {
                    return true;
                }
                return false;
            }

            function applyOutput(item, blob, width, height, settings) {
                var extension;
                var basename;
                var actualType = blob.type || item.file.type;

                if (item.outputUrl && item.outputUrl !== item.originalUrl) {
                    URL.revokeObjectURL(item.outputUrl);
                }

                item.outputBlob = blob;
                item.outputUrl = URL.createObjectURL(blob);
                item.outputDimensions = {
                    width: width,
                    height: height
                };
                item.statusLabel = settings.format !== 'keep' ? 'Converted' : (actualType === item.file.type ? t('image_tools_ready', 'Ready') : 'Smart optimized');
                extension = getFileExtension(actualType, item.file.name);
                basename = item.file.name.replace(/\.[^.]+$/, '');
                item.downloadName = basename + '-optimized.' + extension;
                renderQueue();

                if (downloadAfterCheckbox && downloadAfterCheckbox.checked) {
                    triggerDownload(item);
                }
            }

            function processItem(item) {
                var settings = getSettings();

                item.error = '';
                item.statusLabel = t('image_tools_processing', 'Processing…');
                renderQueue();

                var image = new Image();
                image.onload = function () {
                    var maxWidth = settings.maxWidth || image.width;
                    var maxHeight = settings.maxHeight || image.height;
                    var ratio = Math.min(maxWidth / image.width, maxHeight / image.height, 1);
                    var width = Math.max(1, Math.round(image.width * ratio));
                    var height = Math.max(1, Math.round(image.height * ratio));
                    var canvas = document.createElement('canvas');
                    var context;
                    var hasAlpha;
                    var candidateTypes;
                    var explicitFormat = settings.format !== 'keep';

                    canvas.width = width;
                    canvas.height = height;
                    context = canvas.getContext('2d');

                    if (!context) {
                        item.error = t('image_tools_failed', 'Unable to process this image in the current browser.');
                        item.statusLabel = item.error;
                        renderQueue();
                        return;
                    }

                    context.imageSmoothingEnabled = true;
                    if (Object.prototype.hasOwnProperty.call(context, 'imageSmoothingQuality')) {
                        context.imageSmoothingQuality = 'high';
                    }
                    context.clearRect(0, 0, width, height);
                    context.drawImage(image, 0, 0, width, height);

                    hasAlpha = detectTransparency(canvas);
                    candidateTypes = getCandidateTypes(item, settings, hasAlpha);

                    Promise.all(candidateTypes.map(function (type) {
                        return canvasToBlob(canvas, type, settings.quality).then(function (blob) {
                            if (!blob) {
                                return null;
                            }
                            if (explicitFormat && blob.type !== type) {
                                return null;
                            }
                            return {
                                blob: blob,
                                type: blob.type || type
                            };
                        });
                    })).then(function (results) {
                        var validResults = results.filter(function (entry) {
                            return !!entry && !!entry.blob;
                        });
                        var best;

                        if (!validResults.length) {
                            item.error = explicitFormat ? 'The selected export format is not supported in this browser.' : t('image_tools_failed', 'Unable to process this image in the current browser.');
                            item.statusLabel = item.error;
                            renderQueue();
                            return;
                        }

                        best = validResults.reduce(function (winner, candidate) {
                            var winnerScore;
                            var candidateScore;

                            if (!winner) {
                                return candidate;
                            }

                            winnerScore = winner.blob.size;
                            candidateScore = candidate.blob.size;

                            if (isLossyType(candidate.type) && !isLossyType(winner.type)) {
                                candidateScore *= 0.97;
                            }
                            if (isLossyType(winner.type) && !isLossyType(candidate.type)) {
                                winnerScore *= 0.97;
                            }

                            if (candidateScore < winnerScore) {
                                return candidate;
                            }
                            return winner;
                        }, null);

                        if (shouldKeepOriginalResult(item, best.blob, width, height, best.type, settings)) {
                            cloneOriginalAsOutput(item);
                            item.statusLabel = 'Original kept';
                            renderQueue();
                            if (downloadAfterCheckbox && downloadAfterCheckbox.checked) {
                                triggerDownload(item);
                            }
                            return;
                        }

                        applyOutput(item, best.blob, width, height, settings);
                    }).catch(function () {
                        item.error = t('image_tools_failed', 'Unable to process this image in the current browser.');
                        item.statusLabel = item.error;
                        renderQueue();
                    });
                };

                image.onerror = function () {
                    item.error = t('image_tools_failed', 'Unable to process this image in the current browser.');
                    item.statusLabel = item.error;
                    renderQueue();
                };

                image.src = item.originalUrl;
            }

            function addFiles(fileList) {
                var validCount = 0;
                var incomingFiles = Array.prototype.slice.call(fileList || []);
                var remainingSlots = Math.max(0, maxQueueItems - items.length);

                if (!remainingSlots) {
                    setText(statusNode, 'Queue limit reached. Clear some items before adding more.');
                    return;
                }

                if (incomingFiles.length > remainingSlots) {
                    setText(statusNode, 'Only the first available files were added because the queue limit is 20 images.');
                    incomingFiles = incomingFiles.slice(0, remainingSlots);
                }

                incomingFiles.forEach(function (file) {
                    if (!file || !file.type || file.type.indexOf('image/') !== 0) {
                        return;
                    }

                    validCount += 1;
                    itemCounter += 1;

                    items.push({
                        id: itemCounter,
                        file: file,
                        originalUrl: URL.createObjectURL(file),
                        outputUrl: '',
                        outputBlob: null,
                        statusLabel: t('image_tools_processing', 'Processing…'),
                        error: '',
                        node: null,
                        originalDimensions: null,
                        outputDimensions: null,
                        downloadName: file.name
                    });
                });

                if (!validCount) {
                    setText(statusNode, t('image_tools_invalid', 'Only image files are supported here.'));
                    return;
                }

                items.forEach(function (item) {
                    if (!item.originalDimensions) {
                        var probe = new Image();
                        probe.onload = function () {
                            item.originalDimensions = {
                                width: probe.width,
                                height: probe.height
                            };
                            renderItem(item);
                        };
                        probe.src = item.originalUrl;
                    }
                });

                setText(statusNode, t('image_tools_browser_only', 'Local browser mode. Files stay on this device.'));
                renderQueue();

                if (autoProcessCheckbox && autoProcessCheckbox.checked) {
                    items.forEach(function (item) {
                        if (!item.outputBlob) {
                            processItem(item);
                        }
                    });
                }
            }

            function handleDrop(files) {
                if (dropzone) {
                    dropzone.classList.remove('is-dragover');
                }
                setText(dropCopyNode, t('image_tools_drop_idle', 'Drag PNG, JPG, WEBP, or AVIF files here, or browse from your device.'));
                addFiles(files);
            }

            function handleDownloadAll() {
                items.forEach(function (item, index) {
                    if (item.outputBlob && item.outputUrl) {
                        window.setTimeout(function () {
                            triggerDownload(item);
                        }, index * 120);
                    }
                });
            }

            function clearQueue() {
                items.forEach(cleanupItem);
                items = [];
                renderQueue();
                setText(statusNode, t('image_tools_empty', 'Add one or more images to begin.'));
            }

            function reprocessAll() {
                if (!items.length) {
                    setText(statusNode, t('image_tools_empty', 'Add one or more images to begin.'));
                    return;
                }
                items.forEach(function (item) {
                    processItem(item);
                });
            }

            if (dropzone) {
                ['dragenter', 'dragover'].forEach(function (eventName) {
                    dropzone.addEventListener(eventName, function (event) {
                        event.preventDefault();
                        event.stopPropagation();
                        dropzone.classList.add('is-dragover');
                        setText(dropCopyNode, t('image_tools_drop_active', 'Release to add these images to the queue.'));
                    });
                });

                ['dragleave', 'dragend', 'drop'].forEach(function (eventName) {
                    dropzone.addEventListener(eventName, function (event) {
                        event.preventDefault();
                        event.stopPropagation();
                        if (eventName !== 'drop') {
                            dropzone.classList.remove('is-dragover');
                            setText(dropCopyNode, t('image_tools_drop_idle', 'Drag PNG, JPG, WEBP, or AVIF files here, or browse from your device.'));
                        }
                    });
                });

                dropzone.addEventListener('drop', function (event) {
                    handleDrop(event.dataTransfer ? event.dataTransfer.files : null);
                });
            }

            if (input) {
                input.addEventListener('change', function (event) {
                    handleDrop(event.target.files || []);
                    input.value = '';
                });
            }
            if (browseButton) {
                browseButton.addEventListener('click', function () {
                    if (input) {
                        input.click();
                    }
                });
            }
            if (reprocessButton) {
                reprocessButton.addEventListener('click', reprocessAll);
            }
            if (downloadAllButton) {
                downloadAllButton.addEventListener('click', handleDownloadAll);
            }
            if (clearButton) {
                clearButton.addEventListener('click', clearQueue);
            }
            if (qualityInput) {
                qualityInput.addEventListener('input', updateQualityReadout);
            }
            if (formatSelect) {
                formatSelect.addEventListener('change', updateQualityControls);
            }

            presetButtons.forEach(function (button) {
                button.addEventListener('click', function () {
                    if (!qualityInput || button.disabled) {
                        return;
                    }
                    qualityInput.value = String(button.getAttribute('data-image-tools-preset') || qualityInput.value || '0.94');
                    updateQualityReadout();
                });
            });

            viewButtons.forEach(function (button) {
                button.addEventListener('click', function () {
                    setQueueView(button.getAttribute('data-image-tools-view-toggle'));
                });
            });

            updateQualityControls();
            setQueueView('cards');
            buildEmptyState();
            updateStats();
        }

        function initDesign() {
            var designInput = root.querySelector('[data-image-design-input]');
            var designDropzones = root.querySelectorAll('[data-image-design-dropzone]');
            var designStage = root.querySelector('[data-image-design-stage]');
            var designCanvas = root.querySelector('[data-image-design-canvas]');
            var designEmpty = root.querySelector('[data-image-design-empty]');
            var designStatus = root.querySelector('[data-image-design-status]');
            var designAspectButtons = root.querySelectorAll('[data-image-design-aspect]');
            var designFilterButtons = root.querySelectorAll('[data-image-design-filter]');
            var designActionButtons = root.querySelectorAll('[data-image-design-action]');
            var designAdjustInputs = root.querySelectorAll('[data-image-design-adjust]');
            var designQualityInput = root.querySelector('[data-image-design-quality]');
            var designQualityReadout = root.querySelector('[data-image-design-quality-readout]');
            var designFormatSelect = root.querySelector('[data-image-design-format]');
            var designScaleSelect = root.querySelector('[data-image-design-scale]');
            var layerListNode = root.querySelector('[data-image-design-layer-list]');
            var selectedFields = root.querySelectorAll('[data-image-design-layer-field]');
            var noSelectionNode = root.querySelector('[data-image-design-no-selection]');
            var selectedPanel = root.querySelector('[data-image-design-selected-panel]');
            var watermarkInput = root.querySelector('[data-image-design-watermark]');
            var watermarkSizeInput = root.querySelector('[data-image-design-watermark-size]');
            var watermarkOpacityInput = root.querySelector('[data-image-design-watermark-opacity]');
            var watermarkColorInput = root.querySelector('[data-image-design-watermark-color]');
            var watermarkPositionSelect = root.querySelector('[data-image-design-watermark-position]');
            var watermarkImageInput = root.querySelector('[data-image-design-watermark-image]');
            var watermarkImageScaleInput = root.querySelector('[data-image-design-watermark-image-scale]');
            var designPreviewStage = root.querySelector('[data-image-design-preview-stage]');
            var designDraftStorageKey = 'noesia_swa_image_design_draft_v2';
            var designDraftDbName = 'noesia_swa_image_design';
            var designDraftStoreName = 'drafts';
            var designDraftRecordId = 'main';
            var designPanelStorageKey = 'noesia_swa_image_design_panels_v1';
            var designPreviewCanvas = root.querySelector('[data-image-design-preview-canvas]');
            var designThumbStrip = root.querySelector('[data-image-design-thumbs]');
            var designQuickFont = root.querySelector('[data-image-design-quick-font]');
            var designQuickSize = root.querySelector('[data-image-design-quick-size]');
            var designQuickColor = root.querySelector('[data-image-design-quick-color]');
            var designQuickBgColor = root.querySelector('[data-image-design-quick-bg-color]');
            var designBrushButtons = root.querySelectorAll('[data-image-design-brush]');
            var designPrivacyModeSelect = root.querySelector('[data-image-design-privacy-mode]');
            var designBrushSizeInput = root.querySelector('[data-image-design-brush-size]');
            var designBrushStrengthInput = root.querySelector('[data-image-design-brush-strength]');
            var designBrushSizeReadout = root.querySelector('[data-image-design-brush-size-readout]');
            var designBrushStrengthReadout = root.querySelector('[data-image-design-brush-strength-readout]');
            var designStageBgInput = root.querySelector('[data-image-design-bg-color]');
            var designStageBgPresetButtons = root.querySelectorAll('[data-image-design-bg-preset]');
            var designAddModeSelect = root.querySelector('[data-image-design-add-mode]');
            var readoutNodes = root.querySelectorAll('[data-design-readout]');
            var stageContext = designCanvas ? designCanvas.getContext('2d') : null;
            var designPreviewContext = designPreviewCanvas ? designPreviewCanvas.getContext('2d') : null;
            var stageFrame = null;
            var previewCache = { key: '', canvas: null };
            var originalPreviewCache = { key: '', canvas: null };
            var history = [];
            var historyIndex = -1;
            var historyTimer = null;
            var draftSaveTimer = null;
            var interaction = null;
            var isSpaceDown = false;
            var layerCounter = 0;
            var renderPending = false;
            var resizeObserver;
            var canUseCanvasFilter = (function () {
                try {
                    var probe = document.createElement('canvas').getContext('2d');
                    return !!(probe && ('filter' in probe));
                } catch (error) {
                    return false;
                }
            }());
            var watermarkImageUrl = '';
            var designAssets = [];
            var activeDesignAssetId = null;
            var designAssetCounter = 0;
            var copiedCropLayer = null;
            var layerClipboard = null;
            var layerStyleClipboard = null;
            var activeSnapGuides = [];
            var isShiftDown = false;
            var brushHover = null;

            if (!designCanvas || !designStage || !stageContext) {
                return;
            }

            var state = {
                image: null,
                imageUrl: '',
                imageName: '',
                crop: { x: 0, y: 0, width: 0, height: 0 },
                aspect: 'free',
                viewport: { zoom: 1, panX: 0, panY: 0 },
                safeArea: false,
                previewOriginal: false,
                hasCustomCrop: false,
                filter: 'original',
                adjustments: {
                    brightness: 100,
                    contrast: 100,
                    saturation: 100,
                    warmth: 0,
                    sharpen: 0,
                    vignette: 0,
                    splashTolerance: 60
                },
                splash: {
                    active: false,
                    armed: false,
                    target: null
                },
                retouch: {
                    tool: 'none',
                    size: 96,
                    strength: 42
                },
                retouchStrokes: [],
                layers: [],
                selectedLayerId: null,
                baseLayer: {
                    visible: true,
                    deleted: false,
                    name: 'Base image'
                },
                watermark: {
                    text: '',
                    size: 34,
                    opacity: 0.8,
                    position: 'bottom-right',
                    imageSrc: '',
                    imageScale: 0.28,
                    imageOpacity: 0.9,
                    color: '#ffffff',
                    textOffsetX: 0,
                    textOffsetY: 0,
                    imageOffsetX: 0,
                    imageOffsetY: 0
                },
                exportFormat: 'image/png',
                exportQuality: 0.92,
                exportScale: 1,
                workspaceBackground: '#0f172a',
                showGrid: false,
                quickText: {
                    fontFamily: 'Arial, sans-serif',
                    fontSize: 48,
                    color: '#ffffff',
                    backgroundColor: ''
                }
            };

            var designFilterPresets = {
                'original': {},
                'clean-daylight': { brightness: 104, contrast: 104, saturation: 104, warmth: 4 },
                'soft-portrait': { brightness: 106, contrast: 96, saturation: 92, warmth: 6 },
                'crisp-food': { brightness: 103, contrast: 114, saturation: 122, warmth: 6 },
                'miami-sunset': { brightness: 104, contrast: 108, saturation: 126, warmth: 12, tint: [255, 108, 88], tintAmount: 0.08 },
                'dark-noir': { brightness: 76, contrast: 124, saturation: 42, vignette: 16 },
                'morning-dew': { brightness: 108, contrast: 96, saturation: 102, tint: [140, 220, 255], tintAmount: 0.05 },
                'cyberpunk': { brightness: 100, contrast: 120, saturation: 136, tint: [255, 0, 153], tintAmount: 0.08, hue: -12 },
                'vintage-80s': { brightness: 96, contrast: 108, saturation: 88, sepia: 0.28, warmth: 6 },
                'cinema-warm': { brightness: 98, contrast: 110, saturation: 112, warmth: 10 },
                'arctic-clarity': { brightness: 108, contrast: 108, saturation: 88, warmth: -8 },
                'desert-glow': { brightness: 108, contrast: 104, saturation: 114, warmth: 14, sepia: 0.12 },
                'urban-steel': { brightness: 96, contrast: 112, saturation: 76, warmth: -6 },
                'pearl-soft': { brightness: 108, contrast: 94, saturation: 84 },
                'forest-mist': { brightness: 94, contrast: 108, saturation: 106, tint: [78, 150, 88], tintAmount: 0.06 },
                'food-pop': { brightness: 105, contrast: 120, saturation: 128, warmth: 8 },
                'retro-print': { brightness: 94, contrast: 112, saturation: 88, sepia: 0.24 },
                'night-drive': { brightness: 84, contrast: 120, saturation: 112, tint: [0, 90, 180], tintAmount: 0.08 },
                'berry-fade': { brightness: 102, contrast: 102, saturation: 108, tint: [168, 66, 128], tintAmount: 0.07 },
                'mono-pro': { grayscale: 1, contrast: 112, brightness: 102 },
                'teal-copper': { brightness: 98, contrast: 114, saturation: 108, tint: [30, 120, 120], tintAmount: 0.05, warmth: 6 },
                'breeze': { brightness: 106, contrast: 98, saturation: 98, warmth: -4 },
                'golden-hour': { brightness: 106, contrast: 106, saturation: 116, warmth: 16, sepia: 0.1 },
                'editorial': { brightness: 100, contrast: 116, saturation: 94 },
                'clean-studio': { brightness: 102, contrast: 104, saturation: 98 },
                'velvet-night': { brightness: 80, contrast: 122, saturation: 108, tint: [60, 0, 80], tintAmount: 0.08 },
                'mint-air': { brightness: 106, contrast: 100, saturation: 92, tint: [120, 220, 180], tintAmount: 0.06 },
                'amber-room': { brightness: 104, contrast: 108, saturation: 112, warmth: 18, sepia: 0.16 },
                'lux-silver': { brightness: 104, contrast: 108, saturation: 72, grayscale: 0.12 },
                'sunrise-pop': { brightness: 108, contrast: 110, saturation: 122, warmth: 12 },
                'blue-hour': { brightness: 94, contrast: 112, saturation: 104, warmth: -14 },
                'glass-film': { brightness: 104, contrast: 98, saturation: 92, tint: [215, 235, 255], tintAmount: 0.04 }
            };

            function createDefaultAdjustments() {
                return {
                    brightness: 100,
                    contrast: 100,
                    saturation: 100,
                    warmth: 0,
                    sharpen: 0,
                    vignette: 0,
                    splashTolerance: 60
                };
            }

            function createDefaultSplashState() {
                return {
                    active: false,
                    armed: false,
                    target: null
                };
            }


            function createDefaultRetouchState() {
                return {
                    tool: 'none',
                    size: 96,
                    strength: 42
                };
            }

            function ensureRetouchState() {
                if (!state.retouch) {
                    state.retouch = createDefaultRetouchState();
                }
                if (!Array.isArray(state.retouchStrokes)) {
                    state.retouchStrokes = [];
                }
                return state.retouch;
            }

            function normalizeRetouchTool(tool) {
                return tool === 'blur' || tool === 'pixelate' || tool === 'eraser' || tool === 'privacy' ? tool : 'none';
            }

            function getRetouchTool() {
                return normalizeRetouchTool((ensureRetouchState().tool || 'none'));
            }

            function hasActiveRetouchTool() {
                return getRetouchTool() !== 'none';
            }

            function getRetouchSize() {
                return clamp(Math.round(Number(ensureRetouchState().size || 96)), 12, 260);
            }

            function getRetouchStrength() {
                return clamp(Math.round(Number(ensureRetouchState().strength || 42)), 8, 100);
            }

            function getRetouchToolLabel(tool) {
                switch (normalizeRetouchTool(tool)) {
                case 'pixelate':
                    return 'Pixelate';
                case 'eraser':
                    return 'Eraser';
                case 'privacy':
                    return 'Privacy';
                case 'blur':
                    return 'Blur';
                default:
                    return 'Brush';
                }
            }

            function getRetouchToolActionLabel(tool) {
                switch (normalizeRetouchTool(tool)) {
                case 'pixelate':
                    return 'Pixelating';
                case 'eraser':
                    return 'Erasing';
                case 'privacy':
                    return 'Masking';
                case 'blur':
                    return 'Blurring';
                default:
                    return 'Editing';
                }
            }

            function getRetouchHoverColor(tool) {
                switch (normalizeRetouchTool(tool)) {
                case 'pixelate':
                    return 'rgba(251, 191, 36, 0.92)';
                case 'eraser':
                    return 'rgba(248, 113, 113, 0.92)';
                case 'privacy':
                    return 'rgba(168, 85, 247, 0.92)';
                default:
                    return 'rgba(96, 165, 250, 0.92)';
                }
            }

            function syncBrushControls() {
                var activeTool = getRetouchTool();
                if (designBrushButtons && designBrushButtons.length) {
                    designBrushButtons.forEach(function (button) {
                        button.classList.toggle('is-active', button.getAttribute('data-image-design-brush') === activeTool);
                    });
                }
                if (designBrushSizeInput) {
                    designBrushSizeInput.value = String(getRetouchSize());
                }
                if (designBrushStrengthInput) {
                    designBrushStrengthInput.value = String(getRetouchStrength());
                }
                if (designBrushSizeReadout) {
                    designBrushSizeReadout.textContent = String(getRetouchSize()) + 'px';
                }
                if (designBrushStrengthReadout) {
                    designBrushStrengthReadout.textContent = String(getRetouchStrength()) + '%';
                }
            }

            function ensureLayerRetouchStrokes(layer) {
                if (!layer) {
                    return [];
                }
                if (!Array.isArray(layer.retouchStrokes)) {
                    layer.retouchStrokes = [];
                }
                return layer.retouchStrokes;
            }

            function getRetouchTargetLabel(target) {
                if (!target) {
                    return 'image';
                }
                if (target.kind === 'layer' && target.layer) {
                    return target.layer.name || 'selected image layer';
                }
                return 'base image';
            }

            function getPrivacyShapeMode() {
                if (!designPrivacyModeSelect) {
                    return 'privacy';
                }
                return ['privacy', 'blur', 'pixelate'].indexOf(designPrivacyModeSelect.value) !== -1 ? designPrivacyModeSelect.value : 'privacy';
            }

            function getPrivacyShapeColor(mode) {
                switch (mode) {
                case 'blur':
                    return '#38bdf8';
                case 'pixelate':
                    return '#f59e0b';
                default:
                    return '#0f172a';
                }
            }

            function createCanvasCopy(sourceCanvas) {
                var copy = document.createElement('canvas');
                var copyContext;
                copy.width = Math.max(1, sourceCanvas.width || 1);
                copy.height = Math.max(1, sourceCanvas.height || 1);
                copyContext = copy.getContext('2d');
                if (copyContext) {
                    copyContext.drawImage(sourceCanvas, 0, 0);
                }
                return copy;
            }

            function traceShapePath(ctx, layer) {
                if (layer.shape === 'circle') {
                    ctx.beginPath();
                    ctx.ellipse(layer.x + (layer.width / 2), layer.y + (layer.height / 2), Math.abs(layer.width) / 2, Math.abs(layer.height) / 2, 0, 0, Math.PI * 2);
                    ctx.closePath();
                    return;
                }
                ctx.beginPath();
                ctx.rect(layer.x, layer.y, layer.width, layer.height);
                ctx.closePath();
            }

            function buildShapePrivacyEffectCanvas(sourceCanvas, mode, strength) {
                var normalized = ['privacy', 'blur', 'pixelate'].indexOf(mode) !== -1 ? mode : 'privacy';
                if (normalized === 'blur') {
                    return buildBlurEffectCanvas(sourceCanvas, Math.max(10, Math.round((Number(strength || 42) / 100) * 42)));
                }
                if (normalized === 'pixelate') {
                    return buildPixelateEffectCanvas(sourceCanvas, Math.max(8, Math.round((Number(strength || 42) / 100) * 30)));
                }
                return buildPrivacyEffectCanvas(sourceCanvas, strength || 88);
            }

            function createPrivacyShapeLayer(shape, mode) {
                var layer = createBaseLayer(shape === 'circle' ? 'circle' : 'rect');
                var normalizedMode = ['privacy', 'blur', 'pixelate'].indexOf(mode) !== -1 ? mode : 'privacy';
                var title = normalizedMode === 'blur' ? 'Blur' : (normalizedMode === 'pixelate' ? 'Pixelate' : 'Privacy');
                layer.name = title + ' ' + (shape === 'circle' ? 'round ' : 'box ') + layer.id;
                layer.privacyMode = normalizedMode;
                layer.privacyStrength = normalizedMode === 'privacy' ? 92 : getRetouchStrength();
                layer.fill = normalizedMode === 'privacy' ? '#000000' : 'rgba(0,0,0,0)';
                layer.opacity = normalizedMode === 'privacy' ? 0.94 : 1;
                layer.strokeWidth = 2;
                layer.strokeColor = getPrivacyShapeColor(normalizedMode);
                layer.rotation = 0;
                return layer;
            }

            function getStageImageRect() {
                return state.image ? rectToStage({ x: 0, y: 0, width: state.image.width, height: state.image.height }) : null;
            }

            function getStageFit() {
                if (!state.image || !stageFrame) {
                    return 1;
                }
                return Math.min(stageFrame.width / state.image.width, stageFrame.height / state.image.height) * state.viewport.zoom;
            }

            function getBrushHoverRadius(target) {
                if (!target) {
                    return 0;
                }
                if (target.kind === 'layer' && target.layer && target.sourceWidth && target.layer.width) {
                    return Math.max(8, (getRetouchSize() / Math.max(1, target.sourceWidth)) * target.layer.width * getStageFit());
                }
                return Math.max(8, getRetouchSize() * getStageFit());
            }

            function updateBrushHover(target, stageX, stageY) {
                if (!target || !hasActiveRetouchTool()) {
                    if (brushHover) {
                        brushHover = null;
                        scheduleRender();
                    }
                    return;
                }
                var next = {
                    x: stageX,
                    y: stageY,
                    radius: getBrushHoverRadius(target),
                    tool: getRetouchTool()
                };
                if (!brushHover || Math.abs((brushHover.x || 0) - next.x) > 0.5 || Math.abs((brushHover.y || 0) - next.y) > 0.5 || Math.abs((brushHover.radius || 0) - next.radius) > 0.5 || brushHover.tool !== next.tool) {
                    brushHover = next;
                    scheduleRender();
                }
            }

            function clearBrushHover() {
                if (brushHover) {
                    brushHover = null;
                    scheduleRender();
                }
            }

            function pointToLayerSourcePoint(layer, imagePoint) {
                if (!layer || layer.type !== 'image' || !imagePoint) {
                    return null;
                }
                var sourceWidth = Math.max(1, Math.round((layer.image && layer.image.naturalWidth) || layer.width || 1));
                var sourceHeight = Math.max(1, Math.round((layer.image && layer.image.naturalHeight) || layer.height || 1));
                var centerX = layer.x + (layer.width / 2);
                var centerY = layer.y + (layer.height / 2);
                var dx = imagePoint.x - centerX;
                var dy = imagePoint.y - centerY;
                var localX = dx;
                var localY = dy;
                if (layer.rotation) {
                    var radians = (normalizeRotation(layer.rotation) * Math.PI) / 180;
                    var cos = Math.cos(-radians);
                    var sin = Math.sin(-radians);
                    localX = (dx * cos) - (dy * sin);
                    localY = (dx * sin) + (dy * cos);
                }
                localX += layer.width / 2;
                localY += layer.height / 2;
                if (localX < 0 || localY < 0 || localX > layer.width || localY > layer.height) {
                    return null;
                }
                return {
                    x: clamp((localX / Math.max(1, layer.width)) * sourceWidth, 0, sourceWidth),
                    y: clamp((localY / Math.max(1, layer.height)) * sourceHeight, 0, sourceHeight),
                    sourceWidth: sourceWidth,
                    sourceHeight: sourceHeight
                };
            }

            function getRetouchTargetAtPoint(stageX, stageY, imagePoint) {
                var hit = hitLayer(stageX, stageY);
                var mapped;
                var imageRect;
                if (hit && hit.type === 'image' && !hit.locked) {
                    mapped = pointToLayerSourcePoint(hit, imagePoint);
                    if (mapped) {
                        return {
                            kind: 'layer',
                            layer: hit,
                            point: mapped,
                            sourceWidth: mapped.sourceWidth,
                            sourceHeight: mapped.sourceHeight
                        };
                    }
                }
                imageRect = getStageImageRect();
                if (imageRect && pointInStageRect(stageX, stageY, imageRect) && state.baseLayer && state.baseLayer.visible !== false && !state.baseLayer.deleted) {
                    return {
                        kind: 'base',
                        point: {
                            x: clamp(imagePoint.x, 0, state.image.width),
                            y: clamp(imagePoint.y, 0, state.image.height)
                        },
                        sourceWidth: state.image.width,
                        sourceHeight: state.image.height
                    };
                }
                return null;
            }

            function getRetouchStrokeStore(target) {
                if (!target) {
                    return [];
                }
                if (target.kind === 'layer' && target.layer) {
                    return ensureLayerRetouchStrokes(target.layer);
                }
                ensureRetouchState();
                return state.retouchStrokes;
            }

            function drawStrokePath(ctx, stroke, scaleX, scaleY) {
                var points = Array.isArray(stroke.points) ? stroke.points : [];
                var lineWidth = Math.max(2, ((Number(stroke.size || getRetouchSize()) * (Math.abs(scaleX) + Math.abs(scaleY))) / 2));
                if (!points.length) {
                    return;
                }
                ctx.save();
                ctx.lineCap = 'round';
                ctx.lineJoin = 'round';
                ctx.strokeStyle = '#000000';
                ctx.fillStyle = '#000000';
                ctx.lineWidth = lineWidth;
                if (points.length === 1) {
                    ctx.beginPath();
                    ctx.arc(points[0].x * scaleX, points[0].y * scaleY, lineWidth / 2, 0, Math.PI * 2);
                    ctx.fill();
                    ctx.restore();
                    return;
                }
                ctx.beginPath();
                ctx.moveTo(points[0].x * scaleX, points[0].y * scaleY);
                points.slice(1).forEach(function (point) {
                    ctx.lineTo(point.x * scaleX, point.y * scaleY);
                });
                ctx.stroke();
                ctx.restore();
            }

            function buildBlurEffectCanvas(sourceCanvas, strength) {
                var effectCanvas = document.createElement('canvas');
                var downscaleCanvas = document.createElement('canvas');
                var effectContext = effectCanvas.getContext('2d');
                var downscaleContext = downscaleCanvas.getContext('2d');
                var factor = clamp(Math.round(1 + (Number(strength || 42) / 12)), 2, 10);
                effectCanvas.width = sourceCanvas.width;
                effectCanvas.height = sourceCanvas.height;
                downscaleCanvas.width = Math.max(1, Math.round(sourceCanvas.width / factor));
                downscaleCanvas.height = Math.max(1, Math.round(sourceCanvas.height / factor));
                downscaleContext.clearRect(0, 0, downscaleCanvas.width, downscaleCanvas.height);
                downscaleContext.imageSmoothingEnabled = true;
                if (Object.prototype.hasOwnProperty.call(downscaleContext, 'imageSmoothingQuality')) {
                    downscaleContext.imageSmoothingQuality = 'medium';
                }
                downscaleContext.drawImage(sourceCanvas, 0, 0, downscaleCanvas.width, downscaleCanvas.height);
                effectContext.clearRect(0, 0, effectCanvas.width, effectCanvas.height);
                effectContext.imageSmoothingEnabled = true;
                if (Object.prototype.hasOwnProperty.call(effectContext, 'imageSmoothingQuality')) {
                    effectContext.imageSmoothingQuality = 'high';
                }
                effectContext.drawImage(downscaleCanvas, 0, 0, downscaleCanvas.width, downscaleCanvas.height, 0, 0, effectCanvas.width, effectCanvas.height);
                return effectCanvas;
            }

            function buildPixelateEffectCanvas(sourceCanvas, strength) {
                var effectCanvas = document.createElement('canvas');
                var downscaleCanvas = document.createElement('canvas');
                var effectContext = effectCanvas.getContext('2d');
                var downscaleContext = downscaleCanvas.getContext('2d');
                var factor = clamp(Math.round(1 + (Number(strength || 42) / 4)), 3, 28);
                effectCanvas.width = sourceCanvas.width;
                effectCanvas.height = sourceCanvas.height;
                downscaleCanvas.width = Math.max(1, Math.round(sourceCanvas.width / factor));
                downscaleCanvas.height = Math.max(1, Math.round(sourceCanvas.height / factor));
                downscaleContext.clearRect(0, 0, downscaleCanvas.width, downscaleCanvas.height);
                downscaleContext.imageSmoothingEnabled = false;
                downscaleContext.drawImage(sourceCanvas, 0, 0, downscaleCanvas.width, downscaleCanvas.height);
                effectContext.clearRect(0, 0, effectCanvas.width, effectCanvas.height);
                effectContext.imageSmoothingEnabled = false;
                effectContext.drawImage(downscaleCanvas, 0, 0, downscaleCanvas.width, downscaleCanvas.height, 0, 0, effectCanvas.width, effectCanvas.height);
                return effectCanvas;
            }

            function buildPrivacyEffectCanvas(sourceCanvas, strength) {
                var effectCanvas = document.createElement('canvas');
                var effectContext = effectCanvas.getContext('2d');
                var opacity = clamp(Number(strength || 42) / 100, 0.28, 1);
                effectCanvas.width = sourceCanvas.width;
                effectCanvas.height = sourceCanvas.height;
                effectContext.clearRect(0, 0, effectCanvas.width, effectCanvas.height);
                effectContext.globalAlpha = opacity;
                effectContext.fillStyle = '#000000';
                effectContext.fillRect(0, 0, effectCanvas.width, effectCanvas.height);
                effectContext.globalAlpha = 1;
                return effectCanvas;
            }

            function applyRetouchStrokes(canvas, strokes, coordinateWidth, coordinateHeight) {
                var sourceWidth = Math.max(1, Number(coordinateWidth || canvas.width || 1));
                var sourceHeight = Math.max(1, Number(coordinateHeight || canvas.height || 1));
                var list = Array.isArray(strokes) ? strokes : [];
                var canvasContext = canvas.getContext('2d');
                list.forEach(function (stroke) {
                    var maskCanvas;
                    var maskContext;
                    var maskedCanvas;
                    var maskedContext;
                    var effectCanvas;
                    if (!stroke || !Array.isArray(stroke.points) || !stroke.points.length) {
                        return;
                    }
                    maskCanvas = document.createElement('canvas');
                    maskCanvas.width = canvas.width;
                    maskCanvas.height = canvas.height;
                    maskContext = maskCanvas.getContext('2d');
                    drawStrokePath(maskContext, stroke, canvas.width / sourceWidth, canvas.height / sourceHeight);
                    if (stroke.tool === 'eraser') {
                        canvasContext.save();
                        canvasContext.globalCompositeOperation = 'destination-out';
                        canvasContext.drawImage(maskCanvas, 0, 0);
                        canvasContext.restore();
                        return;
                    }
                    if (stroke.tool === 'privacy') {
                        effectCanvas = buildPrivacyEffectCanvas(canvas, stroke.strength);
                    } else if (stroke.tool === 'pixelate') {
                        effectCanvas = buildPixelateEffectCanvas(canvas, stroke.strength);
                    } else {
                        effectCanvas = buildBlurEffectCanvas(canvas, stroke.strength);
                    }
                    maskedCanvas = document.createElement('canvas');
                    maskedCanvas.width = canvas.width;
                    maskedCanvas.height = canvas.height;
                    maskedContext = maskedCanvas.getContext('2d');
                    maskedContext.drawImage(effectCanvas, 0, 0);
                    maskedContext.globalCompositeOperation = 'destination-in';
                    maskedContext.drawImage(maskCanvas, 0, 0);
                    maskedContext.globalCompositeOperation = 'source-over';
                    canvasContext.drawImage(maskedCanvas, 0, 0);
                });
            }

            function getSelectedImageLayer() {
                var selected = getSelectedLayer();
                return selected && selected.type === 'image' ? selected : null;
            }

            function getToneStateTarget() {
                var selectedImageLayer = getSelectedImageLayer();
                if (selectedImageLayer) {
                    if (!selectedImageLayer.adjustments) {
                        selectedImageLayer.adjustments = createDefaultAdjustments();
                    }
                    if (!selectedImageLayer.splash) {
                        selectedImageLayer.splash = createDefaultSplashState();
                    }
                    if (!selectedImageLayer.filter) {
                        selectedImageLayer.filter = 'original';
                    }
                    return {
                        filter: selectedImageLayer.filter,
                        adjustments: selectedImageLayer.adjustments,
                        splash: selectedImageLayer.splash,
                        isLayer: true,
                        layer: selectedImageLayer
                    };
                }
                return {
                    filter: state.filter,
                    adjustments: state.adjustments,
                    splash: state.splash,
                    isLayer: false,
                    layer: null
                };
            }

            function clampByte(value) {
                return Math.max(0, Math.min(255, Math.round(value)));
            }

            function rgbToHsl(r, g, b) {
                r /= 255; g /= 255; b /= 255;
                var max = Math.max(r, g, b);
                var min = Math.min(r, g, b);
                var h = 0;
                var sVal = 0;
                var l = (max + min) / 2;
                var d;
                if (max !== min) {
                    d = max - min;
                    sVal = l > 0.5 ? d / (2 - max - min) : d / (max + min);
                    switch (max) {
                    case r: h = ((g - b) / d) + (g < b ? 6 : 0); break;
                    case g: h = ((b - r) / d) + 2; break;
                    default: h = ((r - g) / d) + 4; break;
                    }
                    h /= 6;
                }
                return [h, sVal, l];
            }

            function hueToRgb(p, q, t) {
                if (t < 0) { t += 1; }
                if (t > 1) { t -= 1; }
                if (t < 1 / 6) { return p + (q - p) * 6 * t; }
                if (t < 1 / 2) { return q; }
                if (t < 2 / 3) { return p + (q - p) * (2 / 3 - t) * 6; }
                return p;
            }

            function hslToRgb(h, sVal, l) {
                var r; var g; var b; var q; var p;
                if (sVal === 0) {
                    r = g = b = l;
                } else {
                    q = l < 0.5 ? l * (1 + sVal) : l + sVal - (l * sVal);
                    p = (2 * l) - q;
                    r = hueToRgb(p, q, h + 1 / 3);
                    g = hueToRgb(p, q, h);
                    b = hueToRgb(p, q, h - 1 / 3);
                }
                return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
            }

            function getActiveProcessingPreset(filterName, adjustments) {
                var preset = designFilterPresets[filterName || 'original'] || {};
                var sourceAdjustments = adjustments || createDefaultAdjustments();
                return {
                    brightness: ((preset.brightness || 100) * (sourceAdjustments.brightness || 100)) / 100,
                    contrast: ((preset.contrast || 100) * (sourceAdjustments.contrast || 100)) / 100,
                    saturation: ((preset.saturation || 100) * (sourceAdjustments.saturation || 100)) / 100,
                    warmth: (preset.warmth || 0) + (sourceAdjustments.warmth || 0),
                    grayscale: preset.grayscale || 0,
                    sepia: preset.sepia || 0,
                    hue: preset.hue || 0,
                    tint: preset.tint || null,
                    tintAmount: preset.tintAmount || 0
                };
            }

            function applyPixelProcessing(canvas, filterName, adjustments) {
                var preset = getActiveProcessingPreset(filterName, adjustments);
                var ctx = canvas.getContext('2d');
                var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
                var data = imageData.data;
                var brightnessFactor = preset.brightness / 100;
                var contrastFactor = preset.contrast / 100;
                var saturationFactor = preset.saturation / 100;
                var warmth = preset.warmth;
                var index;
                for (index = 0; index < data.length; index += 4) {
                    var r = data[index];
                    var g = data[index + 1];
                    var b = data[index + 2];
                    var gray;
                    var hsl;
                    var shifted;

                    r *= brightnessFactor;
                    g *= brightnessFactor;
                    b *= brightnessFactor;

                    r = ((r / 255 - 0.5) * contrastFactor + 0.5) * 255;
                    g = ((g / 255 - 0.5) * contrastFactor + 0.5) * 255;
                    b = ((b / 255 - 0.5) * contrastFactor + 0.5) * 255;

                    gray = (r * 0.299) + (g * 0.587) + (b * 0.114);
                    r = gray + ((r - gray) * saturationFactor);
                    g = gray + ((g - gray) * saturationFactor);
                    b = gray + ((b - gray) * saturationFactor);

                    if (preset.grayscale) {
                        r = (r * (1 - preset.grayscale)) + (gray * preset.grayscale);
                        g = (g * (1 - preset.grayscale)) + (gray * preset.grayscale);
                        b = (b * (1 - preset.grayscale)) + (gray * preset.grayscale);
                    }

                    if (preset.sepia) {
                        var sr = (r * 0.393) + (g * 0.769) + (b * 0.189);
                        var sg = (r * 0.349) + (g * 0.686) + (b * 0.168);
                        var sb = (r * 0.272) + (g * 0.534) + (b * 0.131);
                        r = (r * (1 - preset.sepia)) + (sr * preset.sepia);
                        g = (g * (1 - preset.sepia)) + (sg * preset.sepia);
                        b = (b * (1 - preset.sepia)) + (sb * preset.sepia);
                    }

                    if (preset.hue) {
                        hsl = rgbToHsl(clampByte(r), clampByte(g), clampByte(b));
                        shifted = hslToRgb((hsl[0] + (preset.hue / 360) + 1) % 1, hsl[1], hsl[2]);
                        r = shifted[0];
                        g = shifted[1];
                        b = shifted[2];
                    }

                    if (warmth) {
                        r += warmth * 1.35;
                        g += warmth * 0.18;
                        b -= warmth * 1.15;
                    }

                    if (preset.tint && preset.tintAmount) {
                        r = (r * (1 - preset.tintAmount)) + (preset.tint[0] * preset.tintAmount);
                        g = (g * (1 - preset.tintAmount)) + (preset.tint[1] * preset.tintAmount);
                        b = (b * (1 - preset.tintAmount)) + (preset.tint[2] * preset.tintAmount);
                    }

                    data[index] = clampByte(r);
                    data[index + 1] = clampByte(g);
                    data[index + 2] = clampByte(b);
                }
                ctx.putImageData(imageData, 0, 0);
            }




            function setDesignStatus(message) {
                setText(designStatus, message);
            }

            function getCurrentAddMode() {
                if (!designAddModeSelect || !designAddModeSelect.value) {
                    return 'thumbnail';
                }
                return designAddModeSelect.value === 'layer' ? 'layer' : 'thumbnail';
            }

            function normalizeRotation(value) {
                var rotation = Number(value || 0) % 360;
                if (rotation < 0) {
                    rotation += 360;
                }
                return rotation;
            }

            function getRotatedRectBounds(x, y, width, height, rotation) {
                var angle = (normalizeRotation(rotation) * Math.PI) / 180;
                if (!angle) {
                    return { x: x, y: y, width: width, height: height };
                }
                var cx = x + (width / 2);
                var cy = y + (height / 2);
                var points = [
                    { x: x, y: y },
                    { x: x + width, y: y },
                    { x: x + width, y: y + height },
                    { x: x, y: y + height }
                ].map(function (point) {
                    var dx = point.x - cx;
                    var dy = point.y - cy;
                    return {
                        x: cx + (dx * Math.cos(angle)) - (dy * Math.sin(angle)),
                        y: cy + (dx * Math.sin(angle)) + (dy * Math.cos(angle))
                    };
                });
                var xs = points.map(function (point) { return point.x; });
                var ys = points.map(function (point) { return point.y; });
                var minX = Math.min.apply(Math, xs);
                var maxX = Math.max.apply(Math, xs);
                var minY = Math.min.apply(Math, ys);
                var maxY = Math.max.apply(Math, ys);
                return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
            }

            function applyWorkspaceBackground() {
                if (!designStage) {
                    return;
                }
                designStage.style.setProperty('--design-stage-bg', state.workspaceBackground || '#0f172a');
                if (designStageBgInput) {
                    designStageBgInput.value = state.workspaceBackground || '#0f172a';
                }
                designStageBgPresetButtons.forEach(function (button) {
                    button.classList.toggle('is-active', button.getAttribute('data-image-design-bg-preset') === (state.workspaceBackground || '#0f172a'));
                });
                designActionButtons.forEach(function (button) {
                    if (button.getAttribute('data-image-design-action') === 'toggle-grid') {
                        button.classList.toggle('is-active', !!state.showGrid);
                    }
                });
            }

            function rotateVectorLayer(layer, degrees) {
                if (!layer || (layer.shape !== 'arrow' && layer.shape !== 'line')) {
                    return;
                }
                var cx = layer.x + (layer.width / 2);
                var cy = layer.y + (layer.height / 2);
                var angle = Math.atan2(layer.height, layer.width) + ((degrees * Math.PI) / 180);
                var length = Math.sqrt((layer.width * layer.width) + (layer.height * layer.height));
                layer.width = Math.round(Math.cos(angle) * length);
                layer.height = Math.round(Math.sin(angle) * length);
                layer.x = Math.round(cx - (layer.width / 2));
                layer.y = Math.round(cy - (layer.height / 2));
            }

            function rotateSelectedSelection(degrees) {
                var selected = getSelectedLayer();
                if (!selected || selected.locked) {
                    setDesignStatus('Select a layer first before rotating.');
                    return;
                }
                if (selected.type === 'shape' && (selected.shape === 'arrow' || selected.shape === 'line')) {
                    rotateVectorLayer(selected, degrees);
                } else {
                    selected.rotation = normalizeRotation((selected.rotation || 0) + degrees);
                }
                syncSelectedLayerControls();
                scheduleRender();
                pushHistory();
                setDesignStatus('Selection rotated.');
            }

            function getPanelCollapseState() {
                try {
                    return JSON.parse(window.localStorage.getItem(designPanelStorageKey) || '{}') || {};
                } catch (error) {
                    return {};
                }
            }

            function setPanelCollapseState(stateMap) {
                try {
                    window.localStorage.setItem(designPanelStorageKey, JSON.stringify(stateMap || {}));
                } catch (error) {
                    // Ignore storage errors.
                }
            }

            function enhanceCollapsiblePanels() {
                var stateMap = getPanelCollapseState();
                var panels = root.querySelectorAll('[data-image-tools-panel="design"] .noesia-swa-image-tools__design-sidebar--left > .noesia-swa-image-tools__panel');
                Array.prototype.forEach.call(panels, function (panel, index) {
                    var head = panel.querySelector('.noesia-swa-image-tools__panel-head');
                    if (!head || head.querySelector('[data-panel-toggle]')) {
                        return;
                    }
                    var titleNode = head.querySelector('h4');
                    var key = 'panel_' + index + '_' + (titleNode ? titleNode.textContent.trim().toLowerCase().replace(/[^a-z0-9]+/g, '-') : ('section-' + index));
                    panel.setAttribute('data-panel-key', key);
                    var toggle = document.createElement('button');
                    toggle.type = 'button';
                    toggle.className = 'noesia-swa-image-tools__panel-toggle';
                    toggle.setAttribute('data-panel-toggle', key);
                    toggle.setAttribute('aria-expanded', stateMap[key] ? 'false' : 'true');
                    toggle.innerHTML = '<span aria-hidden="true">▾</span>';
                    head.appendChild(toggle);
                    if (stateMap[key]) {
                        panel.classList.add('is-collapsed');
                    }
                    toggle.addEventListener('click', function () {
                        panel.classList.toggle('is-collapsed');
                        var collapsed = panel.classList.contains('is-collapsed');
                        stateMap[key] = collapsed;
                        toggle.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
                        setPanelCollapseState(stateMap);
                    });
                });
            }

            function serializeLayer(layer) {
                var copy = cloneDeep(layer || {});
                if (copy && copy.type === 'image') {
                    delete copy.image;
                }
                return copy;
            }

            function serializeAssetsForDraft() {
                saveActiveDesignAssetSnapshot();
                return designAssets.map(function (asset) {
                    var snapshot = asset.id === activeDesignAssetId ? serializeState() : cloneDeep(asset.snapshot || null);
                    return {
                        id: asset.id,
                        name: asset.name,
                        dataUrl: asset.dataUrl || '',
                        snapshot: snapshot
                    };
                }).filter(function (asset) {
                    return !!asset.dataUrl;
                });
            }

            function loadImageFromDataUrl(dataUrl) {
                return new Promise(function (resolve, reject) {
                    var image = new Image();
                    image.onload = function () { resolve(image); };
                    image.onerror = reject;
                    image.src = dataUrl;
                });
            }

            function hydrateImageLayers(layers) {
                (layers || []).forEach(function (layer) {
                    if (layer && layer.type === 'image' && layer.imageSrc) {
                        var image = new Image();
                        image.onload = function () {
                            layer.image = image;
                            scheduleRender();
                        };
                        image.src = layer.imageSrc;
                    }
                });
            }

            function createImageLayerFromImage(image, name, imageSrc) {
                layerCounter += 1;
                var maxWidth = Math.max(120, Math.round(state.crop.width * 0.45));
                var maxHeight = Math.max(120, Math.round(state.crop.height * 0.45));
                var ratio = Math.min(maxWidth / image.naturalWidth, maxHeight / image.naturalHeight, 1);
                var width = Math.max(40, Math.round(image.naturalWidth * ratio));
                var height = Math.max(40, Math.round(image.naturalHeight * ratio));
                return {
                    id: layerCounter,
                    type: 'image',
                    name: name || ('Image ' + layerCounter),
                    x: Math.round(state.crop.x + ((state.crop.width - width) / 2)),
                    y: Math.round(state.crop.y + ((state.crop.height - height) / 2)),
                    width: width,
                    height: height,
                    opacity: 1,
                    visible: true,
                    locked: false,
                    imageSrc: imageSrc || image.src || '',
                    image: image,
                    rotation: 0,
                    filter: 'original',
                    adjustments: createDefaultAdjustments(),
                    splash: createDefaultSplashState(),
                    retouchStrokes: []
                };
            }

            function createEmptyDesignAsset() {
                var canvas = document.createElement('canvas');
                var context = canvas.getContext('2d');
                var size = 1400;
                canvas.width = size;
                canvas.height = size;
                context.clearRect(0, 0, size, size);
                return {
                    id: ++designAssetCounter,
                    name: 'Untitled ' + designAssetCounter,
                    url: canvas.toDataURL('image/png'),
                    dataUrl: canvas.toDataURL('image/png'),
                    previewUrl: canvas.toDataURL('image/png'),
                    image: null,
                    snapshot: null,
                    isGenerated: true
                };
            }

            function buildDraftPayload() {
                if (!designAssets.length) {
                    return null;
                }
                return {
                    assets: serializeAssetsForDraft(),
                    activeAssetId: activeDesignAssetId,
                    savedAt: Date.now(),
                    addMode: getCurrentAddMode()
                };
            }

            function openDraftDatabase() {
                return new Promise(function (resolve) {
                    if (!window.indexedDB) {
                        resolve(null);
                        return;
                    }
                    try {
                        var request = window.indexedDB.open(designDraftDbName, 1);
                        request.onupgradeneeded = function () {
                            var db = request.result;
                            if (!db.objectStoreNames.contains(designDraftStoreName)) {
                                db.createObjectStore(designDraftStoreName, { keyPath: 'id' });
                            }
                        };
                        request.onsuccess = function () {
                            resolve(request.result || null);
                        };
                        request.onerror = function () {
                            resolve(null);
                        };
                    } catch (error) {
                        resolve(null);
                    }
                });
            }

            function persistDraftPayload(payload) {
                return openDraftDatabase().then(function (db) {
                    if (!db) {
                        if (window.localStorage) {
                            try {
                                window.localStorage.setItem(designDraftStorageKey, JSON.stringify(payload));
                            } catch (error) {
                                // Ignore localStorage quota failures.
                            }
                        }
                        return false;
                    }
                    return new Promise(function (resolve) {
                        var transaction = db.transaction(designDraftStoreName, 'readwrite');
                        var store = transaction.objectStore(designDraftStoreName);
                        transaction.oncomplete = function () {
                            try { db.close(); } catch (error) { /* noop */ }
                            resolve(true);
                        };
                        transaction.onerror = function () {
                            try { db.close(); } catch (error) { /* noop */ }
                            if (window.localStorage) {
                                try {
                                    window.localStorage.setItem(designDraftStorageKey, JSON.stringify(payload));
                                } catch (storageError) {
                                    // Ignore localStorage quota failures.
                                }
                            }
                            resolve(false);
                        };
                        store.put({ id: designDraftRecordId, payload: payload, savedAt: payload.savedAt || Date.now() });
                    });
                });
            }

            function loadDraftPayload() {
                return openDraftDatabase().then(function (db) {
                    if (!db) {
                        if (!window.localStorage) {
                            return null;
                        }
                        try {
                            var localRaw = window.localStorage.getItem(designDraftStorageKey);
                            return localRaw ? JSON.parse(localRaw) : null;
                        } catch (error) {
                            return null;
                        }
                    }
                    return new Promise(function (resolve) {
                        var transaction = db.transaction(designDraftStoreName, 'readonly');
                        var store = transaction.objectStore(designDraftStoreName);
                        var request = store.get(designDraftRecordId);
                        request.onsuccess = function () {
                            var result = request.result && request.result.payload ? request.result.payload : null;
                            try { db.close(); } catch (error) { /* noop */ }
                            if (result) {
                                resolve(result);
                                return;
                            }
                            if (window.localStorage) {
                                try {
                                    var localRaw = window.localStorage.getItem(designDraftStorageKey);
                                    resolve(localRaw ? JSON.parse(localRaw) : null);
                                } catch (storageError) {
                                    resolve(null);
                                }
                                return;
                            }
                            resolve(null);
                        };
                        request.onerror = function () {
                            try { db.close(); } catch (error) { /* noop */ }
                            if (window.localStorage) {
                                try {
                                    var localRaw = window.localStorage.getItem(designDraftStorageKey);
                                    resolve(localRaw ? JSON.parse(localRaw) : null);
                                } catch (storageError) {
                                    resolve(null);
                                }
                                return;
                            }
                            resolve(null);
                        };
                    });
                });
            }

            function clearDraftStorage() {
                return openDraftDatabase().then(function (db) {
                    if (window.localStorage) {
                        try {
                            window.localStorage.removeItem(designDraftStorageKey);
                        } catch (error) {
                            // Ignore storage cleanup failures.
                        }
                    }
                    if (!db) {
                        return false;
                    }
                    return new Promise(function (resolve) {
                        var transaction = db.transaction(designDraftStoreName, 'readwrite');
                        var store = transaction.objectStore(designDraftStoreName);
                        transaction.oncomplete = function () {
                            try { db.close(); } catch (error) { /* noop */ }
                            resolve(true);
                        };
                        transaction.onerror = function () {
                            try { db.close(); } catch (error) { /* noop */ }
                            resolve(false);
                        };
                        store.delete(designDraftRecordId);
                    });
                });
            }

            function clearWatermarkState() {
                state.watermark.text = '';
                state.watermark.image = null;
                state.watermark.imageSrc = '';
                state.watermark.imageOpacity = 0.9;
                state.watermark.textOffsetX = 0;
                state.watermark.textOffsetY = 0;
                state.watermark.imageOffsetX = 0;
                state.watermark.imageOffsetY = 0;
                if (watermarkInput) {
                    watermarkInput.value = '';
                }
                if (watermarkImageInput) {
                    watermarkImageInput.value = '';
                }
                if (watermarkImageUrl) {
                    try {
                        URL.revokeObjectURL(watermarkImageUrl);
                    } catch (error) {
                        // Ignore revoke failures.
                    }
                    watermarkImageUrl = '';
                }
            }

            function saveDraft(options) {
                options = options || {};
                var payload = buildDraftPayload();
                if (!payload) {
                    return Promise.resolve(false);
                }
                if (draftSaveTimer) {
                    window.clearTimeout(draftSaveTimer);
                    draftSaveTimer = null;
                }
                if (options.immediate) {
                    return persistDraftPayload(payload);
                }
                return new Promise(function (resolve) {
                    draftSaveTimer = window.setTimeout(function () {
                        draftSaveTimer = null;
                        persistDraftPayload(buildDraftPayload() || payload).then(resolve);
                    }, 260);
                });
            }

            function restoreDraft(options) {
                options = options || {};
                return loadDraftPayload().then(function (parsed) {
                    if (!parsed || !Array.isArray(parsed.assets) || !parsed.assets.length) {
                        if (options.announceEmpty) {
                            setDesignStatus('No saved design draft was found on this browser.');
                        }
                        return false;
                    }
                    return Promise.all(parsed.assets.map(function (asset) {
                        return loadImageFromDataUrl(asset.dataUrl).then(function (image) {
                            return {
                                id: Number(asset.id || (++designAssetCounter)),
                                name: asset.name || ('Recovered ' + designAssetCounter),
                                url: asset.dataUrl,
                                dataUrl: asset.dataUrl,
                                image: image,
                                snapshot: asset.snapshot || createDefaultDesignSnapshot(image)
                            };
                        });
                    })).then(function (assets) {
                        designAssets = assets;
                        designAssetCounter = assets.reduce(function (max, asset) {
                            return Math.max(max, Number(asset.id || 0));
                        }, designAssetCounter);
                        renderDesignThumbStrip();
                        if (designAddModeSelect && parsed.addMode) {
                            designAddModeSelect.value = parsed.addMode === 'layer' ? 'layer' : 'thumbnail';
                        }
                        var active = assets[0];
                        if (parsed.activeAssetId) {
                            active = assets.find(function (asset) {
                                return asset.id === parsed.activeAssetId || asset.name === parsed.activeAssetId;
                            }) || active;
                        }
                        if (active) {
                            activateDesignAsset(active.id);
                            setDesignStatus(options.manual ? 'Design draft restored.' : 'Recovered the last autosaved design draft.');
                        }
                        return true;
                    }).catch(function () {
                        if (options.announceEmpty) {
                            setDesignStatus('The saved draft could not be restored.');
                        }
                        return false;
                    });
                });
            }

            function createDefaultDesignSnapshot(image) {
                return cloneDeep({
                    crop: { x: 0, y: 0, width: image.width, height: image.height },
                    aspect: 'free',
                    viewport: { zoom: 1, panX: 0, panY: 0 },
                    safeArea: false,
                    previewOriginal: false,
                    cropArmed: false,
                    hasCustomCrop: false,
                    filter: 'original',
                    adjustments: {
                        brightness: 100,
                        contrast: 100,
                        saturation: 100,
                        warmth: 0,
                        sharpen: 0,
                        vignette: 0,
                        splashTolerance: 60
                    },
                    splash: { active: false, armed: false, target: null },
                    retouch: { tool: 'none', size: 96, strength: 42 },
                    retouchStrokes: [],
                    layers: [],
                    selectedLayerId: null,
                    baseLayer: {
                        visible: true,
                        deleted: false,
                        name: 'Base image'
                    },
                    watermark: {
                        text: '',
                        size: 34,
                        opacity: 0.8,
                        position: 'bottom-right',
                        imageSrc: '',
                        imageScale: 0.28,
                        imageOpacity: 0.9,
                        color: '#ffffff',
                        textOffsetX: 0,
                        textOffsetY: 0,
                        imageOffsetX: 0,
                        imageOffsetY: 0
                    },
                    exportFormat: 'image/png',
                    exportQuality: 0.92,
                    exportScale: 1,
                    showGrid: false,
                    quickText: {
                        fontFamily: 'Arial, sans-serif',
                        fontSize: 48,
                        color: '#ffffff',
                        backgroundColor: ''
                    }
                });
            }

            function getDesignAssetById(id) {
                return designAssets.find(function (asset) {
                    return asset.id === id;
                }) || null;
            }

            function getActiveDesignAsset() {
                return getDesignAssetById(activeDesignAssetId);
            }

            function createAssetPreviewDataUrl() {
                var previewCanvas;
                var thumbCanvas;
                var maxSide;
                var scale;
                var width;
                var height;
                var ctx;
                if (!state.image) {
                    return '';
                }
                try {
                    previewCanvas = buildCompositionCanvas(false);
                    if (!previewCanvas) {
                        return '';
                    }
                    maxSide = 240;
                    scale = Math.min(1, maxSide / Math.max(previewCanvas.width || 1, previewCanvas.height || 1));
                    width = Math.max(1, Math.round(previewCanvas.width * scale));
                    height = Math.max(1, Math.round(previewCanvas.height * scale));
                    thumbCanvas = document.createElement('canvas');
                    thumbCanvas.width = width;
                    thumbCanvas.height = height;
                    ctx = thumbCanvas.getContext('2d');
                    ctx.drawImage(previewCanvas, 0, 0, previewCanvas.width, previewCanvas.height, 0, 0, width, height);
                    return thumbCanvas.toDataURL('image/png');
                } catch (previewError) {
                    return '';
                }
            }

            function saveActiveDesignAssetSnapshot() {
                var asset = getActiveDesignAsset();
                if (!asset || !state.image) {
                    return;
                }
                asset.snapshot = serializeState();
                asset.previewUrl = createAssetPreviewDataUrl() || asset.previewUrl || asset.dataUrl || asset.url || '';
            }

            function syncPreviewEmptyState() {
                if (!designEmpty) {
                    return;
                }
                designEmpty.hidden = !!state.image;
            }

            function renderDesignThumbStrip() {
                if (!designThumbStrip) {
                    return;
                }
                designThumbStrip.innerHTML = '';
                if (!designAssets.length) {
                    designThumbStrip.innerHTML = '<div class="noesia-swa-image-tools__thumb-empty">' + escapeHtml(t('image_design_thumb_empty', 'Drop or browse more images to build a thumbnail strip.')) + '</div>';
                    return;
                }
                designAssets.forEach(function (asset) {
                    var button = document.createElement('button');
                    button.type = 'button';
                    button.className = 'noesia-swa-image-tools__thumb';
                    if (asset.id === activeDesignAssetId) {
                        button.classList.add('is-active');
                    }
                    button.setAttribute('data-image-design-thumb', String(asset.id));
                    var thumbSrc = asset.previewUrl || asset.dataUrl || asset.url || '';
                    var thumbWidth = asset.image ? asset.image.width : 0;
                    var thumbHeight = asset.image ? asset.image.height : 0;
                    button.innerHTML = '<span class="noesia-swa-image-tools__thumb-image-wrap">' + (thumbSrc ? '<img src="' + escapeHtml(thumbSrc) + '" alt="" class="noesia-swa-image-tools__thumb-image">' : '') + '</span>' +
                        '<span class="noesia-swa-image-tools__thumb-meta"><strong>' + escapeHtml(asset.name) + '</strong><small>' + (thumbWidth ? (thumbWidth + '×' + thumbHeight) : '') + '</small></span>' +
                        '<span class="noesia-swa-image-tools__thumb-remove" data-image-design-thumb-remove="' + String(asset.id) + '" aria-hidden="true">×</span>';
                    designThumbStrip.appendChild(button);
                });
            }

            function activateDesignAsset(id) {
                var asset = getDesignAssetById(id);
                if (!asset) {
                    return;
                }
                if (activeDesignAssetId === id && state.image) {
                    renderDesignThumbStrip();
                    return;
                }
                saveActiveDesignAssetSnapshot();
                activeDesignAssetId = id;
                state.image = asset.image;
                state.imageUrl = asset.url;
                state.imageDataUrl = asset.dataUrl || asset.url;
                state.imageName = asset.name;
                previewCache.key = '';
                previewCache.canvas = null;
                originalPreviewCache.key = '';
                originalPreviewCache.canvas = null;
                history = [];
                historyIndex = -1;
                interaction = null;
                if (asset.snapshot) {
                    applySerializedState(asset.snapshot);
                } else {
                    applySerializedState(createDefaultDesignSnapshot(asset.image));
                }
                asset.previewUrl = asset.previewUrl || asset.dataUrl || asset.url || '';
                pushHistory();
                renderDesignThumbStrip();
                syncPreviewEmptyState();
                scheduleRender();
                saveDraft();
                setDesignStatus('Loaded ' + asset.name + ' into Image Design.');
            }

            function removeDesignAsset(id) {
                var index = designAssets.findIndex(function (asset) {
                    return asset.id === id;
                });
                var nextAsset;
                if (index === -1) {
                    return;
                }
                if (designAssets[index].url) {
                    URL.revokeObjectURL(designAssets[index].url);
                }
                designAssets.splice(index, 1);
                if (!designAssets.length) {
                    activeDesignAssetId = null;
                    state.image = null;
                    state.imageUrl = '';
                    state.imageName = '';
                    state.layers = [];
                    state.selectedLayerId = null;
                    state.baseLayer = { visible: true, deleted: false, name: 'Base image' };
                    history = [];
                    historyIndex = -1;
                    previewCache.key = '';
                    previewCache.canvas = null;
                    originalPreviewCache.key = '';
                    originalPreviewCache.canvas = null;
                    renderDesignThumbStrip();
                    syncPreviewEmptyState();
                    scheduleRender();
                    if (window.localStorage) {
                        window.localStorage.removeItem(designDraftStorageKey);
                    }
                    setDesignStatus('All design images removed.');
                    return;
                }
                if (activeDesignAssetId === id) {
                    nextAsset = designAssets[Math.max(0, index - 1)] || designAssets[0];
                    activateDesignAsset(nextAsset.id);
                } else {
                    renderDesignThumbStrip();
                    saveDraft();
                    setDesignStatus('Design image removed.');
                }
            }

            function queueDesignFiles(fileList) {
                var mode = getCurrentAddMode();
                Array.prototype.forEach.call(fileList || [], function (file) {
                    if (!file || !file.type || file.type.indexOf('image/') !== 0) {
                        return;
                    }
                    var reader = new FileReader();
                    reader.onload = function (event) {
                        var dataUrl = String((event.target && event.target.result) || '');
                        if (!dataUrl) {
                            return;
                        }
                        loadImageFromDataUrl(dataUrl).then(function (image) {
                            if (mode === 'layer' && state.image) {
                                var imageLayer = createImageLayerFromImage(image, file.name.replace(/\.[^.]+$/, ''), dataUrl);
                                state.layers.push(imageLayer);
                                setSelectedLayer(imageLayer.id);
                                pushHistory();
                                scheduleRender();
                                setDesignStatus(file.name + ' added as an image layer.');
                                return;
                            }
                            var asset = {
                                id: ++designAssetCounter,
                                name: file.name,
                                url: dataUrl,
                                dataUrl: dataUrl,
                                previewUrl: dataUrl,
                                image: image,
                                snapshot: createDefaultDesignSnapshot(image)
                            };
                            designAssets.push(asset);
                            renderDesignThumbStrip();
                            if (!activeDesignAssetId) {
                                activateDesignAsset(asset.id);
                            } else {
                                saveDraft();
                                setDesignStatus(file.name + ' added to the thumbnail strip.');
                            }
                        }).catch(function () {
                            setDesignStatus('Unable to load ' + file.name + ' in the current browser.');
                        });
                    };
                    reader.readAsDataURL(file);
                });
            }

            function syncOutputPreviewCanvasSize() {
                if (!designPreviewCanvas || !designPreviewStage || !designPreviewContext) {
                    return null;
                }
                var rect = designPreviewStage.getBoundingClientRect();
                var width = Math.max(280, Math.round((rect.width || 0) - 28));
                var height = Math.max(220, Math.round((rect.height || 0) - 28));
                var dpr = window.devicePixelRatio || 1;
                var targetWidth = Math.round(width * dpr);
                var targetHeight = Math.round(height * dpr);
                if (designPreviewCanvas.width !== targetWidth || designPreviewCanvas.height !== targetHeight) {
                    designPreviewCanvas.width = targetWidth;
                    designPreviewCanvas.height = targetHeight;
                }
                return { width: width, height: height, dpr: dpr };
            }

            function drawOutputPreview() {
                var previewFrame = syncOutputPreviewCanvasSize();
                var exportCanvas;
                var fit;
                var drawWidth;
                var drawHeight;
                var drawX;
                var drawY;
                if (!designPreviewContext || !previewFrame) {
                    return;
                }
                designPreviewContext.setTransform(previewFrame.dpr, 0, 0, previewFrame.dpr, 0, 0);
                designPreviewContext.clearRect(0, 0, previewFrame.width, previewFrame.height);
                designPreviewContext.fillStyle = '#0a0d12';
                designPreviewContext.fillRect(0, 0, previewFrame.width, previewFrame.height);
                if (!state.image) {
                    return;
                }
                exportCanvas = buildExportCanvas(false);
                if (!exportCanvas) {
                    return;
                }
                fit = Math.min(previewFrame.width / exportCanvas.width, previewFrame.height / exportCanvas.height);
                drawWidth = exportCanvas.width * fit;
                drawHeight = exportCanvas.height * fit;
                drawX = (previewFrame.width - drawWidth) / 2;
                drawY = (previewFrame.height - drawHeight) / 2;
                designPreviewContext.drawImage(exportCanvas, drawX, drawY, drawWidth, drawHeight);
            }

            function markPreviewDirty() {
                previewCache.key = '';
                previewCache.canvas = null;
                originalPreviewCache.key = '';
                originalPreviewCache.canvas = null;
                scheduleRender();
            }

            function getStageSize() {
                var rect = designStage.getBoundingClientRect();
                return {
                    width: Math.max(320, Math.round(rect.width || 0) - 28),
                    height: Math.max(360, Math.round((rect.height || 0) - 28 || 640))
                };
            }

            function syncCanvasSize() {
                var size = getStageSize();
                var dpr = window.devicePixelRatio || 1;
                var targetWidth = Math.round(size.width * dpr);
                var targetHeight = Math.round(size.height * dpr);
                if (designCanvas.width !== targetWidth || designCanvas.height !== targetHeight) {
                    designCanvas.width = targetWidth;
                    designCanvas.height = targetHeight;
                }
                stageFrame = {
                    width: size.width,
                    height: size.height,
                    dpr: dpr
                };
            }

            function getSelectedLayer() {
                return state.layers.find(function (layer) {
                    return layer.id === state.selectedLayerId;
                }) || null;
            }

            function setSelectedLayer(id) {
                state.selectedLayerId = id;
                renderLayerList();
                syncSelectedLayerControls();
                syncQuickTextControls();
                scheduleRender();
            }

            function scheduleHistory() {
                if (historyTimer) {
                    window.clearTimeout(historyTimer);
                }
                historyTimer = window.setTimeout(function () {
                    pushHistory();
                }, 180);
            }

            function serializeState() {
                return cloneDeep({
                    crop: state.crop,
                    aspect: state.aspect,
                    viewport: state.viewport,
                    safeArea: state.safeArea,
                    previewOriginal: state.previewOriginal,
                    cropArmed: !!state.cropArmed,
                    hasCustomCrop: !!state.hasCustomCrop,
                    filter: state.filter,
                    adjustments: state.adjustments,
                    splash: state.splash,
                    retouch: state.retouch,
                    retouchStrokes: state.retouchStrokes,
                    layers: state.layers.map(serializeLayer),
                    selectedLayerId: state.selectedLayerId,
                    baseLayer: state.baseLayer,
                    watermark: state.watermark,
                    exportFormat: state.exportFormat,
                    exportQuality: state.exportQuality,
                    exportScale: state.exportScale,
                    workspaceBackground: state.workspaceBackground,
                    showGrid: !!state.showGrid,
                    quickText: state.quickText
                });
            }

            function applySerializedState(snapshot) {
                if (!snapshot) {
                    return;
                }
                state.crop = cloneDeep(snapshot.crop);
                state.aspect = snapshot.aspect;
                state.viewport = cloneDeep(snapshot.viewport);
                state.safeArea = !!snapshot.safeArea;
                state.previewOriginal = !!snapshot.previewOriginal;
                state.cropArmed = !!snapshot.cropArmed;
                state.hasCustomCrop = !!snapshot.hasCustomCrop;
                state.filter = snapshot.filter;
                state.adjustments = cloneDeep(snapshot.adjustments);
                state.splash = cloneDeep(snapshot.splash);
                state.retouch = cloneDeep(snapshot.retouch || { tool: 'none', size: 96, strength: 42 });
                state.retouchStrokes = cloneDeep(snapshot.retouchStrokes || []);
                state.layers = cloneDeep(snapshot.layers || []);
                state.selectedLayerId = snapshot.selectedLayerId;
                state.baseLayer = cloneDeep(snapshot.baseLayer || { visible: true, deleted: false, name: 'Base image' });
                state.watermark = cloneDeep(snapshot.watermark);
                if (!state.watermark.color) { state.watermark.color = '#ffffff'; }
                if (typeof state.watermark.textOffsetX !== 'number') { state.watermark.textOffsetX = 0; }
                if (typeof state.watermark.textOffsetY !== 'number') { state.watermark.textOffsetY = 0; }
                if (typeof state.watermark.imageOffsetX !== 'number') { state.watermark.imageOffsetX = 0; }
                if (typeof state.watermark.imageOffsetY !== 'number') { state.watermark.imageOffsetY = 0; }
                hydrateImageLayers(state.layers);
                state.layers.forEach(function (layer) {
                    if (layer && layer.type === 'image') {
                        if (!layer.adjustments) {
                            layer.adjustments = createDefaultAdjustments();
                        }
                        if (!layer.splash) {
                            layer.splash = createDefaultSplashState();
                        }
                        if (!layer.filter) {
                            layer.filter = 'original';
                        }
                        if (!Array.isArray(layer.retouchStrokes)) {
                            layer.retouchStrokes = [];
                        }
                    }
                });
                if (!Array.isArray(state.retouchStrokes)) {
                    state.retouchStrokes = [];
                }
                if (!state.retouch) {
                    state.retouch = { tool: 'none', size: 96, strength: 42 };
                }
                state.quickText = cloneDeep(snapshot.quickText || state.quickText || { fontFamily: 'Arial, sans-serif', fontSize: 48, color: '#ffffff', backgroundColor: '' });
                if (state.watermark.imageSrc) {
                    var watermarkImage = new Image();
                    watermarkImage.onload = function () {
                        state.watermark.image = watermarkImage;
                        scheduleRender();
                    };
                    watermarkImage.src = state.watermark.imageSrc;
                } else {
                    state.watermark.image = null;
                }
                state.exportFormat = snapshot.exportFormat;
                state.exportQuality = snapshot.exportQuality;
                state.exportScale = snapshot.exportScale;
                state.workspaceBackground = snapshot.workspaceBackground || '#0f172a';
                state.showGrid = !!snapshot.showGrid;
                layerCounter = state.layers.reduce(function (max, layer) {
                    if (!layer) {
                        return max;
                    }
                    if ((layer.type === 'text' || layer.type === 'image' || (layer.type === 'shape' && layer.shape !== 'arrow' && layer.shape !== 'line')) && typeof layer.rotation !== 'number') {
                        layer.rotation = 0;
                    }
                    return Math.max(max, layer.id || 0);
                }, 0);
                syncControlsFromState();
                markPreviewDirty();
            }

            function pushHistory() {
                if (!state.image) {
                    return;
                }
                var snapshot = serializeState();
                var encoded = JSON.stringify(snapshot);
                if (historyIndex >= 0 && JSON.stringify(history[historyIndex]) === encoded) {
                    return;
                }
                history = history.slice(0, historyIndex + 1);
                history.push(snapshot);
                if (history.length > 50) {
                    history.shift();
                }
                historyIndex = history.length - 1;
                saveDraft();
            }

            function undoHistory() {
                if (historyIndex <= 0) {
                    return;
                }
                historyIndex -= 1;
                applySerializedState(history[historyIndex]);
                setDesignStatus('Undo applied.');
            }

            function redoHistory() {
                if (historyIndex >= history.length - 1) {
                    return;
                }
                historyIndex += 1;
                applySerializedState(history[historyIndex]);
                setDesignStatus('Redo applied.');
            }


            function syncQuickTextControls() {
                var selected = getSelectedLayer();
                var source = selected && selected.type === 'text' ? selected : state.quickText;
                if (designQuickFont) {
                    designQuickFont.value = source.fontFamily || 'Arial, sans-serif';
                }
                if (designQuickSize) {
                    designQuickSize.value = String(parseInt(source.fontSize || 48, 10));
                }
                if (designQuickColor) {
                    designQuickColor.value = source.color || '#ffffff';
                }
                if (designQuickBgColor) {
                    designQuickBgColor.value = source.backgroundColor || '#10151e';
                }
            }

            function updateQuickTextFromControl(field, value) {
                state.quickText[field] = value;
                var selected = getSelectedLayer();
                if (selected && selected.type === 'text') {
                    selected[field] = value;
                    if (field === 'fontSize') {
                        selected.fontSize = Math.max(10, parseInt(value || 48, 10) || 48);
                    }
                    scheduleHistory();
                    scheduleRender();
                }
            }

            function updateReadouts() {
                var target = getToneStateTarget();
                var adjustments = target.adjustments || createDefaultAdjustments();
                readoutNodes.forEach(function (node) {
                    var key = node.getAttribute('data-design-readout');
                    if (!key) {
                        return;
                    }
                    if (key === 'brightness' || key === 'contrast' || key === 'saturation') {
                        node.textContent = adjustments[key] + '%';
                    } else {
                        node.textContent = String(adjustments[key]);
                    }
                });
            }

            function syncSelectedLayerControls() {
                var layer = getSelectedLayer();
                var isText = !!(layer && layer.type === 'text');
                var isShape = !!(layer && layer.type === 'shape');
                var isImageLayer = !!(layer && layer.type === 'image');
                if (selectedPanel) {
                    selectedPanel.querySelectorAll('[data-layer-kind]').forEach(function (node) {
                        var kind = node.getAttribute('data-layer-kind');
                        node.hidden = (kind === 'text' && !isText) || (kind === 'shape' && !isShape) || (kind === 'image' && !isImageLayer);
                    });
                }
                if (noSelectionNode) {
                    noSelectionNode.hidden = !!layer;
                }
                selectedFields.forEach(function (field) {
                    var key = field.getAttribute('data-image-design-layer-field');
                    field.disabled = !layer;
                    if (!layer || !key) {
                        if (field.tagName === 'INPUT' || field.tagName === 'TEXTAREA') {
                            if (field.type === 'color') {
                                field.value = '#ffffff';
                            } else {
                                field.value = '';
                            }
                        }
                        return;
                    }
                    var value = layer[key];
                    if (field.type === 'range' || field.type === 'number') {
                        field.value = value;
                    } else if (field.tagName === 'TEXTAREA' || field.tagName === 'SELECT' || field.type === 'text' || field.type === 'color') {
                        field.value = (field.type === 'color' && !value) ? '#10151e' : value;
                    }
                });
            }

            function syncControlsFromState() {
                if (designAddModeSelect) {
                designAddModeSelect.addEventListener('change', function () {
                    saveDraft();
                });
            }

            if (designFormatSelect) {
                    designFormatSelect.value = state.exportFormat;
                }
                if (designQualityInput) {
                    designQualityInput.value = String(state.exportQuality);
                }
                if (designScaleSelect) {
                    designScaleSelect.value = String(state.exportScale);
                }
                if (watermarkInput) {
                    watermarkInput.value = state.watermark.text;
                }
                if (watermarkSizeInput) {
                    watermarkSizeInput.value = String(state.watermark.size);
                }
                if (watermarkOpacityInput) {
                    watermarkOpacityInput.value = String(state.watermark.opacity);
                }
                if (watermarkColorInput) {
                    watermarkColorInput.value = state.watermark.color || '#ffffff';
                }
                if (watermarkPositionSelect) {
                    watermarkPositionSelect.value = state.watermark.position;
                }
                if (watermarkImageScaleInput) {
                    watermarkImageScaleInput.value = String(state.watermark.imageScale);
                }
                designAspectButtons.forEach(function (button) {
                    button.classList.toggle('is-active', button.getAttribute('data-image-design-aspect') === state.aspect);
                });
                var toneTarget = getToneStateTarget();
                designFilterButtons.forEach(function (button) {
                    button.classList.toggle('is-active', button.getAttribute('data-image-design-filter') === toneTarget.filter);
                });
                designAdjustInputs.forEach(function (input) {
                    var key = input.getAttribute('data-image-design-adjust');
                    if (key && Object.prototype.hasOwnProperty.call(toneTarget.adjustments, key)) {
                        input.value = String(toneTarget.adjustments[key]);
                    }
                });
                updateReadouts();
                updateExportReadout();
                applyWorkspaceBackground();
                renderLayerList();
                syncSelectedLayerControls();
                syncQuickTextControls();
                syncBrushControls();
            }

            function updateExportReadout() {
                if (!designQualityInput || !designQualityReadout) {
                    return;
                }
                if (state.exportFormat === 'image/png') {
                    designQualityInput.disabled = true;
                    designQualityReadout.textContent = 'Lossless PNG';
                } else {
                    designQualityInput.disabled = false;
                    designQualityReadout.textContent = Math.round(state.exportQuality * 100) + '%';
                }
            }

            
            function isInputLike(node) {
                if (!node) {
                    return false;
                }
                var tag = node.tagName ? node.tagName.toLowerCase() : '';
                return tag === 'input' || tag === 'textarea' || tag === 'select' || !!node.closest('[contenteditable="true"]');
            }

            function cloneLayerData(layer) {
                if (!layer) {
                    return null;
                }
                var cloned = cloneDeep(layer);
                delete cloned.id;
                delete cloned.image;
                return cloned;
            }

            function cloneLayerStyle(layer) {
                if (!layer) {
                    return null;
                }
                if (layer.type === 'text') {
                    return {
                        type: 'text',
                        fontFamily: layer.fontFamily,
                        fontWeight: layer.fontWeight,
                        fontSize: layer.fontSize,
                        color: layer.color,
                        backgroundColor: layer.backgroundColor,
                        backgroundOpacity: layer.backgroundOpacity,
                        backgroundPaddingX: layer.backgroundPaddingX,
                        backgroundPaddingY: layer.backgroundPaddingY,
                        opacity: layer.opacity,
                        align: layer.align,
                        letterSpacing: layer.letterSpacing,
                        curve: layer.curve,
                        shadowBlur: layer.shadowBlur,
                        shadowColor: layer.shadowColor,
                        strokeWidth: layer.strokeWidth,
                        strokeColor: layer.strokeColor
                    };
                }
                if (layer.type === 'shape') {
                    return {
                        type: 'shape',
                        fill: layer.fill,
                        opacity: layer.opacity,
                        strokeWidth: layer.strokeWidth,
                        strokeColor: layer.strokeColor,
                        privacyMode: layer.privacyMode || '',
                        privacyStrength: layer.privacyStrength || 0
                    };
                }
                if (layer.type === 'image') {
                    return {
                        type: 'image',
                        opacity: layer.opacity
                    };
                }
                return null;
            }

            function applyLayerStyle(target, style) {
                if (!target || !style || target.type !== style.type) {
                    return false;
                }
                Object.keys(style).forEach(function (key) {
                    if (key !== 'type') {
                        target[key] = cloneDeep(style[key]);
                    }
                });
                return true;
            }

            function instantiateLayerFromClipboard(mode) {
                if (!layerClipboard) {
                    return null;
                }
                var next = cloneDeep(layerClipboard.data);
                layerCounter += 1;
                next.id = layerCounter;
                next.visible = true;
                next.locked = false;
                next.name = (next.name || 'Layer') + ' copy';
                if (next.type === 'image' && layerClipboard.imageSrc) {
                    var restored = getImageFromDataUrl(layerClipboard.imageSrc);
                    if (!restored) {
                        return null;
                    }
                    next.imageSrc = layerClipboard.imageSrc;
                    next.image = restored;
                }
                if (mode === 'center') {
                    var bounds = layerBounds(next);
                    var desiredX = state.crop.x + ((state.crop.width - bounds.width) / 2);
                    var desiredY = state.crop.y + ((state.crop.height - bounds.height) / 2);
                    if (next.type === 'text') {
                        next.x = Math.round(desiredX + (bounds.width / 2));
                        next.y = Math.round(desiredY + bounds.height);
                    } else {
                        next.x = Math.round(desiredX);
                        next.y = Math.round(desiredY);
                    }
                } else if (mode === 'offset') {
                    if (typeof next.x === 'number') {
                        next.x += 24;
                    }
                    if (typeof next.y === 'number') {
                        next.y += 24;
                    }
                }
                return next;
            }

            function setLayerClipboardFromSelection(cutMode) {
                var selected = getSelectedLayer();
                if (selected) {
                    layerClipboard = {
                        source: 'layer',
                        data: cloneLayerData(selected),
                        imageSrc: selected.type === 'image' ? selected.imageSrc : ''
                    };
                    if (cutMode) {
                        deleteLayer();
                        setDesignStatus('Layer cut to clipboard.');
                    } else {
                        setDesignStatus('Layer copied to clipboard.');
                    }
                    return true;
                }
                if (state.image && state.crop && state.crop.width > 1 && state.crop.height > 1) {
                    copyCropToClipboard();
                    return true;
                }
                return false;
            }

            function pasteClipboard(mode) {
                var nextLayer;
                if (layerClipboard && layerClipboard.source === 'layer') {
                    nextLayer = instantiateLayerFromClipboard(mode || 'offset');
                    if (!nextLayer) {
                        setDesignStatus('Copied layer source is no longer available.');
                        return;
                    }
                    state.layers.push(nextLayer);
                    setSelectedLayer(nextLayer.id);
                    pushHistory();
                    scheduleRender();
                    setDesignStatus(mode === 'in-place' ? 'Layer pasted in place.' : 'Layer pasted.');
                    return;
                }
                if (copiedCropLayer && copiedCropLayer.dataUrl) {
                    loadImageFromDataUrl(copiedCropLayer.dataUrl).then(function (image) {
                        var cropLayer = createImageLayerFromImage(image, 'Crop layer', copiedCropLayer.dataUrl);
                        if (mode === 'in-place' && copiedCropLayer.bounds) {
                            cropLayer.x = copiedCropLayer.bounds.x;
                            cropLayer.y = copiedCropLayer.bounds.y;
                            cropLayer.width = copiedCropLayer.bounds.width;
                            cropLayer.height = copiedCropLayer.bounds.height;
                        }
                        state.layers.push(cropLayer);
                        setSelectedLayer(cropLayer.id);
                        pushHistory();
                        scheduleRender();
                        setDesignStatus(mode === 'in-place' ? 'Crop pasted in place.' : 'Crop pasted as a new image layer.');
                    });
                    return;
                }
                setDesignStatus('Nothing copied yet.');
            }

            function getSnapTargets(excludeId) {
                var targets = [
                    { type: 'v', value: state.crop.x, source: 'crop-left' },
                    { type: 'v', value: state.crop.x + (state.crop.width / 2), source: 'crop-center-x' },
                    { type: 'v', value: state.crop.x + state.crop.width, source: 'crop-right' },
                    { type: 'h', value: state.crop.y, source: 'crop-top' },
                    { type: 'h', value: state.crop.y + (state.crop.height / 2), source: 'crop-center-y' },
                    { type: 'h', value: state.crop.y + state.crop.height, source: 'crop-bottom' }
                ];
                state.layers.forEach(function (layer) {
                    if (!layer.visible || layer.locked || layer.id === excludeId) {
                        return;
                    }
                    var bounds = layerBounds(layer);
                    targets.push({ type: 'v', value: bounds.x, source: 'layer-left' });
                    targets.push({ type: 'v', value: bounds.x + (bounds.width / 2), source: 'layer-center-x' });
                    targets.push({ type: 'v', value: bounds.x + bounds.width, source: 'layer-right' });
                    targets.push({ type: 'h', value: bounds.y, source: 'layer-top' });
                    targets.push({ type: 'h', value: bounds.y + (bounds.height / 2), source: 'layer-center-y' });
                    targets.push({ type: 'h', value: bounds.y + bounds.height, source: 'layer-bottom' });
                });
                return targets;
            }

            function snapBoundsForLayer(layer, proposedX, proposedY) {
                var preview = cloneDeep(layer);
                preview.x = proposedX;
                preview.y = proposedY;
                var bounds = layerBounds(preview);
                var threshold = Math.max(6, Math.round(10 / Math.max(0.25, state.viewport.zoom)));
                var targets = getSnapTargets(layer.id);
                var bestX = null;
                var bestY = null;
                var candidateX = [bounds.x, bounds.x + (bounds.width / 2), bounds.x + bounds.width];
                var candidateY = [bounds.y, bounds.y + (bounds.height / 2), bounds.y + bounds.height];
                activeSnapGuides = [];
                targets.forEach(function (target) {
                    if (target.type === 'v') {
                        candidateX.forEach(function (value, index) {
                            var diff = target.value - value;
                            if (Math.abs(diff) <= threshold && (!bestX || Math.abs(diff) < Math.abs(bestX.diff))) {
                                bestX = { diff: diff, target: target.value, kind: index };
                            }
                        });
                    } else {
                        candidateY.forEach(function (value, index) {
                            var diff = target.value - value;
                            if (Math.abs(diff) <= threshold && (!bestY || Math.abs(diff) < Math.abs(bestY.diff))) {
                                bestY = { diff: diff, target: target.value, kind: index };
                            }
                        });
                    }
                });
                if (bestX) {
                    proposedX += bestX.diff;
                    activeSnapGuides.push({ axis: 'x', value: bestX.target });
                }
                if (bestY) {
                    proposedY += bestY.diff;
                    activeSnapGuides.push({ axis: 'y', value: bestY.target });
                }
                return { x: proposedX, y: proposedY };
            }

            function drawSnapGuides() {
                if (!activeSnapGuides.length) {
                    return;
                }
                stageContext.save();
                stageContext.strokeStyle = 'rgba(96, 165, 250, 0.9)';
                stageContext.lineWidth = 1.5;
                stageContext.setLineDash([8, 6]);
                activeSnapGuides.forEach(function (guide) {
                    var p1;
                    var p2;
                    if (guide.axis === 'x') {
                        p1 = imageToStage(guide.value, state.crop.y);
                        p2 = imageToStage(guide.value, state.crop.y + state.crop.height);
                    } else {
                        p1 = imageToStage(state.crop.x, guide.value);
                        p2 = imageToStage(state.crop.x + state.crop.width, guide.value);
                    }
                    stageContext.beginPath();
                    stageContext.moveTo(p1.x, p1.y);
                    stageContext.lineTo(p2.x, p2.y);
                    stageContext.stroke();
                });
                stageContext.restore();
            }

function createBaseLayer(type) {
                layerCounter += 1;
                if (type === 'text') {
                    return {
                        id: layerCounter,
                        type: 'text',
                        name: 'Text ' + layerCounter,
                        text: 'Noesia',
                        x: Math.round(state.crop.x + (state.crop.width * 0.5)),
                        y: Math.round(state.crop.y + (state.crop.height * 0.5)),
                        fontFamily: state.quickText.fontFamily || 'Arial, sans-serif',
                        fontWeight: '700',
                        fontSize: Math.max(36, parseInt(state.quickText.fontSize || Math.round(state.crop.width * 0.07), 10) || 48),
                        color: state.quickText.color || '#ffffff',
                        backgroundColor: state.quickText.backgroundColor || '',
                        backgroundOpacity: 0.82,
                        backgroundPaddingX: 18,
                        backgroundPaddingY: 12,
                        opacity: 1,
                        align: 'center',
                        letterSpacing: 0,
                        curve: 0,
                        shadowBlur: 0,
                        shadowColor: '#000000',
                        strokeWidth: 0,
                        strokeColor: '#000000',
                        visible: true,
                        locked: false,
                        rotation: 0
                    };
                }
                var isVector = type === 'arrow' || type === 'line';
                return {
                    id: layerCounter,
                    type: 'shape',
                    name: type === 'circle' ? 'Circle ' + layerCounter : (type === 'arrow' ? 'Arrow ' + layerCounter : (type === 'line' ? 'Line ' + layerCounter : 'Box ' + layerCounter)),
                    shape: type,
                    x: Math.round(state.crop.x + (state.crop.width * 0.2)),
                    y: Math.round(state.crop.y + (state.crop.height * 0.2)),
                    width: isVector ? Math.round(state.crop.width * 0.34) : Math.round(state.crop.width * 0.24),
                    height: isVector ? Math.round(state.crop.height * 0.16) : Math.round(state.crop.height * 0.2),
                    fill: isVector ? '#5ea5ff' : (type === 'circle' ? '#5ea5ff' : '#ffffff'),
                    opacity: 0.9,
                    strokeWidth: isVector ? 8 : 0,
                    strokeColor: isVector ? '#5ea5ff' : '#0f1724',
                    visible: true,
                    locked: false
                };
            }

            function renderLayerList() {
                if (!layerListNode) {
                    return;
                }
                layerListNode.innerHTML = '';

                if (state.image) {
                    var baseRow = document.createElement('div');
                    var baseVisible = !state.baseLayer || state.baseLayer.visible !== false;
                    var baseDeleted = !!(state.baseLayer && state.baseLayer.deleted);
                    baseRow.className = 'noesia-swa-image-tools__layer-row noesia-swa-image-tools__layer-row--base';
                    baseRow.innerHTML = '<span class="noesia-swa-image-tools__layer-icon">🖼</span>' +
                        '<button type="button" class="noesia-swa-image-tools__layer-title" data-base-layer-select="1"><strong>' + escapeHtml((state.baseLayer && state.baseLayer.name) || 'Base image') + '</strong><span>' + (baseDeleted ? 'Base image removed' : 'Current image') + '</span></button>' +
                        '<button type="button" class="noesia-swa-image-tools__layer-toggle" data-base-layer-promote="1" aria-label="Turn base image into a layer">⇪</button>' +
                        '<button type="button" class="noesia-swa-image-tools__layer-toggle" data-base-layer-toggle-visibility="1" aria-label="Toggle base image visibility">' + (baseVisible ? '👁' : '⛔') + '</button>' +
                        '<button type="button" class="noesia-swa-image-tools__layer-toggle noesia-swa-image-tools__layer-toggle--danger" data-base-layer-delete="1" aria-label="Delete base image">×</button>';
                    layerListNode.appendChild(baseRow);
                }

                if (!state.layers.length) {
                    if (!state.image) {
                        layerListNode.innerHTML = '<div class="noesia-swa-image-tools__info-box"><strong>No layers yet</strong><p>Add text, a box, a round shape, or import an extra image as a new layer.</p></div>';
                    }
                    return;
                }

                state.layers.slice().reverse().forEach(function (layer) {
                    var row = document.createElement('div');
                    var layerTypeLabel = 'Text layer';
                    var icon = 'T';
                    if (layer.type === 'shape') {
                        if (layer.shape === 'circle') {
                            layerTypeLabel = 'Round shape';
                            icon = 'O';
                        } else if (layer.shape === 'arrow') {
                            layerTypeLabel = 'Arrow';
                            icon = '↗';
                        } else if (layer.shape === 'line') {
                            layerTypeLabel = 'Line';
                            icon = '⎯';
                        } else {
                            layerTypeLabel = 'Box shape';
                            icon = '□';
                        }
                    } else if (layer.type === 'image') {
                        layerTypeLabel = 'Image layer';
                        icon = '🖼';
                    }
                    row.className = 'noesia-swa-image-tools__layer-row' + (layer.id === state.selectedLayerId ? ' is-selected' : '');
                    row.innerHTML = '<span class="noesia-swa-image-tools__layer-icon">' + icon + '</span>' +
                        '<button type="button" class="noesia-swa-image-tools__layer-title" data-layer-select="' + layer.id + '"><strong>' + escapeHtml(layer.name) + '</strong><span>' + layerTypeLabel + '</span></button>' +
                        '<button type="button" class="noesia-swa-image-tools__layer-toggle" data-layer-toggle-visibility="' + layer.id + '" aria-label="Toggle visibility">' + (layer.visible ? '👁' : '⛔') + '</button>' +
                        '<button type="button" class="noesia-swa-image-tools__layer-toggle" data-layer-toggle-lock="' + layer.id + '" aria-label="Toggle lock">' + (layer.locked ? '🔒' : '🔓') + '</button>' +
                        '<button type="button" class="noesia-swa-image-tools__layer-toggle noesia-swa-image-tools__layer-toggle--danger" data-layer-delete="' + layer.id + '" aria-label="Delete layer">×</button>';
                    layerListNode.appendChild(row);
                });
            }


            function layerBounds(layer) {
                if (layer.type === 'image') {
                    return getRotatedRectBounds(layer.x, layer.y, layer.width, layer.height, layer.rotation || 0);
                }
                if (layer.type === 'shape') {
                    if (layer.shape === 'arrow' || layer.shape === 'line') {
                        var minX = Math.min(layer.x, layer.x + layer.width);
                        var minY = Math.min(layer.y, layer.y + layer.height);
                        var pad = Math.max(8, (layer.strokeWidth || 2) * 1.5);
                        return {
                            x: minX - pad,
                            y: minY - pad,
                            width: Math.abs(layer.width) + (pad * 2),
                            height: Math.abs(layer.height) + (pad * 2)
                        };
                    }
                    return getRotatedRectBounds(layer.x, layer.y, layer.width, layer.height, layer.rotation || 0);
                }
                var measureCanvas = document.createElement('canvas');
                var measureContext = measureCanvas.getContext('2d');
                var lines = String(layer.text || '').split(/\n/);
                var maxWidth = 0;
                measureContext.font = layer.fontWeight + ' ' + layer.fontSize + 'px ' + layer.fontFamily;
                lines.forEach(function (line) {
                    maxWidth = Math.max(maxWidth, measureContext.measureText(line).width + (Math.max(0, line.length - 1) * layer.letterSpacing));
                });
                var height = Math.max(1, lines.length) * layer.fontSize * 1.2;
                if (Math.abs(layer.curve) > 4) {
                    var radius = Math.abs(layer.curve);
                    maxWidth = Math.max(maxWidth, radius * 2);
                    height = Math.max(height, radius * 2);
                }
                return getRotatedRectBounds(
                    layer.x - (layer.align === 'center' ? maxWidth / 2 : (layer.align === 'right' ? maxWidth : 0)),
                    layer.y - height,
                    maxWidth,
                    height,
                    layer.rotation || 0
                );
            }

            function imageToStage(pointX, pointY) {
                if (!state.image || !stageFrame) {
                    return { x: 0, y: 0 };
                }
                var fit = Math.min(stageFrame.width / state.image.width, stageFrame.height / state.image.height) * state.viewport.zoom;
                var centerX = stageFrame.width / 2 + state.viewport.panX;
                var centerY = stageFrame.height / 2 + state.viewport.panY;
                return {
                    x: centerX + ((pointX - (state.image.width / 2)) * fit),
                    y: centerY + ((pointY - (state.image.height / 2)) * fit)
                };
            }

            function stageToImage(pointX, pointY) {
                if (!state.image || !stageFrame) {
                    return { x: 0, y: 0 };
                }
                var fit = Math.min(stageFrame.width / state.image.width, stageFrame.height / state.image.height) * state.viewport.zoom;
                var centerX = stageFrame.width / 2 + state.viewport.panX;
                var centerY = stageFrame.height / 2 + state.viewport.panY;
                return {
                    x: ((pointX - centerX) / fit) + (state.image.width / 2),
                    y: ((pointY - centerY) / fit) + (state.image.height / 2)
                };
            }

            function rectToStage(rect) {
                var topLeft = imageToStage(rect.x, rect.y);
                var bottomRight = imageToStage(rect.x + rect.width, rect.y + rect.height);
                return {
                    x: topLeft.x,
                    y: topLeft.y,
                    width: bottomRight.x - topLeft.x,
                    height: bottomRight.y - topLeft.y
                };
            }

            function fitViewport() {
                state.viewport.zoom = 1;
                state.viewport.panX = 0;
                state.viewport.panY = 0;
                scheduleRender();
            }

            function resetEdits() {
                if (!state.image) {
                    return;
                }
                state.aspect = 'free';
                state.crop = { x: 0, y: 0, width: state.image.width, height: state.image.height };
                state.adjustments = {
                    brightness: 100,
                    contrast: 100,
                    saturation: 100,
                    warmth: 0,
                    sharpen: 0,
                    vignette: 0,
                    splashTolerance: 60
                };
                state.splash = { active: false, armed: false, target: null };
                state.filter = 'original';
                state.layers = [];
                state.selectedLayerId = null;
                state.baseLayer = { visible: true, deleted: false, name: 'Base image' };
                state.previewOriginal = false;
                state.hasCustomCrop = false;
                state.safeArea = false;
                state.watermark.text = '';
                state.watermark.size = 34;
                state.watermark.opacity = 0.8;
                state.watermark.position = 'bottom-right';
                state.watermark.imageSrc = '';
                state.watermark.imageScale = 0.28;
                state.watermark.textOffsetX = 0;
                state.watermark.textOffsetY = 0;
                state.watermark.imageOffsetX = 0;
                state.watermark.imageOffsetY = 0;
                if (watermarkImageInput) {
                    watermarkImageInput.value = '';
                }
                if (watermarkImageUrl) {
                    URL.revokeObjectURL(watermarkImageUrl);
                    watermarkImageUrl = '';
                }
                fitViewport();
                syncControlsFromState();
                pushHistory();
                markPreviewDirty();
                setDesignStatus('Image Design reset.');
            }

            function setAspect(aspect) {
                if (!state.image) {
                    return;
                }
                state.aspect = aspect;
                designAspectButtons.forEach(function (button) {
                    button.classList.toggle('is-active', button.getAttribute('data-image-design-aspect') === aspect);
                });
                if (aspect === 'free') {
                    state.crop = { x: 0, y: 0, width: state.image.width, height: state.image.height };
                    state.hasCustomCrop = false;
                } else {
                    var parts = aspect.split(':');
                    var ratio = Number(parts[0]) / Number(parts[1]);
                    var cropWidth = state.image.width;
                    var cropHeight = cropWidth / ratio;
                    if (cropHeight > state.image.height) {
                        cropHeight = state.image.height;
                        cropWidth = cropHeight * ratio;
                    }
                    state.crop = {
                        x: Math.round((state.image.width - cropWidth) / 2),
                        y: Math.round((state.image.height - cropHeight) / 2),
                        width: Math.round(cropWidth),
                        height: Math.round(cropHeight)
                    };
                    state.hasCustomCrop = true;
                }
                scheduleHistory();
                scheduleRender();
            }

            function getFilterString() {
                var base = [];
                if (designFilters[state.filter] && designFilters[state.filter] !== 'none') {
                    base.push(designFilters[state.filter]);
                }
                base.push('brightness(' + (state.adjustments.brightness / 100) + ')');
                base.push('contrast(' + (state.adjustments.contrast / 100) + ')');
                base.push('saturate(' + (state.adjustments.saturation / 100) + ')');
                return base.join(' ');
            }

            function applyWarmth(canvas, adjustments) {
                var sourceAdjustments = adjustments || createDefaultAdjustments();
                if (!sourceAdjustments.warmth) {
                    return;
                }
                var ctx = canvas.getContext('2d');
                var alpha = Math.abs(sourceAdjustments.warmth) / 240;
                ctx.save();
                ctx.globalCompositeOperation = 'source-atop';
                ctx.fillStyle = sourceAdjustments.warmth > 0 ? 'rgba(255, 151, 61,' + alpha + ')' : 'rgba(83, 141, 255,' + alpha + ')';
                ctx.fillRect(0, 0, canvas.width, canvas.height);
                ctx.restore();
            }

            function applySelectiveColor(canvas, splash, adjustments) {
                var sourceSplash = splash || createDefaultSplashState();
                var sourceAdjustments = adjustments || createDefaultAdjustments();
                if (!sourceSplash.active || !sourceSplash.target) {
                    return;
                }
                var ctx = canvas.getContext('2d');
                var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
                var data = imageData.data;
                var tolerance = Number(sourceAdjustments.splashTolerance || 60);
                var index;
                for (index = 0; index < data.length; index += 4) {
                    var r = data[index];
                    var g = data[index + 1];
                    var b = data[index + 2];
                    var distance = Math.sqrt(
                        Math.pow(r - sourceSplash.target.r, 2) +
                        Math.pow(g - sourceSplash.target.g, 2) +
                        Math.pow(b - sourceSplash.target.b, 2)
                    );
                    if (distance > tolerance) {
                        var gray = Math.round((r * 0.299) + (g * 0.587) + (b * 0.114));
                        data[index] = gray;
                        data[index + 1] = gray;
                        data[index + 2] = gray;
                    }
                }
                ctx.putImageData(imageData, 0, 0);
            }

            function applySharpen(canvas, adjustments) {
                var sourceAdjustments = adjustments || createDefaultAdjustments();
                var amount = Number(sourceAdjustments.sharpen || 0);
                if (!amount) {
                    return;
                }
                var ctx = canvas.getContext('2d');
                var width = canvas.width;
                var height = canvas.height;
                var imageData = ctx.getImageData(0, 0, width, height);
                var source = new Uint8ClampedArray(imageData.data);
                var data = imageData.data;
                var strength = amount / 120;
                var x;
                var y;
                var channel;
                for (y = 1; y < height - 1; y += 1) {
                    for (x = 1; x < width - 1; x += 1) {
                        var index = ((y * width) + x) * 4;
                        var north = index - (width * 4);
                        var south = index + (width * 4);
                        var west = index - 4;
                        var east = index + 4;
                        for (channel = 0; channel < 3; channel += 1) {
                            var value = source[index + channel] * (1 + (4 * strength)) - (
                                source[north + channel] * strength +
                                source[south + channel] * strength +
                                source[west + channel] * strength +
                                source[east + channel] * strength
                            );
                            data[index + channel] = clamp(Math.round(value), 0, 255);
                        }
                    }
                }
                ctx.putImageData(imageData, 0, 0);
            }

            function applyVignette(canvas, adjustments) {
                var sourceAdjustments = adjustments || createDefaultAdjustments();
                var amount = Number(sourceAdjustments.vignette || 0);
                if (!amount) {
                    return;
                }
                var ctx = canvas.getContext('2d');
                var gradient = ctx.createRadialGradient(
                    canvas.width / 2,
                    canvas.height / 2,
                    Math.min(canvas.width, canvas.height) * 0.15,
                    canvas.width / 2,
                    canvas.height / 2,
                    Math.max(canvas.width, canvas.height) * 0.7
                );
                gradient.addColorStop(0, 'rgba(0,0,0,0)');
                gradient.addColorStop(1, 'rgba(0,0,0,' + (amount / 130) + ')');
                ctx.save();
                ctx.fillStyle = gradient;
                ctx.fillRect(0, 0, canvas.width, canvas.height);
                ctx.restore();
            }

            function renderImageSourceToCanvas(targetCanvas, sourceImage, width, height, options) {
                var ctx = targetCanvas.getContext('2d');
                var sourceOptions = options || {};
                targetCanvas.width = width;
                targetCanvas.height = height;
                ctx.clearRect(0, 0, width, height);
                if (!sourceImage) {
                    return targetCanvas;
                }
                ctx.drawImage(sourceImage, 0, 0, width, height);
                if (!sourceOptions.useOriginal) {
                    applyPixelProcessing(targetCanvas, sourceOptions.filter, sourceOptions.adjustments);
                    applySelectiveColor(targetCanvas, sourceOptions.splash, sourceOptions.adjustments);
                    applySharpen(targetCanvas, sourceOptions.adjustments);
                    applyVignette(targetCanvas, sourceOptions.adjustments);
                    applyRetouchStrokes(targetCanvas, sourceOptions.retouchStrokes, sourceOptions.coordinateWidth, sourceOptions.coordinateHeight);
                }
                return targetCanvas;
            }

            function renderSourceToCanvas(targetCanvas, width, height, useOriginal) {
                if (!state.image) {
                    return targetCanvas;
                }
                if (state.baseLayer && (state.baseLayer.deleted || state.baseLayer.visible === false)) {
                    targetCanvas.width = width;
                    targetCanvas.height = height;
                    targetCanvas.getContext('2d').clearRect(0, 0, width, height);
                    return targetCanvas;
                }
                return renderImageSourceToCanvas(targetCanvas, state.image, width, height, {
                    useOriginal: !!useOriginal,
                    filter: state.filter,
                    adjustments: state.adjustments,
                    splash: state.splash,
                    retouchStrokes: state.retouchStrokes,
                    coordinateWidth: state.image.width,
                    coordinateHeight: state.image.height
                });
            }


            function getPreviewCanvas(useOriginal) {
                if (!state.image) {
                    return null;
                }
                var key = [
                    useOriginal ? 'original' : 'edited',
                    state.imageUrl,
                    state.filter,
                    JSON.stringify(state.adjustments),
                    JSON.stringify(state.splash),
                    JSON.stringify(state.retouchStrokes || [])
                ].join('|');
                var cache = useOriginal ? originalPreviewCache : previewCache;
                if (cache.key === key && cache.canvas) {
                    return cache.canvas;
                }
                var limit = 1800;
                var scale = Math.min(1, limit / Math.max(state.image.width, state.image.height));
                var canvas = document.createElement('canvas');
                renderSourceToCanvas(canvas, Math.max(1, Math.round(state.image.width * scale)), Math.max(1, Math.round(state.image.height * scale)), useOriginal);
                cache.key = key;
                cache.canvas = canvas;
                return canvas;
            }

            function drawTextLayer(ctx, layer, stageScale) {
                var lines = String(layer.text || '').split(/\n/);
                var maxWidth = 0;
                var height;
                var anchorX;
                var boxX;
                var boxY;
                var centerX;
                var centerY;
                ctx.save();
                ctx.globalAlpha = layer.opacity;
                ctx.fillStyle = layer.color;
                ctx.strokeStyle = layer.strokeColor;
                ctx.lineWidth = layer.strokeWidth;
                ctx.font = layer.fontWeight + ' ' + layer.fontSize + 'px ' + layer.fontFamily;
                ctx.textAlign = layer.align;
                ctx.textBaseline = 'alphabetic';
                ctx.shadowBlur = layer.shadowBlur;
                ctx.shadowColor = layer.shadowColor;

                lines.forEach(function (line) {
                    maxWidth = Math.max(maxWidth, ctx.measureText(line).width + (Math.max(0, line.length - 1) * layer.letterSpacing));
                });
                height = Math.max(1, lines.length) * layer.fontSize * 1.2;
                if (Math.abs(layer.curve) > 4) {
                    var curveRadius = Math.abs(layer.curve);
                    maxWidth = Math.max(maxWidth, curveRadius * 2);
                    height = Math.max(height, curveRadius * 2);
                }
                anchorX = layer.x;
                if (layer.align === 'center') {
                    boxX = anchorX - (maxWidth / 2);
                } else if (layer.align === 'right') {
                    boxX = anchorX - maxWidth;
                } else {
                    boxX = anchorX;
                }
                boxY = layer.y - height;
                centerX = boxX + (maxWidth / 2);
                centerY = boxY + (height / 2);

                if (layer.rotation) {
                    ctx.translate(centerX, centerY);
                    ctx.rotate((normalizeRotation(layer.rotation) * Math.PI) / 180);
                    ctx.translate(-centerX, -centerY);
                }

                if (layer.backgroundColor && Math.abs(layer.curve) <= 4) {
                    ctx.save();
                    ctx.shadowBlur = 0;
                    ctx.globalAlpha = Math.min(1, layer.opacity * (layer.backgroundOpacity || 0.82));
                    ctx.fillStyle = layer.backgroundColor;
                    ctx.fillRect(
                        boxX - (layer.backgroundPaddingX || 18),
                        boxY - (layer.backgroundPaddingY || 12),
                        maxWidth + ((layer.backgroundPaddingX || 18) * 2),
                        height + ((layer.backgroundPaddingY || 12) * 2)
                    );
                    ctx.restore();
                    ctx.globalAlpha = layer.opacity;
                }

                if (Math.abs(layer.curve) > 4) {
                    var radius = layer.curve;
                    var text = lines.join(' ');
                    var chars = Array.prototype.slice.call(text);
                    var totalWidth = chars.reduce(function (sum, character) {
                        return sum + ctx.measureText(character).width + layer.letterSpacing;
                    }, 0);
                    var circumference = Math.max(1, 2 * Math.PI * Math.abs(radius));
                    var totalAngle = totalWidth / circumference * (Math.PI * 2);
                    var currentAngle = -totalAngle / 2;
                    ctx.translate(layer.x, layer.y);
                    chars.forEach(function (character) {
                        var charWidth = ctx.measureText(character).width + layer.letterSpacing;
                        var angle = charWidth / circumference * (Math.PI * 2);
                        ctx.save();
                        ctx.rotate(currentAngle + (angle / 2));
                        ctx.translate(0, -radius);
                        if (layer.strokeWidth > 0) {
                            ctx.strokeText(character, 0, 0);
                        }
                        ctx.fillText(character, 0, 0);
                        ctx.restore();
                        currentAngle += angle;
                    });
                } else {
                    lines.forEach(function (line, index) {
                        var y = layer.y + (index * layer.fontSize * 1.2);
                        var startX = layer.x;
                        if (layer.letterSpacing) {
                            var chars = Array.prototype.slice.call(line);
                            var currentX = startX;
                            if (layer.align === 'center') {
                                var total = chars.reduce(function (sum, character) {
                                    return sum + ctx.measureText(character).width + layer.letterSpacing;
                                }, 0);
                                currentX = startX - (total / 2);
                            } else if (layer.align === 'right') {
                                var rightTotal = chars.reduce(function (sum2, character2) {
                                    return sum2 + ctx.measureText(character2).width + layer.letterSpacing;
                                }, 0);
                                currentX = startX - rightTotal;
                            }
                            chars.forEach(function (character) {
                                if (layer.strokeWidth > 0) {
                                    ctx.strokeText(character, currentX, y);
                                }
                                ctx.fillText(character, currentX, y);
                                currentX += ctx.measureText(character).width + layer.letterSpacing;
                            });
                        } else {
                            if (layer.strokeWidth > 0) {
                                ctx.strokeText(line, startX, y);
                            }
                            ctx.fillText(line, startX, y);
                        }
                    });
                }
                ctx.restore();
            }

            function drawImageLayer(ctx, layer) {
                if (!layer.image || !layer.image.complete || !layer.image.naturalWidth) {
                    return;
                }
                var needsProcessing = !!(layer.filter && layer.filter !== 'original') || !!(layer.adjustments && (
                    layer.adjustments.brightness !== 100 ||
                    layer.adjustments.contrast !== 100 ||
                    layer.adjustments.saturation !== 100 ||
                    layer.adjustments.warmth !== 0 ||
                    layer.adjustments.sharpen !== 0 ||
                    layer.adjustments.vignette !== 0 ||
                    (layer.splash && layer.splash.active && layer.splash.target)
                )) || !!(layer.retouchStrokes && layer.retouchStrokes.length);
                ctx.save();
                ctx.globalAlpha = layer.opacity;
                if (needsProcessing) {
                    var processedCanvas = document.createElement('canvas');
                    renderImageSourceToCanvas(processedCanvas, layer.image, Math.max(1, Math.round(layer.image.naturalWidth || layer.width)), Math.max(1, Math.round(layer.image.naturalHeight || layer.height)), {
                        useOriginal: false,
                        filter: layer.filter || 'original',
                        adjustments: layer.adjustments || createDefaultAdjustments(),
                        splash: layer.splash || createDefaultSplashState(),
                        retouchStrokes: layer.retouchStrokes || [],
                        coordinateWidth: Math.max(1, Math.round(layer.image.naturalWidth || layer.width || 1)),
                        coordinateHeight: Math.max(1, Math.round(layer.image.naturalHeight || layer.height || 1))
                    });
                    ctx.drawImage(processedCanvas, layer.x, layer.y, layer.width, layer.height);
                } else {
                    ctx.drawImage(layer.image, layer.x, layer.y, layer.width, layer.height);
                }
                ctx.restore();
            }

            function drawShapeLayer(ctx, layer) {
                ctx.save();
                ctx.globalAlpha = layer.opacity;
                ctx.fillStyle = layer.fill;
                ctx.strokeStyle = layer.strokeColor || layer.fill;
                ctx.lineWidth = Math.max(1, layer.strokeWidth || 1);
                ctx.lineCap = 'round';
                ctx.lineJoin = 'round';
                if (layer.rotation && layer.shape !== 'line' && layer.shape !== 'arrow') {
                    ctx.translate(layer.x + (layer.width / 2), layer.y + (layer.height / 2));
                    ctx.rotate((layer.rotation * Math.PI) / 180);
                    ctx.translate(-(layer.x + (layer.width / 2)), -(layer.y + (layer.height / 2)));
                }
                if (layer.privacyMode && layer.shape !== 'line' && layer.shape !== 'arrow') {
                    var sourceSnapshot = createCanvasCopy(ctx.canvas);
                    var effectCanvas = buildShapePrivacyEffectCanvas(sourceSnapshot, layer.privacyMode, layer.privacyStrength || layer.opacity * 100);
                    var maskCanvas = document.createElement('canvas');
                    var maskContext;
                    var maskedCanvas = document.createElement('canvas');
                    var maskedContext;
                    maskCanvas.width = ctx.canvas.width;
                    maskCanvas.height = ctx.canvas.height;
                    maskedCanvas.width = ctx.canvas.width;
                    maskedCanvas.height = ctx.canvas.height;
                    maskContext = maskCanvas.getContext('2d');
                    maskedContext = maskedCanvas.getContext('2d');
                    if (maskContext && maskedContext) {
                        maskContext.fillStyle = '#ffffff';
                        traceShapePath(maskContext, layer);
                        maskContext.fill();
                        maskedContext.drawImage(effectCanvas, 0, 0);
                        maskedContext.globalCompositeOperation = 'destination-in';
                        maskedContext.drawImage(maskCanvas, 0, 0);
                        maskedContext.globalCompositeOperation = 'source-over';
                        ctx.drawImage(maskedCanvas, 0, 0);
                    }
                    if (layer.strokeWidth > 0) {
                        traceShapePath(ctx, layer);
                        ctx.strokeStyle = layer.strokeColor || getPrivacyShapeColor(layer.privacyMode);
                        ctx.stroke();
                    }
                    ctx.restore();
                    return;
                }
                if (layer.shape === 'circle') {
                    traceShapePath(ctx, layer);
                    ctx.fill();
                    if (layer.strokeWidth > 0) {
                        ctx.stroke();
                    }
                } else if (layer.shape === 'line' || layer.shape === 'arrow') {
                    var fromX = layer.x;
                    var fromY = layer.y;
                    var toX = layer.x + layer.width;
                    var toY = layer.y + layer.height;
                    var angle = Math.atan2(toY - fromY, toX - fromX);
                    var strokeColor = layer.fill || layer.strokeColor || '#5ea5ff';
                    var head = Math.max(18, (layer.strokeWidth || 6) * 3.1);
                    var headAngle = Math.PI / 10;
                    if (layer.shape === 'arrow') {
                        var shaftEndX = toX - (head * 0.72 * Math.cos(angle));
                        var shaftEndY = toY - (head * 0.72 * Math.sin(angle));
                        ctx.beginPath();
                        ctx.moveTo(fromX, fromY);
                        ctx.lineTo(shaftEndX, shaftEndY);
                        ctx.strokeStyle = strokeColor;
                        ctx.stroke();

                        ctx.beginPath();
                        ctx.moveTo(toX, toY);
                        ctx.lineTo(toX - (head * Math.cos(angle - headAngle)), toY - (head * Math.sin(angle - headAngle)));
                        ctx.lineTo(toX - (head * Math.cos(angle + headAngle)), toY - (head * Math.sin(angle + headAngle)));
                        ctx.closePath();
                        ctx.fillStyle = strokeColor;
                        ctx.fill();
                    } else {
                        ctx.beginPath();
                        ctx.moveTo(fromX, fromY);
                        ctx.lineTo(toX, toY);
                        ctx.strokeStyle = strokeColor;
                        ctx.stroke();
                    }
                } else {
                    ctx.fillRect(layer.x, layer.y, layer.width, layer.height);
                    if (layer.strokeWidth > 0) {
                        ctx.strokeRect(layer.x, layer.y, layer.width, layer.height);
                    }
                }
                ctx.restore();
            }

            function getWatermarkLayout(cropRect) {
                var margin = Math.max(18, Math.round(Math.min(cropRect.width, cropRect.height) * 0.04));
                var align = 'right';
                var baseline = 'bottom';
                var textX = cropRect.x + cropRect.width - margin;
                var textY = cropRect.y + cropRect.height - margin;
                var cropWidth = cropRect.width;
                var cropHeight = cropRect.height;
                var imageWidth = 0;
                var imageHeight = 0;
                var imageX = cropRect.x + cropWidth - margin;
                var imageY = cropRect.y + cropHeight - margin;
                var textBounds = null;
                var imageBounds = null;
                var measureCanvas;
                var measureContext;
                var textWidth;
                var textHeight;
                var textLeft;
                var textTop;
                var maxWidth;
                var ratio;

                if (state.watermark.position === 'bottom-left') {
                    align = 'left';
                    textX = cropRect.x + margin;
                    textY = cropRect.y + cropRect.height - margin;
                } else if (state.watermark.position === 'top-right') {
                    align = 'right';
                    baseline = 'top';
                    textX = cropRect.x + cropRect.width - margin;
                    textY = cropRect.y + margin;
                } else if (state.watermark.position === 'top-left') {
                    align = 'left';
                    baseline = 'top';
                    textX = cropRect.x + margin;
                    textY = cropRect.y + margin;
                } else if (state.watermark.position === 'center') {
                    align = 'center';
                    baseline = 'middle';
                    textX = cropRect.x + (cropRect.width / 2);
                    textY = cropRect.y + (cropRect.height / 2);
                }

                textX += Number(state.watermark.textOffsetX || 0);
                textY += Number(state.watermark.textOffsetY || 0);

                if (state.watermark.text) {
                    measureCanvas = document.createElement('canvas');
                    measureContext = measureCanvas.getContext('2d');
                    measureContext.font = '700 ' + Math.max(12, Number(state.watermark.size || 34)) + 'px Arial, sans-serif';
                    textWidth = Math.max(1, measureContext.measureText(state.watermark.text).width);
                    textHeight = Math.max(12, Number(state.watermark.size || 34));
                    textLeft = textX;
                    if (align === 'center') {
                        textLeft = textX - (textWidth / 2);
                    } else if (align === 'right') {
                        textLeft = textX - textWidth;
                    }
                    textTop = textY;
                    if (baseline === 'bottom') {
                        textTop = textY - textHeight;
                    } else if (baseline === 'middle') {
                        textTop = textY - (textHeight / 2);
                    }
                    textBounds = {
                        x: textLeft - 12,
                        y: textTop - 12,
                        width: textWidth + 24,
                        height: textHeight + 24,
                        align: align,
                        baseline: baseline,
                        xAnchor: textX,
                        yAnchor: textY
                    };
                }

                if (state.watermark.image && state.watermark.image.complete && state.watermark.image.naturalWidth) {
                    maxWidth = cropWidth * state.watermark.imageScale;
                    ratio = maxWidth / state.watermark.image.naturalWidth;
                    imageWidth = maxWidth;
                    imageHeight = state.watermark.image.naturalHeight * ratio;
                    imageX = cropRect.x + cropWidth - imageWidth - margin;
                    imageY = cropRect.y + cropHeight - imageHeight - margin;
                    if (state.watermark.position === 'bottom-left') {
                        imageX = cropRect.x + margin;
                    } else if (state.watermark.position === 'top-right') {
                        imageY = cropRect.y + margin;
                    } else if (state.watermark.position === 'top-left') {
                        imageX = cropRect.x + margin;
                        imageY = cropRect.y + margin;
                    } else if (state.watermark.position === 'center') {
                        imageX = cropRect.x + ((cropWidth - imageWidth) / 2);
                        imageY = cropRect.y + ((cropHeight - imageHeight) / 2);
                    }
                    imageX += Number(state.watermark.imageOffsetX || 0);
                    imageY += Number(state.watermark.imageOffsetY || 0);
                    imageBounds = {
                        x: imageX,
                        y: imageY,
                        width: imageWidth,
                        height: imageHeight
                    };
                }

                return {
                    text: textBounds,
                    image: imageBounds
                };
            }

            function hitWatermark(x, y) {
                var layout = getWatermarkLayout(state.crop);
                var imageStage;
                var textStage;
                if (layout.text) {
                    textStage = rectToStage(layout.text);
                    if (x >= textStage.x && x <= textStage.x + textStage.width && y >= textStage.y && y <= textStage.y + textStage.height) {
                        return 'text';
                    }
                }
                if (layout.image) {
                    imageStage = rectToStage(layout.image);
                    if (x >= imageStage.x && x <= imageStage.x + imageStage.width && y >= imageStage.y && y <= imageStage.y + imageStage.height) {
                        return 'image';
                    }
                }
                return '';
            }

            function colorToRgba(color, alpha) {
                var safeAlpha = clamp(Number(alpha), 0, 1);
                var value = String(color || '#ffffff').trim();
                var match;
                if (/^#[0-9a-f]{3}$/i.test(value)) {
                    return 'rgba(' + parseInt(value.charAt(1) + value.charAt(1), 16) + ',' + parseInt(value.charAt(2) + value.charAt(2), 16) + ',' + parseInt(value.charAt(3) + value.charAt(3), 16) + ',' + safeAlpha + ')';
                }
                if (/^#[0-9a-f]{6}$/i.test(value)) {
                    return 'rgba(' + parseInt(value.slice(1, 3), 16) + ',' + parseInt(value.slice(3, 5), 16) + ',' + parseInt(value.slice(5, 7), 16) + ',' + safeAlpha + ')';
                }
                match = value.match(/^rgba?\(([^)]+)\)$/i);
                if (match) {
                    var parts = match[1].split(',').map(function (part) {
                        return parseFloat(part.trim());
                    });
                    if (parts.length >= 3) {
                        return 'rgba(' + clamp(parts[0], 0, 255) + ',' + clamp(parts[1], 0, 255) + ',' + clamp(parts[2], 0, 255) + ',' + safeAlpha + ')';
                    }
                }
                return 'rgba(255,255,255,' + safeAlpha + ')';
            }

            function drawWatermark(ctx, cropRect) {
                var layout = getWatermarkLayout(cropRect);
                var textOpacity;
                if (layout.image && state.watermark.image && state.watermark.image.complete && state.watermark.image.naturalWidth) {
                    ctx.save();
                    ctx.globalAlpha = clamp(Number(state.watermark.imageOpacity || 0.9), 0.05, 1);
                    ctx.drawImage(state.watermark.image, layout.image.x, layout.image.y, layout.image.width, layout.image.height);
                    ctx.restore();
                }
                if (layout.text && state.watermark.text) {
                    textOpacity = clamp(Number(state.watermark.opacity), 0, 1);
                    ctx.save();
                    ctx.font = '700 ' + Math.max(12, Number(state.watermark.size || 34)) + 'px Arial, sans-serif';
                    ctx.fillStyle = colorToRgba(state.watermark.color || '#ffffff', textOpacity);
                    ctx.strokeStyle = colorToRgba('#000000', Math.max(0, textOpacity * 0.5));
                    ctx.lineWidth = Math.max(1, Math.round((state.watermark.size || 34) * 0.06));
                    ctx.textAlign = layout.text.align;
                    ctx.textBaseline = layout.text.baseline;
                    ctx.shadowBlur = 18;
                    ctx.shadowColor = colorToRgba('#000000', Math.max(0, textOpacity * 0.35));
                    ctx.strokeText(state.watermark.text, layout.text.xAnchor, layout.text.yAnchor);
                    ctx.fillText(state.watermark.text, layout.text.xAnchor, layout.text.yAnchor);
                    ctx.restore();
                }
            }


            function buildCompositionCanvas(useOriginal) {
                if (!state.image) {
                    return null;
                }
                var composition = document.createElement('canvas');
                composition.width = state.image.width;
                composition.height = state.image.height;
                renderSourceToCanvas(composition, state.image.width, state.image.height, useOriginal);
                if (!useOriginal) {
                    state.layers.forEach(function (layer) {
                        if (!layer.visible) {
                            return;
                        }
                        if (layer.type === 'text') {
                            drawTextLayer(composition.getContext('2d'), layer, 1);
                        } else if (layer.type === 'image') {
                            drawImageLayer(composition.getContext('2d'), layer);
                        } else {
                            drawShapeLayer(composition.getContext('2d'), layer);
                        }
                    });
                    drawWatermark(composition.getContext('2d'), state.crop);
                }
                return composition;
            }

            function drawStage() {
                syncCanvasSize();
                if (!stageFrame) {
                    return;
                }
                stageContext.setTransform(stageFrame.dpr, 0, 0, stageFrame.dpr, 0, 0);
                stageContext.clearRect(0, 0, stageFrame.width, stageFrame.height);
                stageContext.fillStyle = state.workspaceBackground || '#0f172a';
                stageContext.fillRect(0, 0, stageFrame.width, stageFrame.height);

                if (!state.image) {
                    if (designEmpty) {
                        designEmpty.hidden = false;
                    }
                    return;
                }

                if (designEmpty) {
                    designEmpty.hidden = true;
                }

                var previewCanvas = getPreviewCanvas(state.previewOriginal);
                var fit = Math.min(stageFrame.width / state.image.width, stageFrame.height / state.image.height) * state.viewport.zoom;
                var centerX = stageFrame.width / 2 + state.viewport.panX;
                var centerY = stageFrame.height / 2 + state.viewport.panY;
                var drawWidth = state.image.width * fit;
                var drawHeight = state.image.height * fit;
                var drawX = centerX - (drawWidth / 2);
                var drawY = centerY - (drawHeight / 2);

                stageContext.save();
                stageContext.drawImage(previewCanvas, drawX, drawY, drawWidth, drawHeight);
                stageContext.restore();

                if (!state.previewOriginal) {
                    state.layers.forEach(function (layer) {
                        if (!layer.visible) {
                            return;
                        }
                        drawLayerOnStage(layer, fit);
                    });
                    drawWatermarkOnStage();
                }

                drawSnapGuides();
                drawCropOverlayOnStage();
                if (brushHover && hasActiveRetouchTool()) {
                    stageContext.save();
                    stageContext.beginPath();
                    stageContext.arc(brushHover.x, brushHover.y, Math.max(6, brushHover.radius), 0, Math.PI * 2);
                    stageContext.strokeStyle = getRetouchHoverColor(brushHover.tool);
                    stageContext.lineWidth = 2;
                    stageContext.setLineDash([8, 5]);
                    stageContext.stroke();
                    stageContext.restore();
                }

                var selected = getSelectedLayer();
                if (selected && selected.visible) {
                    var bounds = rectToStage(layerBounds(selected));
                    var resizeHandles = getLayerResizeHandles(selected);
                    var rotateHandle = getLayerRotateHandle(selected);
                    stageContext.save();
                    stageContext.strokeStyle = '#60a5fa';
                    stageContext.lineWidth = 2;
                    stageContext.setLineDash([6, 4]);
                    stageContext.strokeRect(bounds.x, bounds.y, bounds.width, bounds.height);
                    stageContext.setLineDash([]);
                    if (rotateHandle) {
                        stageContext.strokeStyle = 'rgba(219, 234, 254, 0.8)';
                        stageContext.lineWidth = 1.5;
                        stageContext.beginPath();
                        stageContext.moveTo(rotateHandle.x, rotateHandle.lineTop);
                        stageContext.lineTo(rotateHandle.x, rotateHandle.y);
                        stageContext.stroke();
                        stageContext.fillStyle = '#ffffff';
                        stageContext.strokeStyle = '#1d4ed8';
                        stageContext.beginPath();
                        stageContext.arc(rotateHandle.x, rotateHandle.y, rotateHandle.size / 2, 0, Math.PI * 2);
                        stageContext.fill();
                        stageContext.stroke();
                    }
                    resizeHandles.forEach(function (handle) {
                        stageContext.fillStyle = handle.axis === 'edge' ? '#dbeafe' : '#ffffff';
                        stageContext.strokeStyle = '#1d4ed8';
                        stageContext.lineWidth = 1.25;
                        stageContext.fillRect(handle.x - (handle.size / 2), handle.y - (handle.size / 2), handle.size, handle.size);
                        stageContext.strokeRect(handle.x - (handle.size / 2), handle.y - (handle.size / 2), handle.size, handle.size);
                    });
                    stageContext.restore();
                }

                drawOutputPreview();
            }

            function drawCropOverlayOnStage() {
                if (!state.image || !isCropOverlayVisible()) {
                    return;
                }
                var cropStage = rectToStage(state.crop);
                var handleSize = 12;
                var midHandleSize = 10;
                var thirdsX1 = cropStage.x + (cropStage.width / 3);
                var thirdsX2 = cropStage.x + ((cropStage.width / 3) * 2);
                var thirdsY1 = cropStage.y + (cropStage.height / 3);
                var thirdsY2 = cropStage.y + ((cropStage.height / 3) * 2);
                var cropEditable = canInteractWithCropOverlay();

                stageContext.save();
                if (cropEditable) {
                    stageContext.fillStyle = 'rgba(6, 8, 12, 0.56)';
                    stageContext.beginPath();
                    stageContext.rect(0, 0, stageFrame.width, stageFrame.height);
                    stageContext.rect(cropStage.x, cropStage.y, cropStage.width, cropStage.height);
                    stageContext.fill('evenodd');
                }

                stageContext.strokeStyle = '#dbeafe';
                stageContext.lineWidth = cropEditable ? 2.5 : 1.5;
                stageContext.setLineDash(cropEditable ? [] : [10, 6]);
                stageContext.strokeRect(cropStage.x, cropStage.y, cropStage.width, cropStage.height);
                stageContext.setLineDash([]);

                if (cropEditable && state.showGrid) {
                    stageContext.strokeStyle = 'rgba(255,255,255,0.38)';
                    stageContext.lineWidth = 1;
                    stageContext.setLineDash([6, 6]);
                    stageContext.beginPath();
                    stageContext.moveTo(thirdsX1, cropStage.y);
                    stageContext.lineTo(thirdsX1, cropStage.y + cropStage.height);
                    stageContext.moveTo(thirdsX2, cropStage.y);
                    stageContext.lineTo(thirdsX2, cropStage.y + cropStage.height);
                    stageContext.moveTo(cropStage.x, thirdsY1);
                    stageContext.lineTo(cropStage.x + cropStage.width, thirdsY1);
                    stageContext.moveTo(cropStage.x, thirdsY2);
                    stageContext.lineTo(cropStage.x + cropStage.width, thirdsY2);
                    stageContext.stroke();
                    stageContext.setLineDash([]);
                }

                if (cropEditable && state.safeArea) {
                    var insetX = cropStage.width * 0.08;
                    var insetY = cropStage.height * 0.08;
                    stageContext.strokeStyle = 'rgba(255,255,255,0.50)';
                    stageContext.lineWidth = 1.25;
                    stageContext.setLineDash([10, 8]);
                    stageContext.strokeRect(cropStage.x + insetX, cropStage.y + insetY, cropStage.width - (insetX * 2), cropStage.height - (insetY * 2));
                    stageContext.setLineDash([]);
                }

                if (cropEditable) {
                    [
                        { x: cropStage.x, y: cropStage.y },
                        { x: cropStage.x + cropStage.width, y: cropStage.y },
                        { x: cropStage.x, y: cropStage.y + cropStage.height },
                        { x: cropStage.x + cropStage.width, y: cropStage.y + cropStage.height }
                    ].forEach(function (point) {
                        stageContext.fillStyle = '#ffffff';
                        stageContext.strokeStyle = '#2563eb';
                        stageContext.lineWidth = 1.5;
                        stageContext.fillRect(point.x - (handleSize / 2), point.y - (handleSize / 2), handleSize, handleSize);
                        stageContext.strokeRect(point.x - (handleSize / 2), point.y - (handleSize / 2), handleSize, handleSize);
                    });

                    [
                        { x: cropStage.x + (cropStage.width / 2), y: cropStage.y },
                        { x: cropStage.x + (cropStage.width / 2), y: cropStage.y + cropStage.height },
                        { x: cropStage.x, y: cropStage.y + (cropStage.height / 2) },
                        { x: cropStage.x + cropStage.width, y: cropStage.y + (cropStage.height / 2) }
                    ].forEach(function (point) {
                        stageContext.fillStyle = '#dbeafe';
                        stageContext.strokeStyle = '#1d4ed8';
                        stageContext.lineWidth = 1.25;
                        stageContext.fillRect(point.x - (midHandleSize / 2), point.y - (midHandleSize / 2), midHandleSize, midHandleSize);
                        stageContext.strokeRect(point.x - (midHandleSize / 2), point.y - (midHandleSize / 2), midHandleSize, midHandleSize);
                    });
                }
                stageContext.restore();
            }

            function drawWatermarkOnStage() {
                if (!state.watermark.text && !(state.watermark.image && state.watermark.image.complete && state.watermark.image.naturalWidth)) {
                    return;
                }
                var composition = document.createElement('canvas');
                composition.width = state.image.width;
                composition.height = state.image.height;
                drawWatermark(composition.getContext('2d'), state.crop);
                var fit = Math.min(stageFrame.width / state.image.width, stageFrame.height / state.image.height) * state.viewport.zoom;
                var centerX = stageFrame.width / 2 + state.viewport.panX;
                var centerY = stageFrame.height / 2 + state.viewport.panY;
                stageContext.drawImage(
                    composition,
                    centerX - ((state.image.width * fit) / 2),
                    centerY - ((state.image.height * fit) / 2),
                    state.image.width * fit,
                    state.image.height * fit
                );
            }

            function drawLayerOnStage(layer) {
                var composition = document.createElement('canvas');
                composition.width = state.image.width;
                composition.height = state.image.height;
                var ctx = composition.getContext('2d');
                if (layer.type === 'text') {
                    drawTextLayer(ctx, layer, 1);
                } else if (layer.type === 'image') {
                    drawImageLayer(ctx, layer);
                } else {
                    drawShapeLayer(ctx, layer);
                }
                var fit = Math.min(stageFrame.width / state.image.width, stageFrame.height / state.image.height) * state.viewport.zoom;
                var centerX = stageFrame.width / 2 + state.viewport.panX;
                var centerY = stageFrame.height / 2 + state.viewport.panY;
                stageContext.drawImage(
                    composition,
                    centerX - ((state.image.width * fit) / 2),
                    centerY - ((state.image.height * fit) / 2),
                    state.image.width * fit,
                    state.image.height * fit
                );
            }

            function scheduleRender() {
                if (renderPending) {
                    return;
                }
                renderPending = true;
                window.requestAnimationFrame(function () {
                    renderPending = false;
                    drawStage();
                });
            }

            function loadImageFile(file) {
                queueDesignFiles(file ? [file] : []);
            }

            function buildExportCanvas(useOriginal) {
                var composition = buildCompositionCanvas(useOriginal);
                if (!composition) {
                    return null;
                }
                var cropRect = state.crop;
                var exportCanvas = document.createElement('canvas');
                var scale = Number(state.exportScale || 1);
                exportCanvas.width = Math.max(1, Math.round(cropRect.width * scale));
                exportCanvas.height = Math.max(1, Math.round(cropRect.height * scale));
                var ctx = exportCanvas.getContext('2d');
                if (state.exportFormat === 'image/jpeg') {
                    ctx.fillStyle = '#ffffff';
                    ctx.fillRect(0, 0, exportCanvas.width, exportCanvas.height);
                }
                ctx.drawImage(
                    composition,
                    cropRect.x,
                    cropRect.y,
                    cropRect.width,
                    cropRect.height,
                    0,
                    0,
                    exportCanvas.width,
                    exportCanvas.height
                );
                return exportCanvas;
            }


            function copyCropToClipboard() {
                if (!state.image || !navigator.clipboard || typeof window.ClipboardItem === 'undefined') {
                    setDesignStatus('Copy crop is not available in this browser.');
                    return;
                }
                var composition = buildCompositionCanvas(false);
                if (!composition) {
                    return;
                }
                var cropRect = state.crop;
                var cropCanvas = document.createElement('canvas');
                cropCanvas.width = Math.max(1, Math.round(cropRect.width));
                cropCanvas.height = Math.max(1, Math.round(cropRect.height));
                cropCanvas.getContext('2d').drawImage(
                    composition,
                    cropRect.x,
                    cropRect.y,
                    cropRect.width,
                    cropRect.height,
                    0,
                    0,
                    cropRect.width,
                    cropRect.height
                );
                canvasToBlob(cropCanvas, 'image/png', 1).then(function (blob) {
                    if (!blob) {
                        setDesignStatus('Unable to build the selected crop.');
                        return;
                    }
                    copiedCropLayer = {
                        dataUrl: URL.createObjectURL(blob),
                        width: cropCanvas.width,
                        height: cropCanvas.height
                    };
                    return navigator.clipboard.write([
                        new window.ClipboardItem({ 'image/png': blob })
                    ]).then(function () {
                        setDesignStatus('Crop copied to clipboard as PNG.');
                    });
                }).catch(function () {
                    setDesignStatus('Copy crop failed in the current browser.');
                });
            }

            function downloadDesign() {
                if (!state.image) {
                    setDesignStatus('Load an image before exporting.');
                    return;
                }
                if (state.exportFormat === 'image/webp' && !supportsImageType('image/webp')) {
                    setDesignStatus('WEBP export is not supported in this browser.');
                    return;
                }
                var exportCanvas = buildExportCanvas(false);
                canvasToBlob(exportCanvas, state.exportFormat, state.exportQuality).then(function (blob) {
                    if (!blob) {
                        setDesignStatus('The selected export format is not supported in this browser.');
                        return;
                    }
                    var url = URL.createObjectURL(blob);
                    var anchor = document.createElement('a');
                    var basename = (state.imageName || 'design').replace(/\.[^.]+$/, '');
                    anchor.href = url;
                    anchor.download = basename + '-design.' + getFileExtension(blob.type, basename);
                    document.body.appendChild(anchor);
                    anchor.click();
                    anchor.remove();
                    window.setTimeout(function () {
                        URL.revokeObjectURL(url);
                    }, 800);
                    setDesignStatus('Design exported as ' + blob.type.replace('image/', '').toUpperCase() + '.');
                });
            }

            function copyDesignToClipboard() {
                if (!state.image) {
                    setDesignStatus('Load an image before copying it to the clipboard.');
                    return;
                }
                if (!navigator.clipboard || typeof window.ClipboardItem === 'undefined') {
                    setDesignStatus('Clipboard image copy is not available in this browser.');
                    return;
                }
                var exportCanvas = buildExportCanvas(false);
                canvasToBlob(exportCanvas, 'image/png', 1).then(function (blob) {
                    if (!blob) {
                        setDesignStatus('Unable to create a PNG clipboard copy in this browser.');
                        return;
                    }
                    return navigator.clipboard.write([
                        new window.ClipboardItem({
                            'image/png': blob
                        })
                    ]).then(function () {
                        setDesignStatus('PNG design copied to clipboard.');
                    }).catch(function () {
                        setDesignStatus('Clipboard write failed in this browser context.');
                    });
                });
            }

            function autoEnhance() {
                if (!state.image) {
                    return;
                }
                var toneTarget = getToneStateTarget();
                var sourceImage = toneTarget.isLayer && toneTarget.layer && toneTarget.layer.image ? toneTarget.layer.image : state.image;
                if (!sourceImage || !sourceImage.naturalWidth || !sourceImage.naturalHeight) {
                    return;
                }
                var sample = document.createElement('canvas');
                var ctx = sample.getContext('2d');
                var sampleWidth = 64;
                var sampleHeight = Math.max(1, Math.round((sourceImage.naturalHeight / sourceImage.naturalWidth) * sampleWidth));
                sample.width = sampleWidth;
                sample.height = sampleHeight;
                ctx.drawImage(sourceImage, 0, 0, sampleWidth, sampleHeight);
                var data = ctx.getImageData(0, 0, sampleWidth, sampleHeight).data;
                var brightness = 0;
                var saturation = 0;
                var count = data.length / 4;
                var index;
                for (index = 0; index < data.length; index += 4) {
                    var r = data[index] / 255;
                    var g = data[index + 1] / 255;
                    var b = data[index + 2] / 255;
                    var max = Math.max(r, g, b);
                    var min = Math.min(r, g, b);
                    brightness += (max + min) / 2;
                    saturation += max === min ? 0 : ((max - min) / (1 - Math.abs(max + min - 1)));
                }
                brightness = brightness / count;
                saturation = saturation / count;
                toneTarget.adjustments.brightness = clamp(Math.round(112 - ((brightness - 0.5) * 40)), 90, 122);
                toneTarget.adjustments.contrast = clamp(Math.round(108 + ((0.5 - brightness) * 24)), 96, 124);
                toneTarget.adjustments.saturation = clamp(Math.round(108 + ((0.35 - saturation) * 70)), 92, 134);
                toneTarget.adjustments.warmth = brightness < 0.42 ? 10 : 4;
                toneTarget.adjustments.sharpen = 18;
                toneTarget.adjustments.vignette = 10;
                syncControlsFromState();
                scheduleHistory();
                if (toneTarget.isLayer) {
                    scheduleRender();
                    setDesignStatus('Auto enhance applied to the selected image layer.');
                } else {
                    markPreviewDirty();
                    setDesignStatus('Auto enhance applied.');
                }
            }

            function togglePreviewOriginal() {
                state.previewOriginal = !state.previewOriginal;
                scheduleRender();
                setDesignStatus(state.previewOriginal ? 'Before view enabled.' : 'Edited preview enabled.');
            }

            function updateLayerField(field, value) {
                var layer = getSelectedLayer();
                if (!layer) {
                    return;
                }
                if (field === 'fontSize' || field === 'letterSpacing' || field === 'curve' || field === 'shadowBlur' || field === 'strokeWidth' || field === 'width' || field === 'height') {
                    layer[field] = Number(value || 0);
                } else if (field === 'opacity') {
                    layer[field] = clamp(Number(value || 0), 0.05, 1);
                } else {
                    layer[field] = (field === 'backgroundColor' && (!value || value === 'transparent')) ? '' : value;
                }
                if (field === 'text') {
                    layer.name = String(layer.text || '').slice(0, 24) || ('Text ' + layer.id);
                }
                renderLayerList();
                scheduleHistory();
                scheduleRender();
            }

            function duplicateLayer() {
                var selected = getSelectedLayer();
                if (!selected) {
                    return;
                }
                layerCounter += 1;
                var duplicate = cloneDeep(selected);
                if (selected.type === 'image' && selected.image) {
                    duplicate.image = selected.image;
                }
                duplicate.id = layerCounter;
                duplicate.name = selected.name + ' copy';
                duplicate.x += 24;
                duplicate.y += 24;
                state.layers.push(duplicate);
                setSelectedLayer(duplicate.id);
                pushHistory();
                setDesignStatus('Layer duplicated.');
            }

            function deleteLayer() {
                var selected = getSelectedLayer();
                if (!selected) {
                    return;
                }
                state.layers = state.layers.filter(function (layer) {
                    return layer.id !== selected.id;
                });
                setSelectedLayer(state.layers.length ? state.layers[state.layers.length - 1].id : null);
                pushHistory();
                setDesignStatus('Layer deleted.');
            }

            function moveLayer(direction) {
                var index = state.layers.findIndex(function (layer) {
                    return layer.id === state.selectedLayerId;
                });
                if (index === -1) {
                    return;
                }
                var nextIndex = direction === 'forward' ? Math.min(state.layers.length - 1, index + 1) : Math.max(0, index - 1);
                if (nextIndex === index) {
                    return;
                }
                var layer = state.layers[index];
                state.layers.splice(index, 1);
                state.layers.splice(nextIndex, 0, layer);
                renderLayerList();
                pushHistory();
                scheduleRender();
            }

            function alignLayer(axis) {
                var layer = getSelectedLayer();
                if (!layer) {
                    return;
                }
                var bounds = layerBounds(layer);
                if (axis === 'x') {
                    layer.x += (state.crop.x + (state.crop.width / 2)) - (bounds.x + (bounds.width / 2));
                } else if (axis === 'y') {
                    layer.y += (state.crop.y + (state.crop.height / 2)) - (bounds.y + (bounds.height / 2));
                } else if (axis === 'left') {
                    layer.x += state.crop.x - bounds.x;
                } else if (axis === 'right') {
                    layer.x += (state.crop.x + state.crop.width) - (bounds.x + bounds.width);
                } else if (axis === 'top') {
                    layer.y += state.crop.y - bounds.y;
                } else if (axis === 'bottom') {
                    layer.y += (state.crop.y + state.crop.height) - (bounds.y + bounds.height);
                }
                scheduleHistory();
                scheduleRender();
            }

            function handleDesignAction(action) {
                switch (action) {
                case 'browse':
                    if (designInput) {
                        designInput.click();
                    }
                    break;
                case 'fit':
                case 'reset-view':
                    fitViewport();
                    setDesignStatus(action === 'fit' ? 'View fitted to stage.' : 'View reset.');
                    break;
                case 'reset-edits':
                    resetEdits();
                    break;
                case 'undo':
                    undoHistory();
                    break;
                case 'redo':
                    redoHistory();
                    break;
                case 'rotate-left':
                    transformBaseImage('rotate-left');
                    break;
                case 'rotate-right':
                    transformBaseImage('rotate-right');
                    break;
                case 'flip-x':
                    transformBaseImage('flip-x');
                    break;
                case 'flip-y':
                    transformBaseImage('flip-y');
                    break;
                case 'brush-clear':
                    if (getSelectedImageLayer()) {
                        getSelectedImageLayer().retouchStrokes = [];
                        scheduleRender();
                        pushHistory();
                        setDesignStatus('Brush effects cleared from the selected image layer.');
                    } else if (state.image) {
                        state.retouchStrokes = [];
                        markPreviewDirty();
                        pushHistory();
                        setDesignStatus('Brush effects cleared from the base image.');
                    }
                    break;
                case 'crop-reset':
                    if (state.image) {
                        state.crop = { x: 0, y: 0, width: state.image.width, height: state.image.height };
                        state.hasCustomCrop = false;
                        state.cropArmed = false;
                        setAspect('free');
                        scheduleRender();
                        pushHistory();
                        setDesignStatus('Crop reset to the full image.');
                    }
                    break;
                case 'toggle-safe-area':
                    state.safeArea = !state.safeArea;
                    scheduleRender();
                    setDesignStatus(state.safeArea ? 'Safe area overlay enabled.' : 'Safe area overlay hidden.');
                    break;
                case 'auto-enhance':
                    autoEnhance();
                    break;
                case 'before-after':
                    togglePreviewOriginal();
                    break;
                case 'sample-color':
                    state.splash.armed = true;
                    state.previewOriginal = false;
                    setDesignStatus('Selective color armed. Click the canvas to sample a color.');
                    break;
                case 'clear-selective-color':
                    state.splash.active = false;
                    state.splash.armed = false;
                    state.splash.target = null;
                    markPreviewDirty();
                    setDesignStatus('Selective color cleared.');
                    break;
                case 'zoom-in':
                    state.viewport.zoom = clamp(state.viewport.zoom * 1.12, 0.2, 8);
                    scheduleRender();
                    break;
                case 'zoom-out':
                    state.viewport.zoom = clamp(state.viewport.zoom / 1.12, 0.2, 8);
                    scheduleRender();
                    break;
                case 'center-crop':
                    if (state.image) {
                        state.crop.x = Math.round((state.image.width - state.crop.width) / 2);
                        state.crop.y = Math.round((state.image.height - state.crop.height) / 2);
                        scheduleRender();
                        pushHistory();
                    }
                    break;
                case 'crop-mode':
                    state.cropArmed = !state.cropArmed;
                    if (state.cropArmed) {
                        setSelectedLayer(null);
                    }
                    setDesignStatus(state.cropArmed ? 'Crop selection armed. Drag directly on the image to mark the crop area.' : 'Crop selection disabled.');
                    scheduleRender();
                    break;
                case 'toggle-grid':
                    state.showGrid = !state.showGrid;
                    applyWorkspaceBackground();
                    saveDraft();
                    setDesignStatus(state.showGrid ? 'Crop guide grid enabled.' : 'Crop guide grid hidden.');
                    break;
                case 'copy-image':
                    copyDesignToClipboard();
                    break;
                case 'copy-crop':
                    copyCropToClipboard();
                    break;
                case 'paste-crop':
                    if (!copiedCropLayer || !copiedCropLayer.dataUrl) {
                        setDesignStatus('Copy a crop first before pasting it as a new layer.');
                        break;
                    }
                    loadImageFromDataUrl(copiedCropLayer.dataUrl).then(function (image) {
                        var cropLayer = createImageLayerFromImage(image, 'Crop layer', copiedCropLayer.dataUrl);
                        state.layers.push(cropLayer);
                        setSelectedLayer(cropLayer.id);
                        pushHistory();
                        scheduleRender();
                        setDesignStatus('Crop pasted as a new image layer.');
                    });
                    break;
                case 'new-thumbnail':
                    (function () {
                        var asset = createEmptyDesignAsset();
                        loadImageFromDataUrl(asset.dataUrl).then(function (image) {
                            asset.image = image;
                            asset.snapshot = createDefaultDesignSnapshot(image);
                            designAssets.push(asset);
                            renderDesignThumbStrip();
                            activateDesignAsset(asset.id);
                            saveDraft();
                            setDesignStatus('Empty thumbnail created.');
                        });
                    }());
                    break;
                case 'clear-watermark':
                    clearWatermarkState();
                    pushHistory();
                    scheduleRender();
                    drawOutputPreview();
                    saveDraft();
                    setDesignStatus('Watermark cleared.');
                    break;
                case 'save-draft':
                    saveDraft({ immediate: true }).then(function () {
                        setDesignStatus('Design draft saved on this browser.');
                    });
                    break;
                case 'download':
                    downloadDesign();
                    break;
                case 'clear-text-bg':
                    state.quickText.backgroundColor = '';
                    if (designQuickBgColor) {
                        designQuickBgColor.value = '#10151e';
                    }
                    if (getSelectedLayer() && getSelectedLayer().type === 'text') {
                        getSelectedLayer().backgroundColor = '';
                        syncSelectedLayerControls();
                        scheduleRender();
                        pushHistory();
                    }
                    setDesignStatus('Text background cleared.');
                    break;
                case 'add-text':
                    if (state.image) {
                        var textLayer = createBaseLayer('text');
                        state.layers.push(textLayer);
                        setSelectedLayer(textLayer.id);
                        pushHistory();
                        scheduleRender();
                    }
                    break;
                case 'add-rect':
                    if (state.image) {
                        var rectLayer = createBaseLayer('rect');
                        state.layers.push(rectLayer);
                        setSelectedLayer(rectLayer.id);
                        pushHistory();
                        scheduleRender();
                    }
                    break;
                case 'add-circle':
                    if (state.image) {
                        var circleLayer = createBaseLayer('circle');
                        state.layers.push(circleLayer);
                        setSelectedLayer(circleLayer.id);
                        pushHistory();
                        scheduleRender();
                    }
                    break;
                case 'add-privacy-rect':
                    if (state.image) {
                        var privacyRectLayer = createPrivacyShapeLayer('rect', getPrivacyShapeMode());
                        state.layers.push(privacyRectLayer);
                        setSelectedLayer(privacyRectLayer.id);
                        pushHistory();
                        scheduleRender();
                        setDesignStatus(getRetouchToolLabel(privacyRectLayer.privacyMode) + ' box added.');
                    }
                    break;
                case 'add-privacy-circle':
                    if (state.image) {
                        var privacyCircleLayer = createPrivacyShapeLayer('circle', getPrivacyShapeMode());
                        state.layers.push(privacyCircleLayer);
                        setSelectedLayer(privacyCircleLayer.id);
                        pushHistory();
                        scheduleRender();
                        setDesignStatus(getRetouchToolLabel(privacyCircleLayer.privacyMode) + ' round added.');
                    }
                    break;
                case 'add-arrow':
                    if (state.image) {
                        var arrowLayer = createBaseLayer('arrow');
                        state.layers.push(arrowLayer);
                        setSelectedLayer(arrowLayer.id);
                        pushHistory();
                        scheduleRender();
                    }
                    break;
                case 'add-line':
                    if (state.image) {
                        var lineLayer = createBaseLayer('line');
                        state.layers.push(lineLayer);
                        setSelectedLayer(lineLayer.id);
                        pushHistory();
                        scheduleRender();
                    }
                    break;
                case 'rotate-selection':
                    rotateSelectedSelection(15);
                    break;
                case 'copy-layer':
                    setLayerClipboardFromSelection(false);
                    break;
                case 'cut-layer':
                    setLayerClipboardFromSelection(true);
                    break;
                case 'paste-center':
                    pasteClipboard('center');
                    break;
                case 'paste-in-place':
                    pasteClipboard('in-place');
                    break;
                case 'copy-style':
                    layerStyleClipboard = cloneLayerStyle(getSelectedLayer());
                    if (layerStyleClipboard) {
                        setDesignStatus('Layer style copied.');
                    }
                    break;
                case 'paste-style':
                    if (applyLayerStyle(getSelectedLayer(), layerStyleClipboard)) {
                        pushHistory();
                        scheduleRender();
                        setDesignStatus('Layer style pasted.');
                    }
                    break;
                case 'duplicate-layer':
                    duplicateLayer();
                    break;
                case 'bring-forward':
                    moveLayer('forward');
                    break;
                case 'send-backward':
                    moveLayer('backward');
                    break;
                case 'align-left':
                    alignLayer('left');
                    break;
                case 'align-center-x':
                    alignLayer('x');
                    break;
                case 'align-right':
                    alignLayer('right');
                    break;
                case 'align-top':
                    alignLayer('top');
                    break;
                case 'align-center-y':
                    alignLayer('y');
                    break;
                case 'align-bottom':
                    alignLayer('bottom');
                    break;
                case 'delete-layer':
                    deleteLayer();
                    break;
                default:
                    break;
                }
            }

            function transformBaseImage(mode) {
                if (!state.image) {
                    return;
                }
                var temp = document.createElement('canvas');
                var ctx = temp.getContext('2d');
                var newWidth = state.image.width;
                var newHeight = state.image.height;
                if (mode === 'rotate-left' || mode === 'rotate-right') {
                    newWidth = state.image.height;
                    newHeight = state.image.width;
                }
                temp.width = newWidth;
                temp.height = newHeight;
                ctx.save();
                if (mode === 'rotate-left') {
                    ctx.translate(0, newHeight);
                    ctx.rotate(-Math.PI / 2);
                } else if (mode === 'rotate-right') {
                    ctx.translate(newWidth, 0);
                    ctx.rotate(Math.PI / 2);
                } else if (mode === 'flip-x') {
                    ctx.translate(newWidth, 0);
                    ctx.scale(-1, 1);
                } else if (mode === 'flip-y') {
                    ctx.translate(0, newHeight);
                    ctx.scale(1, -1);
                }
                ctx.drawImage(state.image, 0, 0);
                ctx.restore();
                var dataUrl = temp.toDataURL('image/png');
                var image = new Image();
                image.onload = function () {
                    state.image = image;
                    state.crop = { x: 0, y: 0, width: image.width, height: image.height };
                    state.viewport = { zoom: 1, panX: 0, panY: 0 };
                    previewCache.key = '';
                    originalPreviewCache.key = '';
                    pushHistory();
                    scheduleRender();
                    setDesignStatus('Base image transformed.');
                };
                image.src = dataUrl;
            }

            function hitCropHandle(x, y) {
                var cropStage = rectToStage(state.crop);
                var handles = {
                    nw: { x: cropStage.x, y: cropStage.y, size: 18 },
                    ne: { x: cropStage.x + cropStage.width, y: cropStage.y, size: 18 },
                    sw: { x: cropStage.x, y: cropStage.y + cropStage.height, size: 18 },
                    se: { x: cropStage.x + cropStage.width, y: cropStage.y + cropStage.height, size: 18 },
                    n: { x: cropStage.x + (cropStage.width / 2), y: cropStage.y, size: 16 },
                    s: { x: cropStage.x + (cropStage.width / 2), y: cropStage.y + cropStage.height, size: 16 },
                    w: { x: cropStage.x, y: cropStage.y + (cropStage.height / 2), size: 16 },
                    e: { x: cropStage.x + cropStage.width, y: cropStage.y + (cropStage.height / 2), size: 16 }
                };
                var found = null;
                Object.keys(handles).forEach(function (key) {
                    var point = handles[key];
                    if (!found && Math.abs(x - point.x) <= point.size && Math.abs(y - point.y) <= point.size) {
                        found = key;
                    }
                });
                return found;
            }

            function getLayerResizeHandles(layer) {
                if (!layer || layer.locked || !layer.visible) {
                    return [];
                }
                var bounds = rectToStage(layerBounds(layer));
                var outward = Math.max(8, Math.round(Math.min(bounds.width, bounds.height) * 0.04));
                var cornerSize = 16;
                var edgeSize = 12;
                return [
                    { key: 'nw', x: bounds.x - outward, y: bounds.y - outward, size: cornerSize, axis: 'corner' },
                    { key: 'n', x: bounds.x + (bounds.width / 2), y: bounds.y - outward, size: edgeSize, axis: 'edge' },
                    { key: 'ne', x: bounds.x + bounds.width + outward, y: bounds.y - outward, size: cornerSize, axis: 'corner' },
                    { key: 'e', x: bounds.x + bounds.width + outward, y: bounds.y + (bounds.height / 2), size: edgeSize, axis: 'edge' },
                    { key: 'se', x: bounds.x + bounds.width + outward, y: bounds.y + bounds.height + outward, size: cornerSize, axis: 'corner' },
                    { key: 's', x: bounds.x + (bounds.width / 2), y: bounds.y + bounds.height + outward, size: edgeSize, axis: 'edge' },
                    { key: 'sw', x: bounds.x - outward, y: bounds.y + bounds.height + outward, size: cornerSize, axis: 'corner' },
                    { key: 'w', x: bounds.x - outward, y: bounds.y + (bounds.height / 2), size: edgeSize, axis: 'edge' }
                ];
            }

            function layerSupportsRotationHandle(layer) {
                return !!(layer && !layer.locked && layer.visible && (layer.type === 'text' || layer.type === 'image' || (layer.type === 'shape' && layer.shape !== 'arrow' && layer.shape !== 'line')));
            }

            function getLayerRotationCenter(layer) {
                var bounds = layerBounds(layer);
                return {
                    x: bounds.x + (bounds.width / 2),
                    y: bounds.y + (bounds.height / 2)
                };
            }

            function getLayerRotateHandle(layer) {
                if (!layerSupportsRotationHandle(layer)) {
                    return null;
                }
                var bounds = rectToStage(layerBounds(layer));
                var offset = Math.max(26, Math.round(Math.min(bounds.width, bounds.height) * 0.2));
                return {
                    key: 'rotate',
                    x: bounds.x + (bounds.width / 2),
                    y: bounds.y - offset,
                    size: 14,
                    lineTop: bounds.y,
                    axis: 'rotate'
                };
            }

            function hitLayerRotate(x, y) {
                var selected = getSelectedLayer();
                var handle = getLayerRotateHandle(selected);
                var radius;
                if (!handle) {
                    return null;
                }
                radius = handle.size + 12;
                if ((Math.abs(x - handle.x) <= radius) && (Math.abs(y - handle.y) <= radius)) {
                    return handle;
                }
                return null;
            }

            function getHandleCursor(handleKey) {
                var map = {
                    nw: 'nwse-resize',
                    se: 'nwse-resize',
                    ne: 'nesw-resize',
                    sw: 'nesw-resize',
                    n: 'ns-resize',
                    s: 'ns-resize',
                    e: 'ew-resize',
                    w: 'ew-resize',
                    rotate: 'grab'
                };
                return map[handleKey] || 'default';
            }

            function hitLayerResize(x, y) {
                var selected = getSelectedLayer();
                var found = null;
                var bounds;
                var edgeInset;
                if (!selected || selected.locked || !selected.visible) {
                    return null;
                }
                bounds = rectToStage(layerBounds(selected));
                edgeInset = Math.max(16, Math.round(Math.min(bounds.width, bounds.height) * 0.08));
                getLayerResizeHandles(selected).forEach(function (handle) {
                    var hitPadding = handle.axis === 'corner' ? 20 : 14;
                    if (!found && x >= (handle.x - (handle.size + hitPadding)) && x <= (handle.x + (handle.size + hitPadding)) && y >= (handle.y - (handle.size + hitPadding)) && y <= (handle.y + (handle.size + hitPadding))) {
                        found = handle;
                    }
                });
                if (found) {
                    return found;
                }
                if (pointInStageRect(x, y, bounds)) {
                    if (x <= bounds.x + edgeInset && y <= bounds.y + edgeInset) {
                        return { key: 'nw', axis: 'corner' };
                    }
                    if (x >= bounds.x + bounds.width - edgeInset && y <= bounds.y + edgeInset) {
                        return { key: 'ne', axis: 'corner' };
                    }
                    if (x <= bounds.x + edgeInset && y >= bounds.y + bounds.height - edgeInset) {
                        return { key: 'sw', axis: 'corner' };
                    }
                    if (x >= bounds.x + bounds.width - edgeInset && y >= bounds.y + bounds.height - edgeInset) {
                        return { key: 'se', axis: 'corner' };
                    }
                    if (Math.abs(y - bounds.y) <= edgeInset) {
                        return { key: 'n', axis: 'edge' };
                    }
                    if (Math.abs((bounds.y + bounds.height) - y) <= edgeInset) {
                        return { key: 's', axis: 'edge' };
                    }
                    if (Math.abs(x - bounds.x) <= edgeInset) {
                        return { key: 'w', axis: 'edge' };
                    }
                    if (Math.abs((bounds.x + bounds.width) - x) <= edgeInset) {
                        return { key: 'e', axis: 'edge' };
                    }
                }
                return null;
            }

            function hitLayer(x, y) {
                var found = null;
                state.layers.slice().reverse().forEach(function (layer) {
                    if (found || !layer.visible || layer.locked) {
                        return;
                    }
                    var bounds = rectToStage(layerBounds(layer));
                    if (x >= bounds.x && x <= bounds.x + bounds.width && y >= bounds.y && y <= bounds.y + bounds.height) {
                        found = layer;
                    }
                });
                return found;
            }

            function pointInStageRect(x, y, rect) {
                return !!rect && x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y + rect.height;
            }

            function pointInStageRectInset(x, y, rect, inset) {
                if (!rect) {
                    return false;
                }
                var left = rect.x + inset;
                var top = rect.y + inset;
                var right = (rect.x + rect.width) - inset;
                var bottom = (rect.y + rect.height) - inset;
                if (right <= left || bottom <= top) {
                    return false;
                }
                return x >= left && x <= right && y >= top && y <= bottom;
            }

            function getLayerDragInset(layer) {
                var bounds = rectToStage(layerBounds(layer));
                return Math.max(16, Math.round(Math.min(bounds.width, bounds.height) * 0.08));
            }

            function getCropDragInset() {
                var cropStage = rectToStage(state.crop);
                return Math.max(16, Math.round(Math.min(cropStage.width, cropStage.height) * 0.08));
            }

            function shouldStartLayerDrag(layer, x, y) {
                if (!layer) {
                    return false;
                }
                return pointInStageRectInset(x, y, rectToStage(layerBounds(layer)), getLayerDragInset(layer));
            }

            function shouldStartCropMove(x, y) {
                return pointInStageRectInset(x, y, rectToStage(state.crop), getCropDragInset());
            }

            function isCropOverlayVisible() {
                return !!(state.image && (state.cropArmed || state.hasCustomCrop || (interaction && String(interaction.mode || '').indexOf('crop-') === 0)));
            }

            function canInteractWithCropOverlay() {
                return !!(state.image && (state.cropArmed || (interaction && String(interaction.mode || '').indexOf('crop-') === 0)));
            }

            function onPointerDown(event) {
                if (!state.image || !stageFrame) {
                    return;
                }
                event.preventDefault();
                if (typeof designCanvas.setPointerCapture === 'function') {
                    try {
                        designCanvas.setPointerCapture(event.pointerId);
                    } catch (pointerCaptureError) {
                        // Ignore pointer capture failures in older browser contexts.
                    }
                }
                var rect = designCanvas.getBoundingClientRect();
                var x = event.clientX - rect.left;
                var y = event.clientY - rect.top;
                var cropRect = rectToStage(state.crop);
                var imagePoint = stageToImage(x, y);
                var imageRect = rectToStage({ x: 0, y: 0, width: state.image.width, height: state.image.height });
                var cropInteractive = canInteractWithCropOverlay();
                var layerRotateHandle = hitLayerRotate(x, y);
                var layerResizeHandle = layerRotateHandle ? null : hitLayerResize(x, y);
                var cropHandle = (cropInteractive && !layerResizeHandle && !layerRotateHandle) ? hitCropHandle(x, y) : null;
                var layer;

                if (state.splash.armed) {
                    sampleSelectiveColor(imagePoint.x, imagePoint.y);
                    return;
                }

                if (hasActiveRetouchTool()) {
                    var retouchTarget = getRetouchTargetAtPoint(x, y, imagePoint);
                    if (retouchTarget) {
                        var stroke = {
                            tool: getRetouchTool(),
                            size: getRetouchSize(),
                            strength: getRetouchStrength(),
                            points: [{ x: retouchTarget.point.x, y: retouchTarget.point.y }]
                        };
                        getRetouchStrokeStore(retouchTarget).push(stroke);
                        interaction = {
                            mode: 'retouch-brush',
                            targetKind: retouchTarget.kind,
                            layerId: retouchTarget.layer ? retouchTarget.layer.id : null,
                            stroke: stroke
                        };
                        if (retouchTarget.layer) {
                            setSelectedLayer(retouchTarget.layer.id);
                        }
                        if (retouchTarget.kind === 'base') {
                            markPreviewDirty();
                        } else {
                            scheduleRender();
                        }
                        setDesignStatus(getRetouchToolActionLabel(stroke.tool) + ' ' + getRetouchTargetLabel(retouchTarget) + '.');
                        return;
                    }
                    setDesignStatus('Brush tools work on the base image or a selected image layer.');
                    return;
                }

                if (isSpaceDown) {
                    interaction = {
                        mode: 'pan',
                        startX: x,
                        startY: y,
                        startPanX: state.viewport.panX,
                        startPanY: state.viewport.panY
                    };
                    designCanvas.style.cursor = 'grabbing';
                    return;
                }

                if (state.cropArmed || event.shiftKey) {
                    interaction = {
                        mode: 'crop-draw',
                        startPoint: imagePoint,
                        autoMarquee: true
                    };
                    state.crop = {
                        x: clamp(Math.round(imagePoint.x), 0, state.image.width - 1),
                        y: clamp(Math.round(imagePoint.y), 0, state.image.height - 1),
                        width: 1,
                        height: 1
                    };
                    state.hasCustomCrop = true;
                    scheduleRender();
                    return;
                }

                if (cropHandle) {
                    interaction = {
                        mode: 'crop-resize',
                        handle: cropHandle,
                        startCrop: cloneDeep(state.crop)
                    };
                    return;
                }

                if (layerRotateHandle) {
                    var rotationTarget = getSelectedLayer();
                    var rotationCenter = rotationTarget ? getLayerRotationCenter(rotationTarget) : null;
                    if (rotationTarget && rotationCenter) {
                        interaction = {
                            mode: 'layer-rotate',
                            layerId: rotationTarget.id,
                            startRotation: Number(rotationTarget.rotation || 0),
                            center: rotationCenter,
                            startAngle: Math.atan2(imagePoint.y - rotationCenter.y, imagePoint.x - rotationCenter.x)
                        };
                        designCanvas.style.cursor = 'grabbing';
                        return;
                    }
                }

                if (layerResizeHandle) {
                    interaction = {
                        mode: 'layer-resize',
                        handle: layerResizeHandle.key,
                        layerId: state.selectedLayerId,
                        startPoint: imagePoint,
                        startBounds: cloneDeep(layerBounds(getSelectedLayer())),
                        startLayer: cloneDeep(getSelectedLayer())
                    };
                    designCanvas.style.cursor = getHandleCursor(layerResizeHandle.key);
                    return;
                }

                var watermarkHit = hitWatermark(x, y);
                if (watermarkHit === 'text') {
                    interaction = {
                        mode: 'watermark-text-drag',
                        startPoint: imagePoint,
                        startOffsetX: Number(state.watermark.textOffsetX || 0),
                        startOffsetY: Number(state.watermark.textOffsetY || 0)
                    };
                    return;
                }
                if (watermarkHit === 'image') {
                    interaction = {
                        mode: 'watermark-image-drag',
                        startPoint: imagePoint,
                        startOffsetX: Number(state.watermark.imageOffsetX || 0),
                        startOffsetY: Number(state.watermark.imageOffsetY || 0)
                    };
                    return;
                }

                layer = hitLayer(x, y);
                if (layer) {
                    setSelectedLayer(layer.id);
                    if (shouldStartLayerDrag(layer, x, y)) {
                        interaction = {
                            mode: 'layer-drag',
                            layerId: layer.id,
                            startPoint: imagePoint,
                            startLayer: cloneDeep(layer)
                        };
                        return;
                    }
                }

                if (cropInteractive && pointInStageRect(x, y, cropRect) && shouldStartCropMove(x, y)) {
                    interaction = {
                        mode: 'crop-move',
                        startPoint: imagePoint,
                        startCrop: cloneDeep(state.crop)
                    };
                    return;
                }

                if (x >= imageRect.x && x <= imageRect.x + imageRect.width && y >= imageRect.y && y <= imageRect.y + imageRect.height) {
                    setSelectedLayer(null);
                    scheduleRender();
                    return;
                }

                setSelectedLayer(null);
            }

            function updateCanvasCursorForPoint(x, y) {
                var rotateHandle = hitLayerRotate(x, y);
                var resizeHandle = rotateHandle ? null : hitLayerResize(x, y);
                var cropHandle = (canInteractWithCropOverlay() && !resizeHandle && !rotateHandle) ? hitCropHandle(x, y) : null;
                var layer = hitLayer(x, y);
                var cropRect = rectToStage(state.crop);
                var imageRect = state.image ? rectToStage({ x: 0, y: 0, width: state.image.width, height: state.image.height }) : null;
                var cropInteractive = canInteractWithCropOverlay();
                var imagePoint = state.image ? stageToImage(x, y) : null;
                var brushTarget = hasActiveRetouchTool() && state.image ? getRetouchTargetAtPoint(x, y, imagePoint) : null;
                if (hasActiveRetouchTool()) {
                    updateBrushHover(brushTarget, x, y);
                }
                if (hasActiveRetouchTool()) {
                    designCanvas.style.cursor = brushTarget ? 'crosshair' : 'not-allowed';
                    return;
                }
                if (rotateHandle) {
                    designCanvas.style.cursor = 'grab';
                    return;
                }
                if (resizeHandle) {
                    designCanvas.style.cursor = getHandleCursor(resizeHandle.key);
                    return;
                }
                if (cropHandle) {
                    designCanvas.style.cursor = getHandleCursor(cropHandle);
                    return;
                }
                if (imageRect && x >= imageRect.x && x <= imageRect.x + imageRect.width && y >= imageRect.y && y <= imageRect.y + imageRect.height && (state.cropArmed || isShiftDown)) {
                    designCanvas.style.cursor = 'crosshair';
                    return;
                }
                if (layer && shouldStartLayerDrag(layer, x, y)) {
                    designCanvas.style.cursor = 'move';
                    return;
                }
                if (cropInteractive && pointInStageRect(x, y, cropRect) && shouldStartCropMove(x, y)) {
                    designCanvas.style.cursor = 'move';
                    return;
                }
                if (imageRect && x >= imageRect.x && x <= imageRect.x + imageRect.width && y >= imageRect.y && y <= imageRect.y + imageRect.height) {
                    designCanvas.style.cursor = 'default';
                    return;
                }
                if (isSpaceDown) {
                    designCanvas.style.cursor = 'grab';
                    return;
                }
                designCanvas.style.cursor = 'default';
            }

            function onPointerMove(event) {
                if (!state.image) {
                    return;
                }
                var rect = designCanvas.getBoundingClientRect();
                var x = event.clientX - rect.left;
                var y = event.clientY - rect.top;
                if (!interaction) {
                    updateCanvasCursorForPoint(x, y);
                    return;
                }
                event.preventDefault();
                var point = stageToImage(x, y);
                var deltaX;
                var deltaY;
                var layer;
                if (interaction.mode === 'pan') {
                    deltaX = x - interaction.startX;
                    deltaY = y - interaction.startY;
                    state.viewport.panX = interaction.startPanX + deltaX;
                    state.viewport.panY = interaction.startPanY + deltaY;
                    scheduleRender();
                    return;
                }
                if (interaction.mode === 'retouch-brush') {
                    var brushTarget = getRetouchTargetAtPoint(x, y, point);
                    if (brushTarget && brushTarget.kind === interaction.targetKind && (!interaction.layerId || (brushTarget.layer && brushTarget.layer.id === interaction.layerId))) {
                        interaction.stroke.points.push({ x: brushTarget.point.x, y: brushTarget.point.y });
                        updateBrushHover(brushTarget, x, y);
                        if (interaction.targetKind === 'base') {
                            markPreviewDirty();
                        } else {
                            scheduleRender();
                        }
                    }
                    return;
                }
                if (interaction.mode === 'crop-move') {
                    deltaX = point.x - interaction.startPoint.x;
                    deltaY = point.y - interaction.startPoint.y;
                    state.crop.x = clamp(Math.round(interaction.startCrop.x + deltaX), 0, Math.max(0, state.image.width - state.crop.width));
                    state.crop.y = clamp(Math.round(interaction.startCrop.y + deltaY), 0, Math.max(0, state.image.height - state.crop.height));
                    state.hasCustomCrop = true;
                    scheduleRender();
                    return;
                }
                if (interaction.mode === 'crop-draw') {
                    var startX = interaction.startPoint.x;
                    var startY = interaction.startPoint.y;
                    var nextX = clamp(Math.round(Math.min(startX, point.x)), 0, state.image.width - 1);
                    var nextY = clamp(Math.round(Math.min(startY, point.y)), 0, state.image.height - 1);
                    var nextWidth = Math.max(1, Math.round(Math.abs(point.x - startX)));
                    var nextHeight = Math.max(1, Math.round(Math.abs(point.y - startY)));
                    state.crop = {
                        x: nextX,
                        y: nextY,
                        width: clamp(nextWidth, 1, state.image.width - nextX),
                        height: clamp(nextHeight, 1, state.image.height - nextY)
                    };
                    state.hasCustomCrop = true;
                    scheduleRender();
                    return;
                }
                if (interaction.mode === 'crop-resize') {
                    resizeCrop(interaction.handle, point);
                    scheduleRender();
                    return;
                }
                if (interaction.mode === 'watermark-text-drag') {
                    deltaX = point.x - interaction.startPoint.x;
                    deltaY = point.y - interaction.startPoint.y;
                    state.watermark.textOffsetX = Math.round(interaction.startOffsetX + deltaX);
                    state.watermark.textOffsetY = Math.round(interaction.startOffsetY + deltaY);
                    scheduleRender();
                    return;
                }
                if (interaction.mode === 'watermark-image-drag') {
                    deltaX = point.x - interaction.startPoint.x;
                    deltaY = point.y - interaction.startPoint.y;
                    state.watermark.imageOffsetX = Math.round(interaction.startOffsetX + deltaX);
                    state.watermark.imageOffsetY = Math.round(interaction.startOffsetY + deltaY);
                    scheduleRender();
                    return;
                }
                if (interaction.mode === 'layer-rotate') {
                    layer = state.layers.find(function (candidateRotate) {
                        return candidateRotate.id === interaction.layerId;
                    });
                    if (!layer) {
                        return;
                    }
                    var currentAngle = Math.atan2(point.y - interaction.center.y, point.x - interaction.center.x);
                    var angleDelta = ((currentAngle - interaction.startAngle) * 180) / Math.PI;
                    layer.rotation = normalizeRotation(interaction.startRotation + angleDelta + 90);
                    syncSelectedLayerControls();
                    scheduleRender();
                    return;
                }
                if (interaction.mode === 'layer-drag') {
                    layer = state.layers.find(function (candidate) {
                        return candidate.id === interaction.layerId;
                    });
                    if (!layer) {
                        return;
                    }
                    deltaX = point.x - interaction.startPoint.x;
                    deltaY = point.y - interaction.startPoint.y;
                    var snapped = snapBoundsForLayer(layer, Math.round(interaction.startLayer.x + deltaX), Math.round(interaction.startLayer.y + deltaY));
                    layer.x = Math.round(snapped.x);
                    layer.y = Math.round(snapped.y);
                    scheduleRender();
                    return;
                }
                if (interaction.mode === 'layer-resize') {
                    layer = state.layers.find(function (candidate2) {
                        return candidate2.id === interaction.layerId;
                    });
                    if (!layer) {
                        return;
                    }
                    deltaX = point.x - interaction.startPoint.x;
                    deltaY = point.y - interaction.startPoint.y;
                    if (layer.type === 'shape' || layer.type === 'image') {
                        var minWidth = 10;
                        var minHeight = 10;
                        var nextX = interaction.startLayer.x;
                        var nextY = interaction.startLayer.y;
                        var nextWidth = interaction.startLayer.width;
                        var nextHeight = interaction.startLayer.height;
                        if (interaction.handle.indexOf('e') !== -1) {
                            nextWidth = interaction.startLayer.width + deltaX;
                        }
                        if (interaction.handle.indexOf('s') !== -1) {
                            nextHeight = interaction.startLayer.height + deltaY;
                        }
                        if (interaction.handle.indexOf('w') !== -1) {
                            nextWidth = interaction.startLayer.width - deltaX;
                            nextX = interaction.startLayer.x + deltaX;
                        }
                        if (interaction.handle.indexOf('n') !== -1) {
                            nextHeight = interaction.startLayer.height - deltaY;
                            nextY = interaction.startLayer.y + deltaY;
                        }
                        if (nextWidth < minWidth) {
                            if (interaction.handle.indexOf('w') !== -1) {
                                nextX -= (minWidth - nextWidth);
                            }
                            nextWidth = minWidth;
                        }
                        if (nextHeight < minHeight) {
                            if (interaction.handle.indexOf('n') !== -1) {
                                nextY -= (minHeight - nextHeight);
                            }
                            nextHeight = minHeight;
                        }
                        layer.x = Math.round(nextX);
                        layer.y = Math.round(nextY);
                        layer.width = Math.round(nextWidth);
                        layer.height = Math.round(nextHeight);
                    } else {
                        layer.fontSize = Math.max(10, Math.round(interaction.startLayer.fontSize + ((deltaX + deltaY) / 4)));
                    }
                    syncSelectedLayerControls();
                    scheduleRender();
                    return;
                }
            }

            function onPointerUp(event) {
                if (event && typeof designCanvas.releasePointerCapture === 'function' && typeof event.pointerId !== 'undefined') {
                    try {
                        if (designCanvas.hasPointerCapture && designCanvas.hasPointerCapture(event.pointerId)) {
                            designCanvas.releasePointerCapture(event.pointerId);
                        }
                    } catch (pointerReleaseError) {
                        // Ignore pointer release failures.
                    }
                }
                if (interaction) {
                    pushHistory();
                }
                activeSnapGuides = [];
                if (interaction && interaction.mode === 'crop-draw') {
                    state.cropArmed = false;
                    setDesignStatus(interaction.autoMarquee ? 'Selection updated. Use Copy crop or export to apply it.' : 'Crop selection updated.');
                } else if (interaction && interaction.mode === 'layer-rotate') {
                    setDesignStatus('Layer rotated.');
                } else if (interaction && interaction.mode === 'retouch-brush') {
                    setDesignStatus(getRetouchToolLabel(interaction.stroke.tool) + ' brush applied.');
                }
                interaction = null;
                if (!hasActiveRetouchTool()) {
                    clearBrushHover();
                }
                if (event) {
                    var rect = designCanvas.getBoundingClientRect();
                    updateCanvasCursorForPoint(event.clientX - rect.left, event.clientY - rect.top);
                } else {
                    designCanvas.style.cursor = 'default';
                }
            }

            function resizeCrop(handle, point) {
                var start = interaction.startCrop;
                var next = cloneDeep(start);
                var minSize = 40;
                if (handle.indexOf('n') !== -1) {
                    next.y = clamp(Math.round(point.y), 0, start.y + start.height - minSize);
                    next.height = Math.round((start.y + start.height) - next.y);
                }
                if (handle.indexOf('s') !== -1) {
                    next.height = clamp(Math.round(point.y - start.y), minSize, state.image.height - start.y);
                }
                if (handle.indexOf('w') !== -1) {
                    next.x = clamp(Math.round(point.x), 0, start.x + start.width - minSize);
                    next.width = Math.round((start.x + start.width) - next.x);
                }
                if (handle.indexOf('e') !== -1) {
                    next.width = clamp(Math.round(point.x - start.x), minSize, state.image.width - start.x);
                }
                if (state.aspect !== 'free') {
                    var parts = state.aspect.split(':');
                    var ratio = Number(parts[0]) / Number(parts[1]);
                    if (handle === 'nw' || handle === 'se') {
                        next.height = Math.round(next.width / ratio);
                    } else {
                        next.width = Math.round(next.height * ratio);
                    }
                    next.width = clamp(next.width, minSize, state.image.width - next.x);
                    next.height = clamp(next.height, minSize, state.image.height - next.y);
                }
                state.crop = next;
                state.hasCustomCrop = true;
            }

            function sampleSelectiveColor(imageX, imageY) {
                var preview = getPreviewCanvas(false);
                var ratioX = preview.width / state.image.width;
                var ratioY = preview.height / state.image.height;
                var sampleX = clamp(Math.round(imageX * ratioX), 0, preview.width - 1);
                var sampleY = clamp(Math.round(imageY * ratioY), 0, preview.height - 1);
                var ctx = preview.getContext('2d');
                var data = ctx.getImageData(sampleX, sampleY, 1, 1).data;
                state.splash.target = {
                    r: data[0],
                    g: data[1],
                    b: data[2]
                };
                state.splash.active = true;
                state.splash.armed = false;
                markPreviewDirty();
                setDesignStatus('Selective color sample captured.');
                pushHistory();
            }

            designActionButtons.forEach(function (button) {
                button.addEventListener('click', function () {
                    handleDesignAction(button.getAttribute('data-image-design-action'));
                });
            });

            designAspectButtons.forEach(function (button) {
                button.addEventListener('click', function () {
                    setAspect(button.getAttribute('data-image-design-aspect'));
                    pushHistory();
                });
            });

            designFilterButtons.forEach(function (button) {
                button.addEventListener('click', function () {
                    var toneTarget = getToneStateTarget();
                    toneTarget.filter = button.getAttribute('data-image-design-filter') || 'original';
                    if (toneTarget.isLayer && toneTarget.layer) {
                        toneTarget.layer.filter = toneTarget.filter;
                    } else {
                        state.filter = toneTarget.filter;
                    }
                    designFilterButtons.forEach(function (candidate) {
                        candidate.classList.toggle('is-active', candidate === button);
                    });
                    scheduleHistory();
                    if (toneTarget.isLayer) {
                        scheduleRender();
                        setDesignStatus('Filter applied to the selected image layer.');
                    } else {
                        markPreviewDirty();
                    }
                });
            });

            designAdjustInputs.forEach(function (input) {
                input.addEventListener('input', function () {
                    var key = input.getAttribute('data-image-design-adjust');
                    var toneTarget = getToneStateTarget();
                    if (!key) {
                        return;
                    }
                    toneTarget.adjustments[key] = Number(input.value || 0);
                    if (toneTarget.isLayer && toneTarget.layer) {
                        toneTarget.layer.adjustments = toneTarget.adjustments;
                    }
                    updateReadouts();
                    scheduleHistory();
                    if (toneTarget.isLayer) {
                        scheduleRender();
                    } else {
                        markPreviewDirty();
                    }
                });
            });

            selectedFields.forEach(function (field) {
                var eventName = field.tagName === 'SELECT' ? 'change' : 'input';
                field.addEventListener(eventName, function () {
                    updateLayerField(field.getAttribute('data-image-design-layer-field'), field.value);
                });
            });


            if (designStageBgInput) {
                designStageBgInput.addEventListener('input', function () {
                    state.workspaceBackground = designStageBgInput.value || '#0f172a';
                    applyWorkspaceBackground();
                    scheduleHistory();
                });
            }

            if (designStageBgPresetButtons && designStageBgPresetButtons.length) {
                designStageBgPresetButtons.forEach(function (button) {
                    button.addEventListener('click', function () {
                        state.workspaceBackground = button.getAttribute('data-image-design-bg-preset') || '#0f172a';
                        applyWorkspaceBackground();
                        scheduleHistory();
                    });
                });
            }


            function promoteBaseImageToLayer() {
                if (!state.image) {
                    return false;
                }
                if (!state.baseLayer) {
                    state.baseLayer = { visible: true, deleted: false, name: 'Base image' };
                }
                if (state.baseLayer.visible === false && !state.baseLayer.deleted) {
                    setDesignStatus('Base image is already being used as a movable layer.');
                    return false;
                }
                var asset = getActiveDesignAsset();
                var imageSrc = (asset && (asset.dataUrl || asset.url)) || state.imageUrl || state.image.src || '';
                var layer = createImageLayerFromImage(state.image, (state.imageName || 'Base image') + ' layer', imageSrc);
                state.layers.push(layer);
                setSelectedLayer(layer.id);
                state.baseLayer.visible = false;
                state.baseLayer.deleted = false;
                renderLayerList();
                markPreviewDirty();
                pushHistory();
                setDesignStatus('Base image converted into a movable layer.');
                return true;
            }

            if (layerListNode) {
                layerListNode.addEventListener('click', function (event) {
                    var selectButton = event.target.closest('[data-layer-select]');
                    var toggleVisibility = event.target.closest('[data-layer-toggle-visibility]');
                    var toggleLock = event.target.closest('[data-layer-toggle-lock]');
                    var deleteButton = event.target.closest('[data-layer-delete]');
                    var basePromote = event.target.closest('[data-base-layer-promote]');
                    var baseToggle = event.target.closest('[data-base-layer-toggle-visibility]');
                    var baseDelete = event.target.closest('[data-base-layer-delete]');
                    var layer;
                    if (basePromote) {
                        promoteBaseImageToLayer();
                        return;
                    }
                    if (baseToggle) {
                        if (!state.baseLayer) {
                            state.baseLayer = { visible: true, deleted: false, name: 'Base image' };
                        }
                        if (state.baseLayer.deleted) {
                            state.baseLayer.deleted = false;
                            state.baseLayer.visible = true;
                            setDesignStatus('Base image restored.');
                        } else {
                            state.baseLayer.visible = !state.baseLayer.visible;
                            setDesignStatus(state.baseLayer.visible ? 'Base image shown.' : 'Base image hidden.');
                        }
                        renderLayerList();
                        markPreviewDirty();
                        pushHistory();
                        return;
                    }
                    if (baseDelete) {
                        if (!state.baseLayer) {
                            state.baseLayer = { visible: true, deleted: false, name: 'Base image' };
                        }
                        state.baseLayer.visible = false;
                        state.baseLayer.deleted = true;
                        renderLayerList();
                        markPreviewDirty();
                        pushHistory();
                        setDesignStatus('Base image removed from the current composition.');
                        return;
                    }
                    if (selectButton) {
                        setSelectedLayer(Number(selectButton.getAttribute('data-layer-select')));
                        return;
                    }
                    if (toggleVisibility) {
                        layer = state.layers.find(function (candidate) {
                            return candidate.id === Number(toggleVisibility.getAttribute('data-layer-toggle-visibility'));
                        });
                        if (layer) {
                            layer.visible = !layer.visible;
                            renderLayerList();
                            scheduleRender();
                            pushHistory();
                        }
                        return;
                    }
                    if (deleteButton) {
                        layer = state.layers.find(function (candidate3) {
                            return candidate3.id === Number(deleteButton.getAttribute('data-layer-delete'));
                        });
                        if (layer) {
                            state.selectedLayerId = layer.id;
                            deleteLayer();
                        }
                        return;
                    }
                    if (toggleLock) {
                        layer = state.layers.find(function (candidate2) {
                            return candidate2.id === Number(toggleLock.getAttribute('data-layer-toggle-lock'));
                        });
                        if (layer) {
                            layer.locked = !layer.locked;
                            renderLayerList();
                            scheduleRender();
                            pushHistory();
                        }
                    }
                });
            }

            if (designInput) {
                designInput.addEventListener('change', function (event) {
                    queueDesignFiles(event.target.files || []);
                    designInput.value = '';
                });
            }

            if (designDropzones && designDropzones.length) {
                Array.prototype.forEach.call(designDropzones, function (dropzone) {
                    ['dragenter', 'dragover'].forEach(function (eventName) {
                        dropzone.addEventListener(eventName, function (event) {
                            event.preventDefault();
                            event.stopPropagation();
                            dropzone.classList.add('is-dragover');
                        });
                    });
                    ['dragleave', 'dragend', 'drop'].forEach(function (eventName) {
                        dropzone.addEventListener(eventName, function (event) {
                            event.preventDefault();
                            event.stopPropagation();
                            if (eventName !== 'drop') {
                                dropzone.classList.remove('is-dragover');
                            }
                        });
                    });
                    dropzone.addEventListener('drop', function (event) {
                        dropzone.classList.remove('is-dragover');
                        queueDesignFiles((event.dataTransfer && event.dataTransfer.files) ? event.dataTransfer.files : []);
                    });
                });
            }

            if (designThumbStrip) {
                designThumbStrip.addEventListener('click', function (event) {
                    var removeButton = event.target.closest('[data-image-design-thumb-remove]');
                    var thumbButton = event.target.closest('[data-image-design-thumb]');
                    if (removeButton) {
                        event.preventDefault();
                        event.stopPropagation();
                        removeDesignAsset(Number(removeButton.getAttribute('data-image-design-thumb-remove')));
                        return;
                    }
                    if (thumbButton) {
                        activateDesignAsset(Number(thumbButton.getAttribute('data-image-design-thumb')));
                    }
                });
            }

            if (designAddModeSelect) {
                designAddModeSelect.addEventListener('change', function () {
                    saveDraft();
                });
            }

            if (designFormatSelect) {
                designFormatSelect.addEventListener('change', function () {
                    state.exportFormat = designFormatSelect.value;
                    updateExportReadout();
                    pushHistory();
                });
            }

            if (designQualityInput) {
                designQualityInput.addEventListener('input', function () {
                    state.exportQuality = clamp(parseFloat(designQualityInput.value || '0.92'), 0.6, 1);
                    updateExportReadout();
                    scheduleHistory();
                });
            }

            if (designScaleSelect) {
                designScaleSelect.addEventListener('change', function () {
                    state.exportScale = clamp(parseInt(designScaleSelect.value || '1', 10), 1, 2);
                    pushHistory();
                });
            }

            if (watermarkInput) {
                watermarkInput.addEventListener('input', function () {
                    state.watermark.text = watermarkInput.value;
                    scheduleHistory();
                    scheduleRender();
                    drawOutputPreview();
                });
            }
            if (watermarkSizeInput) {
                watermarkSizeInput.addEventListener('input', function () {
                    state.watermark.size = Math.max(12, parseInt(watermarkSizeInput.value || '34', 10) || 34);
                    scheduleHistory();
                    scheduleRender();
                    drawOutputPreview();
                });
            }
            function handleWatermarkOpacityChange() {
                state.watermark.opacity = clamp(parseFloat(watermarkOpacityInput.value || '0.8'), 0, 1);
                scheduleHistory();
                scheduleRender();
                drawOutputPreview();
            }

            if (watermarkOpacityInput) {
                watermarkOpacityInput.addEventListener('input', handleWatermarkOpacityChange);
                watermarkOpacityInput.addEventListener('change', handleWatermarkOpacityChange);
            }
            if (watermarkColorInput) {
                watermarkColorInput.addEventListener('input', function () {
                    state.watermark.color = watermarkColorInput.value || '#ffffff';
                    scheduleHistory();
                    scheduleRender();
                    drawOutputPreview();
                });
            }
            if (watermarkPositionSelect) {
                watermarkPositionSelect.addEventListener('change', function () {
                    state.watermark.position = watermarkPositionSelect.value;
                    pushHistory();
                    scheduleRender();
                });
            }
            if (watermarkImageScaleInput) {
                watermarkImageScaleInput.addEventListener('input', function () {
                    state.watermark.imageScale = clamp(parseFloat(watermarkImageScaleInput.value || '0.28'), 0.1, 1);
                    scheduleHistory();
                    scheduleRender();
                });
            }
            if (watermarkImageInput) {
                watermarkImageInput.addEventListener('change', function (event) {
                    var file = (event.target.files || [])[0];
                    if (!file) {
                        return;
                    }
                    if (watermarkImageUrl) {
                        URL.revokeObjectURL(watermarkImageUrl);
                    }
                    watermarkImageUrl = URL.createObjectURL(file);
                    var image = new Image();
                    image.onload = function () {
                        state.watermark.image = image;
                        state.watermark.imageSrc = watermarkImageUrl;
                        pushHistory();
                        scheduleRender();
                        saveDraft();
                        setDesignStatus('Image watermark loaded.');
                    };
                    image.src = watermarkImageUrl;
                });
            }

            if (designStage) {
                ['dragenter', 'dragover'].forEach(function (eventName) {
                    designStage.addEventListener(eventName, function (event) {
                        event.preventDefault();
                        designStage.classList.add('is-dragover');
                    });
                });
                ['dragleave', 'dragend', 'drop'].forEach(function (eventName) {
                    designStage.addEventListener(eventName, function (event) {
                        if (eventName === 'drop') {
                            event.preventDefault();
                            queueDesignFiles(event.dataTransfer ? event.dataTransfer.files : []);
                        }
                        designStage.classList.remove('is-dragover');
                    });
                });
            }

            if (designQuickFont) {
                designQuickFont.addEventListener('change', function () {
                    updateQuickTextFromControl('fontFamily', designQuickFont.value);
                });
            }
            if (designQuickSize) {
                designQuickSize.addEventListener('input', function () {
                    updateQuickTextFromControl('fontSize', Math.max(10, parseInt(designQuickSize.value || '48', 10) || 48));
                });
            }
            if (designQuickColor) {
                designQuickColor.addEventListener('input', function () {
                    updateQuickTextFromControl('color', designQuickColor.value);
                });
            }
            if (designQuickBgColor) {
                designQuickBgColor.addEventListener('input', function () {
                    state.quickText.backgroundColor = designQuickBgColor.value;
                    var selected = getSelectedLayer();
                    if (selected && selected.type === 'text') {
                        selected.backgroundColor = designQuickBgColor.value;
                        scheduleHistory();
                        scheduleRender();
                    }
                });
            }

            if (designBrushButtons && designBrushButtons.length) {
                designBrushButtons.forEach(function (button) {
                    button.addEventListener('click', function () {
                        var tool = normalizeRetouchTool(button.getAttribute('data-image-design-brush'));
                        ensureRetouchState();
                        state.retouch.tool = getRetouchTool() === tool ? 'none' : tool;
                        state.cropArmed = false;
                        syncBrushControls();
                        clearBrushHover();
                        setDesignStatus(state.retouch.tool === 'none' ? 'Brush tools disabled.' : (getRetouchToolLabel(state.retouch.tool) + ' brush ready. Drag on the base image or an image layer.'));
                    });
                });
            }
            if (designBrushSizeInput) {
                designBrushSizeInput.addEventListener('input', function () {
                    ensureRetouchState();
                    state.retouch.size = clamp(Math.round(Number(designBrushSizeInput.value || 96)), 12, 260);
                    syncBrushControls();
                });
            }
            if (designBrushStrengthInput) {
                designBrushStrengthInput.addEventListener('input', function () {
                    ensureRetouchState();
                    state.retouch.strength = clamp(Math.round(Number(designBrushStrengthInput.value || 42)), 8, 100);
                    syncBrushControls();
                });
            }
            if (designPrivacyModeSelect) {
                designPrivacyModeSelect.addEventListener('change', function () {
                    var selectedLayer = getSelectedLayer();
                    var mode = getPrivacyShapeMode();
                    if (selectedLayer && selectedLayer.type === 'shape' && selectedLayer.privacyMode) {
                        selectedLayer.privacyMode = mode;
                        selectedLayer.privacyStrength = mode === 'privacy' ? 92 : getRetouchStrength();
                        selectedLayer.fill = mode === 'privacy' ? '#000000' : 'rgba(0,0,0,0)';
                        selectedLayer.opacity = mode === 'privacy' ? 0.94 : 1;
                        selectedLayer.strokeColor = getPrivacyShapeColor(mode);
                        syncSelectedLayerControls();
                        scheduleRender();
                        pushHistory();
                        setDesignStatus(getRetouchToolLabel(mode) + ' shape updated.');
                        return;
                    }
                    setDesignStatus('New privacy shapes will use ' + getRetouchToolLabel(mode).toLowerCase() + ' mode.');
                });
            }

            designCanvas.addEventListener('pointerdown', onPointerDown);
            designCanvas.addEventListener('pointermove', onPointerMove);
            designCanvas.addEventListener('pointerleave', function () {
                if (!interaction) {
                    designCanvas.style.cursor = 'default';
                }
                clearBrushHover();
            });
            designCanvas.addEventListener('lostpointercapture', function () {
                if (interaction) {
                    onPointerUp();
                }
            });
            window.addEventListener('pointermove', function (event) {
                if (interaction) {
                    onPointerMove(event);
                }
            });
            window.addEventListener('pointerup', onPointerUp);
            window.addEventListener('pointercancel', onPointerUp);
            designCanvas.addEventListener('wheel', function (event) {
                if (!state.image) {
                    return;
                }
                event.preventDefault();
                state.viewport.zoom = clamp(state.viewport.zoom * (event.deltaY < 0 ? 1.08 : 0.92), 0.2, 8);
                scheduleRender();
            }, { passive: false });

            window.addEventListener('keydown', function (event) {
                if (event.key === 'Shift') {
                    isShiftDown = true;
                    if (!interaction && state.image) {
                        designCanvas.style.cursor = 'crosshair';
                    }
                }
                if (event.code === 'Space') {
                    isSpaceDown = true;
                    if (!interaction) {
                        designCanvas.style.cursor = 'grab';
                    }
                }
                if (!state.image) {
                    return;
                }
                if (isInputLike(event.target)) {
                    return;
                }
                var selected = getSelectedLayer();
                var mod = event.ctrlKey || event.metaKey;
                var lower = String(event.key || '').toLowerCase();
                if ((event.key === 'Delete' || event.key === 'Backspace') && selected) {
                    event.preventDefault();
                    deleteLayer();
                    return;
                }
                if (mod && lower === 'z') {
                    event.preventDefault();
                    if (event.shiftKey) {
                        redoHistory();
                    } else {
                        undoHistory();
                    }
                    return;
                }
                if (mod && lower === 'd') {
                    event.preventDefault();
                    duplicateLayer();
                    return;
                }
                if (mod && lower === 'c' && event.altKey) {
                    event.preventDefault();
                    layerStyleClipboard = cloneLayerStyle(selected);
                    if (layerStyleClipboard) {
                        setDesignStatus('Layer style copied.');
                    }
                    return;
                }
                if (mod && lower === 'v' && event.altKey) {
                    event.preventDefault();
                    if (applyLayerStyle(selected, layerStyleClipboard)) {
                        pushHistory();
                        scheduleRender();
                        setDesignStatus('Layer style pasted.');
                    }
                    return;
                }
                if (mod && lower === 'c') {
                    event.preventDefault();
                    setLayerClipboardFromSelection(false);
                    return;
                }
                if (mod && lower === 'x') {
                    event.preventDefault();
                    setLayerClipboardFromSelection(true);
                    return;
                }
                if (mod && lower === 'v') {
                    event.preventDefault();
                    pasteClipboard(event.shiftKey ? 'in-place' : 'center');
                    return;
                }
                if (selected && ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].indexOf(event.key) !== -1) {
                    event.preventDefault();
                    var step = event.shiftKey ? 10 : 1;
                    if (event.key === 'ArrowUp') {
                        selected.y -= step;
                    } else if (event.key === 'ArrowDown') {
                        selected.y += step;
                    } else if (event.key === 'ArrowLeft') {
                        selected.x -= step;
                    } else if (event.key === 'ArrowRight') {
                        selected.x += step;
                    }
                    scheduleHistory();
                    scheduleRender();
                }
            });

            window.addEventListener('keyup', function (event) {
                if (event.key === 'Shift') {
                    isShiftDown = false;
                    if (!interaction && state.image) {
                        designCanvas.style.cursor = 'default';
                    }
                }
                if (event.code === 'Space') {
                    isSpaceDown = false;
                    if (interaction && interaction.mode === 'pan') {
                        onPointerUp();
                    }
                }
            });

            window.addEventListener('keyup', function (event) {
                if (event.key === 'Shift') {
                    isShiftDown = false;
                }
                if (event.code === 'Space') {
                    isSpaceDown = false;
                    if (!interaction) {
                        designCanvas.style.cursor = 'default';
                    }
                }
            });

            if ('ResizeObserver' in window) {
                resizeObserver = new window.ResizeObserver(function () {
                    scheduleRender();
                });
                resizeObserver.observe(designStage);
            }

            window.addEventListener('beforeunload', function () {
                saveDraft();
            });

            syncControlsFromState();
            updateExportReadout();
            enhanceCollapsiblePanels();
            restoreDraft();
            scheduleRender();
        }
    }
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', bootstrap);
    } else {
        bootstrap();
    }

    var observer = new MutationObserver(function () {
        bootstrap();
    });

    observer.observe(document.documentElement, {
        childList: true,
        subtree: true
    });
}(window, document));
