@codingfactory/mediables-vue 2.13.0 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{PixiFrameExporter-BnAievFi.cjs → PixiFrameExporter-BOijjcAa.cjs} +2 -2
- package/dist/{PixiFrameExporter-BnAievFi.cjs.map → PixiFrameExporter-BOijjcAa.cjs.map} +1 -1
- package/dist/{PixiFrameExporter-DwbBy1Iu.js → PixiFrameExporter-cu2jpN20.js} +2 -2
- package/dist/{PixiFrameExporter-DwbBy1Iu.js.map → PixiFrameExporter-cu2jpN20.js.map} +1 -1
- package/dist/components/MediaManagementView.vue.d.ts +3 -1
- package/dist/composables/useAlbums.d.ts +10 -1
- package/dist/composables/useMediaTrash.d.ts +10 -0
- package/dist/editor-DLvndiXG.cjs +2 -0
- package/dist/editor-DLvndiXG.cjs.map +1 -0
- package/dist/{editor-BoDU3YXD.js → editor-OIsQEaJg.js} +18 -2
- package/dist/editor-OIsQEaJg.js.map +1 -0
- package/dist/{index-BGC4rPDc.js → index-Bff5fDnU.js} +13576 -12835
- package/dist/{index-CljyFIEv.cjs.map → index-Bff5fDnU.js.map} +1 -1
- package/dist/index-zFuo-sDY.cjs +357 -0
- package/dist/index-zFuo-sDY.cjs.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/mediables-vanilla.cjs +1 -1
- package/dist/mediables-vanilla.mjs +1 -1
- package/dist/mediables-vue.cjs +1 -1
- package/dist/mediables-vue.mjs +71 -68
- package/dist/render-page/assets/{index-jZGmiMRr.js → index-DQB8PyEU.js} +11 -2
- package/dist/render-page/index.html +1 -1
- package/dist/stores/albumStore.d.ts +17 -0
- package/dist/style.css +1 -1
- package/dist/types/mediaLibraryPicker.d.ts +30 -0
- package/package.json +1 -1
- package/dist/editor-BoDU3YXD.js.map +0 -1
- package/dist/editor-D-cJRASf.cjs +0 -2
- package/dist/editor-D-cJRASf.cjs.map +0 -1
- package/dist/index-BGC4rPDc.js.map +0 -1
- package/dist/index-CljyFIEv.cjs +0 -357
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editor-BoDU3YXD.js","sources":["../resources/js/vanilla-editor/core/EventEmitter.js","../resources/js/vanilla-editor/core/State.js","../resources/js/vanilla-editor/renderer/PixiRenderer.js","../resources/js/vanilla-editor/icons/icons.js","../resources/js/vanilla-editor/filters/categories.js","../resources/js/vanilla-editor/renderer/FilterManager.js","../resources/js/vanilla-editor/renderer/CropManager.js","../resources/js/vanilla-editor/renderer/RemoveBgManager.js","../resources/js/vanilla-editor/ui/UIBuilder.js","../resources/js/vanilla-editor/ui/Toolbar.js","../resources/js/vanilla-editor/ui/CategoryCarousel.js","../resources/js/vanilla-editor/ui/FilterCarousel.js","../resources/js/vanilla-editor/ui/FilterAdjustments.js","../resources/js/vanilla-editor/ui/MobileFilterDrawer.js","../resources/js/vanilla-editor/ui/MobileActiveFilters.js","../resources/js/vanilla-editor/ui/CropControls.js","../resources/js/vanilla-editor/ui/ActiveFiltersPanel.js","../resources/js/vanilla-editor/presets/index.js","../resources/js/vanilla-editor/VanillaImageEditor.js","../resources/js/filters/registry.ts","../resources/js/filters/definitions/adjustment.ts","../resources/js/filters/definitions/adjustmentAdvanced.ts","../resources/js/filters/definitions/alpha.ts","../resources/js/filters/definitions/blur.ts","../resources/js/filters/definitions/colorMatrix.ts","../resources/js/filters/definitions/colorOverlay.ts","../resources/js/filters/definitions/dropShadow.ts","../resources/js/filters/definitions/grayscale.ts","../resources/js/filters/definitions/hslAdjustment.ts","../resources/js/filters/definitions/kawaseBlur.ts","../resources/js/filters/definitions/motionBlur.ts","../resources/js/filters/definitions/radialBlur.ts","../resources/js/filters/definitions/tiltShift.ts","../resources/js/filters/definitions/zoomBlur.ts","../resources/js/filters/definitions/colorGradient.ts","../resources/js/filters/definitions/colorMap.ts","../resources/js/filters/definitions/colorReplace.ts","../resources/js/filters/definitions/multiColorReplace.ts","../resources/js/filters/definitions/rgbSplit.ts","../resources/js/filters/definitions/advancedBloom.ts","../resources/js/filters/definitions/ascii.ts","../resources/js/filters/definitions/backdropBlur.ts","../resources/js/filters/definitions/bevel.ts","../resources/js/filters/definitions/bloom.ts","../resources/js/filters/definitions/bulgePinch.ts","../resources/js/filters/definitions/convolution.ts","../resources/js/filters/definitions/crossHatch.ts","../resources/js/filters/definitions/crt.ts","../resources/js/filters/definitions/displacement.ts","../resources/js/filters/definitions/dot.ts","../resources/js/filters/definitions/emboss.ts","../resources/js/filters/definitions/glitch.ts","../resources/js/filters/definitions/glow.ts","../resources/js/filters/definitions/godray.ts","../resources/js/filters/definitions/lightmap.ts","../resources/js/filters/definitions/noise.ts","../resources/js/filters/definitions/oldFilm.ts","../resources/js/filters/definitions/outline.ts","../resources/js/filters/definitions/pixelate.ts","../resources/js/filters/definitions/reflection.ts","../resources/js/filters/definitions/shockwave.ts","../resources/js/filters/definitions/simplexNoise.ts","../resources/js/filters/definitions/twist.ts","../resources/js/filters/definitions/vignette.ts","../resources/js/filters/index.ts"],"sourcesContent":["/**\n * Simple EventEmitter for vanilla JS\n * Provides pub/sub functionality without external dependencies\n */\nexport class EventEmitter {\n constructor() {\n this._events = new Map()\n }\n\n on(event, callback) {\n if (!this._events.has(event)) {\n this._events.set(event, new Set())\n }\n this._events.get(event).add(callback)\n return () => this.off(event, callback)\n }\n\n off(event, callback) {\n const listeners = this._events.get(event)\n if (listeners) {\n listeners.delete(callback)\n }\n }\n\n emit(event, ...args) {\n const listeners = this._events.get(event)\n if (listeners) {\n listeners.forEach(callback => {\n try {\n callback(...args)\n } catch (e) {\n console.error(`Error in event listener for ${event}:`, e)\n }\n })\n }\n }\n\n once(event, callback) {\n const wrapper = (...args) => {\n this.off(event, wrapper)\n callback(...args)\n }\n return this.on(event, wrapper)\n }\n\n removeAllListeners(event) {\n if (event) {\n this._events.delete(event)\n } else {\n this._events.clear()\n }\n }\n}\n","/**\n * Central state management for the vanilla image editor\n * Replaces Vue's reactivity system with a simple observable pattern\n */\nimport { EventEmitter } from './EventEmitter.js'\n\nexport const TEXT_LAYER_FONT_FAMILIES = Object.freeze([\n 'Inter',\n 'Arial',\n 'Helvetica',\n 'Georgia',\n 'Times New Roman',\n 'Courier New',\n 'Verdana',\n])\n\nconst TEXT_LAYER_BLEND_MODES = Object.freeze(['normal', 'multiply', 'screen', 'overlay'])\nconst DEFAULT_TEXT_BOX = Object.freeze({ x: 0.2, y: 0.2, width: 0.6, height: 0.18 })\nconst DEFAULT_TEXT_STYLE = Object.freeze({\n fontFamily: 'Inter',\n fontSize: 64,\n fontWeight: 700,\n fontStyle: 'normal',\n fill: '#ffffff',\n align: 'center',\n lineHeight: 1.2,\n letterSpacing: 0,\n})\nconst DEFAULT_TEXT_EFFECTS = Object.freeze({\n stroke: Object.freeze({ enabled: false, color: '#000000', width: 0 }),\n shadow: Object.freeze({ enabled: false, color: '#000000', alpha: 0.5, blur: 0, distance: 0, angle: 45 }),\n glow: Object.freeze({ enabled: false, color: '#ffffff', alpha: 0.5, blur: 0 }),\n backdrop: Object.freeze({ enabled: false, color: '#000000', opacity: 0.5, padding: 0, radius: 0, blur: 0 }),\n})\n\nexport class State extends EventEmitter {\n constructor() {\n super()\n this._state = {\n // Image state\n hasImage: false,\n imageUrl: null,\n\n // Mode state\n mode: 'filters', // 'filters' | 'crop'\n\n // View state\n zoom: 1,\n fitScale: 1,\n\n // Filter state\n activeFilters: new Set(),\n filterValues: {},\n selectedFilter: null,\n selectedCategory: 'adjust',\n\n // Crop state\n crop: {\n shape: 'free', // 'free' | 'square' | 'circle'\n aspect: 'free', // 'free' | '1:1' | '4:3' | '16:9' | '3:2' | '2:3'\n rect: null, // { x, y, width, height }\n dirty: false // true once the user changes the generated crop frame\n },\n\n // Transform state\n transform: {\n rotation: 0 // degrees clockwise, normalized to 0..359.999\n },\n\n // Layered editor document state (v2 document contract)\n editorDocument: null,\n editorDocumentId: null,\n editorDocumentRevisionId: null,\n editorDocumentRevisionNumber: null,\n layers: [],\n activeLayerId: null,\n\n // UI state\n theme: 'auto', // 'light' | 'dark' | 'auto'\n isDarkMode: false,\n backgroundRemovalAvailable: false,\n isProcessing: false,\n isSaving: false\n }\n }\n\n /**\n * Get a state value\n * @param {string} key - State key (supports dot notation: 'crop.shape')\n * @returns {*} The state value\n */\n get(key) {\n if (key.includes('.')) {\n const parts = key.split('.')\n let value = this._state\n for (const part of parts) {\n if (value === undefined || value === null) return undefined\n value = value[part]\n }\n return value\n }\n return this._state[key]\n }\n\n /**\n * Set a state value and emit change event\n * @param {string} key - State key (supports dot notation: 'crop.shape')\n * @param {*} value - New value\n */\n set(key, value) {\n const old = this.get(key)\n\n if (key.includes('.')) {\n const parts = key.split('.')\n const lastKey = parts.pop()\n let target = this._state\n for (const part of parts) {\n if (target[part] === undefined) target[part] = {}\n target = target[part]\n }\n target[lastKey] = value\n } else {\n this._state[key] = value\n }\n\n this.emit(`change:${key}`, { value, old })\n this.emit('change', { key, value, old })\n }\n\n /**\n * Get the entire state object (for debugging).\n * WARNING: Shallow copy only — nested objects are live references.\n * For persistence, use getSerializableState() instead.\n */\n getAll() {\n return { ...this._state }\n }\n\n /**\n * Deep clone a JSON-compatible editor payload.\n * @param {*} value\n * @returns {*}\n */\n _clonePlain(value) {\n if (value === null || value === undefined) return value\n return JSON.parse(JSON.stringify(value))\n }\n\n /**\n * Get a deep, serializable snapshot of the editor state.\n * Safe for persistence — no mutable references leak out.\n * @returns {Object} ImageEditorSessionState-compatible object\n */\n getSerializableState() {\n const filters = []\n if (this._state.activeFilters) {\n for (const filterId of this._state.activeFilters) {\n const values = this._state.filterValues[filterId]\n filters.push({\n id: filterId,\n enabled: true,\n values: values ? { ...values } : {}\n })\n }\n }\n\n const crop = this._state.crop\n return {\n version: 1,\n crop: {\n rect: crop?.rect ? { ...crop.rect } : null,\n aspectRatio: crop?.aspect || 'free',\n shape: crop?.shape || 'free'\n },\n transform: {\n rotation: Number(this._state.transform?.rotation) || 0\n },\n filters\n }\n }\n\n /**\n * Store the active immutable v2 editor document snapshot.\n * @param {Object|null} document\n * @param {{ documentId?: string|null, documentRevisionId?: string|null, documentRevisionNumber?: number|null }} binding\n */\n setEditorDocument(document, binding = {}) {\n if (!document || document.version !== 2 || !Array.isArray(document.layers)) {\n this.clearEditorDocument()\n return\n }\n\n const snapshot = this._clonePlain(document)\n const layers = this._clonePlain(snapshot.layers)\n .map(layer => this._normalizeLayerForState(layer))\n const activeLayerId = typeof snapshot.activeLayerId === 'string'\n ? snapshot.activeLayerId\n : (layers[0]?.id ?? null)\n\n this._state.editorDocument = {\n ...snapshot,\n layers,\n activeLayerId,\n }\n this._state.editorDocumentId = binding.documentId ?? snapshot.id ?? null\n this._state.editorDocumentRevisionId = binding.documentRevisionId ?? null\n this._state.editorDocumentRevisionNumber = binding.documentRevisionNumber ?? snapshot.revision ?? null\n this._state.layers = layers\n this._state.activeLayerId = activeLayerId\n\n this.emit('change:editorDocument', { value: this.getSerializableDocument() })\n this.emit('change:layers', { value: this._clonePlain(layers) })\n this.emit('change:activeLayerId', { value: activeLayerId })\n this._syncFilterStateFromActiveLayer()\n }\n\n clearEditorDocument() {\n this._state.editorDocument = null\n this._state.editorDocumentId = null\n this._state.editorDocumentRevisionId = null\n this._state.editorDocumentRevisionNumber = null\n this._state.layers = []\n this._state.activeLayerId = null\n this._state.activeFilters = new Set()\n this._state.filterValues = {}\n this._state.selectedFilter = null\n this.emit('change:editorDocument', { value: null })\n this.emit('change:layers', { value: [] })\n this.emit('change:activeLayerId', { value: null })\n this.emit('change:activeFilters', { value: this._state.activeFilters })\n this.emit('change:filterValues', this._state.filterValues)\n this.emit('change:selectedFilter', { value: null })\n }\n\n /**\n * @returns {Object|null}\n */\n getSerializableDocument() {\n if (!this._state.editorDocument) return null\n\n const document = this._clonePlain(this._state.editorDocument)\n document.layers = this._clonePlain(this._state.layers)\n document.activeLayerId = this._state.activeLayerId\n\n return document\n }\n\n /**\n * @returns {{ documentId: string|null, documentRevisionId: string|null, documentRevisionNumber: number|null }|null}\n */\n getEditorDocumentBinding() {\n if (!this._state.editorDocument) return null\n\n return {\n documentId: this._state.editorDocumentId,\n documentRevisionId: this._state.editorDocumentRevisionId,\n documentRevisionNumber: this._state.editorDocumentRevisionNumber,\n }\n }\n\n /**\n * @param {string} layerId\n * @returns {number}\n */\n _findLayerIndex(layerId) {\n return this._state.layers.findIndex(layer => layer?.id === layerId)\n }\n\n /**\n * @param {Object|null|undefined} layer\n * @returns {boolean}\n */\n _layerLocked(layer) {\n return layer?.locked === true\n }\n\n /**\n * @param {Object[]|null|undefined} layers\n * @returns {boolean}\n */\n _backgroundLayerLocked(layers = this._state.layers) {\n const index = this._backgroundLayerIndex(layers)\n return index !== -1 && this._layerLocked(layers[index])\n }\n\n /**\n * @returns {boolean}\n */\n isBackgroundLayerLocked() {\n return this._backgroundLayerLocked()\n }\n\n /**\n * @param {string} baseId\n * @returns {string}\n */\n _uniqueLayerId(baseId) {\n const existingIds = new Set(this._state.layers.map(layer => layer?.id).filter(Boolean))\n const safeBase = String(baseId || 'layer').replace(/[^a-zA-Z0-9_-]+/g, '-').replace(/^-+|-+$/g, '') || 'layer'\n if (!existingIds.has(safeBase)) return safeBase\n\n for (let suffix = 2; suffix < 10000; suffix += 1) {\n const candidate = `${safeBase}-${suffix}`\n if (!existingIds.has(candidate)) return candidate\n }\n\n return `${safeBase}-${Date.now()}`\n }\n\n /**\n * @param {Object|null|undefined} layer\n * @returns {Object|null|undefined}\n */\n _normalizeLayerForState(layer) {\n if (!layer || typeof layer !== 'object') return layer\n if (layer.type !== 'text' && layer.role !== 'text') {\n return {\n ...layer,\n filters: this._normalizeLayerFilters(layer.filters),\n }\n }\n\n return this._normalizeTextLayer({\n ...layer,\n id: typeof layer.id === 'string' && layer.id.trim() !== '' ? layer.id : this._uniqueLayerId('text-layer'),\n name: typeof layer.name === 'string' && layer.name.trim() !== '' ? layer.name : 'Text',\n }, layer)\n }\n\n /**\n * @param {Array|null|undefined} filters\n * @returns {Array}\n */\n _normalizeLayerFilters(filters) {\n if (!Array.isArray(filters)) return []\n\n return filters\n .filter(filter => filter && typeof filter === 'object' && typeof filter.id === 'string' && filter.id.trim() !== '')\n .map(filter => ({\n id: filter.id.trim(),\n enabled: filter.enabled !== false,\n values: filter.values && typeof filter.values === 'object'\n ? this._clonePlain(filter.values)\n : {},\n }))\n }\n\n /**\n * @param {Object|null|undefined} layer\n * @returns {boolean}\n */\n _layerSupportsFilters(layer) {\n if (!layer || typeof layer !== 'object') return false\n if (layer.type === 'image') return true\n if (layer.type === 'background' || layer.role === 'background') {\n return layer.fill?.kind === 'media'\n }\n\n return false\n }\n\n /**\n * @returns {number}\n */\n _activeFilterLayerIndex() {\n const activeLayerId = this._state.activeLayerId\n if (!activeLayerId || !Array.isArray(this._state.layers)) return -1\n\n const index = this._findLayerIndex(activeLayerId)\n return index !== -1 && this._layerSupportsFilters(this._state.layers[index]) ? index : -1\n }\n\n /**\n * @returns {string|null}\n */\n getActiveFilterLayerId() {\n const index = this._activeFilterLayerIndex()\n return index !== -1 ? this._state.layers[index]?.id ?? null : null\n }\n\n /**\n * @param {string|null|undefined} expectedLayerId\n * @returns {boolean}\n */\n _matchesExpectedFilterLayer(expectedLayerId) {\n if (!this._state.editorDocument) return true\n if (expectedLayerId === undefined) return true\n if (expectedLayerId === null) return this.getActiveFilterLayerId() === null\n\n const expected = typeof expectedLayerId === 'string' ? expectedLayerId.trim() : ''\n if (expected === '') return false\n\n return this.getActiveFilterLayerId() === expected\n }\n\n /**\n * Project the active filterable layer into the legacy filter UI state.\n */\n _syncFilterStateFromActiveLayer() {\n if (!this._state.editorDocument) return\n\n const index = this._activeFilterLayerIndex()\n const activeFilters = new Set()\n const filterValues = {}\n\n if (index !== -1) {\n for (const filter of this._normalizeLayerFilters(this._state.layers[index]?.filters)) {\n if (filter.enabled === false) continue\n activeFilters.add(filter.id)\n filterValues[filter.id] = this._clonePlain(filter.values || {})\n }\n }\n\n const oldSelectedFilter = this._state.selectedFilter\n this._state.activeFilters = activeFilters\n this._state.filterValues = filterValues\n if (oldSelectedFilter && !activeFilters.has(oldSelectedFilter)) {\n this._state.selectedFilter = null\n }\n\n this.emit('change:activeFilters', { value: this._state.activeFilters })\n this.emit('change:filterValues', this._state.filterValues)\n if (this._state.selectedFilter !== oldSelectedFilter) {\n this.emit('change:selectedFilter', { value: this._state.selectedFilter, old: oldSelectedFilter })\n }\n }\n\n /**\n * @param {*} value\n * @param {number} min\n * @param {number} max\n * @param {number} fallback\n * @returns {number}\n */\n _clampNumber(value, min, max, fallback) {\n const numeric = Number(value)\n if (!Number.isFinite(numeric)) return fallback\n\n return Math.max(min, Math.min(max, numeric))\n }\n\n /**\n * @param {*} value\n * @returns {number}\n */\n _normalizeDegrees(value) {\n const numeric = Number(value)\n if (!Number.isFinite(numeric)) return 0\n\n const normalized = numeric % 360\n return normalized < 0 ? normalized + 360 : normalized\n }\n\n /**\n * @param {*} value\n * @returns {boolean}\n */\n _isSupportedTextColor(value) {\n return typeof value === 'string' && /^#[0-9a-f]{6}$/i.test(value)\n }\n\n /**\n * @param {*} value\n * @param {string} fallback\n * @returns {string}\n */\n _normalizeTextColor(value, fallback) {\n return this._isSupportedTextColor(value)\n ? value\n : (this._isSupportedTextColor(fallback) ? fallback : '#000000')\n }\n\n /**\n * @param {*} value\n * @param {boolean} fallback\n * @returns {boolean}\n */\n _normalizeBoolean(value, fallback = false) {\n return typeof value === 'boolean' ? value : fallback === true\n }\n\n /**\n * @param {*} value\n * @param {string} fallback\n * @returns {string}\n */\n _normalizeBlendMode(value, fallback = 'normal') {\n if (TEXT_LAYER_BLEND_MODES.includes(value)) return value\n if (TEXT_LAYER_BLEND_MODES.includes(fallback)) return fallback\n\n return 'normal'\n }\n\n /**\n * @param {*} value\n * @returns {string}\n */\n _normalizeTextFontFamily(value) {\n const candidate = typeof value === 'string' ? value.trim() : ''\n return TEXT_LAYER_FONT_FAMILIES.includes(candidate) ? candidate : DEFAULT_TEXT_STYLE.fontFamily\n }\n\n /**\n * @param {*} value\n * @param {number} fallback\n * @returns {number}\n */\n _normalizeTextFontWeight(value, fallback = DEFAULT_TEXT_STYLE.fontWeight) {\n if (value === 'normal') return 400\n if (value === 'bold') return 700\n\n const numeric = Number(value)\n if (!Number.isFinite(numeric)) return fallback\n if (numeric < 100 || numeric > 900 || numeric % 100 !== 0) return fallback\n\n return numeric\n }\n\n /**\n * @param {Object|null|undefined} box\n * @param {Object|null|undefined} base\n * @returns {{ x: number, y: number, width: number, height: number }}\n */\n _normalizeTextBox(box, base = null) {\n const fallback = base && typeof base === 'object' ? base : DEFAULT_TEXT_BOX\n const source = box && typeof box === 'object' ? box : {}\n\n return {\n x: this._clampNumber(source.x, 0, 1, this._clampNumber(fallback.x, 0, 1, DEFAULT_TEXT_BOX.x)),\n y: this._clampNumber(source.y, 0, 1, this._clampNumber(fallback.y, 0, 1, DEFAULT_TEXT_BOX.y)),\n width: this._clampNumber(source.width, 0.05, 1, this._clampNumber(fallback.width, 0.05, 1, DEFAULT_TEXT_BOX.width)),\n height: this._clampNumber(source.height, 0.05, 1, this._clampNumber(fallback.height, 0.05, 1, DEFAULT_TEXT_BOX.height)),\n }\n }\n\n /**\n * @param {Object|null|undefined} style\n * @param {Object|null|undefined} base\n * @returns {Object}\n */\n _normalizeTextStyle(style, base = null) {\n const fallback = {\n ...DEFAULT_TEXT_STYLE,\n ...(base && typeof base === 'object' ? base : {}),\n }\n const source = style && typeof style === 'object' ? style : {}\n const hasUnsupportedFontSource = !!source.fontSource || !!source.source || !!source.url\n const fontFamily = hasUnsupportedFontSource\n ? DEFAULT_TEXT_STYLE.fontFamily\n : this._normalizeTextFontFamily(source.fontFamily ?? fallback.fontFamily)\n const fontStyle = ['normal', 'italic'].includes(source.fontStyle)\n ? source.fontStyle\n : (['normal', 'italic'].includes(fallback.fontStyle) ? fallback.fontStyle : DEFAULT_TEXT_STYLE.fontStyle)\n const align = ['left', 'center', 'right'].includes(source.align)\n ? source.align\n : (['left', 'center', 'right'].includes(fallback.align) ? fallback.align : DEFAULT_TEXT_STYLE.align)\n const fill = this._isSupportedTextColor(source.fill)\n ? source.fill\n : (this._isSupportedTextColor(fallback.fill) ? fallback.fill : DEFAULT_TEXT_STYLE.fill)\n\n return {\n fontFamily,\n fontSize: this._clampNumber(source.fontSize, 8, 400, this._clampNumber(fallback.fontSize, 8, 400, DEFAULT_TEXT_STYLE.fontSize)),\n fontWeight: this._normalizeTextFontWeight(source.fontWeight, this._normalizeTextFontWeight(fallback.fontWeight, DEFAULT_TEXT_STYLE.fontWeight)),\n fontStyle,\n fill,\n align,\n lineHeight: this._clampNumber(source.lineHeight, 0.8, 3, this._clampNumber(fallback.lineHeight, 0.8, 3, DEFAULT_TEXT_STYLE.lineHeight)),\n letterSpacing: this._clampNumber(source.letterSpacing, -100, 100, this._clampNumber(fallback.letterSpacing, -100, 100, DEFAULT_TEXT_STYLE.letterSpacing)),\n }\n }\n\n /**\n * @param {Object|null|undefined} effects\n * @param {Object|null|undefined} base\n * @returns {Object}\n */\n _normalizeTextEffects(effects, base = null) {\n const source = effects && typeof effects === 'object' ? effects : {}\n const baseEffects = base && typeof base === 'object' ? base : {}\n\n const fallback = {\n stroke: { ...DEFAULT_TEXT_EFFECTS.stroke, ...(baseEffects.stroke && typeof baseEffects.stroke === 'object' ? baseEffects.stroke : {}) },\n shadow: { ...DEFAULT_TEXT_EFFECTS.shadow, ...(baseEffects.shadow && typeof baseEffects.shadow === 'object' ? baseEffects.shadow : {}) },\n glow: { ...DEFAULT_TEXT_EFFECTS.glow, ...(baseEffects.glow && typeof baseEffects.glow === 'object' ? baseEffects.glow : {}) },\n backdrop: { ...DEFAULT_TEXT_EFFECTS.backdrop, ...(baseEffects.backdrop && typeof baseEffects.backdrop === 'object' ? baseEffects.backdrop : {}) },\n }\n const stroke = source.stroke && typeof source.stroke === 'object' ? source.stroke : {}\n const shadow = source.shadow && typeof source.shadow === 'object' ? source.shadow : {}\n const glow = source.glow && typeof source.glow === 'object' ? source.glow : {}\n const backdrop = source.backdrop && typeof source.backdrop === 'object' ? source.backdrop : {}\n\n return {\n stroke: {\n enabled: this._normalizeBoolean(stroke.enabled, fallback.stroke.enabled),\n color: this._normalizeTextColor(stroke.color, fallback.stroke.color),\n width: this._clampNumber(stroke.width, 0, 80, this._clampNumber(fallback.stroke.width, 0, 80, DEFAULT_TEXT_EFFECTS.stroke.width)),\n },\n shadow: {\n enabled: this._normalizeBoolean(shadow.enabled, fallback.shadow.enabled),\n color: this._normalizeTextColor(shadow.color, fallback.shadow.color),\n alpha: this._clampNumber(shadow.alpha, 0, 1, this._clampNumber(fallback.shadow.alpha, 0, 1, DEFAULT_TEXT_EFFECTS.shadow.alpha)),\n blur: this._clampNumber(shadow.blur, 0, 120, this._clampNumber(fallback.shadow.blur, 0, 120, DEFAULT_TEXT_EFFECTS.shadow.blur)),\n distance: this._clampNumber(shadow.distance, 0, 200, this._clampNumber(fallback.shadow.distance, 0, 200, DEFAULT_TEXT_EFFECTS.shadow.distance)),\n angle: this._normalizeDegrees(shadow.angle ?? fallback.shadow.angle ?? DEFAULT_TEXT_EFFECTS.shadow.angle),\n },\n glow: {\n enabled: this._normalizeBoolean(glow.enabled, fallback.glow.enabled),\n color: this._normalizeTextColor(glow.color, fallback.glow.color),\n alpha: this._clampNumber(glow.alpha, 0, 1, this._clampNumber(fallback.glow.alpha, 0, 1, DEFAULT_TEXT_EFFECTS.glow.alpha)),\n blur: this._clampNumber(glow.blur, 0, 120, this._clampNumber(fallback.glow.blur, 0, 120, DEFAULT_TEXT_EFFECTS.glow.blur)),\n },\n backdrop: {\n enabled: this._normalizeBoolean(backdrop.enabled, fallback.backdrop.enabled),\n color: this._normalizeTextColor(backdrop.color, fallback.backdrop.color),\n opacity: this._clampNumber(backdrop.opacity, 0, 1, this._clampNumber(fallback.backdrop.opacity, 0, 1, DEFAULT_TEXT_EFFECTS.backdrop.opacity)),\n padding: this._clampNumber(backdrop.padding, 0, 200, this._clampNumber(fallback.backdrop.padding, 0, 200, DEFAULT_TEXT_EFFECTS.backdrop.padding)),\n radius: this._clampNumber(backdrop.radius, 0, 200, this._clampNumber(fallback.backdrop.radius, 0, 200, DEFAULT_TEXT_EFFECTS.backdrop.radius)),\n blur: this._clampNumber(backdrop.blur, 0, 80, this._clampNumber(fallback.backdrop.blur, 0, 80, DEFAULT_TEXT_EFFECTS.backdrop.blur)),\n },\n }\n }\n\n /**\n * @param {Object|null|undefined} transform\n * @param {Object|null|undefined} base\n * @returns {{ x: number, y: number, scaleX: number, scaleY: number, rotation: number }}\n */\n _normalizeLayerTransform(transform, base = null) {\n const fallback = base && typeof base === 'object' ? base : {}\n const source = transform && typeof transform === 'object' ? transform : {}\n\n return {\n x: this._clampNumber(source.x, -100000, 100000, this._clampNumber(fallback.x, -100000, 100000, 0)),\n y: this._clampNumber(source.y, -100000, 100000, this._clampNumber(fallback.y, -100000, 100000, 0)),\n scaleX: this._clampNumber(source.scaleX, 0.01, 100, this._clampNumber(fallback.scaleX, 0.01, 100, 1)),\n scaleY: this._clampNumber(source.scaleY, 0.01, 100, this._clampNumber(fallback.scaleY, 0.01, 100, 1)),\n rotation: this._normalizeDegrees(source.rotation ?? fallback.rotation ?? 0),\n }\n }\n\n /**\n * @param {Object|null|undefined} input\n * @param {Object|null|undefined} base\n * @returns {Object}\n */\n _normalizeTextPayload(input = {}, base = null) {\n const source = input && typeof input === 'object' ? input : {}\n const baseText = base?.text && typeof base.text === 'object' ? base.text : base\n const contentSource = source.content ?? source.text?.content ?? baseText?.content ?? 'Add text'\n const boxSource = source.box ?? source.text?.box\n const styleSource = source.style ?? source.text?.style\n const effectsSource = source.text?.effects ?? (source.effects && !Array.isArray(source.effects) ? source.effects : undefined)\n\n return {\n content: contentSource == null ? '' : String(contentSource),\n box: this._normalizeTextBox(boxSource, baseText?.box),\n style: this._normalizeTextStyle(styleSource, baseText?.style),\n effects: this._normalizeTextEffects(effectsSource, baseText?.effects),\n }\n }\n\n /**\n * @param {Object} input\n * @param {Object|null|undefined} base\n * @returns {Object}\n */\n _normalizeTextLayer(input = {}, base = null) {\n const source = input && typeof input === 'object' ? input : {}\n\n return {\n id: typeof source.id === 'string' && source.id.trim() !== '' ? source.id : this._uniqueLayerId('text-layer'),\n type: 'text',\n role: 'text',\n name: typeof source.name === 'string' && source.name.trim() !== '' ? source.name.trim() : 'Text',\n visible: source.visible === false ? false : true,\n locked: source.locked === true,\n opacity: this._clampNumber(source.opacity, 0, 1, 1),\n blendMode: this._normalizeBlendMode(source.blendMode, base?.blendMode),\n transform: this._normalizeLayerTransform(source.transform, base?.transform),\n effects: Array.isArray(source.effects) ? this._clonePlain(source.effects) : [],\n metadata: source.metadata && typeof source.metadata === 'object' ? this._clonePlain(source.metadata) : {},\n text: this._normalizeTextPayload(source, base),\n crop: null,\n filters: Array.isArray(source.filters) ? this._clonePlain(source.filters) : [],\n }\n }\n\n /**\n * @param {Object[]} layers\n * @param {number} removedIndex\n * @returns {string|null}\n */\n _nearestEditableLayerId(layers, removedIndex) {\n if (!layers.length) return null\n\n for (let distance = 0; distance < layers.length; distance += 1) {\n const nextIndex = removedIndex + distance\n if (nextIndex < layers.length && !this._layerLocked(layers[nextIndex]) && layers[nextIndex]?.visible !== false) {\n return layers[nextIndex].id ?? null\n }\n\n const previousIndex = removedIndex - distance - 1\n if (previousIndex >= 0 && !this._layerLocked(layers[previousIndex]) && layers[previousIndex]?.visible !== false) {\n return layers[previousIndex].id ?? null\n }\n }\n\n return null\n }\n\n /**\n * @param {Object[]} layers\n * @param {number} fromIndex\n * @param {number} toIndex\n * @returns {boolean}\n */\n _moveCrossesLockedLayer(layers, fromIndex, toIndex) {\n const start = Math.min(fromIndex, toIndex)\n const end = Math.max(fromIndex, toIndex)\n\n for (let index = start; index <= end; index += 1) {\n if (index === fromIndex) continue\n if (this._layerLocked(layers[index])) return true\n }\n\n return false\n }\n\n /**\n * @param {string} layerId\n * @returns {Object|null}\n */\n getLayer(layerId) {\n const layer = this._state.layers.find(candidate => candidate?.id === layerId)\n return layer ? this._clonePlain(layer) : null\n }\n\n /**\n * @param {string|null} layerId\n * @returns {boolean}\n */\n setActiveLayer(layerId) {\n if (layerId !== null && this._findLayerIndex(layerId) === -1) {\n return false\n }\n\n const old = this._state.activeLayerId\n this._state.activeLayerId = layerId\n if (this._state.editorDocument) {\n this._state.editorDocument.activeLayerId = layerId\n }\n this.emit('change:activeLayerId', { value: layerId, old })\n this._syncFilterStateFromActiveLayer()\n\n return true\n }\n\n /**\n * @returns {boolean}\n */\n isActiveLayerLocked() {\n const activeLayerId = this._state.activeLayerId\n if (!activeLayerId) return false\n\n const activeLayer = this._state.layers.find(layer => layer?.id === activeLayerId)\n return !!activeLayer?.locked\n }\n\n /**\n * @param {string} layerId\n * @param {boolean} visible\n * @returns {boolean}\n */\n setLayerVisibility(layerId, visible) {\n const index = this._findLayerIndex(layerId)\n if (index === -1) return false\n\n const layers = this._clonePlain(this._state.layers)\n if (this._layerLocked(layers[index])) return false\n\n layers[index].visible = !!visible\n this._state.layers = layers\n if (this._state.editorDocument) {\n this._state.editorDocument.layers = this._clonePlain(layers)\n }\n\n this.emit('change:layers', { value: this._clonePlain(layers) })\n this.emit('change:layerVisibility', { layerId, visible: !!visible })\n\n return true\n }\n\n /**\n * @param {string} layerId\n * @param {string} name\n * @returns {boolean}\n */\n renameLayer(layerId, name) {\n const index = this._findLayerIndex(layerId)\n if (index === -1) return false\n\n const layers = this._clonePlain(this._state.layers)\n if (this._layerLocked(layers[index])) return false\n\n const nextName = String(name ?? '').trim()\n if (nextName === '') return false\n\n const oldName = layers[index].name ?? ''\n layers[index].name = nextName\n this._commitLayers(layers, 'change:layerRenamed', { layerId, name: nextName, oldName })\n\n return true\n }\n\n /**\n * @param {string} layerId\n * @returns {string|null}\n */\n duplicateLayer(layerId) {\n const index = this._findLayerIndex(layerId)\n if (index === -1) return null\n\n const layers = this._clonePlain(this._state.layers)\n const sourceLayer = layers[index]\n if (this._layerLocked(sourceLayer)) return null\n\n const duplicate = this._clonePlain(sourceLayer)\n duplicate.id = this._uniqueLayerId(`${sourceLayer.id || 'layer'}-copy`)\n duplicate.name = `${String(sourceLayer.name || 'Layer').trim() || 'Layer'} copy`\n duplicate.locked = false\n duplicate.metadata = {\n ...(duplicate.metadata && typeof duplicate.metadata === 'object' ? duplicate.metadata : {}),\n duplicatedFromLayerId: sourceLayer.id ?? null,\n duplicatedAt: new Date().toISOString(),\n }\n\n layers.splice(index + 1, 0, duplicate)\n const oldActiveLayerId = this._state.activeLayerId\n this._state.activeLayerId = duplicate.id\n if (this._state.editorDocument) {\n this._state.editorDocument.activeLayerId = duplicate.id\n }\n\n this._commitLayers(layers, 'change:layerDuplicated', { layerId, duplicateLayerId: duplicate.id })\n this.emit('change:activeLayerId', { value: duplicate.id, old: oldActiveLayerId })\n\n return duplicate.id\n }\n\n /**\n * @param {string} layerId\n * @returns {boolean}\n */\n deleteLayer(layerId) {\n const index = this._findLayerIndex(layerId)\n if (index === -1 || this._state.layers.length <= 1) return false\n\n const layers = this._clonePlain(this._state.layers)\n if (this._layerLocked(layers[index])) return false\n\n const [removed] = layers.splice(index, 1)\n let nextActiveLayerId = this._state.activeLayerId\n if (nextActiveLayerId === layerId || !layers.some(layer => layer?.id === nextActiveLayerId)) {\n nextActiveLayerId = this._nearestEditableLayerId(layers, index)\n const oldActiveLayerId = this._state.activeLayerId\n this._state.activeLayerId = nextActiveLayerId\n if (this._state.editorDocument) {\n this._state.editorDocument.activeLayerId = nextActiveLayerId\n }\n this.emit('change:activeLayerId', { value: nextActiveLayerId, old: oldActiveLayerId })\n }\n\n this._commitLayers(layers, 'change:layerDeleted', { layerId: removed?.id ?? layerId })\n\n return true\n }\n\n /**\n * @param {string} layerId\n * @param {'up'|'down'|'front'|'back'|'bring-forward'|'send-backward'|'bring-to-front'|'send-to-back'} direction\n * @returns {boolean}\n */\n moveLayer(layerId, direction) {\n const fromIndex = this._findLayerIndex(layerId)\n if (fromIndex === -1) return false\n\n const layers = this._clonePlain(this._state.layers)\n if (this._layerLocked(layers[fromIndex])) return false\n\n let toIndex = fromIndex\n switch (direction) {\n case 'up':\n case 'bring-forward':\n toIndex = Math.min(layers.length - 1, fromIndex + 1)\n break\n case 'down':\n case 'send-backward':\n toIndex = Math.max(0, fromIndex - 1)\n break\n case 'front':\n case 'bring-to-front':\n toIndex = layers.length - 1\n break\n case 'back':\n case 'send-to-back':\n toIndex = 0\n break\n default:\n return false\n }\n\n if (toIndex === fromIndex) return false\n if (this._moveCrossesLockedLayer(layers, fromIndex, toIndex)) return false\n\n const [layer] = layers.splice(fromIndex, 1)\n layers.splice(toIndex, 0, layer)\n this._commitLayers(layers, 'change:layerMoved', { layerId, fromIndex, toIndex, direction })\n\n return true\n }\n\n /**\n * @param {string} layerId\n * @param {boolean} locked\n * @returns {boolean}\n */\n setLayerLocked(layerId, locked) {\n const index = this._findLayerIndex(layerId)\n if (index === -1) return false\n\n const layers = this._clonePlain(this._state.layers)\n layers[index].locked = !!locked\n this._state.layers = layers\n if (this._state.editorDocument) {\n this._state.editorDocument.layers = this._clonePlain(layers)\n }\n\n this.emit('change:layers', { value: this._clonePlain(layers) })\n this.emit('change:layerLocked', { layerId, locked: !!locked })\n\n return true\n }\n\n /**\n * @param {string} layerId\n * @param {Object} source\n * @returns {boolean}\n */\n replaceLayerSource(layerId, source) {\n const index = this._findLayerIndex(layerId)\n if (index === -1 || !source || typeof source !== 'object') return false\n\n const layers = this._clonePlain(this._state.layers)\n if (this._layerLocked(layers[index])) return false\n\n layers[index].source = this._clonePlain(source)\n this._state.layers = layers\n if (this._state.editorDocument) {\n this._state.editorDocument.layers = this._clonePlain(layers)\n this._state.editorDocument.updatedAt = new Date().toISOString()\n }\n\n this.emit('change:layers', { value: this._clonePlain(layers) })\n this.emit('change:layerSource', { layerId, source: this._clonePlain(source) })\n\n return true\n }\n\n /**\n * @param {Object} payload\n * @returns {string|null}\n */\n addTextLayer(payload = {}) {\n if (!this._state.editorDocument || !Array.isArray(this._state.layers)) {\n return null\n }\n\n const layers = this._clonePlain(this._state.layers)\n const layer = this._normalizeTextLayer({\n ...(payload && typeof payload === 'object' ? payload : {}),\n id: this._uniqueLayerId(payload?.id || 'text-layer'),\n })\n\n layers.push(layer)\n const oldActiveLayerId = this._state.activeLayerId\n this._state.activeLayerId = layer.id\n if (this._state.editorDocument) {\n this._state.editorDocument.activeLayerId = layer.id\n }\n\n this._commitLayers(layers, 'change:textLayer', { action: 'created', layerId: layer.id })\n this.emit('change:activeLayerId', { value: layer.id, old: oldActiveLayerId })\n\n return layer.id\n }\n\n /**\n * @param {string} layerId\n * @param {Object} patch\n * @returns {boolean}\n */\n updateTextLayer(layerId, patch = {}) {\n const index = this._findLayerIndex(layerId)\n if (index === -1 || !patch || typeof patch !== 'object') return false\n\n const layers = this._clonePlain(this._state.layers)\n const layer = layers[index]\n if (this._layerLocked(layer) || (layer.type !== 'text' && layer.role !== 'text')) {\n return false\n }\n\n const textPatch = patch.text && typeof patch.text === 'object' ? patch.text : {}\n const nextLayer = this._normalizeTextLayer({\n ...layer,\n transform: patch.transform && typeof patch.transform === 'object'\n ? { ...layer.transform, ...patch.transform }\n : layer.transform,\n text: {\n ...(layer.text && typeof layer.text === 'object' ? layer.text : {}),\n ...textPatch,\n ...('content' in patch ? { content: patch.content } : {}),\n ...('box' in patch ? { box: patch.box } : {}),\n ...('style' in patch ? { style: { ...(layer.text?.style || {}), ...(patch.style || {}) } } : {}),\n ...('effects' in patch ? { effects: patch.effects } : {}),\n },\n ...(patch.name !== undefined ? { name: patch.name } : {}),\n ...(patch.opacity !== undefined ? { opacity: patch.opacity } : {}),\n ...(patch.blendMode !== undefined ? { blendMode: patch.blendMode } : {}),\n }, layer)\n\n layers[index] = nextLayer\n this._commitLayers(layers, 'change:textLayer', {\n action: 'updated',\n layerId,\n text: this._clonePlain(nextLayer.text),\n })\n\n return true\n }\n\n _commitLayers(layers, eventName = null, eventPayload = {}) {\n this._state.layers = layers\n if (this._state.editorDocument) {\n this._state.editorDocument.layers = this._clonePlain(layers)\n this._state.editorDocument.updatedAt = new Date().toISOString()\n }\n\n this.emit('change:layers', { value: this._clonePlain(layers) })\n if (eventName) {\n this.emit(eventName, eventPayload)\n }\n }\n\n _backgroundLayerIndex(layers = this._state.layers) {\n return layers.findIndex(layer => layer?.type === 'background' || layer?.role === 'background')\n }\n\n _defaultBackgroundLayer(fill = { kind: 'transparent' }) {\n const existingIds = new Set(this._state.layers.map(layer => layer?.id).filter(Boolean))\n let id = 'background-layer'\n if (existingIds.has(id)) {\n id = `background-layer-${Date.now()}`\n }\n\n return {\n id,\n type: 'background',\n role: 'background',\n name: 'Background',\n visible: true,\n locked: false,\n opacity: 1,\n blendMode: 'normal',\n transform: { x: 0, y: 0, scaleX: 1, scaleY: 1, rotation: 0 },\n effects: [],\n metadata: {},\n fill: this._clonePlain(fill),\n crop: null,\n filters: [],\n }\n }\n\n _normalizeBackgroundFill(fill) {\n if (!fill || typeof fill !== 'object') {\n return { kind: 'transparent' }\n }\n\n const fit = ['cover', 'contain', 'stretch', 'tile'].includes(fill.fit) ? fill.fit : undefined\n if (fill.kind === 'color') {\n return {\n kind: 'color',\n value: typeof fill.value === 'string' ? fill.value : (typeof fill.color === 'string' ? fill.color : '#ffffff'),\n ...(fit ? { fit } : {}),\n }\n }\n\n if (fill.kind === 'gradient') {\n const stops = Array.isArray(fill.stops) && fill.stops.length > 0\n ? fill.stops\n .filter(stop => stop && typeof stop === 'object' && typeof stop.color === 'string')\n .map(stop => ({\n offset: Number.isFinite(Number(stop.offset)) ? Math.max(0, Math.min(1, Number(stop.offset))) : 0,\n color: stop.color,\n }))\n : [\n { offset: 0, color: '#111827' },\n { offset: 1, color: '#f59e0b' },\n ]\n\n return {\n kind: 'gradient',\n gradientType: ['linear', 'radial'].includes(fill.gradientType) ? fill.gradientType : 'linear',\n angle: Number.isFinite(Number(fill.angle)) ? Number(fill.angle) : 135,\n stops,\n fit: fit || 'cover',\n }\n }\n\n if (fill.kind === 'media' && fill.source && typeof fill.source === 'object') {\n return {\n kind: 'media',\n source: this._clonePlain(fill.source),\n fit: fit || 'cover',\n }\n }\n\n return { kind: 'transparent' }\n }\n\n ensureBackgroundLayer(fill = { kind: 'transparent' }) {\n const layers = this._clonePlain(this._state.layers)\n const existingIndex = this._backgroundLayerIndex(layers)\n if (existingIndex !== -1) {\n if (this._layerLocked(layers[existingIndex])) return null\n return layers[existingIndex].id\n }\n\n const layer = this._defaultBackgroundLayer(this._normalizeBackgroundFill(fill))\n const firstSubjectIndex = layers.findIndex(candidate => candidate?.role === 'subject' || candidate?.type === 'image')\n const insertAt = firstSubjectIndex >= 0 ? firstSubjectIndex : 0\n layers.splice(insertAt, 0, layer)\n this._commitLayers(layers, 'change:backgroundLayer', { layerId: layer.id, action: 'created' })\n\n return layer.id\n }\n\n setBackgroundFill(fill) {\n const normalizedFill = this._normalizeBackgroundFill(fill)\n const layerId = this.ensureBackgroundLayer(normalizedFill)\n if (!layerId) return null\n\n const layers = this._clonePlain(this._state.layers)\n const index = this._backgroundLayerIndex(layers)\n if (index === -1) return null\n if (this._layerLocked(layers[index])) return null\n\n const previousFit = layers[index].fill?.fit\n layers[index].fill = this._clonePlain({\n ...normalizedFill,\n ...(\n !normalizedFill.fit && previousFit && normalizedFill.kind !== 'transparent'\n ? { fit: previousFit }\n : {}\n ),\n })\n this._commitLayers(layers, 'change:backgroundFill', { layerId, fill: this._clonePlain(layers[index].fill) })\n\n return layerId\n }\n\n setBackgroundFit(fit) {\n if (!['cover', 'contain', 'stretch', 'tile'].includes(fit)) {\n return false\n }\n\n const layerId = this.ensureBackgroundLayer()\n if (!layerId) return false\n\n const layers = this._clonePlain(this._state.layers)\n const index = this._backgroundLayerIndex(layers)\n if (index === -1) return false\n if (this._layerLocked(layers[index])) return false\n\n const fill = layers[index].fill && typeof layers[index].fill === 'object'\n ? layers[index].fill\n : { kind: 'transparent' }\n layers[index].fill = { ...fill, fit }\n this._commitLayers(layers, 'change:backgroundFit', { layerId, fit })\n\n return true\n }\n\n setBackgroundBlur(amount) {\n const numericAmount = Number.isFinite(Number(amount)) ? Math.max(0, Math.min(100, Number(amount))) : 0\n const layerId = this.ensureBackgroundLayer()\n if (!layerId) return false\n\n const layers = this._clonePlain(this._state.layers)\n const index = this._backgroundLayerIndex(layers)\n if (index === -1) return false\n if (this._layerLocked(layers[index])) return false\n\n const effects = Array.isArray(layers[index].effects)\n ? layers[index].effects.filter(effect => effect?.id !== 'background-blur')\n : []\n if (numericAmount > 0) {\n effects.push({\n id: 'background-blur',\n type: 'blur',\n params: { amount: numericAmount },\n })\n }\n layers[index].effects = effects\n this._commitLayers(layers, 'change:backgroundBlur', { layerId, amount: numericAmount })\n\n return true\n }\n\n removeBackgroundLayer() {\n const layers = this._clonePlain(this._state.layers)\n const index = this._backgroundLayerIndex(layers)\n if (index === -1) return false\n if (this._layerLocked(layers[index])) return false\n\n const [removed] = layers.splice(index, 1)\n if (removed?.id && this._state.activeLayerId === removed.id) {\n const nextActive = this._nearestEditableLayerId(layers, index)\n this._state.activeLayerId = nextActive\n if (this._state.editorDocument) {\n this._state.editorDocument.activeLayerId = nextActive\n }\n this.emit('change:activeLayerId', { value: nextActive, old: removed.id })\n }\n\n this._commitLayers(layers, 'change:backgroundLayer', { layerId: removed?.id ?? null, action: 'removed' })\n\n return true\n }\n\n /**\n * Toggle a filter in the active filters set\n * @param {string} filterId\n * @param {boolean} enabled\n */\n toggleFilter(filterId, enabled, expectedLayerId = undefined) {\n if (this._state.editorDocument) {\n if (!this._matchesExpectedFilterLayer(expectedLayerId)) return false\n\n const index = this._activeFilterLayerIndex()\n if (index === -1) {\n this._syncFilterStateFromActiveLayer()\n return false\n }\n\n const id = typeof filterId === 'string' ? filterId.trim() : ''\n if (id === '') return false\n\n const layers = this._clonePlain(this._state.layers)\n const layer = layers[index]\n const filters = this._normalizeLayerFilters(layer.filters)\n const existingIndex = filters.findIndex(filter => filter.id === id)\n\n if (enabled) {\n if (existingIndex === -1) {\n filters.push({ id, enabled: true, values: {} })\n } else {\n filters[existingIndex].enabled = true\n }\n } else if (existingIndex !== -1) {\n filters.splice(existingIndex, 1)\n }\n\n layer.filters = filters\n this._commitLayers(layers, 'change:layerFilters', {\n layerId: layer.id,\n filterId: id,\n enabled: !!enabled,\n })\n this._syncFilterStateFromActiveLayer()\n\n return true\n }\n\n const filters = new Set(this._state.activeFilters)\n if (enabled) {\n filters.add(filterId)\n } else {\n filters.delete(filterId)\n delete this._state.filterValues[filterId]\n }\n this.set('activeFilters', filters)\n\n return true\n }\n\n /**\n * Update a filter's control value\n * @param {string} filterId\n * @param {string} controlId\n * @param {*} value\n */\n setFilterValue(filterId, controlId, value, expectedLayerId = undefined) {\n if (this._state.editorDocument) {\n if (!this._matchesExpectedFilterLayer(expectedLayerId)) return false\n\n const index = this._activeFilterLayerIndex()\n if (index === -1) {\n this._syncFilterStateFromActiveLayer()\n return false\n }\n\n const id = typeof filterId === 'string' ? filterId.trim() : ''\n if (id === '' || !this._state.activeFilters?.has?.(id)) return false\n\n const layers = this._clonePlain(this._state.layers)\n const layer = layers[index]\n const filters = this._normalizeLayerFilters(layer.filters)\n const filterIndex = filters.findIndex(filter => filter.id === id && filter.enabled !== false)\n if (filterIndex === -1) return false\n\n filters[filterIndex].values = {\n ...(filters[filterIndex].values && typeof filters[filterIndex].values === 'object' ? filters[filterIndex].values : {}),\n [controlId]: this._clonePlain(value),\n }\n layer.filters = filters\n this._commitLayers(layers, 'change:layerFilters', {\n layerId: layer.id,\n filterId: id,\n controlId,\n value: this._clonePlain(value),\n })\n this._syncFilterStateFromActiveLayer()\n this.emit('change:filterValue', { filterId: id, controlId, value })\n\n return true\n }\n\n if (!this._state.filterValues[filterId]) {\n this._state.filterValues[filterId] = {}\n }\n this._state.filterValues[filterId][controlId] = value\n this.emit('change:filterValue', { filterId, controlId, value })\n this.emit('change:filterValues', this._state.filterValues)\n\n return true\n }\n\n /**\n * Get a filter's control values\n * @param {string} filterId\n * @returns {Object} Filter values\n */\n getFilterValues(filterId) {\n return this._state.filterValues[filterId] || {}\n }\n\n /**\n * Initialize filter values from definition defaults\n * @param {string} filterId\n * @param {Array} controls - Control definitions with defaults\n */\n initFilterValues(filterId, controls, expectedLayerId = undefined) {\n if (this._state.editorDocument) {\n if (!this._matchesExpectedFilterLayer(expectedLayerId)) return false\n\n const existing = this.getFilterValues(filterId)\n controls.forEach(ctl => {\n if (!(ctl.id in existing)) {\n this.setFilterValue(filterId, ctl.id, ctl.default, expectedLayerId)\n }\n })\n return true\n }\n\n if (!this._state.filterValues[filterId]) {\n this._state.filterValues[filterId] = {}\n }\n controls.forEach(ctl => {\n if (!(ctl.id in this._state.filterValues[filterId])) {\n this._state.filterValues[filterId][ctl.id] = ctl.default\n }\n })\n this.emit('change:filterValues', this._state.filterValues)\n\n return true\n }\n\n /**\n * Reset all filters\n */\n resetFilters(expectedLayerId = undefined) {\n if (this._state.editorDocument) {\n if (!this._matchesExpectedFilterLayer(expectedLayerId)) return false\n\n const index = this._activeFilterLayerIndex()\n if (index === -1) {\n this._syncFilterStateFromActiveLayer()\n this.emit('filtersReset')\n return false\n }\n\n const layers = this._clonePlain(this._state.layers)\n layers[index].filters = []\n this._commitLayers(layers, 'change:layerFilters', {\n layerId: layers[index].id,\n action: 'reset',\n })\n this._syncFilterStateFromActiveLayer()\n this.emit('filtersReset')\n\n return true\n }\n\n this._state.activeFilters = new Set()\n this._state.filterValues = {}\n this._state.selectedFilter = null\n this.emit('change:activeFilters', { value: this._state.activeFilters })\n this.emit('change:filterValues', this._state.filterValues)\n this.emit('change:selectedFilter', { value: null })\n this.emit('filtersReset')\n\n return true\n }\n\n /**\n * Detect and set dark mode based on preference\n */\n detectTheme() {\n if (this._state.theme === 'auto') {\n const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches\n this.set('isDarkMode', prefersDark)\n } else {\n this.set('isDarkMode', this._state.theme === 'dark')\n }\n }\n}\n\n// Singleton instance\nlet instance = null\n\nexport function getState() {\n if (!instance) {\n instance = new State()\n }\n return instance\n}\n\nexport function createState() {\n return new State()\n}\n","/**\n * PIXI.js v8 Renderer for the vanilla image editor\n * Handles canvas lifecycle, image loading, zoom, and export\n */\nimport { EventEmitter } from '../core/EventEmitter.js'\n\nconst TEXT_BLEND_MODES = Object.freeze(['normal', 'multiply', 'screen', 'overlay'])\nconst DEFAULT_TEXT_EFFECTS = Object.freeze({\n stroke: Object.freeze({ enabled: false, color: '#000000', width: 0 }),\n shadow: Object.freeze({ enabled: false, color: '#000000', alpha: 0.5, blur: 0, distance: 0, angle: 45 }),\n glow: Object.freeze({ enabled: false, color: '#ffffff', alpha: 0.5, blur: 0 }),\n backdrop: Object.freeze({ enabled: false, color: '#000000', opacity: 0.5, padding: 0, radius: 0, blur: 0 }),\n})\n\nexport class PixiRenderer extends EventEmitter {\n constructor() {\n super()\n this.app = null\n this.sprite = null\n this.originalTexture = null\n this.baseTexture = null\n this.fitScale = 1\n this.zoom = 1\n this._container = null\n this._lastExportDimensions = null\n /** @type {Promise<boolean>|null} Resolves when mount() finishes */\n this._mountPromise = null\n this._mountToken = 0\n this._destroyed = false\n this._layerDocument = null\n this._layerDisplayObjects = new Map()\n this._renderableLayerIds = []\n this._loadedTextureUrl = null\n this._layerRenderToken = 0\n this._layerFilterFactory = null\n }\n\n /**\n * Whether the renderer is fully initialized and ready for use.\n * @returns {boolean}\n */\n get isReady() {\n return !!(this.app?.renderer)\n }\n\n /**\n * Get CSS size of the canvas (for proper coordinate mapping).\n * Accesses renderer.canvas directly to avoid PIXI Application's\n * canvas getter which throws when renderer is undefined.\n */\n _getCssSize() {\n const canvas = this.app?.renderer?.canvas\n const w = canvas?.clientWidth ?? this.app?.screen?.width ?? 0\n const h = canvas?.clientHeight ?? this.app?.screen?.height ?? 0\n return { w, h }\n }\n\n /**\n * Force render the stage\n */\n render() {\n try {\n if (this.app?.renderer && this.app?.stage) {\n this.app.renderer.render(this.app.stage)\n }\n } catch (e) {\n console.warn('[PixiRenderer] render error:', e)\n }\n }\n\n /**\n * Wait for the next animation frame, with a timeout fallback for environments\n * where the frame callback never arrives while the editor is open.\n * @param {number} timeoutMs\n * @returns {Promise<void>}\n */\n _waitForNextFrame(timeoutMs = 32) {\n return new Promise((resolve) => {\n if (typeof window === 'undefined') {\n resolve()\n return\n }\n\n let settled = false\n let timeoutId = 0\n\n const finish = () => {\n if (settled) return\n settled = true\n window.clearTimeout(timeoutId)\n resolve()\n }\n\n timeoutId = window.setTimeout(finish, timeoutMs)\n\n if (typeof window.requestAnimationFrame === 'function') {\n window.requestAnimationFrame(() => finish())\n return\n }\n\n finish()\n })\n }\n\n /**\n * Calculate fit scale for a texture\n * @param {PIXI.Texture} tex\n * @returns {number}\n */\n getFitScaleFor(tex) {\n if (!this.app || !tex) return 1\n const { w, h } = this._getCssSize()\n if (w <= 1 || h <= 1) return 1\n let scale = Math.min(w / tex.width, h / tex.height) * 0.9\n if (!Number.isFinite(scale) || scale <= 0) scale = 1\n return scale\n }\n\n /**\n * Apply view transform (position and scale) to sprite\n */\n applyViewTransform(opts = {}) {\n if (!this.app || !this.sprite || !this.originalTexture) return\n\n const s = this.fitScale * this.zoom\n const { w, h } = this._getCssSize()\n\n const desired = opts.keepCenter\n ? { x: this.sprite.x + this.sprite.width / 2, y: this.sprite.y + this.sprite.height / 2 }\n : (opts.center ?? { x: w / 2, y: h / 2 })\n\n this.sprite.width = this.originalTexture.width * s\n this.sprite.height = this.originalTexture.height * s\n this.sprite.x = desired.x - this.sprite.width / 2\n this.sprite.y = desired.y - this.sprite.height / 2\n\n this._syncLayerDisplayObjects()\n\n this.render()\n }\n\n /**\n * Set zoom level\n * @param {number} z - Zoom level (0.1 to 8)\n * @param {Object} opts - Options\n */\n setZoom(z, opts = {}) {\n this.zoom = Math.max(0.1, Math.min(8, z))\n this.applyViewTransform({ keepCenter: opts.keepCenter ?? true })\n this.emit('zoomChange', this.zoom)\n }\n\n /**\n * Fit image to screen\n */\n fitToScreen() {\n if (this.originalTexture) {\n this.fitScale = this.getFitScaleFor(this.originalTexture)\n this.setZoom(1, { keepCenter: false })\n }\n }\n\n /**\n * Mount PIXI application to container\n * @param {HTMLElement} container\n * @param {number} backgroundColor\n * @param {Object} [options]\n * @param {number} [options.backgroundAlpha=1] - 0 makes the canvas transparent\n * so a host-rendered background (e.g. CSS checkerboard) shows through.\n */\n async mount(container, backgroundColor = 0xffffff, options = {}) {\n if (!container) return\n this._destroyed = false\n this._container = container\n const mountToken = ++this._mountToken\n\n const doMount = async () => {\n const PIXI = window.PIXI\n if (!PIXI) {\n throw new Error('PIXI.js not found. Please ensure PIXI is loaded globally.')\n }\n\n // Enable CORS for cross-origin image loading (e.g. S3 presigned URLs)\n if (PIXI.Assets?.setPreferences) {\n PIXI.Assets.setPreferences({ crossOrigin: 'anonymous' })\n }\n\n const width = container.clientWidth || 600\n const height = container.clientHeight || 400\n\n const backgroundAlpha = typeof options.backgroundAlpha === 'number'\n ? options.backgroundAlpha\n : 1\n\n const app = new PIXI.Application()\n this.app = app\n await app.init({\n width,\n height,\n backgroundColor,\n backgroundAlpha,\n antialias: true,\n autoDensity: true,\n resolution: window.devicePixelRatio || 1\n })\n\n if (this._destroyed || this._mountToken !== mountToken || this.app !== app) {\n try {\n app.destroy(true, { children: true, texture: true })\n } catch (_e) {\n // Ignore destroy races; the active renderer has already moved on.\n }\n return false\n }\n\n container.appendChild(app.canvas)\n\n // Style the canvas\n const canvas = app.canvas\n canvas.classList.add('pixi-canvas')\n canvas.style.width = '100%'\n canvas.style.height = '100%'\n canvas.style.transform = 'translateZ(0)'\n canvas.style.willChange = 'transform'\n\n // Accessibility: label the canvas for screen readers\n canvas.setAttribute('role', 'img')\n canvas.setAttribute('aria-label', 'Image editor canvas — use toolbar controls to edit the image')\n\n this.emit('mounted', { width, height })\n return true\n }\n\n this._mountPromise = doMount()\n return await this._mountPromise\n }\n\n /**\n * Load an image texture\n * @param {string} imageUrl - URL, data URL, or blob URL of the image\n * @param {Object} [options]\n * @param {() => boolean} [options.isCurrent] - Returns false when this load\n * has been superseded and must not mutate the renderer.\n */\n async loadTexture(imageUrl, options = {}) {\n const isCurrent = () => typeof options.isCurrent !== 'function' || options.isCurrent() !== false\n\n // Wait for mount() to finish if it's still in progress\n if (this._mountPromise) {\n await this._mountPromise\n }\n\n if (!this.app?.renderer || !isCurrent()) return false\n\n const PIXI = window.PIXI\n\n // Load image via HTMLImageElement then create texture directly.\n // Bypasses PIXI.Assets.load() which can't handle blob: or data: URLs.\n const img = await this._loadImageElement(imageUrl)\n if (!img) {\n console.error('[PixiRenderer.loadTexture] Failed to load image from', imageUrl)\n return false\n }\n\n // Re-check after async — renderer may have been destroyed\n if (!this.app?.renderer || !isCurrent()) return false\n\n // Wait for layout to settle before mutating the renderer. Fall back to a\n // short timeout when the environment never delivers the frame callback.\n await this._waitForNextFrame()\n\n // Re-check after async — this load may have been superseded during frame settlement.\n if (!this.app?.renderer || !isCurrent()) return false\n\n const tex = PIXI.Texture.from(img)\n\n if (!tex) {\n console.error('[PixiRenderer.loadTexture] Failed to create texture from image')\n return false\n }\n\n this.originalTexture = tex\n this.baseTexture = tex\n this._loadedTextureUrl = typeof imageUrl === 'string' ? imageUrl : null\n\n // Remove old sprite\n if (this.sprite) {\n this.app.stage.removeChild(this.sprite)\n this.sprite.destroy()\n }\n\n // Create new sprite\n this.sprite = new PIXI.Sprite(tex)\n this.app.stage.addChild(this.sprite)\n\n // Calculate fit scale and apply\n this.fitScale = this.getFitScaleFor(tex)\n this.zoom = 1\n\n const { w, h } = this._getCssSize()\n this.applyViewTransform({ center: { x: w / 2, y: h / 2 } })\n\n const settledScale = this.getFitScaleFor(tex)\n if (Math.abs(settledScale - this.fitScale) / Math.max(1e-6, settledScale) > 0.02) {\n this.fitScale = settledScale\n this.applyViewTransform({ center: { x: w / 2, y: h / 2 } })\n }\n\n this.render()\n this.emit('textureLoaded', { width: tex.width, height: tex.height })\n return true\n }\n\n /**\n * Render a v2 layer document in preview order. The existing subject sprite\n * remains the filter/crop target; auxiliary layers are synced to its preview\n * geometry until arbitrary per-layer transforms are introduced.\n * @param {Object|null} document\n * @returns {Promise<boolean>}\n */\n async renderLayerDocument(document) {\n if (!this.app?.stage || !this.sprite || !document || !Array.isArray(document.layers)) {\n return false\n }\n\n const PIXI = window.PIXI\n if (!PIXI) return false\n\n const renderToken = ++this._layerRenderToken\n const isCurrentRender = () => renderToken === this._layerRenderToken\n this._destroyLayerDisplayObjects()\n this._layerDocument = JSON.parse(JSON.stringify(document))\n this._renderableLayerIds = []\n\n try {\n this.app.stage.removeChild(this.sprite)\n } catch (_e) {\n // The sprite may not have been attached yet in tests or during reloads.\n }\n\n let subjectAdded = false\n\n for (const layer of this._layerDocument.layers) {\n if (!layer || layer.visible === false) {\n if (layer?.role === 'subject') {\n this.sprite.visible = false\n this.sprite.__layerId = layer.id\n subjectAdded = true\n }\n continue\n }\n\n if (this._isSubjectLayer(layer)) {\n const displayObject = await this._createSubjectDisplayObjectForLayer(PIXI, layer)\n if (!isCurrentRender()) {\n this._destroyTransientDisplayObject(displayObject)\n return false\n }\n if (displayObject) {\n this.sprite.visible = false\n displayObject.__layerId = layer.id\n displayObject.visible = true\n displayObject.alpha = this._layerOpacity(layer)\n this._layerDisplayObjects.set(layer.id, { layer, displayObject })\n this._syncLayerDisplayObject(layer, displayObject)\n this.app.stage.addChild(displayObject)\n this._renderableLayerIds.push(layer.id)\n subjectAdded = true\n continue\n }\n\n this.sprite.__layerId = layer.id\n this.sprite.visible = true\n this.sprite.alpha = this._layerOpacity(layer)\n this._applyLayerFilterInstances(this.sprite, layer)\n this.app.stage.addChild(this.sprite)\n this._renderableLayerIds.push(layer.id)\n subjectAdded = true\n continue\n }\n\n const displayObject = await this._createDisplayObjectForLayer(PIXI, layer)\n if (!isCurrentRender()) {\n this._destroyTransientDisplayObject(displayObject)\n return false\n }\n if (!displayObject) continue\n\n displayObject.__layerId = layer.id\n displayObject.visible = true\n displayObject.alpha = this._layerOpacity(layer)\n this._layerDisplayObjects.set(layer.id, { layer, displayObject })\n this._syncLayerDisplayObject(layer, displayObject)\n this.app.stage.addChild(displayObject)\n this._renderableLayerIds.push(layer.id)\n }\n\n if (!subjectAdded) {\n this.sprite.visible = false\n }\n\n if (!isCurrentRender()) return false\n this.render()\n\n return true\n }\n\n getRenderableLayerIds() {\n return [...this._renderableLayerIds]\n }\n\n setLayerFilterFactory(factory) {\n this._layerFilterFactory = typeof factory === 'function' ? factory : null\n }\n\n applyLayerFilters(document = this._layerDocument) {\n if (!document || !Array.isArray(document.layers)) return false\n\n this._layerDocument = JSON.parse(JSON.stringify(document))\n\n for (const layer of this._layerDocument.layers) {\n if (!layer) continue\n\n const layerEntry = this._layerDisplayObjects.get(layer.id) || null\n if (layerEntry) layerEntry.layer = layer\n\n let displayObject = layerEntry?.displayObject || null\n if (!displayObject && this._isSubjectLayer(layer) && this.sprite?.__layerId === layer.id) {\n displayObject = this.sprite\n }\n\n if (!displayObject) continue\n this._applyLayerFilterInstances(displayObject, layer)\n }\n\n this.render()\n return true\n }\n\n _isSubjectLayer(layer) {\n return layer?.role === 'subject' || layer?.id === 'subject-layer'\n }\n\n _layerSupportsImageFilters(layer) {\n if (!layer || typeof layer !== 'object') return false\n if (layer.type === 'image') return true\n if (layer.type === 'background' || layer.role === 'background') {\n return layer.fill?.kind === 'media'\n }\n\n return false\n }\n\n _layerOpacity(layer) {\n const opacity = Number(layer?.opacity)\n if (!Number.isFinite(opacity)) return 1\n return Math.max(0, Math.min(1, opacity))\n }\n\n _applyLayerFilterInstances(displayObject, layer, context = {}) {\n if (!displayObject || !this._layerSupportsImageFilters(layer)) return\n\n let filters = []\n if (this._layerFilterFactory) {\n try {\n filters = this._layerFilterFactory(layer, {\n displayObject,\n forExport: context.forExport === true,\n previewToNativeScale: context.previewToNativeScale || 1,\n sourceWidth: context.sourceWidth,\n sourceHeight: context.sourceHeight,\n }) || []\n } catch (error) {\n console.error('[PixiRenderer] Failed to create layer filters:', error)\n filters = []\n }\n }\n\n const imageFilters = Array.isArray(filters) ? filters.filter(Boolean) : []\n for (const filter of imageFilters) {\n if (!filter || (typeof filter !== 'object' && typeof filter !== 'function')) continue\n try {\n Object.defineProperty(filter, '__mediablesLayerImageFilter', {\n value: true,\n configurable: true,\n })\n } catch (_error) {\n try {\n filter.__mediablesLayerImageFilter = true\n } catch (_ignored) {}\n }\n }\n\n const preservedFilters = Array.isArray(displayObject.filters)\n ? displayObject.filters.filter(filter => filter?.__mediablesLayerImageFilter !== true)\n : []\n const combinedFilters = [...preservedFilters, ...imageFilters]\n displayObject.filters = combinedFilters.length > 0 ? combinedFilters : null\n }\n\n async _createDisplayObjectForLayer(PIXI, layer) {\n const textDisplayObject = this._createTextDisplayObjectForLayer(PIXI, layer)\n if (textDisplayObject) return textDisplayObject\n\n const imageDisplayObject = await this._createImageDisplayObjectForLayer(PIXI, layer)\n if (imageDisplayObject) return imageDisplayObject\n\n const fill = this._backgroundFillForLayer(layer)\n\n if (fill?.kind === 'media') {\n const texture = await this._textureForLayerSource(PIXI, fill.source)\n if (!texture) return null\n\n const displayObject = this._createBackgroundSprite(PIXI, texture, fill.fit)\n displayObject.__sourceWidth = Number(fill.source?.originalWidth) || texture.width || 1\n displayObject.__sourceHeight = Number(fill.source?.originalHeight) || texture.height || 1\n this._applyLayerEffects(PIXI, displayObject, layer)\n this._applyLayerFilterInstances(displayObject, layer)\n\n return displayObject\n }\n\n if (fill?.kind === 'gradient') {\n const texture = this._createGradientTexture(PIXI, fill, 512, 512)\n if (!texture || typeof PIXI.Sprite !== 'function') return null\n\n const displayObject = new PIXI.Sprite(texture)\n displayObject.__ownsTexture = true\n displayObject.__sourceWidth = 512\n displayObject.__sourceHeight = 512\n this._applyLayerEffects(PIXI, displayObject, layer)\n\n return displayObject\n }\n\n if (this._backgroundColorForLayer(layer) && typeof PIXI.Graphics === 'function') {\n const displayObject = new PIXI.Graphics()\n this._applyLayerEffects(PIXI, displayObject, layer)\n\n return displayObject\n }\n\n return null\n }\n\n _isTextLayer(layer) {\n return layer?.type === 'text' || layer?.role === 'text'\n }\n\n _normalizeTextBox(layer) {\n const box = layer?.text?.box && typeof layer.text.box === 'object'\n ? layer.text.box\n : {}\n\n return {\n x: this._clampNumber(box.x, 0, 1, 0.2),\n y: this._clampNumber(box.y, 0, 1, 0.2),\n width: this._clampNumber(box.width, 0.05, 1, 0.6),\n height: this._clampNumber(box.height, 0.05, 1, 0.18),\n }\n }\n\n _clampNumber(value, min, max, fallback) {\n const numeric = Number(value)\n if (!Number.isFinite(numeric)) return fallback\n\n return Math.max(min, Math.min(max, numeric))\n }\n\n _supportedTextFontFamily(value) {\n const allowed = ['Inter', 'Arial', 'Helvetica', 'Georgia', 'Times New Roman', 'Courier New', 'Verdana']\n const candidate = typeof value === 'string' ? value.trim() : ''\n\n return allowed.includes(candidate) ? candidate : 'Inter'\n }\n\n _supportedTextColor(value, fallback = '#000000') {\n return typeof value === 'string' && /^#[0-9a-f]{6}$/i.test(value)\n ? value\n : fallback\n }\n\n _textBlendMode(layer) {\n const mode = layer?.blendMode\n return TEXT_BLEND_MODES.includes(mode) ? mode : 'normal'\n }\n\n _textContentForLayer(layer) {\n const content = layer?.text?.content\n return content == null ? '' : String(content)\n }\n\n _textStyleForLayer(layer, scale = 1, wordWrapWidth = 1, options = {}) {\n const style = layer?.text?.style && typeof layer.text.style === 'object'\n ? layer.text.style\n : {}\n const effects = this._textEffectsForLayer(layer)\n const fontSize = this._clampNumber(style.fontSize, 8, 400, 64)\n const lineHeight = this._clampNumber(style.lineHeight, 0.8, 3, 1.2)\n const letterSpacing = this._clampNumber(style.letterSpacing, -100, 100, 0)\n const fontWeight = this._normalizeTextFontWeight(style.fontWeight)\n const fontStyle = ['normal', 'italic'].includes(style.fontStyle) ? style.fontStyle : 'normal'\n const align = ['left', 'center', 'right'].includes(style.align) ? style.align : 'center'\n const fill = options.fill || (typeof style.fill === 'string' && /^#[0-9a-f]{6}$/i.test(style.fill) ? style.fill : '#ffffff')\n const textStyle = {\n fontFamily: this._supportedTextFontFamily(style.fontFamily),\n fontSize: fontSize * scale,\n fontWeight,\n fontStyle,\n fill,\n align,\n lineHeight: fontSize * lineHeight * scale,\n letterSpacing: letterSpacing * scale,\n wordWrap: true,\n wordWrapWidth: Math.max(1, wordWrapWidth),\n breakWords: true,\n }\n\n if (options.stroke !== false && effects.stroke.enabled && effects.stroke.width > 0) {\n textStyle.stroke = {\n color: effects.stroke.color,\n width: effects.stroke.width * scale,\n }\n }\n\n return textStyle\n }\n\n _normalizeTextFontWeight(value) {\n if (value === 'normal') return 400\n if (value === 'bold') return 700\n\n const numeric = Number(value)\n if (!Number.isFinite(numeric)) return 700\n if (numeric < 100 || numeric > 900 || numeric % 100 !== 0) return 700\n\n return numeric\n }\n\n _textEffectsForLayer(layer) {\n const source = layer?.text?.effects && typeof layer.text.effects === 'object'\n ? layer.text.effects\n : {}\n const stroke = source.stroke && typeof source.stroke === 'object' ? source.stroke : {}\n const shadow = source.shadow && typeof source.shadow === 'object' ? source.shadow : {}\n const glow = source.glow && typeof source.glow === 'object' ? source.glow : {}\n const backdrop = source.backdrop && typeof source.backdrop === 'object' ? source.backdrop : {}\n\n return {\n stroke: {\n enabled: stroke.enabled === true,\n color: this._supportedTextColor(stroke.color, DEFAULT_TEXT_EFFECTS.stroke.color),\n width: this._clampNumber(stroke.width, 0, 80, DEFAULT_TEXT_EFFECTS.stroke.width),\n },\n shadow: {\n enabled: shadow.enabled === true,\n color: this._supportedTextColor(shadow.color, DEFAULT_TEXT_EFFECTS.shadow.color),\n alpha: this._clampNumber(shadow.alpha, 0, 1, DEFAULT_TEXT_EFFECTS.shadow.alpha),\n blur: this._clampNumber(shadow.blur, 0, 120, DEFAULT_TEXT_EFFECTS.shadow.blur),\n distance: this._clampNumber(shadow.distance, 0, 200, DEFAULT_TEXT_EFFECTS.shadow.distance),\n angle: this._normalizeDegrees(shadow.angle ?? DEFAULT_TEXT_EFFECTS.shadow.angle),\n },\n glow: {\n enabled: glow.enabled === true,\n color: this._supportedTextColor(glow.color, DEFAULT_TEXT_EFFECTS.glow.color),\n alpha: this._clampNumber(glow.alpha, 0, 1, DEFAULT_TEXT_EFFECTS.glow.alpha),\n blur: this._clampNumber(glow.blur, 0, 120, DEFAULT_TEXT_EFFECTS.glow.blur),\n },\n backdrop: {\n enabled: backdrop.enabled === true,\n color: this._supportedTextColor(backdrop.color, DEFAULT_TEXT_EFFECTS.backdrop.color),\n opacity: this._clampNumber(backdrop.opacity, 0, 1, DEFAULT_TEXT_EFFECTS.backdrop.opacity),\n padding: this._clampNumber(backdrop.padding, 0, 200, DEFAULT_TEXT_EFFECTS.backdrop.padding),\n radius: this._clampNumber(backdrop.radius, 0, 200, DEFAULT_TEXT_EFFECTS.backdrop.radius),\n blur: this._clampNumber(backdrop.blur, 0, 80, DEFAULT_TEXT_EFFECTS.backdrop.blur),\n },\n }\n }\n\n _createTextBlurFilter(PIXI, amount) {\n if (amount <= 0 || typeof PIXI?.BlurFilter !== 'function') return null\n\n try {\n let filter\n try {\n filter = new PIXI.BlurFilter({ strength: amount, quality: 4 })\n } catch (_e) {\n filter = new PIXI.BlurFilter(amount)\n }\n\n if (typeof filter.blur === 'number') filter.blur = amount\n if (typeof filter.strength === 'number') filter.strength = amount\n filter.padding = Math.max(Number(filter.padding) || 0, Math.ceil(amount * 2))\n\n return filter\n } catch (_e) {\n return null\n }\n }\n\n _textEffectPadding(effects, scale) {\n const stroke = effects.stroke.enabled ? effects.stroke.width * scale : 0\n const shadow = effects.shadow.enabled\n ? (effects.shadow.distance + effects.shadow.blur * 2) * scale\n : 0\n const glow = effects.glow.enabled ? effects.glow.blur * 2 * scale : 0\n const backdrop = effects.backdrop.enabled\n ? (effects.backdrop.padding + effects.backdrop.blur * 2) * scale\n : 0\n\n return Math.ceil(Math.max(stroke, shadow, glow, backdrop, 0))\n }\n\n _createTextDisplayObjectForLayer(PIXI, layer) {\n if (!this._isTextLayer(layer) || typeof PIXI?.Text !== 'function') return null\n\n const textObject = this._createTextPrimitive(PIXI, layer)\n if (!textObject) return null\n\n if (typeof PIXI.Container !== 'function' || typeof PIXI.Graphics !== 'function') {\n return textObject\n }\n\n const container = new PIXI.Container()\n const mask = new PIXI.Graphics()\n const effectMask = new PIXI.Graphics()\n const backdrop = new PIXI.Graphics()\n const shadow = this._createTextPrimitive(PIXI, layer)\n const glow = this._createTextPrimitive(PIXI, layer)\n container.__isTextLayerContainer = true\n container.__textObject = textObject\n container.__textMask = mask\n container.__textEffectMask = effectMask\n container.__textBackdrop = backdrop\n container.__textShadow = shadow\n container.__textGlow = glow\n backdrop.visible = false\n if (shadow) shadow.visible = false\n if (glow) glow.visible = false\n textObject.mask = mask\n container.addChild(backdrop)\n if (shadow) container.addChild(shadow)\n if (glow) container.addChild(glow)\n container.addChild(textObject)\n container.addChild(effectMask)\n container.addChild(mask)\n\n return container\n }\n\n _createTextPrimitive(PIXI, layer) {\n try {\n return new PIXI.Text({\n text: this._textContentForLayer(layer),\n style: this._textStyleForLayer(layer),\n })\n } catch (_e) {\n try {\n return new PIXI.Text(this._textContentForLayer(layer), this._textStyleForLayer(layer))\n } catch (_ignored) {\n return null\n }\n }\n }\n\n async _createSubjectDisplayObjectForLayer(PIXI, layer) {\n const sourceUrl = this._sourceUrlForLayerSource(layer?.source)\n if (!sourceUrl || sourceUrl === this._loadedTextureUrl) return null\n\n return this._createImageDisplayObjectForLayer(PIXI, layer)\n }\n\n async _createImageDisplayObjectForLayer(PIXI, layer) {\n if (layer?.type !== 'image') return null\n\n const texture = await this._textureForLayerSource(PIXI, layer.source)\n if (!texture || typeof PIXI.Sprite !== 'function') return null\n\n const displayObject = new PIXI.Sprite(texture)\n displayObject.__sourceWidth = Number(layer.source?.originalWidth) || texture.width || 1\n displayObject.__sourceHeight = Number(layer.source?.originalHeight) || texture.height || 1\n this._applyLayerEffects(PIXI, displayObject, layer)\n this._applyLayerFilterInstances(displayObject, layer)\n\n return displayObject\n }\n\n _backgroundFillForLayer(layer) {\n const fill = layer?.fill\n if (fill && typeof fill === 'object') return fill\n\n const source = layer?.source\n if (source?.kind === 'color' && typeof source.color === 'string') {\n return { kind: 'color', value: source.color }\n }\n\n return null\n }\n\n _backgroundColorForLayer(layer) {\n const source = layer?.source\n if (source?.kind === 'color' && typeof source.color === 'string') {\n return source.color\n }\n\n const fill = layer?.fill\n if (fill?.kind === 'color' && typeof fill.value === 'string') {\n return fill.value\n }\n\n return null\n }\n\n _sourceUrlForLayerSource(source) {\n if (!source || typeof source !== 'object') return null\n\n for (const key of ['previewUrl', 'sourceUrl', 'url']) {\n const value = source[key]\n if (typeof value === 'string' && value.trim() !== '') {\n return value\n }\n }\n\n return null\n }\n\n async _textureForLayerSource(PIXI, source) {\n const url = this._sourceUrlForLayerSource(source)\n if (!url) return null\n\n const image = await this._loadImageElement(url)\n if (!image) return null\n\n return PIXI.Texture.from(image)\n }\n\n _createBackgroundSprite(PIXI, texture, fit = 'cover') {\n if (fit === 'tile' && typeof PIXI.TilingSprite === 'function') {\n try {\n const tiled = new PIXI.TilingSprite({ texture, width: 1, height: 1 })\n tiled.__isTilingBackground = true\n\n return tiled\n } catch (_e) {\n try {\n const tiled = new PIXI.TilingSprite(texture, 1, 1)\n tiled.__isTilingBackground = true\n\n return tiled\n } catch (_ignored) {\n // Fall through to a normal sprite if this PIXI build has a\n // different TilingSprite constructor signature.\n }\n }\n }\n\n return new PIXI.Sprite(texture)\n }\n\n _createGradientTexture(PIXI, fill, width, height) {\n if (typeof document === 'undefined' || !PIXI?.Texture?.from) return null\n\n const canvas = document.createElement('canvas')\n canvas.width = Math.max(1, Math.round(width))\n canvas.height = Math.max(1, Math.round(height))\n const context = canvas.getContext('2d')\n if (!context) return null\n\n const stops = Array.isArray(fill?.stops) && fill.stops.length > 0\n ? fill.stops\n : [\n { offset: 0, color: '#111827' },\n { offset: 1, color: '#f59e0b' },\n ]\n\n let gradient\n if (fill?.gradientType === 'radial') {\n const radius = Math.max(canvas.width, canvas.height) / 2\n gradient = context.createRadialGradient(\n canvas.width / 2,\n canvas.height / 2,\n 0,\n canvas.width / 2,\n canvas.height / 2,\n radius\n )\n } else {\n const radians = (Number(fill?.angle) || 0) * Math.PI / 180\n const centerX = canvas.width / 2\n const centerY = canvas.height / 2\n const length = Math.sqrt(canvas.width ** 2 + canvas.height ** 2) / 2\n const dx = Math.cos(radians) * length\n const dy = Math.sin(radians) * length\n gradient = context.createLinearGradient(centerX - dx, centerY - dy, centerX + dx, centerY + dy)\n }\n\n for (const stop of stops) {\n if (!stop || typeof stop.color !== 'string') continue\n const offset = Number.isFinite(Number(stop.offset)) ? Math.max(0, Math.min(1, Number(stop.offset))) : 0\n gradient.addColorStop(offset, stop.color)\n }\n\n context.fillStyle = gradient\n context.fillRect(0, 0, canvas.width, canvas.height)\n\n return PIXI.Texture.from(canvas)\n }\n\n _backgroundBlurAmount(layer) {\n const effects = Array.isArray(layer?.effects) ? layer.effects : []\n const effect = effects.find(candidate => candidate?.id === 'background-blur' || candidate?.type === 'blur')\n const amount = Number(effect?.params?.amount)\n\n return Number.isFinite(amount) ? Math.max(0, amount) : 0\n }\n\n _applyLayerEffects(PIXI, displayObject, layer) {\n const blur = this._backgroundBlurAmount(layer)\n if (blur <= 0 || typeof PIXI?.BlurFilter !== 'function') return\n\n try {\n let filter\n try {\n filter = new PIXI.BlurFilter({ strength: blur, quality: 4 })\n } catch (_e) {\n filter = new PIXI.BlurFilter(blur)\n }\n\n if (typeof filter.blur === 'number') filter.blur = blur\n if (typeof filter.strength === 'number') filter.strength = blur\n filter.padding = Math.max(Number(filter.padding) || 0, Math.ceil(blur * 2))\n displayObject.filters = Array.isArray(displayObject.filters)\n ? [...displayObject.filters, filter]\n : [filter]\n } catch (_e) {\n // Older PIXI bundles may omit BlurFilter. Background blur is optional\n // at render time and remains persisted in the layer document.\n }\n }\n\n _syncLayerDisplayObjects() {\n if (!this.sprite) return\n\n for (const { layer, displayObject } of this._layerDisplayObjects.values()) {\n this._syncLayerDisplayObject(layer, displayObject)\n }\n }\n\n _syncLayerDisplayObject(layer, displayObject) {\n if (!this.sprite || !displayObject) return\n\n if (this._isTextLayer(layer)) {\n this._fitTextDisplayObjectToRect(displayObject, layer, {\n x: this.sprite.x,\n y: this.sprite.y,\n width: this.sprite.width,\n height: this.sprite.height,\n })\n return\n }\n\n const backgroundColor = this._backgroundColorForLayer(layer)\n if (backgroundColor && typeof displayObject.clear === 'function') {\n displayObject.clear()\n displayObject\n .rect(this.sprite.x, this.sprite.y, this.sprite.width, this.sprite.height)\n .fill(backgroundColor)\n return\n }\n\n this._fitDisplayObjectToRect(displayObject, layer, {\n x: this.sprite.x,\n y: this.sprite.y,\n width: this.sprite.width,\n height: this.sprite.height,\n })\n }\n\n _fillTextEffectGraphics(graphics, color, alpha = 1) {\n if (!graphics || typeof graphics.fill !== 'function') return\n\n try {\n graphics.fill({ color, alpha })\n } catch (_e) {\n graphics.fill(color)\n graphics.alpha = alpha\n }\n }\n\n _syncTextEffectPrimitive(PIXI, primitive, layer, effects, kind, scale, width, effectMask) {\n if (!primitive) return\n\n const effect = effects[kind]\n primitive.visible = effect?.enabled === true\n primitive.filters = null\n primitive.mask = primitive.visible ? effectMask : null\n\n if (!primitive.visible) return\n\n primitive.text = this._textContentForLayer(layer)\n primitive.rotation = 0\n\n if (kind === 'shadow') {\n const radians = effect.angle * Math.PI / 180\n primitive.x = Math.cos(radians) * effect.distance * scale\n primitive.y = Math.sin(radians) * effect.distance * scale\n primitive.alpha = effect.alpha\n primitive.style = this._textStyleForLayer(layer, scale, width, {\n fill: effect.color,\n stroke: false,\n })\n const filter = this._createTextBlurFilter(PIXI, effect.blur * scale)\n primitive.filters = filter ? [filter] : null\n return\n }\n\n if (kind === 'glow') {\n primitive.x = 0\n primitive.y = 0\n primitive.alpha = effect.alpha\n primitive.style = this._textStyleForLayer(layer, scale, width, {\n fill: effect.color,\n stroke: false,\n })\n const filter = this._createTextBlurFilter(PIXI, effect.blur * scale)\n primitive.filters = filter ? [filter] : null\n }\n }\n\n _syncTextBackdrop(PIXI, backdrop, effects, scale, width, height, effectMask) {\n if (!backdrop) return\n\n const effect = effects.backdrop\n backdrop.visible = effect.enabled === true\n backdrop.filters = null\n backdrop.mask = backdrop.visible ? effectMask : null\n backdrop.alpha = 1\n\n if (typeof backdrop.clear === 'function') backdrop.clear()\n if (!backdrop.visible) return\n\n const padding = effect.padding * scale\n const radius = effect.radius * scale\n const x = -padding\n const y = -padding\n const backdropWidth = width + padding * 2\n const backdropHeight = height + padding * 2\n\n if (radius > 0 && typeof backdrop.roundRect === 'function') {\n backdrop.roundRect(x, y, backdropWidth, backdropHeight, radius)\n } else if (typeof backdrop.rect === 'function') {\n backdrop.rect(x, y, backdropWidth, backdropHeight)\n }\n this._fillTextEffectGraphics(backdrop, effect.color, effect.opacity)\n\n const filter = this._createTextBlurFilter(PIXI, effect.blur * scale)\n backdrop.filters = filter ? [filter] : null\n }\n\n _fitTextDisplayObjectToRect(displayObject, layer, rect) {\n const box = this._normalizeTextBox(layer)\n const x = rect.x + box.x * rect.width\n const y = rect.y + box.y * rect.height\n const width = box.width * rect.width\n const height = box.height * rect.height\n const sourceWidth = Number(this.originalTexture?.width) || rect.width\n const scale = sourceWidth > 0 ? rect.width / sourceWidth : 1\n const effects = this._textEffectsForLayer(layer)\n\n displayObject.x = x\n displayObject.y = y\n displayObject.rotation = this._normalizeDegrees(Number(layer?.transform?.rotation) || 0) * Math.PI / 180\n displayObject.blendMode = this._textBlendMode(layer)\n displayObject.__textBox = box\n displayObject.__textLayout = { x, y, width, height, scale }\n\n const textObject = displayObject.__textObject || displayObject\n const mask = displayObject.__textMask || null\n const effectMask = displayObject.__textEffectMask || null\n textObject.text = this._textContentForLayer(layer)\n textObject.style = this._textStyleForLayer(layer, scale, width)\n textObject.x = 0\n textObject.y = 0\n textObject.rotation = 0\n\n if (mask && typeof mask.clear === 'function' && typeof mask.rect === 'function' && typeof mask.fill === 'function') {\n mask.clear()\n mask.rect(0, 0, width, height).fill(0xffffff)\n textObject.mask = mask\n }\n\n if (effectMask && typeof effectMask.clear === 'function' && typeof effectMask.rect === 'function' && typeof effectMask.fill === 'function') {\n const padding = this._textEffectPadding(effects, scale)\n effectMask.clear()\n effectMask.rect(-padding, -padding, width + padding * 2, height + padding * 2).fill(0xffffff)\n }\n\n this._syncTextBackdrop(window.PIXI, displayObject.__textBackdrop, effects, scale, width, height, effectMask)\n this._syncTextEffectPrimitive(window.PIXI, displayObject.__textShadow, layer, effects, 'shadow', scale, width, effectMask)\n this._syncTextEffectPrimitive(window.PIXI, displayObject.__textGlow, layer, effects, 'glow', scale, width, effectMask)\n }\n\n _fitDisplayObjectToRect(displayObject, layer, rect) {\n const fill = this._backgroundFillForLayer(layer)\n const fit = fill?.fit || 'cover'\n\n if (displayObject.__isTilingBackground) {\n displayObject.x = rect.x\n displayObject.y = rect.y\n displayObject.width = rect.width\n displayObject.height = rect.height\n displayObject.tilePosition?.set?.(0, 0)\n displayObject.tileScale?.set?.(1, 1)\n return\n }\n\n if (fit === 'stretch' || fill?.kind === 'gradient' || fill?.kind === 'color') {\n displayObject.x = rect.x\n displayObject.y = rect.y\n displayObject.width = rect.width\n displayObject.height = rect.height\n return\n }\n\n const sourceWidth = Number(displayObject.__sourceWidth || fill?.source?.originalWidth || displayObject.texture?.width || rect.width)\n const sourceHeight = Number(displayObject.__sourceHeight || fill?.source?.originalHeight || displayObject.texture?.height || rect.height)\n if (!Number.isFinite(sourceWidth) || !Number.isFinite(sourceHeight) || sourceWidth <= 0 || sourceHeight <= 0) {\n displayObject.x = rect.x\n displayObject.y = rect.y\n displayObject.width = rect.width\n displayObject.height = rect.height\n return\n }\n\n const scale = fit === 'contain'\n ? Math.min(rect.width / sourceWidth, rect.height / sourceHeight)\n : Math.max(rect.width / sourceWidth, rect.height / sourceHeight)\n const width = sourceWidth * scale\n const height = sourceHeight * scale\n\n displayObject.x = rect.x + (rect.width - width) / 2\n displayObject.y = rect.y + (rect.height - height) / 2\n displayObject.width = width\n displayObject.height = height\n }\n\n _destroyLayerDisplayObjects() {\n if (!this._layerDisplayObjects?.size) {\n return\n }\n\n for (const { displayObject } of this._layerDisplayObjects.values()) {\n try {\n this.app?.stage?.removeChild?.(displayObject)\n } catch (_e) {\n // Ignore stale PIXI parent references during reload.\n }\n const ownsTexture = displayObject?.__ownsTexture === true\n displayObject?.destroy?.({ children: true, texture: ownsTexture, textureSource: ownsTexture })\n }\n\n this._layerDisplayObjects.clear()\n this._renderableLayerIds = []\n }\n\n _destroyTransientDisplayObject(displayObject) {\n if (!displayObject) return\n\n try {\n this.app?.stage?.removeChild?.(displayObject)\n } catch (_e) {\n // Ignore stale PIXI parent references during render races.\n }\n\n const ownsTexture = displayObject?.__ownsTexture === true\n displayObject?.destroy?.({ children: true, texture: ownsTexture, textureSource: ownsTexture })\n }\n\n /**\n * Normalize degrees to the 0..360 range.\n * @param {number} degrees\n * @returns {number}\n */\n _normalizeDegrees(degrees) {\n if (!Number.isFinite(degrees)) return 0\n const normalized = degrees % 360\n return normalized < 0 ? normalized + 360 : normalized\n }\n\n /**\n * Calculate the axis-aligned bounds for a rotated rectangle.\n * @param {number} width\n * @param {number} height\n * @param {number} degrees\n * @returns {{ width: number, height: number }}\n */\n getRotatedBounds(width, height, degrees) {\n const rotation = this._normalizeDegrees(degrees)\n if (rotation === 0) {\n return {\n width: Math.max(1, Math.round(width)),\n height: Math.max(1, Math.round(height)),\n }\n }\n\n const radians = rotation * Math.PI / 180\n const rawCos = Math.abs(Math.cos(radians))\n const rawSin = Math.abs(Math.sin(radians))\n const cos = rawCos < 1e-10 ? 0 : rawCos\n const sin = rawSin < 1e-10 ? 0 : rawSin\n\n return {\n width: Math.max(1, Math.ceil(width * cos + height * sin)),\n height: Math.max(1, Math.ceil(width * sin + height * cos)),\n }\n }\n\n /**\n * Permanently rotate the working texture. This keeps crop math simple:\n * after rotation, sprite coordinates and texture dimensions both describe\n * the visible image exactly.\n *\n * @param {number} degrees Clockwise degrees to add to the working texture.\n * @returns {boolean}\n */\n rotateBy(degrees) {\n const rotation = this._normalizeDegrees(degrees)\n if (rotation === 0) return true\n\n if (!this.app?.renderer || !this.originalTexture || !this.sprite) {\n return false\n }\n\n const PIXI = window.PIXI\n const srcW = Math.round(this.originalTexture.width)\n const srcH = Math.round(this.originalTexture.height)\n if (srcW <= 0 || srcH <= 0) return false\n\n const { width: outW, height: outH } = this.getRotatedBounds(srcW, srcH, rotation)\n const radians = rotation * Math.PI / 180\n\n const container = new PIXI.Container()\n const src = new PIXI.Sprite(this.originalTexture)\n src.anchor?.set?.(0.5)\n src.x = outW / 2\n src.y = outH / 2\n src.rotation = radians\n container.addChild(src)\n\n const rt = PIXI.RenderTexture.create({ width: outW, height: outH, resolution: 1 })\n\n try {\n this.app.renderer.render({\n container,\n target: rt,\n clear: true,\n clearColor: [0, 0, 0, 0],\n })\n } catch (e) {\n console.error('[PixiRenderer.rotateBy] Rotation render failed:', e)\n rt.destroy(true)\n return false\n } finally {\n container.removeChildren()\n src.destroy({ children: false, texture: false, textureSource: false })\n container.destroy({ children: false })\n }\n\n const prevTexture = this.originalTexture\n const previousFilters = Array.isArray(this.sprite.filters)\n ? [...this.sprite.filters]\n : null\n\n if (prevTexture && prevTexture !== this.baseTexture) {\n prevTexture.destroy(true)\n }\n\n this.originalTexture = rt\n this._lastExportDimensions = null\n\n this.app.stage.removeChild(this.sprite)\n this.sprite.destroy({ children: false, texture: false, textureSource: false })\n\n const newSprite = new PIXI.Sprite(rt)\n if (previousFilters?.length) {\n newSprite.filters = previousFilters\n }\n this.app.stage.addChild(newSprite)\n this.sprite = newSprite\n\n this.fitScale = this.getFitScaleFor(rt)\n this.zoom = 1\n this.applyViewTransform({ keepCenter: false })\n this.render()\n this.emit('textureRotated', { width: outW, height: outH, degrees: rotation })\n\n return true\n }\n\n /**\n * Export the current image with filters applied.\n *\n * @param {string} format - 'png' or 'jpeg'\n * @param {number} quality - Quality for jpeg (0-1)\n * @param {number} maxEdge - Maximum edge size in pixels (0 for original)\n * @param {boolean} dontUpscale - Don't upscale smaller images\n * @param {number} [maxPixels=0] - Max total pixel count (width*height). 0 disables.\n * Backend API often limits payload size (blowglass caps at 8M pixels); set this\n * to keep the export under that cap while preserving aspect ratio.\n * @returns {string|null} Data URL\n */\n exportImage(format = 'png', quality = 0.92, maxEdge = 0, dontUpscale = true, maxPixels = 0) {\n if (!this.app?.renderer || !this.originalTexture || !this.sprite) {\n console.error('[PixiRenderer.exportImage] Missing app/renderer, texture, or sprite', {\n hasApp: !!this.app,\n hasRenderer: !!this.app?.renderer,\n hasTexture: !!this.originalTexture,\n hasSprite: !!this.sprite\n })\n return null\n }\n\n const PIXI = window.PIXI\n const srcW = Math.round(this.originalTexture.width)\n const srcH = Math.round(this.originalTexture.height)\n\n if (srcW <= 0 || srcH <= 0) {\n console.error('[PixiRenderer.exportImage] Invalid texture dimensions', { srcW, srcH })\n return null\n }\n\n const previewW = this.sprite.width\n const previewH = this.sprite.height\n\n if (previewW <= 0 || previewH <= 0) {\n console.error('[PixiRenderer.exportImage] Sprite has zero dimensions')\n return null\n }\n\n // Filter parameters (blur, distance, outline thickness, etc.) are in\n // render-target pixel units. The user tunes them while looking at the\n // preview, where the image is downscaled to fit the viewport. To make\n // the export visually match the preview at native resolution, scale\n // those size-dependent params by (preview pixels) / (source pixels).\n //\n // Filters opt in by exposing a createExportFilter({previewToNativeScale})\n // method that returns a fresh, scaled instance. Filters that don't have\n // size-dependent params (color-matrix, alpha, hue) just pass through.\n const previewSourceScale = previewW / srcW // e.g. 0.186\n const previewToNativeScale = previewSourceScale > 0\n ? 1 / previewSourceScale // e.g. 5.37\n : 1\n\n const layerDocumentForExport = this._layerDocument\n const hasLayerDocumentForExport = layerDocumentForExport && Array.isArray(layerDocumentForExport.layers)\n\n const exportFilters = []\n if (!hasLayerDocumentForExport && Array.isArray(this.sprite.filters)) {\n for (const f of this.sprite.filters) {\n if (!f) continue\n if (typeof f.createExportFilter === 'function') {\n const cloned = f.createExportFilter({ previewToNativeScale })\n if (cloned) exportFilters.push(cloned)\n } else {\n // Filter doesn't need scaling — reuse the live instance.\n exportFilters.push(f)\n }\n }\n }\n\n // PIXI's filter pipeline SUMS the padding of each filter in a chain\n // (each filter's framebuffer must contain the previous filter's bleed).\n // Use sum, not max, to size the render target margin.\n let totalPadding = 0\n for (const f of exportFilters) {\n const p = typeof f.getExportPadding === 'function'\n ? Number(f.getExportPadding()) || 0\n : (typeof f._exportPadding === 'number'\n ? f._exportPadding\n : (typeof f.padding === 'number' ? f.padding : 0))\n if (p > 0) totalPadding += p\n }\n // Floor at 64px so small/default filters with no reported padding still\n // have room to bleed. Doubling on retry covers anything bigger.\n const initialMargin = Math.max(Math.ceil(totalPadding), 64)\n\n // Render an isolated export-only container. We DON'T render app.stage —\n // it carries preview transforms, the editor's viewport, and possibly\n // crop overlays. Building a clean container with a fresh sprite using\n // the SAME originalTexture (no copy) gives us deterministic coordinates\n // and lets us scale + filter without mutating the live preview sprite.\n const renderWithMargin = (margin) => {\n const renderW = Math.ceil(srcW + 2 * margin)\n const renderH = Math.ceil(srcH + 2 * margin)\n\n const exportRoot = new PIXI.Container()\n const exportSprites = []\n\n const addSubjectSprite = (layer = null) => {\n const exportSprite = new PIXI.Sprite(this.originalTexture)\n exportSprite.x = margin\n exportSprite.y = margin\n exportSprite.scale.set(1, 1)\n exportSprite.alpha = layer ? this._layerOpacity(layer) : 1\n if (layer) {\n this._applyLayerFilterInstances(exportSprite, layer, {\n forExport: true,\n previewToNativeScale,\n sourceWidth: srcW,\n sourceHeight: srcH,\n })\n }\n\n if (exportFilters.length > 0) {\n exportSprite.filters = exportFilters\n // Force PIXI's filter measurement to use the sprite's local geometry\n // bounds (0,0,srcW,srcH). Without this, PIXI computes filter area\n // from the global render-target rectangle, which can clip on certain\n // configs.\n exportSprite.filterArea = new PIXI.Rectangle(0, 0, srcW, srcH)\n }\n\n exportRoot.addChild(exportSprite)\n exportSprites.push(exportSprite)\n }\n\n const addImageLayer = (layer) => {\n const liveDisplayObject = this._layerDisplayObjects.get(layer.id)?.displayObject\n const texture = liveDisplayObject?.texture || (this._isSubjectLayer(layer) ? this.originalTexture : null)\n if (!texture || typeof PIXI.Sprite !== 'function') return false\n\n const exportSprite = new PIXI.Sprite(texture)\n exportSprite.__sourceWidth = Number(layer.source?.originalWidth || liveDisplayObject?.__sourceWidth || texture.width || srcW)\n exportSprite.__sourceHeight = Number(layer.source?.originalHeight || liveDisplayObject?.__sourceHeight || texture.height || srcH)\n this._fitDisplayObjectToRect(exportSprite, layer, { x: margin, y: margin, width: srcW, height: srcH })\n exportSprite.alpha = this._layerOpacity(layer)\n\n if (!hasLayerDocumentForExport && this._isSubjectLayer(layer) && exportFilters.length > 0) {\n exportSprite.filters = exportFilters\n exportSprite.filterArea = new PIXI.Rectangle(0, 0, srcW, srcH)\n }\n\n this._applyLayerEffects(PIXI, exportSprite, layer)\n this._applyLayerFilterInstances(exportSprite, layer, {\n forExport: true,\n previewToNativeScale,\n sourceWidth: srcW,\n sourceHeight: srcH,\n })\n exportRoot.addChild(exportSprite)\n exportSprites.push(exportSprite)\n\n return true\n }\n\n const addBackgroundLayer = (layer) => {\n const fill = this._backgroundFillForLayer(layer)\n const backgroundColor = this._backgroundColorForLayer(layer)\n const rect = { x: margin, y: margin, width: srcW, height: srcH }\n let background = null\n\n if (backgroundColor && typeof PIXI.Graphics === 'function') {\n background = new PIXI.Graphics()\n background.rect(margin, margin, srcW, srcH).fill(backgroundColor)\n } else if (fill?.kind === 'gradient' && typeof PIXI.Sprite === 'function') {\n const texture = this._createGradientTexture(PIXI, fill, srcW, srcH)\n if (!texture) return false\n background = new PIXI.Sprite(texture)\n background.__ownsTexture = true\n background.__sourceWidth = srcW\n background.__sourceHeight = srcH\n this._fitDisplayObjectToRect(background, layer, rect)\n } else if (fill?.kind === 'media') {\n const liveDisplayObject = this._layerDisplayObjects.get(layer.id)?.displayObject\n const texture = liveDisplayObject?.texture\n if (!texture) return false\n\n background = this._createBackgroundSprite(PIXI, texture, fill.fit)\n background.__sourceWidth = Number(fill.source?.originalWidth || liveDisplayObject.__sourceWidth || texture.width || 1)\n background.__sourceHeight = Number(fill.source?.originalHeight || liveDisplayObject.__sourceHeight || texture.height || 1)\n this._fitDisplayObjectToRect(background, layer, rect)\n }\n\n if (!background) return false\n\n background.alpha = this._layerOpacity(layer)\n this._applyLayerEffects(PIXI, background, layer)\n this._applyLayerFilterInstances(background, layer, {\n forExport: true,\n previewToNativeScale,\n sourceWidth: srcW,\n sourceHeight: srcH,\n })\n exportRoot.addChild(background)\n exportSprites.push(background)\n\n return true\n }\n\n const addTextLayer = (layer) => {\n const textDisplayObject = this._createTextDisplayObjectForLayer(PIXI, layer)\n if (!textDisplayObject) return false\n\n this._fitTextDisplayObjectToRect(textDisplayObject, layer, { x: margin, y: margin, width: srcW, height: srcH })\n textDisplayObject.alpha = this._layerOpacity(layer)\n exportRoot.addChild(textDisplayObject)\n exportSprites.push(textDisplayObject)\n\n return true\n }\n\n const layerDocument = layerDocumentForExport\n const hasLayerDocument = hasLayerDocumentForExport\n if (hasLayerDocument) {\n for (const layer of layerDocument.layers) {\n if (!layer || layer.visible === false) continue\n\n if (this._isTextLayer(layer)) {\n addTextLayer(layer)\n continue\n }\n\n if (layer.type === 'image') {\n if (!addImageLayer(layer) && this._isSubjectLayer(layer)) {\n addSubjectSprite(layer)\n }\n continue\n }\n\n if (this._isSubjectLayer(layer)) {\n if (!addImageLayer(layer)) addSubjectSprite(layer)\n continue\n }\n\n addBackgroundLayer(layer)\n }\n } else {\n addSubjectSprite()\n }\n\n if (!hasLayerDocument && exportRoot.children?.length === 0) {\n addSubjectSprite()\n }\n\n const rt = PIXI.RenderTexture.create({\n width: renderW,\n height: renderH,\n resolution: 1,\n })\n const childCount = exportRoot.children?.length ?? 0\n\n try {\n this.app.renderer.render({\n container: exportRoot,\n target: rt,\n clear: true,\n clearColor: [0, 0, 0, 0],\n })\n const canvas = this.app.renderer.extract?.canvas?.(rt)\n if (!canvas) return null\n return { canvas, width: renderW, height: renderH, margin, childCount }\n } finally {\n // Filter instances are owned by exportFilters; don't destroy them\n // here (some are clones we'll discard, others are shared with\n // preview). Destroy the temp sprite/container/rt only.\n for (const exportSprite of exportSprites) {\n exportSprite.filters = null\n }\n exportRoot.removeChildren()\n for (const exportSprite of exportSprites) {\n const ownsTexture = exportSprite?.__ownsTexture === true\n exportSprite.destroy({ children: false, texture: ownsTexture, textureSource: ownsTexture })\n }\n exportRoot.destroy({ children: false })\n rt.destroy(true)\n }\n }\n\n // Scan the alpha channel for the non-transparent bounding box. Returns\n // {x, y, width, height, touchesEdge} where touchesEdge indicates the\n // bbox reaches the outer boundary of the canvas (i.e. we probably\n // clipped bleed and should re-render with a bigger margin).\n const scanAlphaBounds = (canvas, w, h) => {\n const ctx = typeof canvas.getContext === 'function' ? canvas.getContext('2d') : null\n if (!ctx) return null\n let pixels\n try {\n pixels = ctx.getImageData(0, 0, w, h).data\n } catch (e) {\n console.error('[PixiRenderer.exportImage] getImageData failed:', e)\n return null\n }\n const threshold = 1 // ignore alpha noise from dithering/interpolation\n let minX = w, minY = h, maxX = -1, maxY = -1\n const stride = 4\n const rowStride = w * stride\n for (let y = 0; y < h; y++) {\n const rowStart = y * rowStride\n for (let x = 0; x < w; x++) {\n if (pixels[rowStart + x * stride + 3] >= threshold) {\n if (x < minX) minX = x\n if (x > maxX) maxX = x\n if (y < minY) minY = y\n if (y > maxY) maxY = y\n }\n }\n }\n if (maxX < 0) return null // fully transparent\n const width = maxX - minX + 1\n const height = maxY - minY + 1\n const touchesEdge = minX === 0 || minY === 0 || maxX === w - 1 || maxY === h - 1\n return { x: minX, y: minY, width, height, touchesEdge }\n }\n\n let result = null\n try {\n let rendered = renderWithMargin(initialMargin)\n if (!rendered) {\n console.error('[PixiRenderer.exportImage] Initial render failed')\n return null\n }\n\n let bounds = scanAlphaBounds(rendered.canvas, rendered.width, rendered.height)\n if (!bounds) {\n if (hasLayerDocumentForExport && rendered.childCount === 0) {\n bounds = {\n x: rendered.margin,\n y: rendered.margin,\n width: srcW,\n height: srcH,\n touchesEdge: false,\n }\n } else {\n console.warn('[PixiRenderer.exportImage] No non-transparent content to export')\n return null\n }\n }\n\n // If the bbox reached an edge, a filter bled further than we planned.\n // Grow the margin and retry once (double is enough for any sane filter;\n // more than that and we'd hit the pixel budget anyway).\n if (bounds.touchesEdge && initialMargin < srcW && initialMargin < srcH) {\n const retryMargin = Math.max(initialMargin * 4, 256)\n const retried = renderWithMargin(retryMargin)\n if (retried) {\n const retriedBounds = scanAlphaBounds(retried.canvas, retried.width, retried.height)\n if (retriedBounds && !retriedBounds.touchesEdge) {\n rendered = retried\n bounds = retriedBounds\n } else {\n // Second attempt still clipped — accept the larger result even if\n // still touching the edge. Better than losing the first pass.\n rendered = retried\n bounds = retriedBounds ?? bounds\n }\n }\n }\n\n // Apply maxEdge / maxPixels to the trimmed bbox.\n let outW = bounds.width\n let outH = bounds.height\n if (maxEdge > 0) {\n const edge = Math.max(outW, outH)\n let s = maxEdge / edge\n if (dontUpscale) s = Math.min(1, s)\n outW = Math.max(1, Math.round(outW * s))\n outH = Math.max(1, Math.round(outH * s))\n }\n if (maxPixels > 0 && outW * outH > maxPixels) {\n const s = Math.sqrt(maxPixels / (outW * outH))\n outW = Math.max(1, Math.floor(outW * s))\n outH = Math.max(1, Math.floor(outH * s))\n }\n\n // Copy the bbox region from the large canvas onto a correctly-sized\n // output canvas, scaling if the cap forced a downscale.\n const outCanvas = document.createElement('canvas')\n outCanvas.width = outW\n outCanvas.height = outH\n const outCtx = outCanvas.getContext('2d')\n if (!outCtx) {\n console.error('[PixiRenderer.exportImage] Failed to get 2d context for output canvas')\n return null\n }\n outCtx.drawImage(\n rendered.canvas,\n bounds.x, bounds.y, bounds.width, bounds.height,\n 0, 0, outW, outH\n )\n\n result = outCanvas.toDataURL(`image/${format}`, quality)\n\n // Record the post-trim export dimensions so getExportDimensions()\n // returns what was actually saved (including or excluding bleed).\n this._lastExportDimensions = { width: outW, height: outH }\n\n return result || null\n } catch (e) {\n console.error('[PixiRenderer.exportImage] Export failed:', e)\n return null\n }\n // No live sprite mutation — export uses an isolated container/sprite\n // that's destroyed inside renderWithMargin's own finally block.\n }\n\n /**\n * Get the actual export dimensions at the current filter state.\n *\n * When an export has been performed, returns the exact trimmed dimensions\n * from that export. Otherwise falls back to source texture size plus a\n * rough filter-padding estimate — the real dimensions are only known for\n * certain after exportImage() runs the bbox scan.\n *\n * @returns {{ width: number, height: number }}\n */\n getExportDimensions() {\n if (this._lastExportDimensions) {\n return { ...this._lastExportDimensions }\n }\n\n const tex = this.originalTexture\n const w = Math.round(tex?.width || 0)\n const h = Math.round(tex?.height || 0)\n\n let padding = 0\n const filters = this.sprite?.filters\n if (Array.isArray(filters)) {\n for (const f of filters) {\n if (!f) continue\n const p = typeof f._exportPadding === 'number'\n ? f._exportPadding\n : (typeof f.padding === 'number' ? f.padding : 0)\n if (p > padding) padding = p\n }\n }\n\n return {\n width: w + 2 * padding,\n height: h + 2 * padding,\n }\n }\n\n /**\n * Export the current image as a Blob with correct dimensions.\n * @param {string} format - 'png' or 'jpeg'\n * @param {number} quality - Quality for jpeg (0-1)\n * @param {{ maxPixels?: number, maxEdge?: number, dontUpscale?: boolean }} [options]\n * @returns {Promise<{ blob: Blob, width: number, height: number } | null>}\n */\n async exportBlob(format = 'png', quality = 0.92, options = {}) {\n const dataUrl = this.exportImage(\n format,\n quality,\n options.maxEdge ?? 0,\n options.dontUpscale !== false,\n options.maxPixels ?? 0\n )\n if (!dataUrl) return null\n\n const response = await fetch(dataUrl)\n const blob = await response.blob()\n const dims = this.getExportDimensions()\n\n return { blob, width: dims.width, height: dims.height }\n }\n\n /**\n * Resize renderer to container\n * @param {HTMLElement} container\n */\n resizeTo(container) {\n if (!this.app?.renderer || !container) return\n\n const w = container.clientWidth\n const h = container.clientHeight\n\n // Skip if dimensions haven't changed (prevents ResizeObserver loop)\n if (w === Math.round(this.app.screen.width) && h === Math.round(this.app.screen.height)) return\n // Skip zero-size containers (modal not yet laid out)\n if (w <= 0 || h <= 0) return\n\n this.app.renderer.resize(w, h)\n\n if (this.originalTexture && this.sprite) {\n const prevCenter = {\n x: this.sprite.x + this.sprite.width / 2,\n y: this.sprite.y + this.sprite.height / 2\n }\n this.fitScale = this.getFitScaleFor(this.originalTexture)\n this.applyViewTransform({ center: prevCenter })\n }\n }\n\n /**\n * Set background color\n * @param {number} color - Hex color\n */\n setBackgroundColor(color) {\n if (this.app?.renderer?.background) {\n this.app.renderer.background.color = color\n }\n }\n\n /**\n * Load an image URL into an HTMLImageElement.\n * Handles blob:, data:, and http(s): URLs.\n * @param {string} url\n * @returns {Promise<HTMLImageElement|null>}\n */\n _loadImageElement(url) {\n return new Promise((resolve) => {\n const img = new Image()\n // Set crossOrigin for http(s) URLs to avoid tainted canvas on export\n if (typeof url === 'string' && /^https?:\\/\\//.test(url)) {\n img.crossOrigin = 'anonymous'\n }\n img.onload = () => resolve(img)\n img.onerror = () => {\n console.error('[PixiRenderer] Image load failed:', url?.substring(0, 100))\n resolve(null)\n }\n img.src = url\n })\n }\n\n /**\n * Clean up and destroy\n */\n destroy() {\n this._destroyed = true\n this._mountToken += 1\n this._mountPromise = null\n this._destroyLayerDisplayObjects()\n if (this.app) {\n try {\n this.app.destroy(true, { children: true, texture: true })\n } catch (_e) {\n // PIXI may throw if textures were already released during export.\n // Safe to ignore — we're destroying the renderer anyway.\n }\n this.app = null\n }\n this.sprite = null\n this.originalTexture = null\n this.baseTexture = null\n this._container = null\n this.removeAllListeners()\n }\n}\n","/**\n * SVG Icons for the vanilla image editor\n * Uses inline SVG for zero dependencies\n */\n\n// Navigation icons\nexport const chevronLeft = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"48\" d=\"M328 112L184 256l144 144\"/></svg>`\n\nexport const chevronRight = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"48\" d=\"M184 112l144 144-144 144\"/></svg>`\n\n// Zoom icons\nexport const zoomIn = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M221.09 64a157.09 157.09 0 10157.09 157.09A157.1 157.1 0 00221.09 64z\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M338.29 338.29L448 448M256 184v74m-37-37h74\"/></svg>`\n\nexport const zoomOut = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M221.09 64a157.09 157.09 0 10157.09 157.09A157.1 157.1 0 00221.09 64z\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M338.29 338.29L448 448M184 221h74\"/></svg>`\n\nexport const expand = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M432 320v112H320M80 192V80h112M320 80h112v112M192 432H80V320\"/></svg>`\n\n// Editor mode icons\nexport const settings = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M262.29 192.31a64 64 0 1057.4 57.4 64.13 64.13 0 00-57.4-57.4z\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M416.39 256a154.34 154.34 0 01-1.53 20.79l45.21 35.46a10.81 10.81 0 012.45 13.75l-42.77 74a10.81 10.81 0 01-13.14 4.59l-44.9-18.08a16.11 16.11 0 00-15.17 1.75A164.48 164.48 0 01325 400.8a15.94 15.94 0 00-8.82 12.14l-6.73 47.89a11.08 11.08 0 01-10.68 9.17h-85.54a11.11 11.11 0 01-10.69-8.87l-6.72-47.82a16.07 16.07 0 00-9-12.22 155.3 155.3 0 01-21.46-12.57 16 16 0 00-15.11-1.71l-44.89 18.07a10.81 10.81 0 01-13.14-4.58l-42.77-74a10.8 10.8 0 012.45-13.75l38.21-30a16.05 16.05 0 006-14.08c-.36-4.17-.58-8.33-.58-12.5s.21-8.27.58-12.35a16 16 0 00-6.07-13.94l-38.19-30A10.81 10.81 0 0149.48 186l42.77-74a10.81 10.81 0 0113.14-4.59l44.9 18.08a16.11 16.11 0 0015.17-1.75A164.48 164.48 0 01187 111.2a15.94 15.94 0 008.82-12.14l6.73-47.89A11.08 11.08 0 01213.23 42h85.54a11.11 11.11 0 0110.69 8.87l6.72 47.82a16.07 16.07 0 009 12.22 155.3 155.3 0 0121.46 12.57 16 16 0 0015.11 1.71l44.89-18.07a10.81 10.81 0 0113.14 4.58l42.77 74a10.8 10.8 0 01-2.45 13.75l-38.21 30a16.05 16.05 0 00-6.05 14.08c.33 4.14.55 8.3.55 12.47z\"/></svg>`\n\nexport const water = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M400 320c0 88.37-55.63 144-144 144s-144-55.63-144-144c0-94.83 103.23-222.85 134.89-259.88a12 12 0 0118.23 0C296.77 97.15 400 225.17 400 320z\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M344 328a72 72 0 01-72 72\"/></svg>`\n\nexport const colorPalette = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-miterlimit=\"10\" stroke-width=\"32\" d=\"M430.11 347.9c-6.6-6.1-16.3-7.6-24.6-9-11.5-1.9-15.9-4-22.6-10-14.3-12.7-14.3-31.1 0-43.8l30.3-26.9c46.4-41 46.4-108.2 0-149.2-34.2-30.1-80.1-45-127.8-45-55.7 0-113.9 20.3-158.8 60.1-83.5 73.8-83.5 194.7 0 268.5 41.5 36.7 97.5 55 152.9 55.4h1.7c55.4 0 110-17.9 148.8-52.4 14.4-12.7 11.99-36.6.1-47.7z\"/><circle cx=\"144\" cy=\"208\" r=\"32\"/><circle cx=\"152\" cy=\"311\" r=\"32\"/><circle cx=\"224\" cy=\"144\" r=\"32\"/><circle cx=\"256\" cy=\"367\" r=\"32\"/><circle cx=\"328\" cy=\"144\" r=\"32\"/></svg>`\n\nexport const sparkles = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M259.92 262.91L216.4 149.77a9 9 0 00-16.8 0l-43.52 113.14a9 9 0 01-5.17 5.17L37.77 311.6a9 9 0 000 16.8l113.14 43.52a9 9 0 015.17 5.17l43.52 113.14a9 9 0 0016.8 0l43.52-113.14a9 9 0 015.17-5.17l113.14-43.52a9 9 0 000-16.8l-113.14-43.52a9 9 0 01-5.17-5.17zM108 68L88 16 68 68 16 88l52 20 20 52 20-52 52-20-52-20zM426.67 117.33L400 48l-26.67 69.33L304 144l69.33 26.67L400 240l26.67-69.33L496 144l-69.33-26.67z\"/></svg>`\n\nexport const move = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M176 112l80-80 80 80M255.98 32l.02 448M176 400l80 80 80-80M400 176l80 80-80 80M112 176l-80 80 80 80M32 256h448\"/></svg>`\n\nexport const brush = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M452.37 59.63h0a40.49 40.49 0 00-57.26 0L184 294.74c23.08 4.7 46.12 27.29 49.26 49.26l219.11-227.11a40.49 40.49 0 000-57.26z\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M138 336c-29.88 0-54 24.5-54 54.86 0 23.95-20.67 36.57-34 44.78 15.08 8.08 32.23 12.36 50 12.36 48.49 0 88-38.89 88-88 0-30.36-24.12-54-50-54z\"/></svg>`\n\nexport const flash = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M315.27 33L96 304h128l-31.51 173.23a2.36 2.36 0 002.33 2.77h0a2.36 2.36 0 001.89-.95L416 208H288l31.66-173.25a2.45 2.45 0 00-2.44-2.75h0a2.42 2.42 0 00-1.95 1z\"/></svg>`\n\nexport const crop = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M144 48v272a48 48 0 0048 48h272\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M368 464V192a48 48 0 00-48-48H48\"/></svg>`\n\n// Action icons\nexport const save = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M380.93 57.37A32 32 0 00358.3 48H94.22A46.21 46.21 0 0048 94.22v323.56A46.21 46.21 0 0094.22 464h323.56A46.36 46.36 0 00464 417.78V153.7a32 32 0 00-9.37-22.63zM256 416a64 64 0 1164-64 63.92 63.92 0 01-64 64zm48-224H112a16 16 0 01-16-16v-64a16 16 0 0116-16h192a16 16 0 0116 16v64a16 16 0 01-16 16z\"/></svg>`\n\nexport const close = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M368 368L144 144M368 144L144 368\"/></svg>`\n\nexport const refresh = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M320 146s24.36-12-64-12a160 160 0 10160 160\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M256 58l80 80-80 80\"/></svg>`\n\nexport const rotateCcw = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M176 112l-64 64 64 64\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M112 176h176a112 112 0 110 224H160\"/></svg>`\n\nexport const rotateCw = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M336 112l64 64-64 64\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M400 176H224a112 112 0 100 224h128\"/></svg>`\n\nexport const trash = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M112 112l20 320c.95 18.49 14.4 32 32 32h184c17.67 0 30.87-13.51 32-32l20-320\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-miterlimit=\"10\" stroke-width=\"32\" d=\"M80 112h352\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M192 112V72h0a23.93 23.93 0 0124-24h80a23.93 23.93 0 0124 24h0v40M256 176v224M184 176l8 224M328 176l-8 224\"/></svg>`\n\nexport const openFolder = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M64 192v-72a40 40 0 0140-40h75.89a40 40 0 0122.19 6.72l27.84 18.56a40 40 0 0022.19 6.72H408a40 40 0 0140 40v40\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M479.9 226.55L463.68 392a40 40 0 01-39.93 40H88.25a40 40 0 01-39.93-40L32.1 226.55A32 32 0 0164 192h384.1a32 32 0 0131.8 34.55z\"/></svg>`\n\nexport const checkmark = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M416 128L192 384l-96-96\"/></svg>`\n\nexport const layers = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M48 256l208 112 208-112-208-112L48 256z\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M48 336l208 112 208-112M48 176L256 64l208 112\"/></svg>`\n\nexport const eye = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M48 256s80-144 208-144 208 144 208 144-80 144-208 144S48 256 48 256z\"/><circle cx=\"256\" cy=\"256\" r=\"64\" fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32\"/></svg>`\n\nexport const eyeOff = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M432 448L80 64M160 160c-67.2 36.8-112 96-112 96s80 144 208 144c35.8 0 68.4-11.3 96-28.1M224.4 113.8A199.6 199.6 0 01256 112c128 0 208 144 208 144a334.2 334.2 0 01-65.1 78.6\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M213.3 213.3A64 64 0 10298.7 298.7\"/></svg>`\n\nexport const lockClosed = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><rect x=\"96\" y=\"208\" width=\"320\" height=\"240\" rx=\"32\" fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M160 208v-64a96 96 0 01192 0v64\"/></svg>`\n\nexport const lockOpen = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><rect x=\"96\" y=\"208\" width=\"320\" height=\"240\" rx=\"32\" fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M160 208v-64a96 96 0 01168-63.7\"/></svg>`\n\nexport const pencil = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M96 352l-32 96 96-32L421.5 154.5a45.3 45.3 0 000-64h0a45.3 45.3 0 00-64 0L96 352z\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M320 128l64 64\"/></svg>`\n\nexport const duplicate = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><rect x=\"144\" y=\"144\" width=\"288\" height=\"288\" rx=\"32\" fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M80 368V112a32 32 0 0132-32h256\"/></svg>`\n\nexport const text = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M96 112V80h320v32M256 80v352M184 432h144\"/></svg>`\n\n// Shape icons\nexport const square = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><rect x=\"64\" y=\"64\" width=\"384\" height=\"384\" rx=\"48\" fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32\"/></svg>`\n\nexport const circle = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><circle cx=\"256\" cy=\"256\" r=\"208\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\"/></svg>`\n\nexport const freeform = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M80 96h64l64 320h64l64-160h96\"/></svg>`\n\n// Theme icons\nexport const sunny = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-miterlimit=\"10\" stroke-width=\"32\" d=\"M256 48v48M256 416v48M403.08 108.92l-33.94 33.94M142.86 369.14l-33.94 33.94M464 256h-48M96 256H48M403.08 403.08l-33.94-33.94M142.86 142.86l-33.94-33.94\"/><circle cx=\"256\" cy=\"256\" r=\"80\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-miterlimit=\"10\" stroke-width=\"32\"/></svg>`\n\nexport const moon = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M160 136c0-30.62 4.51-61.61 16-88C99.57 81.27 48 159.32 48 248c0 119.29 96.71 216 216 216 88.68 0 166.73-51.57 200-128-26.39 11.49-57.38 16-88 16-119.29 0-216-96.71-216-216z\"/></svg>`\n\n// Category-specific icons\nexport const film = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M436 80H76a44.05 44.05 0 00-44 44v264a44.05 44.05 0 0044 44h360a44.05 44.05 0 0044-44V124a44.05 44.05 0 00-44-44z\"/><circle cx=\"256\" cy=\"256\" r=\"80\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M220 80v56M292 80v56M220 376v56M292 376v56M80 144h56M80 224h56M80 304h56M376 144h56M376 224h56M376 304h56\"/></svg>`\n\nexport const contrast = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><circle cx=\"256\" cy=\"256\" r=\"208\" fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32\"/><path fill=\"currentColor\" d=\"M256 464c-114.88 0-208-93.12-208-208S141.12 48 256 48z\"/></svg>`\n\n// Filter mode icon (for toolbar)\nexport const filter = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M32 144h448M112 256h288M208 368h96\"/></svg>`\n\n// Person/portrait icon (for background removal)\nexport const personOutline = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M344 144c-3.92 52.87-44 96-88 96s-84.15-43.12-88-96c-4-55 35-96 88-96s92 42 88 96z\"/><path fill=\"none\" stroke=\"currentColor\" stroke-miterlimit=\"10\" stroke-width=\"32\" d=\"M256 304c-87 0-175.3 48-191.64 138.6C62.39 453.52 68.57 464 80 464h352c11.44 0 17.62-10.48 15.65-21.4C431.3 352 343 304 256 304z\"/></svg>`\n","/**\n * Editor category single source of truth.\n *\n * UI categories (what the user sees) are fewer than registry categories\n * (what the filter registry uses internally). For example, Color Matrix\n * lives in the 'advanced' registry category but appears under the 'adjust'\n * UI category. Keep these two lookups in sync by deriving both from the\n * EDITOR_CATEGORIES array below.\n */\nimport * as icons from '../icons/icons.js'\n\n/**\n * Ordered list of UI categories shown in the editor.\n * Each entry may include a list of registry categories that feed it.\n * Categories without a `registryCategories` field (e.g. 'crop') don't\n * consume filters from the registry.\n *\n * @typedef {Object} EditorCategory\n * @property {string} id - UI category id\n * @property {string} name - Display name\n * @property {string} [icon] - SVG icon markup\n * @property {string[]} [registryCategories] - Registry categories aggregated under this UI category\n */\n\n/** @type {EditorCategory[]} */\nexport const EDITOR_CATEGORIES = [\n {\n id: 'adjust',\n name: 'Adjust',\n icon: icons.settings,\n registryCategories: ['adjust', 'advanced'], // adjustment, adjustmentAdvanced, alpha, colorMatrix\n },\n {\n id: 'blur',\n name: 'Blur',\n icon: icons.water,\n registryCategories: ['blur'],\n },\n {\n id: 'color',\n name: 'Color',\n icon: icons.colorPalette,\n registryCategories: ['color'],\n },\n {\n id: 'effects',\n name: 'Effects',\n icon: icons.sparkles,\n registryCategories: ['effects'],\n },\n {\n id: 'distortion',\n name: 'Distortion',\n icon: icons.move,\n registryCategories: ['distortion'],\n },\n {\n id: 'light',\n name: 'Light',\n icon: icons.flash,\n registryCategories: ['light'],\n },\n {\n id: 'stylize',\n name: 'Stylize',\n icon: icons.film,\n registryCategories: ['stylize'],\n },\n {\n id: 'text',\n name: 'Text',\n icon: icons.text,\n },\n {\n id: 'background',\n name: 'Background',\n icon: icons.brush,\n },\n {\n id: 'layers',\n name: 'Layers',\n icon: icons.layers,\n },\n {\n id: 'crop',\n name: 'Crop',\n icon: icons.crop,\n },\n]\n\n/**\n * UI category id -> list of registry categories it aggregates.\n * Used by FilterManager.getFiltersByCategory.\n */\nexport const UI_TO_REGISTRY = Object.fromEntries(\n EDITOR_CATEGORIES\n .filter(c => Array.isArray(c.registryCategories) && c.registryCategories.length > 0)\n .map(c => [c.id, c.registryCategories])\n)\n\n/**\n * Registry category id -> UI category id.\n * Used when we have a filter's registry category and need to highlight the\n * right UI chip (e.g. colorMatrix.category === 'advanced' -> UI 'adjust').\n */\nexport const REGISTRY_TO_UI = Object.fromEntries(\n EDITOR_CATEGORIES\n .filter(c => Array.isArray(c.registryCategories))\n .flatMap(c => c.registryCategories.map(rc => [rc, c.id]))\n)\n\n/**\n * Resolve a UI category id to its list of registry categories.\n * Falls back to treating the id as a registry category if not found.\n *\n * @param {string} uiCategoryId\n * @returns {string[]}\n */\nexport function getRegistryCategoriesForUi(uiCategoryId) {\n return UI_TO_REGISTRY[uiCategoryId] || [uiCategoryId]\n}\n\n/**\n * Resolve a filter's registry category to its UI category id.\n * Falls back to the registry category itself if no mapping exists.\n *\n * @param {string} registryCategoryId\n * @returns {string}\n */\nexport function getUiCategoryForRegistry(registryCategoryId) {\n return REGISTRY_TO_UI[registryCategoryId] || registryCategoryId\n}\n","/**\n * Filter Manager for the vanilla image editor\n * Manages filter creation, application, and state\n */\nimport { EventEmitter } from '../core/EventEmitter.js'\nimport { getRegistryCategoriesForUi } from '../filters/categories.js'\n\nexport class FilterManager extends EventEmitter {\n constructor(state, pixiRenderer) {\n super()\n this.state = state\n this.renderer = pixiRenderer\n this.instances = {} // Filter instances by ID\n this._filterRegistry = null\n }\n\n /**\n * Set the filter registry (from mediables/filters)\n * @param {Object} registry - { getFilter, getAllFilters, getFiltersByCategory }\n */\n setRegistry(registry) {\n this._filterRegistry = registry\n this.renderer?.setLayerFilterFactory?.((layer, context) => this.createFiltersForLayer(layer, context))\n }\n\n /**\n * Get filter definition by ID\n * @param {string} filterId\n * @returns {Object|null}\n */\n getFilterDef(filterId) {\n if (!this._filterRegistry) {\n console.warn('[FilterManager] No filter registry set')\n return null\n }\n return this._filterRegistry.getFilter(filterId)\n }\n\n /**\n * Get all filters\n * @returns {Array}\n */\n getAllFilters() {\n return this._filterRegistry?.getAllFilters() || []\n }\n\n /**\n * Get filters by category\n * Maps UI category names to registry category names\n * @param {string} category - UI category ID\n * @returns {Array}\n */\n getFiltersByCategory(category) {\n if (!this._filterRegistry) return []\n\n // Resolve the UI category to its list of registry categories\n const registryCategories = getRegistryCategoriesForUi(category)\n\n // Collect filters from all matching registry categories\n const filters = []\n const seenIds = new Set()\n\n for (const registryCat of registryCategories) {\n const catFilters = this._filterRegistry.getFiltersByCategory(registryCat) || []\n for (const filter of catFilters) {\n // Avoid duplicates\n if (!seenIds.has(filter.id)) {\n seenIds.add(filter.id)\n filters.push(filter)\n }\n }\n }\n\n return filters\n }\n\n /**\n * Normalize UI values from various input types\n * @param {*} value\n * @returns {*}\n */\n _normalizeValue(value) {\n if (Array.isArray(value)) {\n // Array of objects (like colorStops) - keep as-is\n if (value.length > 0 && typeof value[0] === 'object') return value\n // Range value - take first number\n return Number(value[0] ?? 0)\n }\n if (typeof value === 'string') {\n // Hex color - keep as string\n if (value.startsWith('#')) return value\n // Numeric string\n return value.trim() === '' ? 0 : Number(value)\n }\n return value\n }\n\n /**\n * Get a deep property from an object.\n * Returns undefined if any segment along the path is missing.\n * @param {Object} target\n * @param {string} path\n * @returns {*}\n */\n _getDeepProp(target, path) {\n if (!target || !path) return undefined\n\n if (!path.includes('.') && !path.includes('[')) {\n return target[path]\n }\n\n const tokens = path.replace(/\\[(\\d+)\\]/g, '.$1').split('.').filter(Boolean)\n let obj = target\n for (const key of tokens) {\n if (obj == null) return undefined\n obj = obj[key]\n }\n return obj\n }\n\n /**\n * Set a deep property on an object\n * @param {Object} target\n * @param {string} path\n * @param {*} value\n */\n _setDeepProp(target, path, value) {\n if (!target || !path) return\n\n if (!path.includes('.') && !path.includes('[')) {\n target[path] = value\n return\n }\n\n const tokens = path.replace(/\\[(\\d+)\\]/g, '.$1').split('.').filter(Boolean)\n let obj = target\n for (let i = 0; i < tokens.length - 1; i++) {\n const key = tokens[i]\n if (!(key in obj)) return\n obj = obj[key]\n if (obj == null) return\n }\n const last = tokens[tokens.length - 1]\n obj[last] = value\n }\n\n /**\n * Initialize filter values from definition defaults.\n * Seeds BOTH defaultParams (e.g. colorStops) and control defaults so that\n * filters with dynamic parameters not backed by a static control still have\n * their state populated.\n * @param {string} filterId\n */\n initializeValues(filterId, expectedLayerId = undefined) {\n const def = this.getFilterDef(filterId)\n if (!def) return\n\n const values = this.state.getFilterValues(filterId)\n const controlIds = new Set((def.controls || []).map(c => c.id))\n\n // Seed defaultParams entries not covered by any control (e.g. colorStops)\n if (def.defaultParams) {\n for (const [key, value] of Object.entries(def.defaultParams)) {\n if (!controlIds.has(key) && !(key in values)) {\n this.state.setFilterValue(filterId, key, value, expectedLayerId)\n }\n }\n }\n\n // Seed static control defaults\n if (def.controls) {\n def.controls.forEach(ctl => {\n if (!(ctl.id in values)) {\n this.state.setFilterValue(filterId, ctl.id, ctl.default, expectedLayerId)\n }\n })\n }\n }\n\n /**\n * Reset all filter values to their defaults (unconditionally).\n * Resets BOTH defaultParams and control defaults.\n * @param {string} filterId\n */\n resetValues(filterId, expectedLayerId = undefined) {\n const def = this.getFilterDef(filterId)\n if (!def) return\n\n const controlIds = new Set((def.controls || []).map(c => c.id))\n\n // Reset defaultParams entries (including dynamic state like colorStops)\n if (def.defaultParams) {\n for (const [key, value] of Object.entries(def.defaultParams)) {\n if (!controlIds.has(key)) {\n this.state.setFilterValue(filterId, key, value, expectedLayerId)\n }\n }\n }\n\n // Reset static controls\n if (def.controls) {\n def.controls.forEach(ctl => {\n this.state.setFilterValue(filterId, ctl.id, ctl.default, expectedLayerId)\n })\n }\n }\n\n /**\n * Toggle a filter on/off\n * @param {string} filterId\n * @param {boolean} enabled\n */\n toggle(filterId, enabled, expectedLayerId = undefined) {\n const toggled = this.state.toggleFilter(filterId, enabled, expectedLayerId)\n if (toggled === false) return false\n\n if (enabled) {\n this.initializeValues(filterId, expectedLayerId)\n } else {\n delete this.instances[filterId]\n }\n\n this.applyFilters()\n this.emit('filterToggled', { filterId, enabled })\n\n return true\n }\n\n /**\n * Update a filter control value.\n *\n * The `controlId` may be either a static control id (from def.controls) or a\n * dynamic path (e.g. 'colorStops[0].color') produced by a filter's\n * getDynamicControls(). Static control ids are stored in state keyed by the\n * control id. Dynamic paths are NOT stored as flat path keys — instead, we\n * apply them to the live instance and then sync the filter's serializable\n * params back into state, so recreation via applyFilters() rebuilds from\n * the canonical shape (e.g. a colorStops array, not 'colorStops[0].color').\n *\n * Returns true when the filter was updated in-place. Returns false when the\n * caller should invoke applyFilters() to recreate the filter from state —\n * this happens when the property target is a method (which would be\n * silently corrupted by a direct write) or when the property doesn't exist.\n *\n * @param {string} filterId\n * @param {string} controlId - Static control id or dynamic property path\n * @param {*} value\n * @returns {boolean} True if updated in-place, false if caller must recreate\n */\n updateValue(filterId, controlId, value, expectedLayerId = undefined) {\n const normalized = this._normalizeValue(value)\n\n if (!this._matchesExpectedFilterLayer(expectedLayerId)) return false\n\n const def = this.getFilterDef(filterId)\n const ctl = def?.controls.find(c => c.id === controlId)\n const isDynamicPath = !ctl && (controlId.includes('[') || controlId.includes('.'))\n\n // Store static control values in state keyed by control id. Skip dynamic\n // paths here — we sync state via getSerializableParams after the update.\n if (!isDynamicPath) {\n const stored = this.state.setFilterValue(filterId, controlId, normalized, expectedLayerId)\n if (stored === false) return false\n }\n\n const inst = this.instances[filterId]\n if (!inst) return false\n\n // If controlId matches a static control, use its property; otherwise\n // treat controlId itself as the path (covers dynamic controls).\n const path = ctl?.property || controlId\n\n // 1. Prefer updateUIParam if the filter defines one\n if (typeof inst.updateUIParam === 'function') {\n inst.updateUIParam(path, normalized)\n // After a dynamic-path update, sync the filter's canonical params back\n // to state so recreation sees the edit. We skip this for static paths\n // (cheap tight-loop updates don't need the round-trip).\n if (isDynamicPath && typeof inst.getSerializableParams === 'function') {\n const synced = inst.getSerializableParams()\n for (const [key, val] of Object.entries(synced)) {\n this.state.setFilterValue(filterId, key, val, expectedLayerId)\n }\n }\n return true\n }\n\n // 2. Never overwrite a method on the filter with a value —\n // PIXI's ColorMatrixFilter.brightness etc. are methods, not properties.\n // Silently writing a number there would corrupt the filter.\n const existing = this._getDeepProp(inst, path)\n if (typeof existing === 'function') {\n return false\n }\n\n // 3. Uniforms (WebGL shader inputs)\n if (inst.uniforms && path in inst.uniforms) {\n inst.uniforms[path] = normalized\n return true\n }\n\n // 4. Direct write if the path is a writable non-function property\n if (existing !== undefined) {\n this._setDeepProp(inst, path, normalized)\n return true\n }\n\n // 5. Unknown path — let the caller recreate\n return false\n }\n\n /**\n * Perform a filter action (e.g. addColorStop, removeColorStop) and sync\n * any resulting state changes back into State.js before recreating the\n * filter. Without this sync, recreation via applyFilters() would rebuild\n * from stale state and undo the action.\n *\n * @param {string} filterId\n * @param {string} action - Action name understood by filter.updateUIParam\n */\n performFilterAction(filterId, action, expectedLayerId = undefined) {\n if (!this._matchesExpectedFilterLayer(expectedLayerId)) return false\n\n const inst = this.instances[filterId]\n if (!inst || typeof inst.updateUIParam !== 'function') return false\n\n // 1. Apply the action to the live instance\n inst.updateUIParam(action, true)\n\n // 2. Serialize resulting params back to state so recreation sees them\n if (typeof inst.getSerializableParams === 'function') {\n const params = inst.getSerializableParams()\n for (const [key, value] of Object.entries(params)) {\n this.state.setFilterValue(filterId, key, value, expectedLayerId)\n }\n }\n\n // 3. Re-apply filters (recreation now uses the updated state)\n this.applyFilters()\n this.emit('filterActionPerformed', { filterId, action })\n\n return true\n }\n\n _matchesExpectedFilterLayer(expectedLayerId) {\n if (expectedLayerId === undefined) return true\n\n const document = this._layerDocument()\n if (!document) return true\n\n if (expectedLayerId === null) {\n if (typeof this.state.getActiveFilterLayerId === 'function') {\n return this.state.getActiveFilterLayerId() === null\n }\n\n return this.state.get('activeLayerId') === null\n }\n\n const expected = typeof expectedLayerId === 'string' ? expectedLayerId.trim() : ''\n if (expected === '') return false\n\n if (typeof this.state.getActiveFilterLayerId === 'function') {\n return this.state.getActiveFilterLayerId() === expected\n }\n\n return this.state.get('activeLayerId') === expected\n }\n\n _layerDocument() {\n const document = this.state.getSerializableDocument?.()\n return document && document.version === 2 && Array.isArray(document.layers) ? document : null\n }\n\n _sourceDimensionsForLayer(layer, context = {}) {\n const source = layer?.source || layer?.fill?.source || null\n\n return {\n width: Math.round(Number(context.sourceWidth || source?.originalWidth || this.renderer?.originalTexture?.width || this.renderer?.sprite?.width || 0)),\n height: Math.round(Number(context.sourceHeight || source?.originalHeight || this.renderer?.originalTexture?.height || this.renderer?.sprite?.height || 0)),\n }\n }\n\n _paramsForFilterState(def, filterState, dimensions) {\n const values = filterState?.values && typeof filterState.values === 'object' ? filterState.values : {}\n const params = def.defaultParams ? { ...def.defaultParams } : {}\n\n if (def.controls && Array.isArray(def.controls)) {\n def.controls.forEach(c => {\n const key = c.property || c.id\n params[key] = values[c.id] ?? c.default\n })\n }\n\n const controlIds = new Set((def.controls || []).map(c => c.id))\n for (const [key, value] of Object.entries(values)) {\n if (!controlIds.has(key)) {\n params[key] = value\n }\n }\n\n params._sourceWidth = dimensions.width\n params._sourceHeight = dimensions.height\n\n return params\n }\n\n createFiltersForLayer(layer, context = {}) {\n if (!Array.isArray(layer?.filters) || layer.filters.length === 0) return []\n\n const filters = []\n const activeLayerId = this.state.get('activeLayerId')\n const trackInstances = layer.id === activeLayerId && context.forExport !== true\n const dimensions = this._sourceDimensionsForLayer(layer, context)\n\n for (const filterState of layer.filters) {\n if (!filterState || filterState.enabled === false || typeof filterState.id !== 'string') continue\n\n try {\n const def = this.getFilterDef(filterState.id)\n if (!def?.createFilter || typeof def.createFilter !== 'function') continue\n\n const filter = def.createFilter(this._paramsForFilterState(def, filterState, dimensions))\n if (!filter) continue\n\n let renderFilter = filter\n if (context.forExport === true && typeof filter.createExportFilter === 'function') {\n renderFilter = filter.createExportFilter({\n previewToNativeScale: context.previewToNativeScale || 1,\n }) || filter\n }\n\n filters.push(renderFilter)\n if (trackInstances) {\n this.instances[filterState.id] = filter\n }\n } catch (error) {\n console.error(`[FilterManager] Error creating layer filter ${filterState.id}:`, error)\n }\n }\n\n return filters\n }\n\n /**\n * Apply all active filters to the sprite\n *\n * This method recreates all filter instances on each call to ensure\n * PIXI v8's filter pipeline correctly processes changes.\n */\n applyFilters() {\n const layerDocument = this._layerDocument()\n if (layerDocument) {\n for (const key in this.instances) {\n delete this.instances[key]\n }\n\n this.renderer?.setLayerFilterFactory?.((layer, context) => this.createFiltersForLayer(layer, context))\n const applied = this.renderer?.applyLayerFilters?.(layerDocument)\n this.emit('filtersApplied', {\n count: this.state.get('activeFilters')?.size ?? 0,\n failed: [],\n scopedToLayer: true,\n })\n if (!applied) {\n this.renderer?.render?.()\n }\n return\n }\n\n const sprite = this.renderer.sprite\n if (!sprite) return\n\n // Clear old instances (matches Vue version behavior)\n // PIXI v8 requires fresh instances for reliable filter pipeline processing\n for (const key in this.instances) {\n delete this.instances[key]\n }\n\n const filters = []\n const failedFilters = []\n const activeFilters = this.state.get('activeFilters')\n\n activeFilters.forEach(id => {\n try {\n const def = this.getFilterDef(id)\n if (!def) {\n console.warn(`[FilterManager] Filter definition not found: ${id}`)\n return\n }\n\n if (!def.createFilter || typeof def.createFilter !== 'function') {\n console.warn(`[FilterManager] Filter has no createFilter method: ${id}`)\n return\n }\n\n const values = this.state.getFilterValues(id)\n\n // Start with defaultParams (lowest priority)\n const params = def.defaultParams ? { ...def.defaultParams } : {}\n\n // Overlay static control values, keyed by property (falls back to control id)\n if (def.controls && Array.isArray(def.controls)) {\n def.controls.forEach(c => {\n const key = c.property || c.id\n params[key] = values[c.id] ?? c.default\n })\n }\n\n // Overlay any additional state values that aren't backed by a static\n // control (e.g. colorStops, cssGradient). These are seeded into state\n // by initializeValues and mutated by performFilterAction so they must\n // participate in recreation.\n const controlIds = new Set((def.controls || []).map(c => c.id))\n for (const [key, value] of Object.entries(values)) {\n if (!controlIds.has(key)) {\n params[key] = value\n }\n }\n\n // Provide source-image dimensions as reserved params so filters that\n // accept normalized (0-1) coordinate inputs in their UI can convert\n // to render-target pixel units (pixi-filters' TwistFilter, for\n // example, wants offset/radius in pixels). Filters that don't need\n // this just ignore the fields.\n const sprite = this.renderer.sprite\n const tex = this.renderer.originalTexture\n params._sourceWidth = Math.round(tex?.width || sprite?.width || 0)\n params._sourceHeight = Math.round(tex?.height || sprite?.height || 0)\n\n // Create the filter instance\n const f = def.createFilter(params)\n if (f) {\n filters.push(f)\n this.instances[id] = f\n }\n } catch (error) {\n console.error(`[FilterManager] Error creating filter ${id}:`, error)\n failedFilters.push(id)\n }\n })\n\n // CRITICAL FIX: Clear filters first for PIXI v8 compatibility\n // IMPORTANT: PIXI v8 doesn't recognize filter changes unless we clear first.\n // This forces PIXI to re-process the filter pipeline on the next render.\n try {\n sprite.filters = null\n sprite.filters = filters.length ? filters : null\n this.renderer.render()\n this.emit('filtersApplied', { count: filters.length, failed: failedFilters })\n } catch (error) {\n console.error('[FilterManager] Error applying filters to sprite:', error)\n\n // Try to recover by removing all filters\n try {\n sprite.filters = null\n this.renderer.render()\n } catch (recoveryError) {\n console.error('[FilterManager] Recovery failed:', recoveryError)\n }\n\n this.emit('filtersError', { error, failedFilters })\n }\n\n // Notify about failed filters\n if (failedFilters.length > 0) {\n console.warn(`[FilterManager] ${failedFilters.length} filter(s) failed to create:`, failedFilters)\n }\n }\n\n /**\n * Reset all filters.\n * IMPORTANT: Only clears filter instances and sprite.filters.\n * Does NOT touch baseTexture/originalTexture/sprite — that would\n * destroy any applied crop, which is a separate concern.\n */\n resetAll(expectedLayerId = undefined) {\n // Clear instances\n for (const key in this.instances) {\n delete this.instances[key]\n }\n\n // Reset state. In a layer document this clears the active layer only.\n const reset = this.state.resetFilters(expectedLayerId)\n if (reset === false) return false\n\n const layerDocument = this._layerDocument()\n if (layerDocument) {\n this.applyFilters()\n this.emit('filtersReset')\n return true\n }\n\n // Clear sprite filters only — preserve the current texture/sprite\n if (this.renderer.sprite) {\n this.renderer.sprite.filters = null\n }\n\n this.renderer.render()\n this.emit('filtersReset')\n\n return true\n }\n\n /**\n * Get a filter instance\n * @param {string} filterId\n * @returns {Object|null}\n */\n getInstance(filterId) {\n return this.instances[filterId] || null\n }\n}\n","/**\n * Crop Manager for the vanilla image editor\n * Handles crop mode, overlay rendering, and crop application\n */\nimport { EventEmitter } from '../core/EventEmitter.js'\n\nexport class CropManager extends EventEmitter {\n /**\n * Padding factor for auto-zoom: image will be ~91% of crop size (1/1.1).\n * Higher values = more aggressive zoom-out, more padding around image.\n */\n static AUTO_ZOOM_PADDING = 1.1\n\n /**\n * Minimum interval (ms) between auto-zoom adjustments during drag.\n */\n static AUTO_ZOOM_THROTTLE_MS = 100\n\n constructor(state, pixiRenderer) {\n super()\n this.state = state\n this.renderer = pixiRenderer\n\n // Internal state\n this._overlayCanvas = null\n this._isDragging = false\n this._dragStart = null\n this._dragMode = null\n this._startRect = null\n this._hoverMode = null\n\n // Auto-zoom throttle timestamp\n this._lastAutoZoomCheck = 0\n\n // UI constants\n this.HANDLE_SIZE = 14\n this.EDGE_HIT_PAD = 10\n\n // Bound handlers\n this._onPointerDown = this._handlePointerDown.bind(this)\n this._onPointerMove = this._handlePointerMove.bind(this)\n this._onPointerUp = this._handlePointerUp.bind(this)\n }\n\n /**\n * Set the overlay canvas element\n * @param {HTMLCanvasElement} canvas\n */\n setOverlayCanvas(canvas) {\n this._overlayCanvas = canvas\n }\n\n /**\n * Get aspect ratio value from string\n * @param {string} aspect\n * @returns {number|null}\n */\n _getAspectRatio(aspect) {\n if (!aspect || aspect === 'free') return null\n\n const aspectMap = {\n '1:1': 1,\n '4:3': 4/3,\n '16:9': 16/9,\n '3:2': 3/2,\n '2:3': 2/3\n }\n\n if (aspectMap[aspect] !== undefined) return aspectMap[aspect]\n\n // Parse custom ratio strings like '3:1', '21:9'\n const parts = aspect.split(':')\n if (parts.length === 2) {\n const w = parseFloat(parts[0])\n const h = parseFloat(parts[1])\n if (Number.isFinite(w) && Number.isFinite(h) && h > 0) {\n return w / h\n }\n }\n\n return null\n }\n\n /**\n * Apply aspect ratio constraint to crop rect\n */\n applyAspectRatio() {\n const rect = this.state.get('crop.rect')\n const aspect = this.state.get('crop.aspect')\n\n if (!rect || aspect === 'free') return\n\n const targetAspect = this._getAspectRatio(aspect)\n if (!targetAspect) return\n\n const currentAspect = rect.width / rect.height\n if (Math.abs(currentAspect - targetAspect) < 0.01) return\n\n if (currentAspect > targetAspect) {\n rect.width = rect.height * targetAspect\n } else {\n rect.height = rect.width / targetAspect\n }\n\n this.state.set('crop.rect', rect)\n }\n\n /**\n * Constrain crop rect to bounds\n */\n constrainCropRect() {\n const rect = this.state.get('crop.rect')\n if (!rect) return\n\n const sprite = this.renderer.sprite\n const app = this.renderer.app\n if (!sprite || !app) return\n\n const shape = this.state.get('crop.shape')\n\n // All three shapes (free, square, circle) use the SCREEN bounds now, so\n // the user can drag crop handles outside the image to add transparent\n // padding around it. When the crop is applied, any area outside the\n // sprite stays transparent — this is the canvas-expansion users want\n // for drop-shadow, outline, glow, etc. that render past the original\n // image bounds. Previously only circle allowed this; free/square were\n // clamped to the sprite rectangle.\n const bounds = { x: 0, y: 0, w: app.screen.width, h: app.screen.height }\n\n rect.x = Math.max(bounds.x, Math.min(rect.x, bounds.x + bounds.w - rect.width))\n rect.y = Math.max(bounds.y, Math.min(rect.y, bounds.y + bounds.h - rect.height))\n rect.width = Math.min(rect.width, bounds.w)\n rect.height = Math.min(rect.height, bounds.h)\n\n // Keep circle/square 1:1\n if (shape !== 'free' || this.state.get('crop.aspect') === '1:1') {\n const side = Math.min(rect.width, rect.height)\n rect.width = side\n rect.height = side\n }\n\n this.state.set('crop.rect', rect)\n }\n\n /**\n * Calculate the target zoom level for auto-zoom when crop exceeds image bounds.\n * Pure function — returns the new zoom level, or null if no adjustment is needed.\n *\n * @param {{ width: number, height: number }} cropRect - Current crop dimensions\n * @param {number} spriteWidth - Current sprite width on screen\n * @param {number} spriteHeight - Current sprite height on screen\n * @param {number} texWidth - Original texture width (pixels)\n * @param {number} texHeight - Original texture height (pixels)\n * @param {number} fitScale - Current fit-to-screen scale\n * @param {number} currentZoom - Current zoom level\n * @returns {number|null} Target zoom level, or null if no zoom needed\n */\n static calcAutoZoom(cropRect, spriteWidth, spriteHeight, texWidth, texHeight, fitScale, currentZoom) {\n if (!cropRect || !texWidth || !texHeight || !fitScale) return null\n\n const overflowW = cropRect.width > spriteWidth\n const overflowH = cropRect.height > spriteHeight\n\n if (!overflowW && !overflowH) return null\n\n const pad = CropManager.AUTO_ZOOM_PADDING\n let targetZoom = currentZoom\n\n // Only zoom out for the dimension(s) where overflow occurs\n if (overflowW) {\n const zoomForW = cropRect.width / (pad * texWidth * fitScale)\n targetZoom = Math.min(targetZoom, zoomForW)\n }\n if (overflowH) {\n const zoomForH = cropRect.height / (pad * texHeight * fitScale)\n targetZoom = Math.min(targetZoom, zoomForH)\n }\n\n // Clamp to minimum zoom\n targetZoom = Math.max(0.1, targetZoom)\n\n // Only return if this would actually zoom out (threshold avoids micro-adjustments)\n if (targetZoom >= currentZoom - 0.01) return null\n\n return targetZoom\n }\n\n /**\n * Check if auto-zoom is needed and apply it (throttled).\n * Called during crop resize drags when autoZoomOnCropOverflow is enabled.\n */\n _checkAutoZoom() {\n if (!this.state.get('autoZoomOnCropOverflow')) return\n\n // Throttle to avoid excessive zoom adjustments during drag\n const now = Date.now()\n if (now - this._lastAutoZoomCheck < CropManager.AUTO_ZOOM_THROTTLE_MS) return\n this._lastAutoZoomCheck = now\n\n const rect = this.state.get('crop.rect')\n const sprite = this.renderer.sprite\n const tex = this.renderer.originalTexture\n if (!rect || !sprite || !tex) return\n\n const targetZoom = CropManager.calcAutoZoom(\n rect,\n sprite.width,\n sprite.height,\n tex.width,\n tex.height,\n this.renderer.fitScale,\n this.renderer.zoom\n )\n\n if (targetZoom !== null) {\n this.renderer.setZoom(targetZoom, { keepCenter: true })\n }\n }\n\n /**\n * Draw crop overlay on canvas\n */\n drawOverlay() {\n const overlay = this._overlayCanvas\n if (!overlay) return\n\n const app = this.renderer.app\n if (!app) return\n\n const cv = app.canvas\n const cssW = cv.clientWidth\n const cssH = cv.clientHeight\n const dpr = window.devicePixelRatio || 1\n\n // DPR-aware canvas sizing\n if (overlay.width !== Math.max(1, Math.floor(cssW * dpr)) ||\n overlay.height !== Math.max(1, Math.floor(cssH * dpr))) {\n overlay.width = Math.max(1, Math.floor(cssW * dpr))\n overlay.height = Math.max(1, Math.floor(cssH * dpr))\n overlay.style.width = cssW + 'px'\n overlay.style.height = cssH + 'px'\n }\n\n const ctx = overlay.getContext('2d')\n if (!ctx) return\n\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\n ctx.clearRect(0, 0, cssW, cssH)\n\n // Dark overlay\n ctx.fillStyle = 'rgba(0, 0, 0, 0.5)'\n ctx.fillRect(0, 0, cssW, cssH)\n\n const rect = this.state.get('crop.rect')\n if (!rect) return\n\n const shape = this.state.get('crop.shape')\n\n // Clear crop area\n ctx.save()\n if (shape === 'circle') {\n const centerX = rect.x + rect.width / 2\n const centerY = rect.y + rect.height / 2\n const radius = Math.min(rect.width, rect.height) / 2\n ctx.beginPath()\n ctx.arc(centerX, centerY, radius, 0, Math.PI * 2)\n ctx.clip()\n } else {\n ctx.beginPath()\n ctx.rect(rect.x, rect.y, rect.width, rect.height)\n ctx.clip()\n }\n ctx.clearRect(rect.x, rect.y, rect.width, rect.height)\n ctx.restore()\n\n // Draw border\n ctx.strokeStyle = '#ffffff'\n ctx.lineWidth = 2\n ctx.setLineDash([5, 5])\n\n if (shape === 'circle') {\n ctx.beginPath()\n ctx.arc(\n rect.x + rect.width / 2,\n rect.y + rect.height / 2,\n Math.min(rect.width, rect.height) / 2,\n 0,\n Math.PI * 2\n )\n ctx.stroke()\n } else {\n ctx.strokeRect(rect.x, rect.y, rect.width, rect.height)\n }\n\n // Grid (rule-of-thirds)\n ctx.setLineDash([])\n ctx.strokeStyle = 'rgba(255,255,255,0.3)'\n ctx.lineWidth = 1\n const thirdW = rect.width / 3\n const thirdH = rect.height / 3\n\n for (let i = 1; i <= 2; i++) {\n ctx.beginPath()\n ctx.moveTo(rect.x + thirdW * i, rect.y)\n ctx.lineTo(rect.x + thirdW * i, rect.y + rect.height)\n ctx.stroke()\n\n ctx.beginPath()\n ctx.moveTo(rect.x, rect.y + thirdH * i)\n ctx.lineTo(rect.x + rect.width, rect.y + thirdH * i)\n ctx.stroke()\n }\n\n // Draw 8 resize handles\n const hs = this.HANDLE_SIZE\n const corners = [\n { x: rect.x, y: rect.y, m: 'resize-nw' },\n { x: rect.x + rect.width, y: rect.y, m: 'resize-ne' },\n { x: rect.x, y: rect.y + rect.height, m: 'resize-sw' },\n { x: rect.x + rect.width, y: rect.y + rect.height, m: 'resize-se' }\n ]\n const edges = [\n { x: rect.x + rect.width/2, y: rect.y, m: 'n' },\n { x: rect.x + rect.width/2, y: rect.y + rect.height, m: 's' },\n { x: rect.x, y: rect.y + rect.height/2, m: 'w' },\n { x: rect.x + rect.width, y: rect.y + rect.height/2, m: 'e' }\n ]\n\n const all = [...corners, ...edges]\n for (const h of all) {\n const hover = this._hoverMode === h.m\n const size = hover ? hs + 4 : hs\n ctx.beginPath()\n ctx.rect(h.x - size/2, h.y - size/2, size, size)\n ctx.fillStyle = hover ? '#4da3ff' : '#ffffff'\n ctx.strokeStyle = 'rgba(0,0,0,0.6)'\n ctx.lineWidth = 1\n ctx.fill()\n ctx.stroke()\n }\n }\n\n /**\n * Hit test for handles\n * @param {number} px\n * @param {number} py\n * @returns {string|null}\n */\n _hitHandle(px, py) {\n const rect = this.state.get('crop.rect')\n if (!rect) return null\n\n const near = (ax, ay, bx, by, pad) =>\n Math.abs(ax - bx) <= pad && Math.abs(ay - by) <= pad\n\n // Corners\n if (near(px, py, rect.x, rect.y, this.HANDLE_SIZE)) return 'resize-nw'\n if (near(px, py, rect.x + rect.width, rect.y, this.HANDLE_SIZE)) return 'resize-ne'\n if (near(px, py, rect.x, rect.y + rect.height, this.HANDLE_SIZE)) return 'resize-sw'\n if (near(px, py, rect.x + rect.width, rect.y + rect.height, this.HANDLE_SIZE)) return 'resize-se'\n\n // Edges\n if (Math.abs(py - rect.y) <= this.EDGE_HIT_PAD && px >= rect.x && px <= rect.x + rect.width) return 'n'\n if (Math.abs(py - (rect.y + rect.height)) <= this.EDGE_HIT_PAD && px >= rect.x && px <= rect.x + rect.width) return 's'\n if (Math.abs(px - rect.x) <= this.EDGE_HIT_PAD && py >= rect.y && py <= rect.y + rect.height) return 'w'\n if (Math.abs(px - (rect.x + rect.width)) <= this.EDGE_HIT_PAD && py >= rect.y && py <= rect.y + rect.height) return 'e'\n\n // Interior = move\n if (px >= rect.x && px <= rect.x + rect.width && py >= rect.y && py <= rect.y + rect.height) return 'move'\n\n return null\n }\n\n /**\n * Handle pointer down event\n */\n _handlePointerDown(event) {\n const rect = this.state.get('crop.rect')\n if (!rect) return\n\n const pos = event.global\n this._dragMode = this._hitHandle(pos.x, pos.y)\n\n if (this._dragMode) {\n this._isDragging = true\n this._dragStart = { x: pos.x, y: pos.y }\n this._startRect = { ...rect }\n // Reset auto-zoom throttle so first check in new drag is immediate\n this._lastAutoZoomCheck = 0\n }\n }\n\n /**\n * Handle pointer move event\n */\n _handlePointerMove(event) {\n const app = this.renderer.app\n if (!app) return\n\n const pos = event.global\n\n // Hover feedback when not dragging\n if (!this._isDragging || !this._dragStart || !this._startRect) {\n this._hoverMode = this._hitHandle(pos.x, pos.y)\n app.stage.cursor =\n this._hoverMode === 'move' ? 'move' :\n this._hoverMode === 'n' || this._hoverMode === 's' ? 'ns-resize' :\n this._hoverMode === 'e' || this._hoverMode === 'w' ? 'ew-resize' :\n this._hoverMode?.endsWith('nw') || this._hoverMode?.endsWith('se') ? 'nwse-resize' :\n this._hoverMode?.endsWith('ne') || this._hoverMode?.endsWith('sw') ? 'nesw-resize' :\n 'crosshair'\n this.drawOverlay()\n return\n }\n\n const rect = this.state.get('crop.rect')\n if (!rect) return\n\n const dx = pos.x - this._dragStart.x\n const dy = pos.y - this._dragStart.y\n\n switch (this._dragMode) {\n case 'move':\n rect.x = this._startRect.x + dx\n rect.y = this._startRect.y + dy\n break\n case 'n':\n rect.y = this._startRect.y + dy\n rect.height = this._startRect.height - dy\n break\n case 's':\n rect.height = this._startRect.height + dy\n break\n case 'w':\n rect.x = this._startRect.x + dx\n rect.width = this._startRect.width - dx\n break\n case 'e':\n rect.width = this._startRect.width + dx\n break\n case 'resize-nw':\n rect.x = this._startRect.x + dx\n rect.y = this._startRect.y + dy\n rect.width = this._startRect.width - dx\n rect.height = this._startRect.height - dy\n break\n case 'resize-ne':\n rect.y = this._startRect.y + dy\n rect.width = this._startRect.width + dx\n rect.height = this._startRect.height - dy\n break\n case 'resize-sw':\n rect.x = this._startRect.x + dx\n rect.width = this._startRect.width - dx\n rect.height = this._startRect.height + dy\n break\n case 'resize-se':\n rect.width = this._startRect.width + dx\n rect.height = this._startRect.height + dy\n break\n }\n\n // Minimum size\n rect.width = Math.max(50, rect.width)\n rect.height = Math.max(50, rect.height)\n\n this.state.set('crop.rect', rect)\n this.state.set('crop.dirty', true)\n\n // Enforce circle to 1:1\n const shape = this.state.get('crop.shape')\n if (shape === 'circle' && this.state.get('crop.aspect') !== '1:1') {\n this.state.set('crop.aspect', '1:1')\n }\n\n this.applyAspectRatio()\n\n // Auto-zoom when crop exceeds image bounds (only for resize, not move)\n if (this._dragMode !== 'move') {\n this._checkAutoZoom()\n }\n\n this.constrainCropRect()\n this.drawOverlay()\n }\n\n /**\n * Handle pointer up event\n */\n _handlePointerUp() {\n this._isDragging = false\n this._dragMode = null\n this._dragStart = null\n this._startRect = null\n }\n\n /**\n * Enable crop mode\n */\n enable() {\n const app = this.renderer.app\n const sprite = this.renderer.sprite\n if (!app || !sprite) return\n\n // Initialize crop rect if needed\n let rect = this.state.get('crop.rect')\n if (!rect) {\n const shape = this.state.get('crop.shape')\n if (shape === 'circle') {\n this.state.set('crop.aspect', '1:1')\n }\n\n const aspect = this.state.get('crop.aspect')\n const targetAspect = this._getAspectRatio(aspect)\n\n let width, height\n\n if (targetAspect) {\n // For a known aspect ratio, calculate the maximum rect that fits\n // within the sprite bounds while maintaining the ratio.\n // Use 90% of sprite dimensions to leave visible padding.\n const maxW = sprite.width * 0.9\n const maxH = sprite.height * 0.9\n\n if (maxW / maxH > targetAspect) {\n // Height is the constraint\n height = maxH\n width = height * targetAspect\n } else {\n // Width is the constraint\n width = maxW\n height = width / targetAspect\n }\n } else {\n // Free or square: use the classic 70%-of-screen square\n const size = Math.min(app.screen.width, app.screen.height) * 0.7\n width = size\n height = size\n }\n\n const x = sprite.x + (sprite.width - width) / 2\n const y = sprite.y + (sprite.height - height) / 2\n\n rect = { x, y, width, height }\n this.state.set('crop.rect', rect)\n\n if (aspect !== 'free') {\n this.constrainCropRect()\n }\n }\n\n this.state.set('crop.dirty', false)\n\n // Make stage interactive\n const stage = app.stage\n stage.eventMode = 'static'\n stage.hitArea = app.screen\n stage.cursor = 'crosshair'\n\n // Attach handlers\n stage.on('pointerdown', this._onPointerDown)\n stage.on('pointermove', this._onPointerMove)\n stage.on('pointerup', this._onPointerUp)\n stage.on('pointerupoutside', this._onPointerUp)\n\n this.state.set('mode', 'crop')\n this.drawOverlay()\n this.emit('enabled')\n }\n\n /**\n * Disable crop mode\n */\n disable() {\n const app = this.renderer.app\n if (!app) return\n\n const stage = app.stage\n stage.off('pointerdown', this._onPointerDown)\n stage.off('pointermove', this._onPointerMove)\n stage.off('pointerup', this._onPointerUp)\n stage.off('pointerupoutside', this._onPointerUp)\n\n stage.eventMode = 'auto'\n stage.cursor = 'default'\n\n this.state.set('crop.rect', null)\n this.state.set('crop.dirty', false)\n\n // Clear overlay\n if (this._overlayCanvas) {\n const ctx = this._overlayCanvas.getContext('2d')\n ctx?.clearRect(0, 0, this._overlayCanvas.width, this._overlayCanvas.height)\n }\n\n this.state.set('mode', 'filters')\n this.emit('disabled')\n }\n\n /**\n * Apply the crop\n * @returns {{ texture: PIXI.Texture, preservedZoom: number }|null}\n */\n apply() {\n const app = this.renderer.app\n const sprite = this.renderer.sprite\n const tex = this.renderer.originalTexture\n const rect = this.state.get('crop.rect')\n\n if (!rect || !sprite || !app || !tex) return null\n\n const PIXI = window.PIXI\n const prevZoom = this.renderer.zoom\n\n // Map view rect to output pixels\n const scaleX = tex.width / sprite.width\n const scaleY = tex.height / sprite.height\n const rawTx = (rect.x - sprite.x) * scaleX\n const rawTy = (rect.y - sprite.y) * scaleY\n\n let outW = Math.round(Math.max(1, rect.width * scaleX))\n let outH = Math.round(Math.max(1, rect.height * scaleY))\n let offsetX = Math.round(rawTx)\n let offsetY = Math.round(rawTy)\n\n if (outW <= 0 || outH <= 0) return null\n\n // Build off-screen container for crop\n const container = new PIXI.Container()\n const src = new PIXI.Sprite(tex)\n\n // Handle circle crop\n const shape = this.state.get('crop.shape')\n if (shape === 'circle') {\n const side = Math.round(Math.max(outW, outH))\n const cx = offsetX + outW / 2\n const cy = offsetY + outH / 2\n offsetX = Math.round(cx - side / 2)\n offsetY = Math.round(cy - side / 2)\n outW = outH = side\n\n const g = new PIXI.Graphics()\n if (typeof g.circle === 'function' && typeof g.fill === 'function') {\n g.circle(outW / 2, outH / 2, outW / 2).fill(0xffffff)\n } else {\n g.beginFill(0xffffff, 1)\n g.drawCircle(outW / 2, outH / 2, outW / 2)\n g.endFill()\n }\n src.mask = g\n container.addChild(g)\n }\n\n src.x = -offsetX\n src.y = -offsetY\n container.addChild(src)\n\n const rt = PIXI.RenderTexture.create({ width: outW, height: outH })\n app.renderer.render({\n container,\n target: rt,\n clear: true\n })\n\n container.destroy({ children: true })\n\n // Destroy the previous derived render texture to free GPU memory.\n // Only destroy if it's a derived texture (not the original base texture).\n const prevTexture = this.renderer.originalTexture\n if (prevTexture && prevTexture !== this.renderer.baseTexture) {\n prevTexture.destroy(true)\n }\n\n // Update textures\n this.renderer.originalTexture = rt\n\n // Replace sprite\n app.stage.removeChild(sprite)\n sprite.destroy()\n\n const newSprite = new PIXI.Sprite(rt)\n app.stage.addChild(newSprite)\n this.renderer.sprite = newSprite\n\n // Recalculate fit and apply transform\n this.renderer.fitScale = this.renderer.getFitScaleFor(rt)\n this.renderer.setZoom(prevZoom, { keepCenter: false })\n this.renderer.applyViewTransform()\n this.renderer.render()\n\n // Save the applied crop in ROOT-SOURCE pixel coordinates.\n // When a user reopens the editor and crops again, `offsetX/offsetY` are relative\n // to the already-cropped working texture. Compose them with the previously applied\n // rect so the serialized state can be replayed against the original source image.\n const previousAppliedRect = this.state.get('crop.appliedRect')\n const hasPreviousAppliedRect = previousAppliedRect\n && Number.isFinite(previousAppliedRect.x)\n && Number.isFinite(previousAppliedRect.y)\n && Number.isFinite(previousAppliedRect.width)\n && Number.isFinite(previousAppliedRect.height)\n const appliedPixelRect = hasPreviousAppliedRect\n ? {\n x: Math.round(previousAppliedRect.x + offsetX),\n y: Math.round(previousAppliedRect.y + offsetY),\n width: outW,\n height: outH,\n }\n : { x: offsetX, y: offsetY, width: outW, height: outH }\n const appliedShape = this.state.get('crop.shape') || 'free'\n const appliedAspect = this.state.get('crop.aspect') || 'free'\n\n // Disable crop mode (clears crop.rect for the interactive overlay)\n this.disable()\n\n // Persist the applied crop for serialization/reopen fidelity.\n // These are the texture-pixel coordinates that were baked into the texture.\n this.state.set('crop.appliedRect', appliedPixelRect)\n this.state.set('crop.appliedShape', appliedShape)\n this.state.set('crop.appliedAspect', appliedAspect)\n this.state.set('crop.dirty', false)\n\n this.emit('applied', { width: outW, height: outH })\n return { texture: rt, preservedZoom: prevZoom }\n }\n\n /**\n * Apply a crop from saved texture-pixel coordinates (for state rehydration).\n * Unlike apply(), this does not read from crop.rect or require the interactive overlay.\n * @param {{ x: number, y: number, width: number, height: number }} pixelRect\n * @param {'free'|'circle'} shape\n * @returns {{ texture: Object, preservedZoom: number }|null}\n */\n applyFromPixelRect(pixelRect, shape = 'free') {\n const app = this.renderer.app\n const sprite = this.renderer.sprite\n const tex = this.renderer.originalTexture\n\n if (!pixelRect || !sprite || !app || !tex) return null\n\n const PIXI = window.PIXI\n const prevZoom = this.renderer.zoom\n\n let outW = Math.round(Math.max(1, pixelRect.width))\n let outH = Math.round(Math.max(1, pixelRect.height))\n let offsetX = Math.round(pixelRect.x)\n let offsetY = Math.round(pixelRect.y)\n\n if (outW <= 0 || outH <= 0) return null\n\n // Build off-screen container for crop\n const container = new PIXI.Container()\n const src = new PIXI.Sprite(tex)\n\n // Handle circle crop\n if (shape === 'circle') {\n const side = Math.round(Math.max(outW, outH))\n const cx = offsetX + outW / 2\n const cy = offsetY + outH / 2\n offsetX = Math.round(cx - side / 2)\n offsetY = Math.round(cy - side / 2)\n outW = outH = side\n\n const g = new PIXI.Graphics()\n if (typeof g.circle === 'function' && typeof g.fill === 'function') {\n g.circle(outW / 2, outH / 2, outW / 2).fill(0xffffff)\n } else {\n g.beginFill(0xffffff, 1)\n g.drawCircle(outW / 2, outH / 2, outW / 2)\n g.endFill()\n }\n src.mask = g\n container.addChild(g)\n }\n\n src.x = -offsetX\n src.y = -offsetY\n container.addChild(src)\n\n const rt = PIXI.RenderTexture.create({ width: outW, height: outH })\n app.renderer.render({ container, target: rt, clear: true })\n container.destroy({ children: true })\n\n // Destroy the previous derived render texture to free GPU memory.\n const prevTexture = this.renderer.originalTexture\n if (prevTexture && prevTexture !== this.renderer.baseTexture) {\n prevTexture.destroy(true)\n }\n\n // Update textures\n this.renderer.originalTexture = rt\n\n // Replace sprite\n app.stage.removeChild(sprite)\n sprite.destroy()\n\n const newSprite = new PIXI.Sprite(rt)\n app.stage.addChild(newSprite)\n this.renderer.sprite = newSprite\n\n // Recalculate fit and apply transform\n this.renderer.fitScale = this.renderer.getFitScaleFor(rt)\n this.renderer.setZoom(prevZoom, { keepCenter: false })\n this.renderer.applyViewTransform()\n this.renderer.render()\n\n return { texture: rt, preservedZoom: prevZoom }\n }\n\n /**\n * Cancel crop\n */\n cancel() {\n this.disable()\n this.emit('cancelled')\n }\n\n /**\n * Set crop shape\n * @param {'free'|'square'|'circle'} shape\n */\n setShape(shape) {\n // Respect lockCropShape from preset — ignore shape changes when locked\n if (this.state.get('lockCropShape')) return\n\n this.state.set('crop.shape', shape)\n this.state.set('crop.dirty', true)\n if (shape === 'circle' || shape === 'square') {\n this.state.set('crop.aspect', '1:1')\n }\n this.applyAspectRatio()\n this.constrainCropRect()\n this.drawOverlay()\n }\n\n /**\n * Set aspect ratio\n * @param {'free'|'1:1'|'4:3'|'16:9'|'3:2'|'2:3'|string} aspect\n */\n setAspect(aspect) {\n // Respect lockAspectRatio from preset — ignore changes when locked\n if (this.state.get('lockAspectRatio')) return\n\n const shape = this.state.get('crop.shape')\n if (shape !== 'free') {\n // Manual aspect selection switches back to rectangular crop mode.\n if (this.state.get('lockCropShape')) return\n\n this.state.set('crop.shape', 'free')\n }\n\n this.state.set('crop.aspect', aspect)\n this.state.set('crop.dirty', true)\n this.applyAspectRatio()\n this.constrainCropRect()\n this.drawOverlay()\n }\n}\n","/**\n * Background Removal Manager for the vanilla image editor\n * Handles communication with the background removal service\n */\n\nexport class RemoveBgManager {\n /**\n * Create a new RemoveBgManager\n * @param {Object} options\n * @param {string} [options.endpoint] - API endpoint for uploaded preview background removal\n * @param {string} [options.optionsEndpoint] - API endpoint for background-removal capability/options\n * @param {string} [options.savedEndpoint] - API endpoint template for saved-media removal\n * @param {string} [options.fallbackEndpoint] - Fallback endpoint if primary fails\n */\n constructor(options = {}) {\n this._endpoint = options.endpoint || '/api/v1/media/background-removal/preview'\n this._optionsEndpoint = options.optionsEndpoint || '/api/v1/media/background-removal/options'\n this._savedEndpoint = options.savedEndpoint || '/api/v1/media/{media}/background-removal'\n this._fallbackEndpoint = options.fallbackEndpoint || null\n this._activeControllers = new Set()\n }\n\n _createAbortController() {\n if (typeof AbortController === 'undefined') {\n return null\n }\n\n const controller = new AbortController()\n this._activeControllers.add(controller)\n return controller\n }\n\n _releaseAbortController(controller) {\n if (controller) {\n this._activeControllers.delete(controller)\n }\n }\n\n cancelActiveRequests(reason = 'cancelled') {\n const controllers = Array.from(this._activeControllers)\n this._activeControllers.clear()\n\n for (const controller of controllers) {\n if (!controller.signal.aborted) {\n controller.abort(reason)\n }\n }\n\n return controllers.length\n }\n\n /**\n * Build a stable preview request so callers can stale-guard the response.\n * @param {string|Blob} imageData\n * @param {Object} options\n * @returns {Promise<Object>}\n */\n async preparePreviewRequest(imageData, options = {}) {\n const blob = typeof imageData === 'string'\n ? await this._dataUrlToBlob(imageData)\n : imageData\n\n return {\n ...options,\n blob,\n operationId: options.operationId || this._uuid(),\n sessionKey: options.sessionKey || this._uuid(),\n sourceHash: options.sourceHash || await this._sha256Hex(blob),\n targetRef: options.targetRef || null,\n tier: options.tier || 'balanced',\n }\n }\n\n /**\n * @param {string|Blob} imageData\n * @returns {Promise<string>}\n */\n async computeImageDataHash(imageData) {\n const blob = typeof imageData === 'string'\n ? await this._dataUrlToBlob(imageData)\n : imageData\n\n return this._sha256Hex(blob)\n }\n\n /**\n * Remove background from an image\n * @param {string} imageData - Data URL or Blob of the image\n * @param {Object} options\n * @param {string} [options.tier='balanced'] - Quality tier: 'fast', 'balanced', 'best'\n * @param {string} [options.model] - Explicit model name (overrides tier)\n * @param {boolean} [options.alpha_matting=false] - Enable alpha matting for edge refinement\n * @param {number} [options.alpha_f=10] - Alpha matting foreground threshold\n * @param {number} [options.alpha_fr=15] - Alpha matting foreground radius\n * @param {number} [options.alpha_erode_size=10] - Alpha matting erode size\n * @returns {Promise<{dataUrl: string, model: string, processMs: string}>}\n */\n async removeBackground(imageData, options = {}) {\n const request = typeof Blob !== 'undefined' && options.blob instanceof Blob\n ? options\n : await this.preparePreviewRequest(imageData, options)\n const blob = request.blob\n const operationId = request.operationId\n const sessionKey = request.sessionKey\n const sourceHash = request.sourceHash\n\n const formData = new FormData()\n formData.append('image_file', blob, 'image.png')\n formData.append('operation_id', operationId)\n formData.append('session_key', sessionKey)\n formData.append('source_hash', sourceHash)\n formData.append('tier', request.tier || 'balanced')\n\n if (request.targetRef) {\n formData.append('target_ref', request.targetRef)\n }\n\n if (request.model) {\n formData.append('model', request.model)\n }\n\n if (request.alpha_matting) {\n formData.append('alpha_matting', 'true')\n formData.append('alpha_f', String(request.alpha_f ?? 10))\n formData.append('alpha_fr', String(request.alpha_fr ?? 15))\n formData.append('alpha_erode_size', String(request.alpha_erode_size ?? 10))\n }\n\n if (request.max_megapixels !== undefined) {\n formData.append('max_megapixels', String(request.max_megapixels))\n }\n\n let response\n let error\n const controller = this._createAbortController()\n const withSignal = (init) => controller ? { ...init, signal: controller.signal } : init\n\n try {\n // Try primary endpoint\n try {\n response = await fetch(this._endpoint, withSignal({\n method: 'POST',\n body: formData,\n credentials: 'include' // For Sanctum auth\n }))\n } catch (e) {\n if (controller?.signal.aborted) {\n throw e\n }\n error = e\n }\n\n // Try fallback if primary failed\n if ((!response || !response.ok) && this._fallbackEndpoint) {\n try {\n response = await fetch(this._fallbackEndpoint, withSignal({\n method: 'POST',\n body: formData\n }))\n } catch (e) {\n if (controller?.signal.aborted) {\n throw e\n }\n // Keep original error if fallback also fails\n if (!error) error = e\n }\n }\n\n // Check for network error\n if (!response) {\n throw error || new Error('Network error: Unable to connect to background removal service')\n }\n\n // Check for HTTP error\n if (!response.ok) {\n let errorMessage = `Background removal failed (HTTP ${response.status})`\n try {\n const errorText = await response.text()\n if (errorText) errorMessage += `: ${errorText}`\n } catch (_) {}\n throw new Error(errorMessage)\n }\n\n // Read response\n const resultBlob = await response.blob()\n const dataUrl = await this._blobToDataUrl(resultBlob)\n\n return {\n dataUrl,\n model: response.headers.get('X-Model-Used') || 'unknown',\n processMs: response.headers.get('X-Process-Ms') || '0',\n operationId: response.headers.get('X-Operation-Id') || operationId,\n sessionKey: response.headers.get('X-Session-Key') || sessionKey,\n sourceHash: response.headers.get('X-Source-Hash') || sourceHash,\n targetRef: response.headers.get('X-Target-Ref') || request.targetRef || null,\n }\n } finally {\n this._releaseAbortController(controller)\n }\n }\n\n /**\n * Remove the background from a persisted editor-document layer.\n * @param {Object} options\n * @param {string} options.targetMediaUuid\n * @param {string} options.operationId\n * @param {string} options.documentId\n * @param {string} options.documentRevisionId\n * @param {string} options.targetLayerId\n * @param {string} options.expectedSourceHash\n * @param {string} [options.tier]\n * @returns {Promise<Object>}\n */\n async removeSavedMediaBackground(options) {\n const endpoint = this._savedEndpoint.replace('{media}', encodeURIComponent(options.targetMediaUuid))\n const payload = {\n operation_id: options.operationId,\n document_id: options.documentId,\n document_revision_id: options.documentRevisionId,\n target_layer_id: options.targetLayerId,\n expected_source_hash: options.expectedSourceHash,\n tier: options.tier || 'balanced',\n }\n\n if (options.model) payload.model = options.model\n if (options.alpha_matting !== undefined) payload.alpha_matting = !!options.alpha_matting\n if (options.max_megapixels !== undefined) payload.max_megapixels = Number(options.max_megapixels)\n\n const controller = this._createAbortController()\n let response\n try {\n response = await fetch(endpoint, {\n method: 'POST',\n body: JSON.stringify(payload),\n credentials: 'include',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n ...(controller ? { signal: controller.signal } : {}),\n })\n\n if (!response.ok) {\n let errorMessage = `Background removal failed (HTTP ${response.status})`\n try {\n const data = await response.json()\n if (data?.message) errorMessage += `: ${data.message}`\n } catch (_) {}\n throw new Error(errorMessage)\n }\n\n return await response.json()\n } finally {\n this._releaseAbortController(controller)\n }\n }\n\n /**\n * Convert a data URL to a Blob\n * @param {string} dataUrl\n * @returns {Promise<Blob>}\n */\n async _dataUrlToBlob(dataUrl) {\n // Handle both fetch-able URLs and data URLs\n if (dataUrl.startsWith('data:')) {\n const [header, data] = dataUrl.split(',')\n const mimeMatch = header.match(/:(.*?);/)\n const mime = mimeMatch ? mimeMatch[1] : 'image/png'\n const binary = atob(data)\n const array = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) {\n array[i] = binary.charCodeAt(i)\n }\n return new Blob([array], { type: mime })\n }\n\n // Fetch URL and convert to blob\n const response = await fetch(dataUrl)\n return response.blob()\n }\n\n /**\n * Convert a Blob to a data URL\n * @param {Blob} blob\n * @returns {Promise<string>}\n */\n _blobToDataUrl(blob) {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = () => resolve(reader.result)\n reader.onerror = () => reject(new Error('Failed to read blob as data URL'))\n reader.readAsDataURL(blob)\n })\n }\n\n /**\n * Check if the background removal service is available\n * @returns {Promise<boolean>}\n */\n async isAvailable() {\n const options = await this.getOptions()\n\n return options.enabled === true && options.service?.available === true\n }\n\n /**\n * @returns {Promise<Object>}\n */\n async getOptions() {\n try {\n const response = await fetch(this._optionsEndpoint, {\n method: 'GET',\n credentials: 'include'\n })\n if (!response.ok) {\n return { enabled: false, service: { available: false } }\n }\n\n const payload = await response.json()\n\n return payload && typeof payload === 'object'\n ? payload\n : { enabled: false, service: { available: false } }\n } catch (_) {\n // Try fallback\n if (this._fallbackEndpoint) {\n try {\n const response = await fetch(this._fallbackEndpoint, {\n method: 'OPTIONS'\n })\n return {\n enabled: response.ok,\n service: { available: response.ok },\n }\n } catch (_) {}\n }\n return { enabled: false, service: { available: false } }\n }\n }\n\n _uuid() {\n if (globalThis.crypto?.randomUUID) {\n return globalThis.crypto.randomUUID()\n }\n\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (char) => {\n const random = Math.floor(Math.random() * 16)\n const value = char === 'x' ? random : (random & 0x3) | 0x8\n return value.toString(16)\n })\n }\n\n async _sha256Hex(blob) {\n const buffer = await blob.arrayBuffer()\n const digest = await globalThis.crypto.subtle.digest('SHA-256', buffer)\n return [...new Uint8Array(digest)]\n .map((byte) => byte.toString(16).padStart(2, '0'))\n .join('')\n }\n}\n","/**\n * UI Builder - DOM helpers and component factories\n * Creates UI elements without external dependencies\n */\n\n/**\n * Create an element with attributes and children\n * @param {string} tag - HTML tag name\n * @param {Object} attrs - Attributes and properties\n * @param {...(string|HTMLElement)} children - Child elements or text\n * @returns {HTMLElement}\n */\nexport function el(tag, attrs = {}, ...children) {\n const element = document.createElement(tag)\n\n for (const [key, value] of Object.entries(attrs)) {\n // Skip undefined and null values\n if (value === undefined || value === null) continue\n\n if (key === 'className') {\n element.className = value\n } else if (key === 'style' && typeof value === 'object') {\n Object.assign(element.style, value)\n } else if (key.startsWith('on') && typeof value === 'function') {\n const event = key.slice(2).toLowerCase()\n element.addEventListener(event, value)\n } else if (key === 'dataset' && typeof value === 'object') {\n Object.assign(element.dataset, value)\n } else {\n element.setAttribute(key, value)\n }\n }\n\n for (const child of children) {\n if (typeof child === 'string') {\n element.appendChild(document.createTextNode(child))\n } else if (child instanceof HTMLElement) {\n element.appendChild(child)\n }\n }\n\n return element\n}\n\n/**\n * Create a slider with label and value display\n * @param {Object} options\n * @returns {HTMLElement}\n */\nexport function createSlider({ id, label, min = 0, max = 1, step = 0.01, value = 0.5, onChange }) {\n // Extract control ID from the id (format: \"filterId-controlId\")\n const controlId = id.includes('-') ? id.split('-').slice(1).join('-') : id\n const wrapper = el('div', {\n className: 'slider-control slider-wrapper',\n 'data-control': controlId,\n 'data-testid': `slider-${controlId}`\n })\n\n const header = el('div', { className: 'slider-header' },\n el('label', { for: id, className: 'slider-label' }, label),\n el('span', { className: 'slider-value', id: `${id}-value` }, formatValue(value))\n )\n\n const input = el('input', {\n type: 'range',\n id,\n className: 'slider-input',\n min: String(min),\n max: String(max),\n step: String(step),\n value: String(value),\n onInput: (e) => {\n const val = parseFloat(e.target.value)\n const display = wrapper.querySelector('.slider-value')\n if (display) display.textContent = formatValue(val)\n onChange?.(val)\n }\n })\n\n wrapper.appendChild(header)\n wrapper.appendChild(input)\n\n // Method to update value programmatically\n wrapper.setValue = (val) => {\n input.value = String(val)\n const display = wrapper.querySelector('.slider-value')\n if (display) display.textContent = formatValue(val)\n }\n\n return wrapper\n}\n\n/**\n * Format a numeric value for display\n */\nfunction formatValue(val) {\n if (Number.isInteger(val)) return String(val)\n return val.toFixed(2)\n}\n\n/**\n * Create a toggle switch\n * @param {Object} options\n * @returns {HTMLElement}\n */\nexport function createToggle({ id, label, checked = false, onChange }) {\n const wrapper = el('div', { className: 'toggle-control' })\n\n const labelEl = el('label', { className: 'toggle-label', for: id }, label)\n\n const input = el('input', {\n type: 'checkbox',\n id,\n className: 'toggle-input',\n checked: checked ? 'checked' : undefined,\n onChange: (e) => onChange?.(e.target.checked)\n })\n\n // Click handler for the visual toggle element\n const toggle = el('div', {\n className: 'toggle-switch',\n onClick: (e) => {\n // Prevent double-triggering if clicking directly on the input\n if (e.target === input) return\n input.checked = !input.checked\n onChange?.(input.checked)\n }\n })\n\n const slider = el('span', { className: 'toggle-slider' })\n toggle.appendChild(input)\n toggle.appendChild(slider)\n\n wrapper.appendChild(labelEl)\n wrapper.appendChild(toggle)\n\n wrapper.setChecked = (val) => {\n input.checked = val\n }\n\n return wrapper\n}\n\n/**\n * Create a color picker\n * @param {Object} options\n * @returns {HTMLElement}\n */\nexport function createColorPicker({ id, label, value = '#000000', onChange }) {\n const wrapper = el('div', { className: 'color-control' })\n\n const labelEl = el('label', { className: 'color-label', for: id }, label)\n\n const input = el('input', {\n type: 'color',\n id,\n className: 'color-input',\n value,\n onInput: (e) => onChange?.(e.target.value)\n })\n\n wrapper.appendChild(labelEl)\n wrapper.appendChild(input)\n\n wrapper.setValue = (val) => {\n input.value = val\n }\n\n return wrapper\n}\n\n/**\n * Create a text input that commits on Enter or blur (not on every keystroke).\n * This deferred-commit behavior is important for inputs that trigger expensive\n * parsing on change (e.g. the CSS gradient input, which creates a full PIXI\n * filter on each commit).\n *\n * @param {Object} options\n * @param {string} options.id\n * @param {string} options.label\n * @param {string} [options.value]\n * @param {string} [options.placeholder]\n * @param {Function} [options.onCommit] - Called with trimmed value on Enter or blur when value changed\n * @returns {HTMLElement}\n */\nexport function createTextInput({ id, label, value = '', placeholder = '', onCommit }) {\n const wrapper = el('div', {\n className: 'text-control',\n 'data-control': id,\n 'data-testid': `text-${id}`\n })\n\n const labelEl = el('label', { className: 'text-label', for: id }, label)\n\n let lastCommitted = value\n\n const input = el('input', {\n type: 'text',\n id,\n className: 'text-input',\n value,\n placeholder,\n onKeyDown: (e) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n commit()\n input.blur()\n }\n },\n onBlur: () => commit()\n })\n\n function commit() {\n const next = input.value\n if (next === lastCommitted) return\n lastCommitted = next\n onCommit?.(next)\n }\n\n wrapper.appendChild(labelEl)\n wrapper.appendChild(input)\n\n wrapper.setValue = (val) => {\n const next = val == null ? '' : String(val)\n input.value = next\n lastCommitted = next\n }\n\n return wrapper\n}\n\n/**\n * Create a select dropdown\n * @param {Object} options\n * @returns {HTMLElement}\n */\nexport function createSelect({ id, label, options = [], value, onChange }) {\n const wrapper = el('div', { className: 'select-control' })\n\n const labelEl = el('label', { className: 'select-label', for: id }, label)\n\n const select = el('select', {\n id,\n className: 'select-input',\n onChange: (e) => onChange?.(e.target.value)\n })\n\n for (const opt of options) {\n const option = el('option', { value: opt.value }, opt.label)\n if (opt.value === value) option.selected = true\n select.appendChild(option)\n }\n\n wrapper.appendChild(labelEl)\n wrapper.appendChild(select)\n\n wrapper.setValue = (val) => {\n select.value = val\n }\n\n return wrapper\n}\n\n/**\n * Create a button\n * @param {Object} options\n * @returns {HTMLElement}\n */\nexport function createButton({ label, className = '', onClick, icon = null, disabled = false }) {\n const button = el('button', {\n type: 'button',\n className: `btn ${className}`.trim(),\n onClick,\n disabled: disabled ? 'disabled' : undefined\n })\n\n if (icon) {\n const iconEl = el('span', { className: 'btn-icon' })\n iconEl.innerHTML = icon\n // Mark decorative icon SVG as hidden from screen readers\n const svg = iconEl.querySelector('svg')\n if (svg) svg.setAttribute('aria-hidden', 'true')\n button.appendChild(iconEl)\n }\n\n if (label) {\n button.appendChild(document.createTextNode(label))\n }\n\n return button\n}\n\n/**\n * Create an icon button\n * @param {Object} options\n * @returns {HTMLElement}\n */\nexport function createIconButton({ icon, title, className = '', onClick, disabled = false, testId = null, ariaLabel = null }) {\n const attrs = {\n type: 'button',\n className: `icon-btn ${className}`.trim(),\n title,\n 'aria-label': ariaLabel || title,\n onClick,\n disabled: disabled ? 'disabled' : undefined\n }\n\n if (testId) {\n attrs.dataset = { testid: testId }\n }\n\n const button = el('button', attrs)\n\n button.innerHTML = icon\n // Mark decorative icon SVG as hidden from screen readers\n const svg = button.querySelector('svg')\n if (svg) svg.setAttribute('aria-hidden', 'true')\n return button\n}\n\n/**\n * Create a chip/tag\n * @param {Object} options\n * @returns {HTMLElement}\n */\nexport function createChip({ label, icon, active = false, onClick }) {\n const chip = el('button', {\n type: 'button',\n className: `chip ${active ? 'active' : ''}`.trim(),\n onClick\n })\n\n if (icon) {\n const iconEl = el('span', { className: 'chip-icon' })\n iconEl.innerHTML = icon\n // Mark decorative icon SVG as hidden from screen readers\n const svg = iconEl.querySelector('svg')\n if (svg) svg.setAttribute('aria-hidden', 'true')\n chip.appendChild(iconEl)\n }\n\n chip.appendChild(el('span', { className: 'chip-label' }, label))\n\n chip.setActive = (isActive) => {\n chip.classList.toggle('active', isActive)\n }\n\n return chip\n}\n\n/**\n * Create a card component\n * @param {Object} options\n * @returns {HTMLElement}\n */\nexport function createCard({ className = '', children = [] }) {\n const card = el('div', { className: `card ${className}`.trim() })\n\n for (const child of children) {\n card.appendChild(child)\n }\n\n return card\n}\n\n/**\n * Create scrollable container\n * @param {Object} options\n * @returns {HTMLElement}\n */\nexport function createScrollContainer({ className = '', horizontal = false, children = [] }) {\n const container = el('div', {\n className: `scroll-container ${horizontal ? 'horizontal' : 'vertical'} ${className}`.trim()\n })\n\n for (const child of children) {\n container.appendChild(child)\n }\n\n return container\n}\n","/**\n * Toolbar component for the vanilla image editor\n * Provides zoom controls, mode switching, and action buttons\n */\nimport { el, createIconButton } from './UIBuilder.js'\nimport * as icons from '../icons/icons.js'\n\nexport class Toolbar {\n constructor(state, editor) {\n this.state = state\n this.editor = editor\n this.element = null\n this._removeBgBtn = null\n this._removeBgTierSelect = null\n this._removeBgStatus = null\n this._removeBgTier = 'balanced'\n this._unsubscribers = []\n }\n\n /**\n * Create and render the toolbar\n * @returns {HTMLElement}\n */\n render() {\n this.element = el('div', { className: 'editor-toolbar' })\n\n // Left section - Open image\n const leftSection = el('div', { className: 'toolbar-section toolbar-left' })\n\n const openBtn = createIconButton({\n icon: icons.openFolder,\n title: 'Open Image',\n className: 'toolbar-btn',\n testId: 'btn-open-image',\n ariaLabel: 'Open image file',\n onClick: () => this.editor.openFilePicker()\n })\n leftSection.appendChild(openBtn)\n\n // Center section - Zoom controls\n const centerSection = el('div', { className: 'toolbar-section toolbar-center' })\n\n const zoomOutBtn = createIconButton({\n icon: icons.zoomOut,\n title: 'Zoom Out',\n className: 'toolbar-btn',\n testId: 'btn-zoom-out',\n ariaLabel: 'Zoom out',\n onClick: () => {\n const current = this.state.get('zoom')\n this.editor.setZoom(current - 0.25)\n }\n })\n\n this._zoomLabel = el('span', {\n className: 'zoom-label',\n 'aria-live': 'polite',\n 'aria-atomic': 'true',\n role: 'status'\n }, '100%')\n\n const zoomInBtn = createIconButton({\n icon: icons.zoomIn,\n title: 'Zoom In',\n className: 'toolbar-btn',\n testId: 'btn-zoom-in',\n ariaLabel: 'Zoom in',\n onClick: () => {\n const current = this.state.get('zoom')\n this.editor.setZoom(current + 0.25)\n }\n })\n\n const fitBtn = createIconButton({\n icon: icons.expand,\n title: 'Fit to Screen',\n className: 'toolbar-btn',\n testId: 'btn-fit-screen',\n ariaLabel: 'Fit to screen',\n onClick: () => this.editor.fitToScreen()\n })\n\n centerSection.appendChild(zoomOutBtn)\n centerSection.appendChild(this._zoomLabel)\n centerSection.appendChild(zoomInBtn)\n centerSection.appendChild(fitBtn)\n\n // Right section - Theme toggle, Reset, Save, Close\n const rightSection = el('div', { className: 'toolbar-section toolbar-right' })\n\n this._themeBtn = createIconButton({\n icon: this.state.get('isDarkMode') ? icons.sunny : icons.moon,\n title: 'Toggle Theme',\n className: 'toolbar-btn toolbar-btn-theme',\n testId: 'btn-toggle-theme',\n ariaLabel: 'Toggle theme',\n onClick: () => this.editor.toggleTheme()\n })\n\n // Crop button (mobile only — hidden via CSS on desktop)\n this._cropBtn = createIconButton({\n icon: icons.crop,\n title: 'Crop',\n className: 'toolbar-btn toolbar-btn-crop',\n testId: 'btn-crop',\n ariaLabel: 'Crop image',\n onClick: () => {\n const currentMode = this.state.get('mode')\n if (currentMode === 'crop') {\n this.editor.setMode('filters')\n } else {\n this.editor.setMode('crop')\n }\n }\n })\n\n const removeBgGroup = el('div', { className: 'remove-bg-control' })\n this._removeBgTierSelect = el('select', {\n className: 'remove-bg-tier-select',\n title: 'Background removal quality',\n 'aria-label': 'Background removal quality',\n dataset: { testid: 'select-remove-background-tier' },\n onChange: (event) => {\n this._removeBgTier = event.target.value\n },\n })\n for (const option of [\n ['fast', 'Fast'],\n ['balanced', 'Balanced'],\n ['best', 'Best'],\n ]) {\n const optionEl = el('option', { value: option[0] }, option[1])\n if (option[0] === this._removeBgTier) optionEl.selected = true\n this._removeBgTierSelect.appendChild(optionEl)\n }\n\n this._removeBgBtn = createIconButton({\n icon: icons.personOutline,\n title: 'Remove Background',\n className: 'toolbar-btn toolbar-btn-remove-bg',\n testId: 'btn-remove-background',\n ariaLabel: 'Remove background',\n disabled: !this._canRemoveBackground(),\n onClick: async () => {\n if (!this._canRemoveBackground()) return\n this._setRemoveBgStatus('Removing background...')\n try {\n await this.editor.removeBackground({ tier: this._removeBgTier })\n this._setRemoveBgStatus('Background removed')\n } catch (_error) {\n this._setRemoveBgStatus('Background removal failed')\n } finally {\n this._updateRemoveBgButton()\n }\n }\n })\n\n this._removeBgStatus = el('span', {\n className: 'sr-only',\n role: 'status',\n 'aria-live': 'polite',\n 'aria-atomic': 'true',\n })\n\n removeBgGroup.appendChild(this._removeBgTierSelect)\n removeBgGroup.appendChild(this._removeBgBtn)\n removeBgGroup.appendChild(this._removeBgStatus)\n\n const resetBtn = createIconButton({\n icon: icons.refresh,\n title: 'Reset All',\n className: 'toolbar-btn',\n testId: 'btn-reset-all',\n ariaLabel: 'Reset all changes',\n onClick: () => this.editor.resetAll()\n })\n\n const saveBtn = createIconButton({\n icon: icons.save,\n title: 'Save Image',\n className: 'toolbar-btn toolbar-btn-primary',\n testId: 'btn-save-edit',\n ariaLabel: 'Save image',\n onClick: () => this.editor.save()\n })\n\n const closeBtn = createIconButton({\n icon: icons.close,\n title: 'Close',\n className: 'toolbar-btn',\n testId: 'btn-cancel-edit',\n ariaLabel: 'Close editor',\n onClick: () => this.editor.close()\n })\n\n rightSection.appendChild(this._themeBtn)\n rightSection.appendChild(this._cropBtn)\n rightSection.appendChild(removeBgGroup)\n rightSection.appendChild(resetBtn)\n rightSection.appendChild(saveBtn)\n rightSection.appendChild(closeBtn)\n\n // Assemble toolbar\n this.element.appendChild(leftSection)\n this.element.appendChild(centerSection)\n this.element.appendChild(rightSection)\n\n // Subscribe to state changes\n this._subscribeToState()\n\n return this.element\n }\n\n /**\n * Subscribe to state changes\n */\n _subscribeToState() {\n // Zoom changes\n const unsubZoom = this.state.on('change:zoom', ({ value }) => {\n this._zoomLabel.textContent = `${Math.round(value * 100)}%`\n })\n this._unsubscribers.push(unsubZoom)\n\n // Theme changes\n const unsubTheme = this.state.on('change:isDarkMode', ({ value }) => {\n this._themeBtn.innerHTML = value ? icons.sunny : icons.moon\n })\n this._unsubscribers.push(unsubTheme)\n\n // Mode changes — update crop button active state\n const unsubMode = this.state.on('change:mode', ({ value }) => {\n if (this._cropBtn) {\n this._cropBtn.classList.toggle('toolbar-btn-primary', value === 'crop')\n }\n })\n this._unsubscribers.push(unsubMode)\n\n const unsubHasImage = this.state.on('change:hasImage', () => this._updateRemoveBgButton())\n this._unsubscribers.push(unsubHasImage)\n\n const unsubProcessing = this.state.on('change:isProcessing', () => this._updateRemoveBgButton())\n this._unsubscribers.push(unsubProcessing)\n\n const unsubAvailability = this.state.on('change:backgroundRemovalAvailable', () => this._updateRemoveBgButton())\n this._unsubscribers.push(unsubAvailability)\n\n const unsubDocument = this.state.on('change:editorDocument', () => this._updateRemoveBgButton())\n this._unsubscribers.push(unsubDocument)\n\n const unsubLayers = this.state.on('change:layers', () => this._updateRemoveBgButton())\n this._unsubscribers.push(unsubLayers)\n\n const unsubActiveLayer = this.state.on('change:activeLayerId', () => this._updateRemoveBgButton())\n this._unsubscribers.push(unsubActiveLayer)\n }\n\n _canRemoveBackground() {\n if (typeof this.editor.canRemoveBackground === 'function') {\n return this.editor.canRemoveBackground()\n }\n\n return !!this.state.get('hasImage') && typeof this.editor.removeBackground === 'function'\n }\n\n _updateRemoveBgButton() {\n if (!this._removeBgBtn) return\n const busy = this.state.get('isProcessing') === true\n const disabled = !this._canRemoveBackground() || busy\n this._removeBgBtn.disabled = disabled\n this._removeBgBtn.setAttribute('aria-disabled', disabled ? 'true' : 'false')\n this._removeBgBtn.setAttribute('aria-busy', busy ? 'true' : 'false')\n if (this._removeBgTierSelect) {\n this._removeBgTierSelect.disabled = disabled\n this._removeBgTierSelect.setAttribute('aria-disabled', disabled ? 'true' : 'false')\n }\n }\n\n _setRemoveBgStatus(message) {\n if (this._removeBgStatus) {\n this._removeBgStatus.textContent = message\n }\n }\n\n /**\n * Update zoom display\n * @param {number} zoom\n */\n updateZoom(zoom) {\n if (this._zoomLabel) {\n this._zoomLabel.textContent = `${Math.round(zoom * 100)}%`\n }\n }\n\n /**\n * Clean up\n */\n destroy() {\n this._unsubscribers.forEach(unsub => unsub())\n this._unsubscribers = []\n this.element?.remove()\n this.element = null\n }\n}\n","/**\n * Category Carousel component for the vanilla image editor\n * Displays filter categories as scrollable chips\n */\nimport { el, createIconButton, createChip } from './UIBuilder.js'\nimport * as icons from '../icons/icons.js'\nimport {\n EDITOR_CATEGORIES,\n REGISTRY_TO_UI,\n getUiCategoryForRegistry,\n} from '../filters/categories.js'\n\nconst CATEGORIES = EDITOR_CATEGORIES\n\n// Back-compat exports for any downstream code still importing these names.\n// The canonical source now lives in filters/categories.js.\nexport { REGISTRY_TO_UI as REGISTRY_CATEGORY_MAP }\nexport { getUiCategoryForRegistry }\n\nexport class CategoryCarousel {\n constructor(state, editor) {\n this.state = state\n this.editor = editor\n this.element = null\n this._chips = new Map()\n this._scrollIndex = 0\n this._unsubscribers = []\n }\n\n /**\n * Create and render the category carousel\n * @param {Function} onSelect - Callback when category is selected\n * @returns {HTMLElement}\n */\n render(onSelect) {\n this._onSelect = onSelect\n this.element = el('div', {\n className: 'category-carousel-container',\n 'data-testid': 'category-carousel'\n })\n\n // Left navigation button\n this._leftBtn = createIconButton({\n icon: icons.chevronLeft,\n title: 'Previous categories',\n className: 'carousel-nav carousel-nav-left',\n onClick: () => this._scrollLeft()\n })\n\n // Carousel container\n this._carousel = el('div', { className: 'category-carousel' })\n\n // Create category chips\n CATEGORIES.forEach(cat => {\n const chip = createChip({\n label: cat.name,\n icon: cat.icon,\n active: this.state.get('selectedCategory') === cat.id,\n onClick: () => this._selectCategory(cat.id)\n })\n chip.dataset.categoryId = cat.id\n chip.dataset.category = cat.id\n chip.dataset.testid = `category-${cat.id}`\n this._chips.set(cat.id, chip)\n this._carousel.appendChild(chip)\n })\n\n // Right navigation button\n this._rightBtn = createIconButton({\n icon: icons.chevronRight,\n title: 'Next categories',\n className: 'carousel-nav carousel-nav-right',\n onClick: () => this._scrollRight()\n })\n\n // Pagination dots\n this._pagination = el('div', {\n className: 'carousel-pagination',\n role: 'tablist',\n 'aria-label': 'Category pages'\n })\n const pageCount = Math.ceil(CATEGORIES.length / 3)\n for (let i = 0; i < pageCount; i++) {\n const dot = el('button', {\n type: 'button',\n className: `pagination-dot ${i === 0 ? 'active' : ''}`,\n role: 'tab',\n 'aria-label': `Page ${i + 1} of ${pageCount}`,\n 'aria-selected': i === 0 ? 'true' : 'false',\n onClick: () => this._scrollToPage(i)\n })\n this._pagination.appendChild(dot)\n }\n\n // Assemble\n this.element.appendChild(this._leftBtn)\n this.element.appendChild(this._carousel)\n this.element.appendChild(this._rightBtn)\n this.element.appendChild(this._pagination)\n\n // Subscribe to state changes\n this._subscribeToState()\n\n // Update button states\n this._updateNavButtons()\n\n return this.element\n }\n\n /**\n * Subscribe to state changes\n */\n _subscribeToState() {\n const unsub = this.state.on('change:selectedCategory', ({ value }) => {\n this._chips.forEach((chip, id) => {\n chip.setActive(id === value)\n })\n })\n this._unsubscribers.push(unsub)\n }\n\n /**\n * Select a category\n * @param {string} categoryId\n */\n _selectCategory(categoryId) {\n this.state.set('selectedCategory', categoryId)\n\n // Only change mode when switching between crop ↔ filters.\n // Avoid calling setMode('filters') when already in filters mode —\n // it unnecessarily triggers cropManager.disable() + double applyFilters().\n const currentMode = this.state.get('mode')\n if (categoryId === 'crop') {\n if (currentMode !== 'crop') {\n this.editor.setMode('crop')\n }\n } else if (currentMode !== 'filters') {\n this.editor.setMode('filters')\n }\n\n // Scroll the selected chip into view\n const selectedChip = this._chips.get(categoryId)\n if (selectedChip && this._carousel) {\n selectedChip.scrollIntoView({ behavior: 'smooth', inline: 'center', block: 'nearest' })\n }\n\n this._onSelect?.(categoryId)\n }\n\n /**\n * Scroll carousel left\n */\n _scrollLeft() {\n if (this._scrollIndex > 0) {\n this._scrollIndex--\n this._scrollCarousel()\n }\n }\n\n /**\n * Scroll carousel right\n */\n _scrollRight() {\n if (this._scrollIndex < CATEGORIES.length - 3) {\n this._scrollIndex++\n this._scrollCarousel()\n }\n }\n\n /**\n * Scroll to a specific page\n * @param {number} pageIndex\n */\n _scrollToPage(pageIndex) {\n this._scrollIndex = pageIndex * 3\n this._scrollCarousel()\n }\n\n /**\n * Animate carousel scroll\n */\n _scrollCarousel() {\n if (this._carousel) {\n const chip = this._carousel.querySelector('.chip')\n const itemWidth = chip?.clientWidth || 100\n this._carousel.scrollTo({\n left: this._scrollIndex * (itemWidth + 8), // 8px gap\n behavior: 'smooth'\n })\n }\n this._updateNavButtons()\n this._updatePagination()\n }\n\n /**\n * Update navigation button states\n */\n _updateNavButtons() {\n if (this._leftBtn) {\n this._leftBtn.disabled = this._scrollIndex === 0\n }\n if (this._rightBtn) {\n this._rightBtn.disabled = this._scrollIndex >= CATEGORIES.length - 3\n }\n }\n\n /**\n * Update pagination dot states\n */\n _updatePagination() {\n if (this._pagination) {\n const dots = this._pagination.querySelectorAll('.pagination-dot')\n const activePage = Math.floor(this._scrollIndex / 3)\n dots.forEach((dot, i) => {\n const isActive = i === activePage\n dot.classList.toggle('active', isActive)\n dot.setAttribute('aria-selected', isActive ? 'true' : 'false')\n })\n }\n }\n\n /**\n * Set the selected category\n * @param {string} categoryId\n */\n setSelected(categoryId) {\n this._selectCategory(categoryId)\n }\n\n /**\n * Clean up\n */\n destroy() {\n this._unsubscribers.forEach(unsub => unsub())\n this._unsubscribers = []\n this._chips.clear()\n this.element?.remove()\n this.element = null\n }\n}\n","/**\n * Filter Carousel component for the vanilla image editor\n * Displays filters in the current category as scrollable cards\n */\nimport { el, createIconButton } from './UIBuilder.js'\nimport * as icons from '../icons/icons.js'\n\nexport class FilterCarousel {\n constructor(state, filterManager) {\n this.state = state\n this.filterManager = filterManager\n this.element = null\n this._filterCards = new Map()\n this._scrollIndex = 0\n this._unsubscribers = []\n this._onToggle = null\n this._onSelect = null\n }\n\n /**\n * Create and render the filter carousel\n * @param {Object} options - { onToggle, onSelect }\n * @returns {HTMLElement}\n */\n render({ onToggle, onSelect }) {\n this._onToggle = onToggle\n this._onSelect = onSelect\n\n this.element = el('div', { className: 'filter-carousel-container' })\n\n // Left navigation button\n this._leftBtn = createIconButton({\n icon: icons.chevronLeft,\n title: 'Previous filters',\n className: 'carousel-nav carousel-nav-left',\n onClick: () => this._scrollLeft()\n })\n\n // Carousel container\n this._carousel = el('div', { className: 'filter-carousel' })\n\n // Right navigation button\n this._rightBtn = createIconButton({\n icon: icons.chevronRight,\n title: 'Next filters',\n className: 'carousel-nav carousel-nav-right',\n onClick: () => this._scrollRight()\n })\n\n // Assemble\n this.element.appendChild(this._leftBtn)\n this.element.appendChild(this._carousel)\n this.element.appendChild(this._rightBtn)\n\n // Subscribe to state changes\n this._subscribeToState()\n\n // Initial render\n this._renderFilters()\n\n return this.element\n }\n\n /**\n * Subscribe to state changes\n */\n _subscribeToState() {\n // Re-render when category changes\n const unsubCat = this.state.on('change:selectedCategory', () => {\n this._renderFilters()\n })\n this._unsubscribers.push(unsubCat)\n\n // Update active states\n const unsubActive = this.state.on('change:activeFilters', () => {\n this._updateActiveStates()\n })\n this._unsubscribers.push(unsubActive)\n\n // Update selected state\n const unsubSelected = this.state.on('change:selectedFilter', () => {\n this._updateSelectedState()\n })\n this._unsubscribers.push(unsubSelected)\n }\n\n /**\n * Render filters for current category\n */\n _renderFilters() {\n // Clear existing\n this._carousel.innerHTML = ''\n this._filterCards.clear()\n this._scrollIndex = 0\n\n const category = this.state.get('selectedCategory')\n if (category === 'crop') return\n\n const filters = this.filterManager.getFiltersByCategory(category)\n const activeFilters = this.state.get('activeFilters')\n const selectedFilter = this.state.get('selectedFilter')\n\n filters.forEach(filter => {\n const card = this._createFilterCard(filter, {\n isActive: activeFilters.has(filter.id),\n isSelected: selectedFilter === filter.id\n })\n this._filterCards.set(filter.id, card)\n this._carousel.appendChild(card)\n })\n\n this._updateNavButtons()\n }\n\n /**\n * Create a filter card\n * @param {Object} filter\n * @param {Object} options\n * @returns {HTMLElement}\n */\n _createFilterCard(filter, { isActive, isSelected }) {\n const card = el('div', {\n className: `filter-card ${isActive ? 'active' : ''} ${isSelected ? 'selected' : ''}`,\n 'data-filter': filter.id,\n 'data-testid': `filter-${filter.id}`,\n onClick: () => this._handleCardClick(filter.id)\n })\n\n // Thumbnail/preview area\n const preview = el('div', { className: 'filter-preview' })\n const previewText = el('span', { className: 'filter-preview-text' }, filter.name.charAt(0))\n preview.appendChild(previewText)\n\n // Filter name\n const name = el('span', { className: 'filter-name', title: filter.name }, filter.name)\n\n // Toggle button (checkbox visual)\n const toggle = el('button', {\n className: `filter-toggle ${isActive ? 'active' : ''}`,\n onClick: (e) => {\n e.stopPropagation()\n // Check current state at click time, not creation time\n const currentlyActive = this.state.get('activeFilters').has(filter.id)\n const willBeActive = !currentlyActive\n this._handleToggle(filter.id, willBeActive)\n\n // UX improvement: When toggling a filter ON, also select it to show settings\n if (willBeActive) {\n this.state.set('selectedFilter', filter.id)\n this._onSelect?.(filter.id)\n }\n }\n })\n toggle.innerHTML = isActive ? icons.checkmark : ''\n\n card.appendChild(preview)\n card.appendChild(name)\n card.appendChild(toggle)\n\n // Store references for updates\n card._toggle = toggle\n card._isActive = isActive\n\n return card\n }\n\n /**\n * Handle filter card click (select)\n * @param {string} filterId\n */\n _handleCardClick(filterId) {\n const activeFilters = this.state.get('activeFilters')\n\n // If not active, toggle it on first\n if (!activeFilters.has(filterId)) {\n this._handleToggle(filterId, true)\n }\n\n this.state.set('selectedFilter', filterId)\n this._onSelect?.(filterId)\n }\n\n /**\n * Handle filter toggle\n * @param {string} filterId\n * @param {boolean} enabled\n */\n _handleToggle(filterId, enabled) {\n this._onToggle?.(filterId, enabled)\n }\n\n /**\n * Update active states based on state\n */\n _updateActiveStates() {\n const activeFilters = this.state.get('activeFilters')\n\n this._filterCards.forEach((card, filterId) => {\n const isActive = activeFilters.has(filterId)\n card.classList.toggle('active', isActive)\n card._toggle.classList.toggle('active', isActive)\n card._toggle.innerHTML = isActive ? icons.checkmark : ''\n card._isActive = isActive\n })\n }\n\n /**\n * Update selected state based on state\n */\n _updateSelectedState() {\n const selectedFilter = this.state.get('selectedFilter')\n\n this._filterCards.forEach((card, filterId) => {\n card.classList.toggle('selected', filterId === selectedFilter)\n })\n }\n\n /**\n * Scroll carousel left\n */\n _scrollLeft() {\n if (this._scrollIndex > 0) {\n this._scrollIndex--\n this._scrollCarousel()\n }\n }\n\n /**\n * Scroll carousel right\n */\n _scrollRight() {\n const maxIndex = Math.max(0, this._filterCards.size - 3)\n if (this._scrollIndex < maxIndex) {\n this._scrollIndex++\n this._scrollCarousel()\n }\n }\n\n /**\n * Animate carousel scroll\n */\n _scrollCarousel() {\n if (this._carousel) {\n const card = this._carousel.querySelector('.filter-card')\n const itemWidth = card?.clientWidth || 120\n this._carousel.scrollTo({\n left: this._scrollIndex * (itemWidth + 8),\n behavior: 'smooth'\n })\n }\n this._updateNavButtons()\n }\n\n /**\n * Update navigation button states\n */\n _updateNavButtons() {\n const maxIndex = Math.max(0, this._filterCards.size - 3)\n if (this._leftBtn) {\n this._leftBtn.disabled = this._scrollIndex === 0\n }\n if (this._rightBtn) {\n this._rightBtn.disabled = this._scrollIndex >= maxIndex\n }\n }\n\n /**\n * Clean up\n */\n destroy() {\n this._unsubscribers.forEach(unsub => unsub())\n this._unsubscribers = []\n this._filterCards.clear()\n this.element?.remove()\n this.element = null\n }\n}\n","/**\n * Filter Adjustments component for the vanilla image editor\n * Dynamic slider controls for the selected filter\n */\nimport { el, createSlider, createToggle, createColorPicker, createSelect, createButton, createTextInput } from './UIBuilder.js'\n\nexport class FilterAdjustments {\n constructor(state, filterManager) {\n this.state = state\n this.filterManager = filterManager\n this.element = null\n this._controls = new Map()\n this._onChange = null\n this._onReset = null\n this._onAction = null\n this._unsubscribers = []\n }\n\n /**\n * Create and render the filter adjustments panel\n * @param {Object} options - { onChange, onReset, onAction }\n * @returns {HTMLElement}\n */\n render({ onChange, onReset, onAction }) {\n this._onChange = onChange\n this._onReset = onReset\n this._onAction = onAction\n\n this.element = el('div', { className: 'filter-adjustments' })\n\n // Subscribe to state changes\n this._subscribeToState()\n\n // Initial render\n this._renderControls()\n\n return this.element\n }\n\n /**\n * Subscribe to state changes\n */\n _subscribeToState() {\n // Re-render when selected filter changes\n const unsubSelected = this.state.on('change:selectedFilter', () => {\n this._renderControls()\n })\n this._unsubscribers.push(unsubSelected)\n\n // Update values when filter values change\n const unsubValues = this.state.on('change:filterValues', () => {\n this._updateValues()\n })\n this._unsubscribers.push(unsubValues)\n }\n\n /**\n * Render controls for the selected filter.\n *\n * Renders both the static controls from def.controls and any dynamic\n * controls the filter instance exposes via getDynamicControls() (e.g.\n * per-stop color/offset/alpha rows for Color Gradient).\n */\n _renderControls() {\n this.element.innerHTML = ''\n this._controls.clear()\n\n const filterId = this.state.get('selectedFilter')\n if (!filterId) {\n this.element.appendChild(\n el('div', { className: 'no-filter-selected' }, 'Select a filter to adjust')\n )\n return\n }\n\n const def = this.filterManager.getFilterDef(filterId)\n if (!def) {\n this.element.appendChild(\n el('div', { className: 'no-filter-selected' }, 'Filter not found')\n )\n return\n }\n\n // Header with filter name and reset button\n const header = el('div', { className: 'adjustments-header' })\n header.appendChild(el('span', { className: 'adjustments-title' }, def.name))\n header.appendChild(createButton({\n label: 'Reset',\n className: 'btn-text',\n onClick: () => this._handleReset(filterId)\n }))\n this.element.appendChild(header)\n\n // Controls grid\n const grid = el('div', { className: 'adjustments-grid' })\n\n const values = this.state.getFilterValues(filterId)\n\n // 1. Static controls from the filter definition\n ;(def.controls || []).forEach(ctl => {\n const value = values[ctl.id] ?? ctl.default\n const controlEl = this._createControl(filterId, ctl, value)\n if (controlEl) {\n this._controls.set(ctl.id, controlEl)\n grid.appendChild(controlEl)\n }\n })\n\n // 2. Dynamic controls from the filter instance (e.g. color stops)\n const instance = this.filterManager.getInstance(filterId)\n if (instance && typeof instance.getDynamicControls === 'function') {\n let dynamicControls = []\n try {\n dynamicControls = instance.getDynamicControls() || []\n } catch (err) {\n console.error('[FilterAdjustments] getDynamicControls threw:', err)\n }\n dynamicControls.forEach(ctl => {\n // Dynamic controls use their 'property' path as the update key\n // (e.g. 'colorStops[0].color'). Fall back to id.\n const stateKey = ctl.property || ctl.id\n const value = values[stateKey] ?? ctl.default\n const controlEl = this._createControl(filterId, ctl, value)\n if (controlEl) {\n this._controls.set(ctl.id, controlEl)\n grid.appendChild(controlEl)\n }\n })\n }\n\n this.element.appendChild(grid)\n }\n\n /**\n * Create a control element based on type.\n *\n * The update key passed to _handleChange is `ctl.property || ctl.id`.\n * Dynamic controls (e.g. from getDynamicControls) use their property\n * path (e.g. 'colorStops[0].color') so FilterManager.updateValue can\n * route the write correctly. Static controls without a property fall\n * back to the control id, matching the legacy contract.\n *\n * @param {string} filterId\n * @param {Object} ctl - Control definition\n * @param {*} value - Current value\n * @returns {HTMLElement|null}\n */\n _createControl(filterId, ctl, value) {\n // Skip hidden controls\n if (ctl.hidden) return null\n\n // Get the control label (prefer label, fallback to id)\n const label = ctl.label || ctl.id\n\n // Normalize control type (handle aliases)\n const controlType = this._normalizeControlType(ctl.type)\n\n // Update key: dynamic controls pass their property path; static ones\n // use their id (FilterManager.updateValue resolves property via the\n // control definition for static controls).\n const updateKey = ctl.property || ctl.id\n\n switch (controlType) {\n case 'slider':\n return createSlider({\n id: `${filterId}-${ctl.id}`,\n label: label,\n min: ctl.min ?? 0,\n max: ctl.max ?? 1,\n step: ctl.step ?? 0.01,\n value: typeof value === 'number' ? value : (ctl.default ?? 0),\n onChange: (val) => this._handleChange(filterId, updateKey, val)\n })\n\n case 'toggle':\n return createToggle({\n id: `${filterId}-${ctl.id}`,\n label: label,\n checked: !!value,\n onChange: (val) => this._handleChange(filterId, updateKey, val)\n })\n\n case 'color':\n return createColorPicker({\n id: `${filterId}-${ctl.id}`,\n label: label,\n value: typeof value === 'string' && value.startsWith('#') ? value : (ctl.default || '#000000'),\n onChange: (val) => this._handleChange(filterId, updateKey, val)\n })\n\n case 'select':\n // Normalize options format\n const options = this._normalizeOptions(ctl.options)\n return createSelect({\n id: `${filterId}-${ctl.id}`,\n label: label,\n options: options,\n value: value ?? ctl.default,\n onChange: (val) => this._handleChange(filterId, updateKey, val)\n })\n\n case 'text':\n return createTextInput({\n id: `${filterId}-${ctl.id}`,\n label: label,\n value: typeof value === 'string' ? value : (ctl.default ?? ''),\n placeholder: ctl.placeholder || '',\n onCommit: (val) => this._handleChange(filterId, updateKey, val)\n })\n\n case 'button':\n const wrapper = el('div', { className: 'button-control' })\n wrapper.appendChild(createButton({\n label: label,\n className: 'btn-secondary',\n onClick: () => this._handleAction(filterId, ctl.action || ctl.id)\n }))\n return wrapper\n\n default:\n console.warn(`[FilterAdjustments] Unknown control type: ${ctl.type}`)\n return null\n }\n }\n\n /**\n * Normalize control type (handle aliases)\n * @param {string} type\n * @returns {string}\n */\n _normalizeControlType(type) {\n const typeMap = {\n 'slider': 'slider',\n 'range': 'slider',\n 'toggle': 'toggle',\n 'checkbox': 'toggle',\n 'color': 'color',\n 'select': 'select',\n 'dropdown': 'select',\n 'button': 'button',\n 'text': 'text'\n }\n return typeMap[type] || type\n }\n\n /**\n * Normalize options array format\n * @param {Array} options\n * @returns {Array}\n */\n _normalizeOptions(options) {\n if (!options || !Array.isArray(options)) return []\n\n return options.map(opt => {\n // Already in { value, label } format\n if (typeof opt === 'object' && opt.value !== undefined) {\n return { value: opt.value, label: opt.label || String(opt.value) }\n }\n // Simple string value\n if (typeof opt === 'string') {\n return { value: opt, label: opt }\n }\n // Number value\n if (typeof opt === 'number') {\n return { value: opt, label: String(opt) }\n }\n return { value: opt, label: String(opt) }\n })\n }\n\n /**\n * Handle control value change\n * @param {string} filterId\n * @param {string} controlId\n * @param {*} value\n */\n _handleChange(filterId, controlId, value) {\n this._onChange?.(filterId, controlId, value)\n }\n\n /**\n * Handle reset button\n * @param {string} filterId\n */\n _handleReset(filterId) {\n this._onReset?.(filterId)\n this._renderControls() // Re-render to show default values\n }\n\n /**\n * Handle button action. Dynamic controls (e.g. color stop rows) depend on\n * filter state that can change as a result of the action (add/remove stop),\n * so re-render after the action completes.\n *\n * @param {string} filterId\n * @param {string} action\n */\n _handleAction(filterId, action) {\n this._onAction?.(filterId, action)\n this._renderControls()\n }\n\n /**\n * Update control values from state\n */\n _updateValues() {\n const filterId = this.state.get('selectedFilter')\n if (!filterId) return\n\n const values = this.state.getFilterValues(filterId)\n const def = this.filterManager.getFilterDef(filterId)\n if (!def) return\n\n def.controls.forEach(ctl => {\n const controlEl = this._controls.get(ctl.id)\n if (controlEl && typeof controlEl.setValue === 'function') {\n const value = values[ctl.id] ?? ctl.default\n controlEl.setValue(value)\n }\n })\n }\n\n /**\n * Show panel\n */\n show() {\n if (this.element) {\n this.element.style.display = ''\n }\n }\n\n /**\n * Hide panel\n */\n hide() {\n if (this.element) {\n this.element.style.display = 'none'\n }\n }\n\n /**\n * Clean up\n */\n destroy() {\n this._unsubscribers.forEach(unsub => unsub())\n this._unsubscribers = []\n this._controls.clear()\n this.element?.remove()\n this.element = null\n }\n}\n","/**\n * Mobile Filter Drawer - Inline panel that replaces carousels for filter adjustments\n * Sized to match the controls section height, scrollable within that space\n */\nimport { el, createSlider, createToggle, createColorPicker, createSelect, createButton, createIconButton, createTextInput } from './UIBuilder.js'\nimport * as icons from '../icons/icons.js'\n\nexport class MobileFilterDrawer {\n constructor(state, filterManager) {\n this.state = state\n this.filterManager = filterManager\n this._drawer = null\n this._body = null\n this._titleEl = null\n this._isOpen = false\n this._currentFilterId = null\n this._controls = new Map()\n this._onChange = null\n this._onReset = null\n this._onRemove = null\n this._onAction = null\n this._container = null\n }\n\n /**\n * Build the drawer DOM and append to container (should be the controls section)\n * @param {HTMLElement} container - Parent element (controls-section)\n * @param {Object} callbacks - { onChange, onReset, onRemove, onAction }\n */\n build(container, { onChange, onReset, onRemove, onAction }) {\n this._onChange = onChange\n this._onReset = onReset\n this._onRemove = onRemove\n this._onAction = onAction\n this._container = container\n\n // Drawer panel — absolutely positioned within controls section\n this._drawer = el('div', { className: 'mobile-filter-drawer' })\n\n // Header — compact: filter name + reset + close\n const header = el('div', { className: 'drawer-header' })\n this._titleEl = el('span', { className: 'drawer-title' }, 'Filter')\n\n const headerActions = el('div', { className: 'drawer-header-actions' })\n\n const resetBtn = createButton({\n label: 'Reset',\n className: 'btn-text',\n onClick: () => {\n if (this._currentFilterId) {\n this._onReset?.(this._currentFilterId)\n this._renderControls()\n }\n }\n })\n\n const removeBtn = createButton({\n label: 'Remove',\n className: 'btn-text btn-danger',\n onClick: () => {\n if (this._currentFilterId) {\n this._onRemove?.(this._currentFilterId)\n this.close()\n }\n }\n })\n\n const closeBtn = createIconButton({\n icon: icons.close,\n title: 'Close',\n className: 'btn-icon-sm',\n ariaLabel: 'Close drawer',\n onClick: () => this.close()\n })\n\n headerActions.appendChild(resetBtn)\n headerActions.appendChild(removeBtn)\n headerActions.appendChild(closeBtn)\n header.appendChild(this._titleEl)\n header.appendChild(headerActions)\n this._drawer.appendChild(header)\n\n // Body (scrollable controls area)\n this._body = el('div', { className: 'drawer-body' })\n this._drawer.appendChild(this._body)\n\n // Append to container\n container.appendChild(this._drawer)\n }\n\n /**\n * Open the drawer for a specific filter\n * @param {string} filterId\n */\n open(filterId) {\n if (this._isOpen && this._currentFilterId === filterId) return\n\n this._currentFilterId = filterId\n this._renderControls()\n\n if (!this._isOpen) {\n this._isOpen = true\n this._sizeToContainer()\n this._animateOpen()\n }\n }\n\n /**\n * Close the drawer\n */\n close() {\n if (!this._isOpen) return\n this._isOpen = false\n this._animateClose()\n this._currentFilterId = null\n }\n\n /**\n * Check if drawer is open\n * @returns {boolean}\n */\n get isOpen() {\n return this._isOpen\n }\n\n /**\n * Size the drawer to match the container (controls section) height\n */\n _sizeToContainer() {\n if (!this._container || !this._drawer) return\n const h = this._container.offsetHeight\n if (h > 0) {\n this._drawer.style.height = h + 'px'\n }\n }\n\n /**\n * Animate drawer open (CSS transition)\n */\n _animateOpen() {\n this._drawer.style.transition = 'none'\n this._drawer.style.transform = 'translateY(100%)'\n this._drawer.offsetHeight // force reflow\n this._drawer.style.transition = 'transform 0.25s cubic-bezier(0.33, 1, 0.68, 1)'\n this._drawer.style.transform = 'translateY(0)'\n }\n\n /**\n * Animate drawer close (CSS transition)\n */\n _animateClose() {\n this._drawer.style.transition = 'transform 0.2s cubic-bezier(0.32, 0, 0.67, 0)'\n this._drawer.style.transform = 'translateY(100%)'\n }\n\n /**\n * Render controls for the current filter.\n * Renders both static (def.controls) and dynamic (instance.getDynamicControls)\n * controls so filters like Color Gradient show per-stop rows.\n */\n _renderControls() {\n this._body.innerHTML = ''\n this._controls.clear()\n\n if (!this._currentFilterId) return\n\n const def = this.filterManager.getFilterDef(this._currentFilterId)\n if (!def) return\n\n this._titleEl.textContent = def.name\n\n const grid = el('div', { className: 'adjustments-grid' })\n const values = this.state.getFilterValues(this._currentFilterId)\n\n // Static controls\n ;(def.controls || []).forEach(ctl => {\n if (ctl.hidden) return\n const controlEl = this._createControl(this._currentFilterId, ctl, values[ctl.id] ?? ctl.default)\n if (controlEl) {\n this._controls.set(ctl.id, controlEl)\n grid.appendChild(controlEl)\n }\n })\n\n // Dynamic controls (e.g. per-stop color gradient rows)\n const instance = this.filterManager.getInstance(this._currentFilterId)\n if (instance && typeof instance.getDynamicControls === 'function') {\n let dynamicControls = []\n try {\n dynamicControls = instance.getDynamicControls() || []\n } catch (err) {\n console.error('[MobileFilterDrawer] getDynamicControls threw:', err)\n }\n dynamicControls.forEach(ctl => {\n const stateKey = ctl.property || ctl.id\n const value = values[stateKey] ?? ctl.default\n const controlEl = this._createControl(this._currentFilterId, ctl, value)\n if (controlEl) {\n this._controls.set(ctl.id, controlEl)\n grid.appendChild(controlEl)\n }\n })\n }\n\n this._body.appendChild(grid)\n }\n\n /**\n * Create a control element based on type. See FilterAdjustments._createControl\n * for the update-key contract (property path for dynamic controls, id for static).\n * @param {string} filterId\n * @param {Object} ctl\n * @param {*} value\n * @returns {HTMLElement|null}\n */\n _createControl(filterId, ctl, value) {\n if (ctl.hidden) return null\n const label = ctl.label || ctl.id\n const controlType = this._normalizeControlType(ctl.type)\n const updateKey = ctl.property || ctl.id\n\n switch (controlType) {\n case 'slider':\n return createSlider({\n id: `drawer-${filterId}-${ctl.id}`,\n label,\n min: ctl.min ?? 0,\n max: ctl.max ?? 1,\n step: ctl.step ?? 0.01,\n value: typeof value === 'number' ? value : (ctl.default ?? 0),\n onChange: (val) => this._onChange?.(filterId, updateKey, val)\n })\n\n case 'toggle':\n return createToggle({\n id: `drawer-${filterId}-${ctl.id}`,\n label,\n checked: !!value,\n onChange: (val) => this._onChange?.(filterId, updateKey, val)\n })\n\n case 'color':\n return createColorPicker({\n id: `drawer-${filterId}-${ctl.id}`,\n label,\n value: typeof value === 'string' && value.startsWith('#') ? value : (ctl.default || '#000000'),\n onChange: (val) => this._onChange?.(filterId, updateKey, val)\n })\n\n case 'select': {\n const options = this._normalizeOptions(ctl.options)\n return createSelect({\n id: `drawer-${filterId}-${ctl.id}`,\n label,\n options,\n value: value ?? ctl.default,\n onChange: (val) => this._onChange?.(filterId, updateKey, val)\n })\n }\n\n case 'text':\n return createTextInput({\n id: `drawer-${filterId}-${ctl.id}`,\n label,\n value: typeof value === 'string' ? value : (ctl.default ?? ''),\n placeholder: ctl.placeholder || '',\n onCommit: (val) => this._onChange?.(filterId, updateKey, val)\n })\n\n case 'button': {\n const wrapper = el('div', { className: 'button-control' })\n wrapper.appendChild(createButton({\n label,\n className: 'btn-secondary',\n onClick: () => {\n this._onAction?.(filterId, ctl.action || ctl.id)\n // Re-render so dynamic controls pick up state changes from the action\n this._renderControls()\n }\n }))\n return wrapper\n }\n\n default:\n return null\n }\n }\n\n /**\n * Normalize control type\n * @param {string} type\n * @returns {string}\n */\n _normalizeControlType(type) {\n const typeMap = {\n 'slider': 'slider',\n 'range': 'slider',\n 'toggle': 'toggle',\n 'checkbox': 'toggle',\n 'color': 'color',\n 'select': 'select',\n 'dropdown': 'select',\n 'button': 'button',\n 'text': 'text'\n }\n return typeMap[type] || type\n }\n\n /**\n * Normalize options array\n * @param {Array} options\n * @returns {Array}\n */\n _normalizeOptions(options) {\n if (!options || !Array.isArray(options)) return []\n return options.map(opt => {\n if (typeof opt === 'object' && opt.value !== undefined) {\n return { value: opt.value, label: opt.label || String(opt.value) }\n }\n if (typeof opt === 'string') return { value: opt, label: opt }\n if (typeof opt === 'number') return { value: opt, label: String(opt) }\n return { value: opt, label: String(opt) }\n })\n }\n\n /**\n * Clean up\n */\n destroy() {\n this._controls.clear()\n this._drawer?.remove()\n this._drawer = null\n this._isOpen = false\n this._currentFilterId = null\n this._container = null\n }\n}\n","/**\n * Mobile Active Filters Carousel\n * Horizontal scrollable row of active filter chips with checkmark toggles.\n * Shown below the filter carousel on mobile only.\n */\nimport { el } from './UIBuilder.js'\n\nexport class MobileActiveFilters {\n constructor(state, filterManager) {\n this.state = state\n this.filterManager = filterManager\n this.element = null\n this._scrollContainer = null\n this._chips = new Map()\n this._unsubscribers = []\n this._onToggle = null\n this._onSelect = null\n }\n\n /**\n * @param {Object} callbacks - { onToggle(filterId, enabled), onSelect(filterId) }\n * @returns {HTMLElement}\n */\n render({ onToggle, onSelect }) {\n this._onToggle = onToggle\n this._onSelect = onSelect\n\n this.element = el('div', {\n className: 'mobile-active-filters',\n 'data-testid': 'mobile-active-filters'\n })\n\n this._scrollContainer = el('div', { className: 'mobile-active-filters-scroll' })\n this.element.appendChild(this._scrollContainer)\n\n this._subscribeToState()\n this._renderChips()\n\n return this.element\n }\n\n _subscribeToState() {\n const unsubActive = this.state.on('change:activeFilters', () => {\n this._renderChips()\n })\n this._unsubscribers.push(unsubActive)\n\n const unsubSelected = this.state.on('change:selectedFilter', () => {\n this._updateSelectedState()\n })\n this._unsubscribers.push(unsubSelected)\n }\n\n _renderChips() {\n this._scrollContainer.innerHTML = ''\n this._chips.clear()\n\n const activeFilters = this.state.get('activeFilters')\n\n if (!activeFilters || activeFilters.size === 0) {\n const placeholder = el('div', {\n className: 'active-filter-placeholder'\n }, 'No active filters')\n this._scrollContainer.appendChild(placeholder)\n return\n }\n\n activeFilters.forEach(filterId => {\n const def = this.filterManager.getFilterDef(filterId)\n if (!def) return\n\n const chip = this._createChip(filterId, def)\n this._chips.set(filterId, chip)\n this._scrollContainer.appendChild(chip)\n })\n\n this._updateSelectedState()\n }\n\n _createChip(filterId, def) {\n const chip = el('div', {\n className: 'active-filter-chip',\n 'data-filter-id': filterId,\n 'data-testid': `active-chip-${filterId}`\n })\n\n // Filter name — tap to open drawer\n const label = el('span', {\n className: 'active-filter-chip-label',\n onClick: (e) => {\n e.stopPropagation()\n this._onSelect?.(filterId)\n }\n }, def.name)\n\n // Checkmark toggle — tap to remove filter\n const check = el('button', {\n className: 'active-filter-chip-check',\n 'aria-label': `Remove ${def.name} filter`,\n onClick: (e) => {\n e.stopPropagation()\n this._onToggle?.(filterId, false)\n }\n })\n check.innerHTML = '<svg width=\"10\" height=\"10\" viewBox=\"0 0 12 12\"><path d=\"M2 6l3 3 5-5\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>'\n\n chip.appendChild(label)\n chip.appendChild(check)\n\n return chip\n }\n\n _updateSelectedState() {\n const selectedFilter = this.state.get('selectedFilter')\n this._chips.forEach((chip, filterId) => {\n chip.classList.toggle('selected', filterId === selectedFilter)\n })\n }\n\n destroy() {\n this._unsubscribers.forEach(unsub => unsub())\n this._unsubscribers = []\n this._chips.clear()\n this.element?.remove()\n this.element = null\n }\n}\n","/**\n * Crop Controls component for the vanilla image editor\n * Provides shape selection and aspect ratio controls\n */\nimport { el, createButton, createChip } from './UIBuilder.js'\nimport * as icons from '../icons/icons.js'\n\nconst SHAPES = [\n { id: 'free', name: 'Free', icon: icons.freeform },\n { id: 'square', name: 'Square', icon: icons.square },\n { id: 'circle', name: 'Circle', icon: icons.circle }\n]\n\nconst ASPECT_RATIOS = [\n { id: 'free', name: 'Free' },\n { id: '1:1', name: '1:1' },\n { id: '4:3', name: '4:3' },\n { id: '16:9', name: '16:9' },\n { id: '3:2', name: '3:2' },\n { id: '2:3', name: '2:3' }\n]\n\nconst ROTATION_PRESETS = [\n { id: '0', label: '0°', angle: 0 },\n { id: '90', label: '90°', angle: 90 },\n { id: '180', label: '180°', angle: 180 },\n { id: '270', label: '270°', angle: 270 }\n]\n\nfunction normalizeAngle(angle) {\n if (!Number.isFinite(Number(angle))) return 0\n const normalized = Number(angle) % 360\n return normalized < 0 ? normalized + 360 : normalized\n}\n\nexport class CropControls {\n constructor(state, cropManager, editor = null) {\n this.state = state\n this.cropManager = cropManager\n this.editor = editor\n this.element = null\n this._shapeChips = new Map()\n this._aspectChips = new Map()\n this._rotationPresetChips = new Map()\n this._rotationRange = null\n this._rotationNumber = null\n this._rotationValue = null\n this._unsubscribers = []\n }\n\n /**\n * Apply crop and return the editor UI to filter mode.\n * If crop application cannot complete, force-disable crop mode to avoid\n * leaving the editor stuck in crop controls.\n */\n _applyCropAndReturnToFilters() {\n const result = this.cropManager.apply()\n\n if (result === null && typeof this.cropManager.disable === 'function') {\n this.cropManager.disable()\n }\n\n this.state.set('selectedCategory', 'adjust')\n }\n\n /**\n * Create and render the crop controls\n * @returns {HTMLElement}\n */\n render() {\n this.element = el('div', {\n className: 'crop-controls',\n 'data-testid': 'crop-controls'\n })\n\n this.element.appendChild(this._renderRotationSection())\n\n // Shape selection section\n const shapeSection = el('div', { className: 'crop-section' })\n shapeSection.appendChild(el('label', { className: 'section-label' }, 'Shape'))\n\n const shapeRow = el('div', { className: 'chip-row' })\n const currentShape = this.state.get('crop.shape')\n\n SHAPES.forEach(shape => {\n const chip = createChip({\n label: shape.name,\n icon: shape.icon,\n active: currentShape === shape.id,\n onClick: () => this._selectShape(shape.id)\n })\n chip.dataset.shape = shape.id\n chip.dataset.testid = `crop-shape-${shape.id}`\n this._shapeChips.set(shape.id, chip)\n shapeRow.appendChild(chip)\n })\n\n shapeSection.appendChild(shapeRow)\n this.element.appendChild(shapeSection)\n\n // Hide shape section when shape is locked (preset enforces a specific shape)\n if (this.state.get('lockCropShape')) {\n shapeSection.style.display = 'none'\n }\n this._shapeSection = shapeSection\n\n // Aspect ratio section (only for free shape)\n this._aspectSection = el('div', { className: 'crop-section' })\n this._aspectSection.appendChild(el('label', { className: 'section-label' }, 'Aspect Ratio'))\n\n const aspectRow = el('div', { className: 'chip-row aspect-row' })\n const currentAspect = this.state.get('crop.aspect')\n\n ASPECT_RATIOS.forEach(aspect => {\n const chip = createChip({\n label: aspect.name,\n active: currentAspect === aspect.id,\n onClick: () => this._selectAspect(aspect.id)\n })\n chip.dataset.ratio = aspect.id\n chip.dataset.testid = `crop-ratio-${aspect.id}`\n this._aspectChips.set(aspect.id, chip)\n aspectRow.appendChild(chip)\n })\n\n this._aspectSection.appendChild(aspectRow)\n this.element.appendChild(this._aspectSection)\n\n // Show/hide aspect ratios based on shape\n this._updateAspectVisibility()\n\n // Action buttons\n const actionRow = el('div', { className: 'crop-actions' })\n\n const cancelBtn = createButton({\n label: 'Cancel',\n className: 'btn-secondary crop-cancel-btn',\n icon: icons.close,\n onClick: () => this.cropManager.cancel()\n })\n cancelBtn.dataset.testid = 'cancel-crop'\n\n const applyBtn = createButton({\n label: 'Apply Crop',\n className: 'btn-primary crop-apply-btn',\n icon: icons.checkmark,\n onClick: () => this._applyCropAndReturnToFilters()\n })\n applyBtn.dataset.testid = 'apply-crop'\n\n actionRow.appendChild(cancelBtn)\n actionRow.appendChild(applyBtn)\n this.element.appendChild(actionRow)\n\n // Subscribe to state changes\n this._subscribeToState()\n\n return this.element\n }\n\n _renderRotationSection() {\n const section = el('div', { className: 'crop-section rotation-section' })\n section.appendChild(el('label', { className: 'section-label' }, 'Rotate'))\n\n const quickRow = el('div', { className: 'rotation-action-row' })\n const rotateLeft = createButton({\n label: 'Left 90°',\n className: 'btn-secondary rotation-action-btn',\n icon: icons.rotateCcw,\n onClick: () => this._rotateBy(-90)\n })\n rotateLeft.dataset.testid = 'rotate-left-90'\n\n const rotateRight = createButton({\n label: 'Right 90°',\n className: 'btn-secondary rotation-action-btn',\n icon: icons.rotateCw,\n onClick: () => this._rotateBy(90)\n })\n rotateRight.dataset.testid = 'rotate-right-90'\n\n const rotateHalf = createButton({\n label: 'Rotate 180°',\n className: 'btn-secondary rotation-action-btn',\n onClick: () => this._rotateBy(180)\n })\n rotateHalf.dataset.testid = 'rotate-180'\n\n const rotateThreeQuarter = createButton({\n label: 'Rotate 270°',\n className: 'btn-secondary rotation-action-btn',\n onClick: () => this._rotateBy(270)\n })\n rotateThreeQuarter.dataset.testid = 'rotate-270'\n\n quickRow.appendChild(rotateLeft)\n quickRow.appendChild(rotateRight)\n quickRow.appendChild(rotateHalf)\n quickRow.appendChild(rotateThreeQuarter)\n section.appendChild(quickRow)\n\n const presetRow = el('div', { className: 'chip-row rotation-preset-row' })\n const current = normalizeAngle(this.state.get('transform.rotation') ?? 0)\n ROTATION_PRESETS.forEach(preset => {\n const chip = createChip({\n label: preset.label,\n active: Math.round(current) === preset.angle,\n onClick: () => this._setRotation(preset.angle)\n })\n chip.dataset.angle = preset.id\n chip.dataset.testid = `rotation-preset-${preset.id}`\n this._rotationPresetChips.set(preset.id, chip)\n presetRow.appendChild(chip)\n })\n section.appendChild(presetRow)\n\n const arbitrary = el('div', { className: 'rotation-arbitrary' })\n const header = el('div', { className: 'rotation-angle-header' },\n el('label', { className: 'rotation-angle-label', for: 'image-editor-rotation-angle' }, 'Angle'),\n el('span', { className: 'rotation-angle-value' }, this._formatAngle(current))\n )\n this._rotationValue = header.querySelector('.rotation-angle-value')\n\n this._rotationRange = el('input', {\n id: 'image-editor-rotation-angle',\n type: 'range',\n className: 'slider-input rotation-range',\n min: '0',\n max: '360',\n step: '1',\n value: String(Math.round(current)),\n 'aria-label': 'Rotation angle',\n onInput: (event) => this._previewAngleValue(event.target.value),\n onChange: (event) => this._setRotation(Number(event.target.value))\n })\n\n this._rotationNumber = el('input', {\n type: 'number',\n className: 'text-input rotation-number-input',\n min: '-360',\n max: '360',\n step: '1',\n value: this._formatPlainAngle(current),\n 'aria-label': 'Rotation angle in degrees',\n onKeyDown: (event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n this._setRotation(Number(event.target.value))\n event.target.blur()\n }\n },\n onBlur: (event) => this._setRotation(Number(event.target.value))\n })\n\n const inputRow = el('div', { className: 'rotation-angle-row' },\n this._rotationRange,\n this._rotationNumber\n )\n\n arbitrary.appendChild(header)\n arbitrary.appendChild(inputRow)\n\n const reset = createButton({\n label: 'Reset rotation',\n className: 'btn-text rotation-reset-btn',\n onClick: () => this._setRotation(0)\n })\n reset.dataset.testid = 'reset-rotation'\n arbitrary.appendChild(reset)\n\n section.appendChild(arbitrary)\n\n return section\n }\n\n /**\n * Subscribe to state changes\n */\n _subscribeToState() {\n // Shape changes\n const unsubShape = this.state.on('change:crop.shape', ({ value }) => {\n this._shapeChips.forEach((chip, id) => {\n chip.setActive(id === value)\n })\n this._updateAspectVisibility()\n })\n this._unsubscribers.push(unsubShape)\n\n // Aspect changes\n const unsubAspect = this.state.on('change:crop.aspect', ({ value }) => {\n this._aspectChips.forEach((chip, id) => {\n chip.setActive(id === value)\n })\n })\n this._unsubscribers.push(unsubAspect)\n\n const unsubRotation = this.state.on('change:transform.rotation', ({ value }) => {\n this._syncRotationControls(value)\n })\n this._unsubscribers.push(unsubRotation)\n }\n\n _rotateBy(delta) {\n const rotated = this.editor?.rotateBy?.(delta)\n if (rotated === false) return\n this._syncRotationControls(this.state.get('transform.rotation') ?? 0)\n }\n\n _setRotation(angle) {\n const normalized = normalizeAngle(angle)\n const rotated = this.editor?.setRotationAngle?.(normalized)\n if (rotated === false) {\n this._syncRotationControls(this.state.get('transform.rotation') ?? 0)\n return\n }\n this._syncRotationControls(normalized)\n }\n\n _previewAngleValue(rawValue) {\n const normalized = normalizeAngle(Number(rawValue))\n if (this._rotationValue) {\n this._rotationValue.textContent = this._formatAngle(normalized)\n }\n if (this._rotationNumber) {\n this._rotationNumber.value = this._formatPlainAngle(normalized)\n }\n this._refreshPresetChips(normalized)\n }\n\n _syncRotationControls(value) {\n const normalized = normalizeAngle(value)\n if (this._rotationValue) {\n this._rotationValue.textContent = this._formatAngle(normalized)\n }\n if (this._rotationRange) {\n this._rotationRange.value = String(Math.round(normalized))\n }\n if (this._rotationNumber) {\n this._rotationNumber.value = this._formatPlainAngle(normalized)\n }\n this._refreshPresetChips(normalized)\n }\n\n _refreshPresetChips(angle) {\n const rounded = Math.round(normalizeAngle(angle)) % 360\n this._rotationPresetChips.forEach((chip, id) => {\n chip.setActive(Number(id) === rounded)\n })\n }\n\n _formatAngle(angle) {\n return `${this._formatPlainAngle(angle)}°`\n }\n\n _formatPlainAngle(angle) {\n const normalized = normalizeAngle(angle)\n return Number.isInteger(normalized) ? String(normalized) : normalized.toFixed(1)\n }\n\n /**\n * Select a crop shape\n * @param {string} shapeId\n */\n _selectShape(shapeId) {\n this.cropManager.setShape(shapeId)\n }\n\n /**\n * Select an aspect ratio\n * @param {string} aspectId\n */\n _selectAspect(aspectId) {\n this.cropManager.setAspect(aspectId)\n }\n\n /**\n * Update aspect ratio section visibility\n */\n _updateAspectVisibility() {\n const shape = this.state.get('crop.shape')\n const lockAspect = this.state.get('lockAspectRatio')\n // Hide aspect ratios when: shape is not free (circle/square are always 1:1),\n // OR aspect ratio is locked by preset\n if (this._aspectSection) {\n this._aspectSection.style.display = (shape === 'free' && !lockAspect) ? '' : 'none'\n }\n }\n\n /**\n * Show controls\n */\n show() {\n if (this.element) {\n this.element.style.display = ''\n }\n }\n\n /**\n * Hide controls\n */\n hide() {\n if (this.element) {\n this.element.style.display = 'none'\n }\n }\n\n /**\n * Clean up\n */\n destroy() {\n this._unsubscribers.forEach(unsub => unsub())\n this._unsubscribers = []\n this._shapeChips.clear()\n this._aspectChips.clear()\n this._rotationPresetChips.clear()\n this.element?.remove()\n this.element = null\n }\n}\n","/**\n * Active Filters Panel component for the vanilla image editor\n * Displays currently active filters with quick controls\n */\nimport { el, createButton, createIconButton } from './UIBuilder.js'\nimport * as icons from '../icons/icons.js'\n\nexport class ActiveFiltersPanel {\n constructor(state, filterManager) {\n this.state = state\n this.filterManager = filterManager\n this.element = null\n this._filterItems = new Map()\n this._unsubscribers = []\n this._onRemove = null\n this._onReset = null\n this._onClearAll = null\n this._onUpdateValue = null\n this._onSelect = null\n }\n\n /**\n * Create and render the active filters panel\n * @param {Object} options - { onRemove, onReset, onClearAll, onUpdateValue, onSelect }\n * @returns {HTMLElement}\n */\n render({ onRemove, onReset, onClearAll, onUpdateValue, onSelect }) {\n this._onRemove = onRemove\n this._onReset = onReset\n this._onClearAll = onClearAll\n this._onUpdateValue = onUpdateValue\n this._onSelect = onSelect\n\n this.element = el('div', {\n className: 'active-filters-panel',\n 'data-testid': 'active-filters-panel'\n })\n\n // Header\n const header = el('div', { className: 'panel-header' })\n header.appendChild(el('h3', { className: 'panel-title' }, 'Active Filters'))\n const clearAllBtn = createButton({\n label: 'Clear All',\n className: 'btn-text btn-danger',\n onClick: () => this._handleClearAll()\n })\n clearAllBtn.dataset.testid = 'clear-all-filters'\n header.appendChild(clearAllBtn)\n this.element.appendChild(header)\n\n // Filter list container\n this._listContainer = el('div', { className: 'active-filters-list' })\n this.element.appendChild(this._listContainer)\n\n // Subscribe to state changes\n this._subscribeToState()\n\n // Initial render\n this._renderFilterList()\n\n return this.element\n }\n\n /**\n * Subscribe to state changes\n */\n _subscribeToState() {\n // Re-render when active filters change\n const unsubActive = this.state.on('change:activeFilters', () => {\n this._renderFilterList()\n })\n this._unsubscribers.push(unsubActive)\n\n // Update values display\n const unsubValues = this.state.on('change:filterValues', () => {\n this._updateValuesDisplay()\n })\n this._unsubscribers.push(unsubValues)\n\n // Update selected state\n const unsubSelected = this.state.on('change:selectedFilter', () => {\n this._updateSelectedState()\n })\n this._unsubscribers.push(unsubSelected)\n }\n\n /**\n * Update selected state for all items\n */\n _updateSelectedState() {\n const selectedFilter = this.state.get('selectedFilter')\n this._filterItems.forEach((item, filterId) => {\n item.classList.toggle('selected', filterId === selectedFilter)\n })\n }\n\n /**\n * Render the filter list\n */\n _renderFilterList() {\n this._listContainer.innerHTML = ''\n this._filterItems.clear()\n\n const activeFilters = this.state.get('activeFilters')\n\n if (activeFilters.size === 0) {\n this._listContainer.appendChild(\n el('div', { className: 'no-filters-message' }, 'No filters active')\n )\n return\n }\n\n activeFilters.forEach(filterId => {\n const def = this.filterManager.getFilterDef(filterId)\n if (!def) return\n\n const item = this._createFilterItem(filterId, def)\n this._filterItems.set(filterId, item)\n this._listContainer.appendChild(item)\n })\n }\n\n /**\n * Create a filter item\n * @param {string} filterId\n * @param {Object} def - Filter definition\n * @returns {HTMLElement}\n */\n _createFilterItem(filterId, def) {\n const selectedFilter = this.state.get('selectedFilter')\n const isSelected = selectedFilter === filterId\n\n const item = el('div', {\n className: `active-filter-item ${isSelected ? 'selected' : ''}`,\n 'data-active-filter': filterId,\n 'data-testid': `active-filter-${filterId}`,\n onClick: (e) => {\n // Don't select if clicking on action buttons\n if (e.target.closest('.filter-item-actions')) return\n this._handleSelect(filterId)\n }\n })\n\n // Header row with name and actions\n const headerRow = el('div', { className: 'filter-item-header' })\n\n const name = el('span', { className: 'filter-item-name' }, def.name)\n\n const actions = el('div', { className: 'filter-item-actions' })\n\n const resetBtn = createIconButton({\n icon: icons.refresh,\n title: 'Reset filter',\n className: 'btn-icon-sm',\n onClick: () => this._handleReset(filterId)\n })\n\n const removeBtn = createIconButton({\n icon: icons.trash,\n title: 'Remove filter',\n className: 'btn-icon-sm btn-danger',\n onClick: () => this._handleRemove(filterId)\n })\n\n actions.appendChild(resetBtn)\n actions.appendChild(removeBtn)\n\n headerRow.appendChild(name)\n headerRow.appendChild(actions)\n item.appendChild(headerRow)\n\n // Values summary\n const values = this.state.getFilterValues(filterId)\n const summaryEl = el('div', { className: 'filter-item-summary' })\n summaryEl.textContent = this._getValuesSummary(def, values)\n item.appendChild(summaryEl)\n item._summaryEl = summaryEl\n\n return item\n }\n\n /**\n * Normalize control type (handle aliases)\n * @param {string} type\n * @returns {string}\n */\n _normalizeControlType(type) {\n const typeMap = {\n 'slider': 'slider',\n 'range': 'slider',\n 'toggle': 'toggle',\n 'checkbox': 'toggle',\n 'color': 'color',\n 'select': 'select',\n 'dropdown': 'select',\n 'button': 'button'\n }\n return typeMap[type] || type\n }\n\n /**\n * Get a summary of filter values\n * @param {Object} def - Filter definition\n * @param {Object} values - Current values\n * @returns {string}\n */\n _getValuesSummary(def, values) {\n if (!def.controls || !Array.isArray(def.controls)) {\n return 'Default values'\n }\n\n const parts = []\n def.controls.forEach(ctl => {\n const controlType = this._normalizeControlType(ctl.type)\n if (controlType === 'button') return\n\n const label = ctl.label || ctl.id\n const value = values[ctl.id] ?? ctl.default\n if (value === ctl.default) return // Skip default values\n\n if (controlType === 'slider') {\n parts.push(`${label}: ${this._formatValue(value)}`)\n } else if (controlType === 'toggle') {\n if (value) parts.push(label)\n } else if (controlType === 'color') {\n parts.push(`${label}: ${value}`)\n } else if (controlType === 'select') {\n parts.push(`${label}: ${value}`)\n }\n })\n\n return parts.length > 0 ? parts.join(', ') : 'Default values'\n }\n\n /**\n * Format a numeric value for display\n * @param {number} value\n * @returns {string}\n */\n _formatValue(value) {\n if (typeof value !== 'number') return String(value)\n if (Number.isInteger(value)) return String(value)\n return value.toFixed(2)\n }\n\n /**\n * Update values display for all items\n */\n _updateValuesDisplay() {\n this._filterItems.forEach((item, filterId) => {\n const def = this.filterManager.getFilterDef(filterId)\n if (!def || !item._summaryEl) return\n\n const values = this.state.getFilterValues(filterId)\n item._summaryEl.textContent = this._getValuesSummary(def, values)\n })\n }\n\n /**\n * Handle filter removal\n * @param {string} filterId\n */\n _handleRemove(filterId) {\n this._onRemove?.(filterId)\n }\n\n /**\n * Handle filter reset\n * @param {string} filterId\n */\n _handleReset(filterId) {\n this._onReset?.(filterId)\n }\n\n /**\n * Handle clear all\n */\n _handleClearAll() {\n this._onClearAll?.()\n }\n\n /**\n * Handle filter selection\n * @param {string} filterId\n */\n _handleSelect(filterId) {\n this.state.set('selectedFilter', filterId)\n this._onSelect?.(filterId)\n }\n\n /**\n * Show panel\n */\n show() {\n if (this.element) {\n this.element.style.display = ''\n }\n }\n\n /**\n * Hide panel\n */\n hide() {\n if (this.element) {\n this.element.style.display = 'none'\n }\n }\n\n /**\n * Clean up\n */\n destroy() {\n this._unsubscribers.forEach(unsub => unsub())\n this._unsubscribers = []\n this._filterItems.clear()\n this.element?.remove()\n this.element = null\n }\n}\n","/**\n * Editor Preset System\n *\n * Presets configure the image editor for specific use cases (avatars, banners, etc.).\n * Each preset defines initial tool state, crop shape, aspect ratio, and control visibility.\n *\n * @example\n * import { getPreset, PRESETS } from './presets/index.js'\n *\n * // Get a built-in preset by name\n * const avatarPreset = getPreset('avatar')\n *\n * // Use directly\n * const editor = new VanillaImageEditor(container, { preset: avatarPreset })\n *\n * // Or pass by name (resolved later)\n * const editor = new VanillaImageEditor(container, { preset: 'avatar' })\n */\n\n/**\n * @typedef {Object} EditorPreset\n * @property {string} name - Preset identifier (e.g., 'avatar', 'banner', 'product')\n * @property {'crop'|'filters'} initialMode - Which tool is active when editor opens\n * @property {'free'|'square'|'circle'} cropShape - Default crop shape\n * @property {string} aspectRatio - Aspect ratio: 'free', '1:1', '4:3', '16:9', '3:2', '2:3', or custom like '3:1'\n * @property {boolean} autoZoomOnCropOverflow - Smart zoom-out when crop exceeds image bounds\n * @property {boolean} lockCropShape - Prevent user from changing crop shape\n * @property {boolean} lockAspectRatio - Prevent user from changing aspect ratio\n * @property {boolean} showFilters - Whether filter panel is available\n * @property {boolean} showCropControls - Whether crop controls are available\n * @property {number} [maxExportWidth] - Optional max output width in pixels\n * @property {number} [maxExportHeight] - Optional max output height in pixels\n */\n\n/**\n * Default values for an EditorPreset. Used as the base when merging.\n * @type {EditorPreset}\n */\nconst DEFAULT_PRESET = {\n name: 'free',\n initialMode: 'filters',\n cropShape: 'free',\n aspectRatio: 'free',\n autoZoomOnCropOverflow: false,\n lockCropShape: false,\n lockAspectRatio: false,\n showFilters: true,\n showCropControls: true,\n maxExportWidth: undefined,\n maxExportHeight: undefined\n}\n\n/**\n * Built-in presets.\n * @type {Record<string, EditorPreset>}\n */\nexport const PRESETS = {\n free: {\n ...DEFAULT_PRESET\n },\n\n avatar: {\n ...DEFAULT_PRESET,\n name: 'avatar',\n initialMode: 'crop',\n cropShape: 'circle',\n aspectRatio: '1:1',\n autoZoomOnCropOverflow: true,\n lockCropShape: true,\n lockAspectRatio: true\n },\n\n banner: {\n ...DEFAULT_PRESET,\n name: 'banner',\n initialMode: 'crop',\n cropShape: 'square',\n aspectRatio: '16:9',\n autoZoomOnCropOverflow: false,\n lockCropShape: false,\n lockAspectRatio: true\n },\n\n cover: {\n ...DEFAULT_PRESET,\n name: 'cover',\n initialMode: 'crop',\n cropShape: 'free',\n aspectRatio: '24:5',\n autoZoomOnCropOverflow: true,\n lockCropShape: true,\n lockAspectRatio: true\n },\n\n product: {\n ...DEFAULT_PRESET,\n name: 'product',\n initialMode: 'filters',\n cropShape: 'square',\n aspectRatio: '1:1',\n autoZoomOnCropOverflow: false,\n lockCropShape: false,\n lockAspectRatio: false\n }\n}\n\n/**\n * Resolve a preset by name or return a custom preset object as-is.\n * Falls back to the 'free' preset if the name is not recognized.\n *\n * @param {string|EditorPreset} preset - Preset name or custom preset object\n * @returns {EditorPreset} Resolved preset\n */\nexport function getPreset(preset) {\n if (!preset) {\n return { ...PRESETS.free }\n }\n\n // If it's already an object, merge with defaults to fill missing fields\n if (typeof preset === 'object' && preset !== null) {\n return { ...DEFAULT_PRESET, ...preset }\n }\n\n // Look up by name, fallback to 'free'\n const found = PRESETS[preset]\n if (found) {\n return { ...found }\n }\n\n return { ...PRESETS.free }\n}\n\n/**\n * Merge a preset with explicit option overrides.\n * Options take precedence over preset values.\n *\n * @param {EditorPreset} preset - Base preset\n * @param {Partial<EditorPreset>} overrides - Explicit overrides\n * @returns {EditorPreset} Merged result\n */\nexport function mergePresetWithOverrides(preset, overrides) {\n if (!overrides || Object.keys(overrides).length === 0) {\n return { ...preset }\n }\n\n const merged = { ...preset }\n\n // Only apply overrides that are explicitly defined (not undefined)\n for (const key of Object.keys(overrides)) {\n if (overrides[key] !== undefined) {\n merged[key] = overrides[key]\n }\n }\n\n return merged\n}\n\n/**\n * Parse an aspect ratio string into a numeric value.\n * Handles standard ratios ('1:1', '16:9', etc.) and custom strings ('3:1', '21:9').\n * Returns null for 'free' or invalid values.\n *\n * @param {string} ratio - Aspect ratio string\n * @returns {number|null} Numeric ratio (width / height), or null for 'free'\n */\nexport function parseAspectRatio(ratio) {\n if (!ratio || ratio === 'free') {\n return null\n }\n\n const parts = ratio.split(':')\n if (parts.length === 2) {\n const w = parseFloat(parts[0])\n const h = parseFloat(parts[1])\n if (Number.isFinite(w) && Number.isFinite(h) && h > 0) {\n return w / h\n }\n }\n\n return null\n}\n\nexport { DEFAULT_PRESET }\n","/**\n * VanillaImageEditor - Main orchestrator class\n * Framework-agnostic image editor using vanilla JavaScript\n */\nimport { EventEmitter } from './core/EventEmitter.js'\nimport { createState } from './core/State.js'\nimport { PixiRenderer } from './renderer/PixiRenderer.js'\nimport { FilterManager } from './renderer/FilterManager.js'\nimport { CropManager } from './renderer/CropManager.js'\nimport { RemoveBgManager } from './renderer/RemoveBgManager.js'\nimport { Toolbar } from './ui/Toolbar.js'\nimport { CategoryCarousel, REGISTRY_CATEGORY_MAP } from './ui/CategoryCarousel.js'\nimport { FilterCarousel } from './ui/FilterCarousel.js'\nimport { FilterAdjustments } from './ui/FilterAdjustments.js'\nimport { MobileFilterDrawer } from './ui/MobileFilterDrawer.js'\nimport { MobileActiveFilters } from './ui/MobileActiveFilters.js'\nimport { CropControls } from './ui/CropControls.js'\nimport { ActiveFiltersPanel } from './ui/ActiveFiltersPanel.js'\nimport { el } from './ui/UIBuilder.js'\nimport { getPreset, mergePresetWithOverrides } from './presets/index.js'\n\nfunction normalizeRotationAngle(angle) {\n if (!Number.isFinite(Number(angle))) return 0\n const normalized = Number(angle) % 360\n return normalized < 0 ? normalized + 360 : normalized\n}\n\nfunction shortestRotationDelta(from, to) {\n const current = normalizeRotationAngle(from)\n const target = normalizeRotationAngle(to)\n return ((target - current + 540) % 360) - 180\n}\n\nexport class VanillaImageEditor extends EventEmitter {\n /**\n * Create a new VanillaImageEditor\n * @param {HTMLElement} container - Container element to mount the editor\n * @param {Object} options - Configuration options\n */\n constructor(container, options = {}) {\n super()\n\n if (!container) {\n throw new Error('VanillaImageEditor: container element is required')\n }\n\n this._container = container\n\n // Lifecycle guards\n this._destroyed = false\n this._loadVersion = 0\n this._objectUrls = new Set() // Track created object URLs for cleanup\n this._activeObjectUrl = null\n\n // Resolve preset: if a preset name or object is provided, resolve it\n // then merge with any explicit option overrides (options win over preset)\n const resolvedPreset = options.preset\n ? getPreset(options.preset)\n : null\n\n // Build effective options: defaults ← preset ← explicit options\n const presetOverrides = resolvedPreset ? {\n initialMode: resolvedPreset.initialMode === 'crop' ? 'crop' : 'adjust',\n cropShape: resolvedPreset.cropShape,\n initialAspectRatio: resolvedPreset.aspectRatio\n } : {}\n\n this._options = {\n theme: 'auto',\n initialImage: null,\n initialMode: 'adjust',\n cropShape: 'free',\n initialAspectRatio: 'free',\n backgroundRemoval: {\n enabled: true,\n endpoint: '/api/v1/media/background-removal/preview',\n optionsEndpoint: '/api/v1/media/background-removal/options',\n fallbackEndpoint: null\n },\n ...presetOverrides,\n ...options\n }\n\n // Store the resolved preset for state flags and later use\n this._preset = resolvedPreset\n\n // Initialize state\n this._state = createState()\n\n // Set initial state from options\n this._state.set('theme', this._options.theme)\n this._state.set('crop.shape', this._options.cropShape)\n this._state.set('crop.aspect', this._options.initialAspectRatio)\n\n // Apply preset state flags\n if (this._preset) {\n this._state.set('lockCropShape', !!this._preset.lockCropShape)\n this._state.set('lockAspectRatio', !!this._preset.lockAspectRatio)\n this._state.set('showFilters', this._preset.showFilters !== false)\n this._state.set('showCropControls', this._preset.showCropControls !== false)\n this._state.set('autoZoomOnCropOverflow', !!this._preset.autoZoomOnCropOverflow)\n }\n\n // Initialize managers\n this._renderer = new PixiRenderer()\n this._filterManager = new FilterManager(this._state, this._renderer)\n this._cropManager = new CropManager(this._state, this._renderer)\n\n // Background removal manager (optional)\n this._removeBgManager = null\n this._backgroundRemovalAvailable = false\n if (this._options.backgroundRemoval?.enabled !== false) {\n this._removeBgManager = new RemoveBgManager({\n endpoint: this._options.backgroundRemoval?.endpoint,\n optionsEndpoint: this._options.backgroundRemoval?.optionsEndpoint,\n fallbackEndpoint: this._options.backgroundRemoval?.fallbackEndpoint\n })\n }\n\n // Loading overlay element\n this._loadingOverlay = null\n\n // Mobile detection\n this._isMobile = typeof window !== 'undefined' ? window.innerWidth <= 768 : false\n\n // UI components\n this._toolbar = null\n this._categoryCarousel = null\n this._filterCarousel = null\n this._filterAdjustments = null\n this._mobileFilterDrawer = null\n this._mobileActiveFilters = null\n this._cropControls = null\n this._activeFiltersPanel = null\n\n // DOM elements\n this._editorEl = null\n this._canvasContainer = null\n this._cropOverlay = null\n this._controlsSection = null\n this._filterControlsEl = null\n this._fileInput = null\n\n // Resize observer\n this._resizeObserver = null\n\n // Initialize\n this._initPromise = Promise.resolve(this._init()).catch((error) => {\n if (!this._destroyed) {\n this.emit('error', error instanceof Error ? error : new Error(String(error)))\n }\n })\n }\n\n /**\n * Initialize the editor\n */\n async _init() {\n // Detect theme\n this._state.detectTheme()\n\n // Build DOM structure\n this._buildDOM()\n\n // Mount PIXI renderer\n const mounted = await this._renderer.mount(\n this._canvasContainer,\n this._state.get('isDarkMode') ? 0x0a0a0a : 0xffffff\n )\n if (!mounted || this._destroyed) return\n\n // Set crop overlay canvas\n this._cropManager.setOverlayCanvas(this._cropOverlay)\n\n // Initialize UI components\n this._initUI()\n\n // Set up resize handling\n this._setupResizeObserver()\n this._setupWindowResize()\n\n // Subscribe to state changes\n this._subscribeToState()\n void this._refreshBackgroundRemovalAvailability()\n\n // Load initial image if provided\n if (this._options.initialImage) {\n await this.loadImage(this._options.initialImage)\n }\n\n this.emit('ready')\n }\n\n /**\n * Build DOM structure\n */\n _buildDOM() {\n // Clear container\n this._container.innerHTML = ''\n\n // Main editor element\n this._editorEl = el('div', {\n className: `vanilla-image-editor ${this._state.get('isDarkMode') ? 'dark' : 'light'}`\n })\n\n // Toolbar\n const toolbarContainer = el('div', { className: 'editor-toolbar-container' })\n this._editorEl.appendChild(toolbarContainer)\n this._toolbarContainer = toolbarContainer\n\n // Content area (canvas + controls)\n const content = el('div', { className: 'editor-content' })\n\n // Canvas section\n const canvasSection = el('div', { className: 'canvas-section' })\n this._canvasContainer = el('div', { className: 'canvas-container' })\n\n // Crop overlay canvas (decorative — hidden from screen readers)\n this._cropOverlay = el('canvas', { className: 'crop-overlay', 'aria-hidden': 'true' })\n\n canvasSection.appendChild(this._canvasContainer)\n canvasSection.appendChild(this._cropOverlay)\n content.appendChild(canvasSection)\n\n // Controls section\n this._controlsSection = el('div', { className: 'controls-section' })\n content.appendChild(this._controlsSection)\n\n this._editorEl.appendChild(content)\n\n // Hidden file input\n this._fileInput = el('input', {\n type: 'file',\n accept: 'image/*',\n className: 'hidden-file-input',\n 'aria-label': 'Choose image file to edit',\n onChange: (e) => this._handleFileSelect(e)\n })\n this._editorEl.appendChild(this._fileInput)\n\n this._container.appendChild(this._editorEl)\n }\n\n /**\n * Initialize UI components\n */\n _initUI() {\n // Toolbar\n this._toolbar = new Toolbar(this._state, this)\n this._toolbarContainer.appendChild(this._toolbar.render())\n\n // Build filter controls container\n this._filterControlsEl = el('div', { className: 'filter-controls-container' })\n\n // Category carousel\n this._categoryCarousel = new CategoryCarousel(this._state, this)\n this._filterControlsEl.appendChild(this._categoryCarousel.render((categoryId) => {\n // Category selected\n }))\n\n // Two-column layout for filters\n const filterLayout = el('div', { className: 'filter-layout' })\n\n // Left column\n const leftColumn = el('div', { className: 'filter-left-column' })\n\n // Filter carousel\n this._filterCarousel = new FilterCarousel(this._state, this._filterManager)\n leftColumn.appendChild(this._filterCarousel.render({\n onToggle: (filterId, enabled) => this._handleFilterToggle(filterId, enabled),\n onSelect: (filterId) => {\n this._handleFilterSelect(filterId)\n // On mobile, open the drawer instead of inline adjustments\n if (this._isMobile && this._mobileFilterDrawer) {\n this._mobileFilterDrawer.open(filterId)\n }\n }\n }))\n\n // Filter adjustments\n this._filterAdjustments = new FilterAdjustments(this._state, this._filterManager)\n leftColumn.appendChild(this._filterAdjustments.render({\n onChange: (filterId, controlId, value) => this._handleFilterChange(filterId, controlId, value),\n onReset: (filterId) => this._handleFilterReset(filterId),\n onAction: (filterId, action) => this._handleFilterAction(filterId, action)\n }))\n\n filterLayout.appendChild(leftColumn)\n\n // Right column - Active filters panel\n const rightColumn = el('div', { className: 'filter-right-column' })\n this._activeFiltersPanel = new ActiveFiltersPanel(this._state, this._filterManager)\n rightColumn.appendChild(this._activeFiltersPanel.render({\n onRemove: (filterId) => this._handleFilterToggle(filterId, false),\n onReset: (filterId) => this._handleFilterReset(filterId),\n onClearAll: () => this.resetAll(),\n onSelect: (filterId) => this._handleFilterSelect(filterId)\n }))\n filterLayout.appendChild(rightColumn)\n\n this._filterControlsEl.appendChild(filterLayout)\n\n // Mobile active filters carousel (shown below filter carousel on mobile)\n this._mobileActiveFilters = new MobileActiveFilters(this._state, this._filterManager)\n this._filterControlsEl.appendChild(this._mobileActiveFilters.render({\n onToggle: (filterId, enabled) => this._handleFilterToggle(filterId, enabled),\n onSelect: (filterId) => {\n this._handleFilterSelect(filterId)\n if (this._isMobile && this._mobileFilterDrawer) {\n this._mobileFilterDrawer.open(filterId)\n }\n }\n }))\n\n // Crop controls\n this._cropControls = new CropControls(this._state, this._cropManager, this)\n this._cropControlsEl = this._cropControls.render()\n this._cropControlsEl.style.display = 'none'\n\n // Add to controls section\n this._controlsSection.appendChild(this._filterControlsEl)\n this._controlsSection.appendChild(this._cropControlsEl)\n\n // Mobile filter drawer (appended to controls section — sized to match it)\n this._mobileFilterDrawer = new MobileFilterDrawer(this._state, this._filterManager)\n this._mobileFilterDrawer.build(this._controlsSection, {\n onChange: (filterId, controlId, value) => this._handleFilterChange(filterId, controlId, value),\n onReset: (filterId) => this._handleFilterReset(filterId),\n onRemove: (filterId) => {\n this._handleFilterToggle(filterId, false)\n this._state.set('selectedFilter', null)\n },\n onAction: (filterId, action) => this._handleFilterAction(filterId, action)\n })\n }\n\n /**\n * Set up resize observer with debounce to prevent infinite loops.\n * Without debounce, PIXI renderer.resize() changes the canvas buffer\n * which triggers another ResizeObserver notification, causing a loop\n * that floods the console with \"ResizeObserver loop completed\" errors\n * and prevents the image from rendering (gray canvas).\n */\n _setupResizeObserver() {\n let resizeTimer = null\n this._resizeObserver = new ResizeObserver(() => {\n clearTimeout(resizeTimer)\n resizeTimer = setTimeout(() => {\n if (this._canvasContainer) {\n this._renderer.resizeTo(this._canvasContainer)\n if (this._state.get('mode') === 'crop') {\n this._cropManager.drawOverlay()\n }\n }\n }, 50)\n })\n this._resizeObserver.observe(this._canvasContainer)\n }\n\n /**\n * Set up window resize listener for mobile detection\n */\n _setupWindowResize() {\n this._handleWindowResize = () => {\n this._isMobile = window.innerWidth <= 768\n // Close drawer if switching to desktop\n if (!this._isMobile && this._mobileFilterDrawer?.isOpen) {\n this._mobileFilterDrawer.close()\n }\n }\n window.addEventListener('resize', this._handleWindowResize)\n }\n\n /**\n * Subscribe to state changes\n */\n _subscribeToState() {\n // Mode changes\n this._state.on('change:mode', ({ value }) => {\n this._updateModeUI(value)\n // Re-apply filters when returning from crop mode — crop may replace the sprite\n if (value === 'filters') {\n this._filterManager.applyFilters()\n }\n })\n\n // Theme changes\n this._state.on('change:isDarkMode', ({ value }) => {\n this._editorEl.classList.toggle('dark', value)\n this._editorEl.classList.toggle('light', !value)\n this._renderer.setBackgroundColor(value ? 0x0a0a0a : 0xffffff)\n })\n\n // Has image changes\n this._state.on('change:hasImage', ({ value }) => {\n this._editorEl.classList.toggle('has-image', value)\n })\n\n // Zoom changes from renderer\n this._renderer.on('zoomChange', (zoom) => {\n this._state.set('zoom', zoom)\n })\n }\n\n /**\n * Update UI based on mode\n * @param {string} mode\n */\n _updateModeUI(mode) {\n if (mode === 'crop') {\n this._filterControlsEl.style.display = 'none'\n this._cropControlsEl.style.display = ''\n // Close mobile drawer when entering crop mode\n if (this._mobileFilterDrawer?.isOpen) {\n this._mobileFilterDrawer.close()\n }\n } else {\n this._filterControlsEl.style.display = ''\n this._cropControlsEl.style.display = 'none'\n }\n }\n\n /**\n * Handle file selection\n * @param {Event} event\n */\n async _handleFileSelect(event) {\n const file = event.target.files?.[0]\n if (file) {\n await this.loadImage(file)\n }\n // Reset input\n this._fileInput.value = ''\n }\n\n /**\n * Handle filter toggle\n * @param {string} filterId\n * @param {boolean} enabled\n */\n _handleFilterToggle(filterId, enabled) {\n this._filterManager.toggle(filterId, enabled)\n }\n\n /**\n * Handle filter select\n * @param {string} filterId\n */\n _handleFilterSelect(filterId) {\n this._state.set('selectedFilter', filterId)\n }\n\n /**\n * Handle filter value change\n * @param {string} filterId\n * @param {string} controlId\n * @param {*} value\n */\n _handleFilterChange(filterId, controlId, value) {\n const inPlace = this._filterManager.updateValue(filterId, controlId, value)\n if (!inPlace) {\n this._filterManager.applyFilters()\n }\n this._renderer.render()\n }\n\n /**\n * Handle filter reset\n * @param {string} filterId\n */\n _handleFilterReset(filterId) {\n this._filterManager.resetValues(filterId)\n this._filterManager.applyFilters()\n }\n\n /**\n * Handle filter action (button click).\n * Delegates to FilterManager.performFilterAction which syncs state after\n * the action so the result survives filter recreation.\n * @param {string} filterId\n * @param {string} action\n */\n _handleFilterAction(filterId, action) {\n this._filterManager.performFilterAction(filterId, action)\n }\n\n _revokeObjectUrl(url) {\n if (!url || !this._objectUrls.has(url)) return\n\n URL.revokeObjectURL(url)\n this._objectUrls.delete(url)\n\n if (this._activeObjectUrl === url) {\n this._activeObjectUrl = null\n }\n }\n\n _replaceActiveObjectUrl(url) {\n const previousUrl = this._activeObjectUrl\n this._activeObjectUrl = url\n this._objectUrls.add(url)\n\n if (previousUrl && previousUrl !== url) {\n this._revokeObjectUrl(previousUrl)\n }\n }\n\n _clearActiveObjectUrl() {\n if (this._activeObjectUrl) {\n this._revokeObjectUrl(this._activeObjectUrl)\n }\n }\n\n // ==================== Public API ====================\n\n /**\n * Set the filter registry (from mediables/filters)\n * @param {Object} registry - { getFilter, getAllFilters, getFiltersByCategory }\n */\n setFilterRegistry(registry) {\n this._filterManager.setRegistry(registry)\n }\n\n /**\n * Load an image into the editor\n * @param {string|Blob|File} imageSource - URL, data URL, Blob, or File object\n * @param {Object} [options] - Load options\n * @param {Object|null} [options.state] - ImageEditorSessionState to restore\n * @param {string|number} [options.sessionKey] - Session boundary identifier\n */\n async loadImage(imageSource, options = {}) {\n if (this._destroyed) return\n this._removeBgManager?.cancelActiveRequests?.('image-load')\n\n const loadVersion = ++this._loadVersion\n let url = imageSource\n let ownedObjectUrl = null\n\n // Reset prior session state BEFORE loading — prevents stale bleed\n this._resetEditorState()\n this._state.set('hasImage', false)\n this._state.set('imageUrl', null)\n\n // For Blob/File, create an object URL instead of base64 (lower memory)\n if (imageSource instanceof Blob) {\n url = URL.createObjectURL(imageSource)\n ownedObjectUrl = url\n this._objectUrls.add(url)\n }\n\n const loaded = await this._renderer.loadTexture(url, {\n isCurrent: () => !this._destroyed && this._loadVersion === loadVersion,\n })\n\n // Guard: bail if destroyed or a newer load started during the await\n if (this._destroyed || this._loadVersion !== loadVersion) {\n this._revokeObjectUrl(ownedObjectUrl)\n return\n }\n\n // Guard: bail if texture load failed (bad URL, CORS, 403, etc.)\n if (!loaded) {\n this._revokeObjectUrl(ownedObjectUrl)\n this.emit('error', new Error('Failed to load image'))\n return\n }\n\n if (ownedObjectUrl) {\n this._replaceActiveObjectUrl(ownedObjectUrl)\n } else {\n this._clearActiveObjectUrl()\n }\n\n this._state.set('hasImage', true)\n this._state.set('imageUrl', url)\n\n // Restore editor state if provided\n if (options.state) {\n this._hydrateState(options.state)\n }\n\n // Apply initial mode from preset/options after image loads\n // Crop mode requires an image to be loaded first\n if (this._options.initialMode === 'crop') {\n this.setMode('crop')\n }\n\n this.emit('imageLoaded', { url })\n }\n\n /**\n * Reset all editor state (filters + crop) to a clean baseline.\n * Called at the start of loadImage() to prevent stale state bleed between sessions.\n */\n _resetEditorState() {\n // Reset filters — clears active set, values, sprite.filters\n this._filterManager.resetAll()\n\n // Reset crop state (both interactive and applied/baked)\n this._state.set('crop.rect', null)\n this._state.set('crop.appliedRect', null)\n this._state.set('crop.appliedShape', null)\n this._state.set('crop.appliedAspect', null)\n this._state.set('crop.dirty', false)\n this._state.set('crop.shape', this._options.cropShape || 'free')\n this._state.set('crop.aspect', this._options.initialAspectRatio || 'free')\n this._state.set('transform.rotation', 0)\n\n // Ensure we're in filters mode (not stuck in crop)\n if (this._state.get('mode') === 'crop') {\n this._cropManager.disable()\n this._state.set('mode', 'filters')\n }\n }\n\n /**\n * Hydrate editor state from a canonical ImageEditorSessionState object.\n * Restores filter stack + values and crop metadata (shape, aspect, rect).\n * @param {Object} state - ImageEditorSessionState\n */\n _hydrateState(state) {\n if (!state || state.version !== 1) return\n\n const rotation = normalizeRotationAngle(state.transform?.rotation ?? 0)\n if (rotation !== 0 && this._renderer.rotateBy(rotation)) {\n this._state.set('transform.rotation', rotation)\n }\n\n // Restore crop: if a pixel-rect was saved, re-apply the crop to the texture.\n // This is the critical path for reopen fidelity — without it, the user sees\n // the uncropped root source image.\n if (state.crop) {\n const shape = state.crop.shape || 'free'\n const aspect = state.crop.aspectRatio || 'free'\n\n if (state.crop.rect) {\n // Apply the crop to the loaded texture using pixel coordinates\n this._cropManager.applyFromPixelRect(state.crop.rect, shape)\n\n // Store the applied crop metadata for getSerializableState()\n this._state.set('crop.appliedRect', { ...state.crop.rect })\n this._state.set('crop.appliedShape', shape)\n this._state.set('crop.appliedAspect', aspect)\n }\n\n this._state.set('crop.shape', shape)\n this._state.set('crop.aspect', aspect)\n }\n\n // Restore filters\n if (Array.isArray(state.filters)) {\n let restoredFilterId = null\n\n for (const filter of state.filters) {\n if (!filter.enabled) continue\n if (restoredFilterId === null) {\n restoredFilterId = filter.id\n }\n this._state.toggleFilter(filter.id, true)\n this._filterManager.initializeValues(filter.id)\n if (filter.values) {\n for (const [controlId, value] of Object.entries(filter.values)) {\n this._state.setFilterValue(filter.id, controlId, value)\n }\n }\n }\n\n if (restoredFilterId !== null) {\n this._state.set('selectedFilter', restoredFilterId)\n\n const filterDef = this._filterManager.getFilterDef(restoredFilterId)\n if (typeof filterDef?.category === 'string') {\n const category = REGISTRY_CATEGORY_MAP[filterDef.category] ?? filterDef.category\n this._state.set('selectedCategory', category)\n }\n }\n\n this._filterManager.applyFilters()\n }\n }\n\n /**\n * Open the file picker dialog\n */\n openFilePicker() {\n this._fileInput?.click()\n }\n\n /**\n * Export the current image.\n *\n * @param {string} format - 'png' or 'jpeg'\n * @param {number} quality - Quality for jpeg (0-1)\n * @param {Object} [options]\n * @param {number} [options.maxEdge] - Cap the longest edge to this pixel count\n * @param {number} [options.maxPixels] - Cap total pixel count (width*height)\n * @returns {string|null} Data URL\n */\n exportImage(format = 'png', quality = 0.92, options = {}) {\n if (!this._state.get('hasImage')) {\n return null\n }\n\n if (!this._applyPendingCropBeforeExport('VanillaImageEditor.exportImage')) {\n return null\n }\n\n return this._renderer.exportImage(\n format,\n quality,\n options.maxEdge ?? 0,\n options.dontUpscale !== false,\n options.maxPixels ?? 0\n )\n }\n\n /**\n * Export the current image as a Blob after finalizing pending crop edits.\n *\n * @param {string} format - 'png' or 'jpeg'\n * @param {number} quality - Quality for jpeg (0-1)\n * @param {Object} [options]\n * @returns {Promise<{blob: Blob, width: number, height: number}|null>}\n */\n async exportBlob(format = 'png', quality = 0.92, options = {}) {\n if (!this._state.get('hasImage')) {\n return null\n }\n\n if (!this._applyPendingCropBeforeExport('VanillaImageEditor.exportBlob')) {\n return null\n }\n\n return this._renderer.exportBlob(format, quality, options)\n }\n\n _applyPendingCropBeforeExport(context) {\n const pendingCropRect = this._state.get('crop.rect')\n if (pendingCropRect) {\n const appliedCrop = this._cropManager.apply()\n if (!appliedCrop) {\n console.error(`[${context}] Failed to apply pending crop before export`)\n return false\n }\n }\n\n return true\n }\n\n /**\n * Save the image (triggers download and emits 'save' event)\n */\n async save() {\n if (!this._state.get('hasImage')) return\n\n this._state.set('isSaving', true)\n let objectUrl = null\n\n try {\n const exported = await this.exportBlob('png', 0.92)\n if (!exported) throw new Error('Failed to export image')\n\n // Trigger download\n const link = document.createElement('a')\n objectUrl = URL.createObjectURL(exported.blob)\n link.href = objectUrl\n link.download = `edited-image-${Date.now()}.png`\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n\n this.emit('save', {\n blob: exported.blob,\n mimeType: exported.blob.type || 'image/png',\n dimensions: { width: exported.width, height: exported.height },\n state: this.getSerializableState()\n })\n } catch (error) {\n this.emit('error', { error })\n } finally {\n if (objectUrl) URL.revokeObjectURL(objectUrl)\n this._state.set('isSaving', false)\n }\n }\n\n /**\n * Get a canonical, serializable snapshot of the current editor state.\n * Safe for persistence — returns a deep copy with no mutable references.\n * @returns {Object} ImageEditorSessionState\n */\n getSerializableState() {\n const activeFilters = this._state.get('activeFilters')\n const filters = []\n\n if (activeFilters) {\n for (const filterId of activeFilters) {\n const values = this._state.getFilterValues(filterId)\n filters.push({\n id: filterId,\n enabled: true,\n values: { ...values }\n })\n }\n }\n\n // Prefer appliedRect (baked into texture via CropManager.apply()) over\n // crop.rect (the interactive selection, cleared by disable()).\n const appliedRect = this._state.get('crop.appliedRect')\n const interactiveRect = this._state.get('crop.rect')\n const cropRect = appliedRect || interactiveRect\n\n return {\n version: 1,\n crop: {\n rect: cropRect ? { ...cropRect } : null,\n aspectRatio: this._state.get('crop.appliedAspect') || this._state.get('crop.aspect') || 'free',\n shape: this._state.get('crop.appliedShape') || this._state.get('crop.shape') || 'free'\n },\n transform: {\n rotation: normalizeRotationAngle(this._state.get('transform.rotation') ?? 0)\n },\n filters\n }\n }\n\n /**\n * Close the editor (emits 'cancel' event)\n */\n close() {\n this.emit('cancel')\n }\n\n /**\n * Set zoom level\n * @param {number} zoom\n */\n setZoom(zoom) {\n this._renderer.setZoom(zoom)\n }\n\n /**\n * Fit image to screen\n */\n fitToScreen() {\n this._renderer.fitToScreen()\n }\n\n /**\n * Reset all filters\n */\n resetAll() {\n this._filterManager.resetAll()\n }\n\n rotateBy(degrees) {\n const current = this._state.get('transform.rotation') ?? 0\n return this.setRotationAngle(Number(current) + Number(degrees))\n }\n\n setRotationAngle(angle) {\n if (!this._state.get('hasImage')) return false\n\n const current = normalizeRotationAngle(this._state.get('transform.rotation') ?? 0)\n const target = normalizeRotationAngle(angle)\n const delta = shortestRotationDelta(current, target)\n const wasCropping = this._state.get('mode') === 'crop'\n\n if (Math.abs(delta) > 0.001) {\n if (wasCropping) {\n this._cropManager.disable()\n }\n\n const rotated = this._renderer.rotateBy(delta)\n if (!rotated) {\n if (wasCropping) {\n this._cropManager.enable()\n }\n return false\n }\n\n this._filterManager.applyFilters()\n this._state.set('crop.rect', null)\n this._state.set('crop.dirty', false)\n\n if (wasCropping) {\n this._cropManager.enable()\n }\n }\n\n this._state.set('transform.rotation', target)\n this.emit('transformChanged', { rotation: target })\n return true\n }\n\n resetRotation() {\n return this.setRotationAngle(0)\n }\n\n /**\n * Toggle theme\n */\n toggleTheme() {\n const isDark = this._state.get('isDarkMode')\n this._state.set('isDarkMode', !isDark)\n }\n\n /**\n * Set theme\n * @param {'light'|'dark'|'auto'} theme\n */\n setTheme(theme) {\n this._state.set('theme', theme)\n this._state.detectTheme()\n }\n\n /**\n * Set editor mode\n * @param {'filters'|'crop'} mode\n */\n setMode(mode) {\n if (mode === 'crop') {\n this._cropManager.enable()\n } else {\n this._cropManager.disable()\n }\n this._state.set('mode', mode)\n }\n\n /**\n * Get current state (for debugging)\n * @returns {Object}\n */\n getState() {\n return this._state.getAll()\n }\n\n // ==================== Background Removal ====================\n\n /**\n * Remove the background from the current image\n * @param {Object} options\n * @param {string} [options.tier='balanced'] - Quality tier: 'fast', 'balanced', 'best'\n * @param {string} [options.model] - Explicit model name (overrides tier)\n * @param {boolean} [options.alpha_matting=false] - Enable alpha matting for edge refinement\n * @returns {Promise<{model: string, processMs: string}>}\n */\n async removeBackground(options = {}) {\n if (!this._removeBgManager) {\n throw new Error('Background removal is not enabled')\n }\n\n if (!this._state.get('hasImage')) {\n throw new Error('No image loaded')\n }\n if (!this.canRemoveBackground()) {\n throw new Error('Background removal is not available for the current editor state')\n }\n\n this._state.set('isProcessing', true)\n this._showLoadingOverlay('Removing background...')\n\n try {\n // Export current image state\n const imageData = this.exportImage('png')\n if (!imageData) {\n throw new Error('Failed to export image for background removal')\n }\n\n // Send to background removal service\n const previewRequest = await this._removeBgManager.preparePreviewRequest(imageData, options)\n const previewContext = this._buildPreviewBackgroundRemovalContext(previewRequest)\n const result = await this._removeBgManager.removeBackground(previewRequest.blob, previewRequest)\n if (!await this._isCurrentPreviewBackgroundRemovalContext(previewContext, result)) {\n this.emit('background-removal-stale', {\n operationId: previewContext.operationId,\n sourceHash: previewContext.sourceHash\n })\n\n return { stale: true }\n }\n\n // Load the result back into the editor\n await this.loadImage(result.dataUrl)\n\n this.emit('background-removed', {\n model: result.model,\n processMs: result.processMs\n })\n\n return {\n model: result.model,\n processMs: result.processMs\n }\n } catch (error) {\n this.emit('error', { error, context: 'background-removal' })\n throw error\n } finally {\n this._state?.set?.('isProcessing', false)\n this._hideLoadingOverlay()\n }\n }\n\n /**\n * Check if background removal is available\n * @returns {Promise<boolean>}\n */\n async isBackgroundRemovalAvailable() {\n if (!this._removeBgManager) return false\n return this._refreshBackgroundRemovalAvailability()\n }\n\n canRemoveBackground() {\n return !!this._removeBgManager\n && this._state.get('hasImage') === true\n && this._backgroundRemovalAvailable === true\n }\n\n async _refreshBackgroundRemovalAvailability() {\n if (!this._removeBgManager) {\n this._backgroundRemovalAvailable = false\n this._state.set('backgroundRemovalAvailable', false)\n return false\n }\n\n const available = await this._removeBgManager.isAvailable()\n if (this._destroyed) return false\n\n this._backgroundRemovalAvailable = available\n this._state.set('backgroundRemovalAvailable', available)\n\n return available\n }\n\n _buildPreviewBackgroundRemovalContext(request) {\n return {\n loadVersion: this._loadVersion,\n imageUrl: this._state.get('imageUrl') ?? null,\n operationId: request.operationId,\n sessionKey: request.sessionKey,\n sourceHash: request.sourceHash,\n targetRef: request.targetRef ?? null\n }\n }\n\n async _isCurrentPreviewBackgroundRemovalContext(context, result = null) {\n if (this._destroyed || this._loadVersion !== context.loadVersion || this._state.get('hasImage') !== true) return false\n if ((this._state.get('imageUrl') ?? null) !== context.imageUrl) return false\n if (result) {\n if (result.operationId && result.operationId !== context.operationId) return false\n if (result.sessionKey && result.sessionKey !== context.sessionKey) return false\n if (result.sourceHash && result.sourceHash !== context.sourceHash) return false\n if (result.targetRef && context.targetRef && result.targetRef !== context.targetRef) return false\n }\n\n const currentImageData = this.exportImage('png')\n if (!currentImageData) return false\n\n return await this._removeBgManager.computeImageDataHash(currentImageData) === context.sourceHash\n }\n\n // ==================== Loading Overlay ====================\n\n /**\n * Show the loading overlay\n * @param {string} message - Message to display\n */\n _showLoadingOverlay(message) {\n if (!this._loadingOverlay) {\n this._loadingOverlay = el('div', { className: 'editor-loading-overlay' }, [\n el('div', { className: 'editor-loading-spinner' }),\n el('div', { className: 'editor-loading-text' }, message)\n ])\n } else {\n const textEl = this._loadingOverlay.querySelector('.editor-loading-text')\n if (textEl) textEl.textContent = message\n }\n\n // Append to canvas section (above canvas)\n const canvasSection = this._canvasContainer?.parentElement\n if (canvasSection && !this._loadingOverlay.parentElement) {\n canvasSection.appendChild(this._loadingOverlay)\n }\n }\n\n /**\n * Hide the loading overlay\n */\n _hideLoadingOverlay() {\n this._loadingOverlay?.remove()\n }\n\n /**\n * Destroy the editor and clean up\n */\n destroy() {\n // Mark destroyed FIRST — guards async operations that may resolve after this\n this._destroyed = true\n this._removeBgManager?.cancelActiveRequests?.('editor-destroy')\n\n // Revoke all object URLs created during this session\n for (const url of this._objectUrls) {\n try { URL.revokeObjectURL(url) } catch (_e) { /* ignore */ }\n }\n this._objectUrls.clear()\n this._activeObjectUrl = null\n\n // Clean up resize observer\n this._resizeObserver?.disconnect()\n\n // Clean up managers\n this._renderer.destroy()\n this._cropManager.disable()\n\n // Clean up window resize listener\n if (this._handleWindowResize) {\n window.removeEventListener('resize', this._handleWindowResize)\n }\n\n // Clean up UI components\n this._toolbar?.destroy()\n this._categoryCarousel?.destroy()\n this._filterCarousel?.destroy()\n this._filterAdjustments?.destroy()\n this._mobileFilterDrawer?.destroy()\n this._mobileActiveFilters?.destroy()\n this._cropControls?.destroy()\n this._activeFiltersPanel?.destroy()\n\n // Remove DOM\n this._editorEl?.remove()\n\n // Clear references\n this._container = null\n this._state = null\n\n this.emit('destroyed')\n this.removeAllListeners()\n }\n}\n","/**\n * Filter Registry System\n * Centralized storage and management for filter definitions\n */\n// Since we can't directly import Filter, use any for now\n// and let the type system infer from usage\ntype Filter = any;\n\n/**\n * Interface for a filter control definition \n * Defines the UI representation of a filter parameter\n */\nexport interface ControlDefinition {\n id: string;\n type: 'slider' | 'toggle' | 'color' | 'select' | 'range' | 'button' | 'text';\n label: string;\n property?: string;\n action?: string;\n min?: number;\n max?: number;\n step?: number;\n default?: number | boolean | string;\n options?: Array<{ label: string; value: string | number }>;\n tooltip?: string;\n /** Placeholder text for 'text' type controls. */\n placeholder?: string;\n /** Hide this control from the UI without removing it from the definition. */\n hidden?: boolean;\n}\n\nexport type FilterMediaTarget = 'image' | 'video';\n\n/**\n * Interface for a filter definition\n * Contains all metadata needed to create and manage a filter\n */\nexport interface FilterDefinition {\n id: string;\n name: string;\n category: string;\n description?: string;\n thumbnail?: string;\n /**\n * Optional media compatibility tags.\n * Omitted means compatible with both image and video pipelines.\n */\n mediaTargets?: FilterMediaTarget[];\n createFilter: (params: Record<string, any>) => Filter;\n defaultParams: Record<string, any>;\n controls: ControlDefinition[];\n}\n\n// Filter registry storage\nconst filters = new Map<string, FilterDefinition>();\n\n// Category registry storage\nconst categories = new Map<string, string[]>();\n\nfunction isMediaCompatible(\n definition: FilterDefinition,\n target: FilterMediaTarget\n): boolean {\n if (!Array.isArray(definition.mediaTargets) || definition.mediaTargets.length === 0) {\n return true;\n }\n\n return definition.mediaTargets.includes(target);\n}\n\n/**\n * Register a filter in the global registry\n * @param definition The filter definition to register\n * @returns The provided filter definition (for chaining)\n */\nexport function registerFilter(definition: FilterDefinition): FilterDefinition {\n // Ensure the filter has a unique ID\n if (filters.has(definition.id)) {\n console.warn(`Filter with ID ${definition.id} already exists. Overwriting.`);\n }\n \n // Store the filter definition\n filters.set(definition.id, definition);\n \n // Add to category registry\n if (!categories.has(definition.category)) {\n categories.set(definition.category, []);\n }\n categories.get(definition.category)?.push(definition.id);\n \n return definition;\n}\n\n/**\n * Get a filter definition by ID\n * @param id The ID of the filter to retrieve\n * @returns The filter definition or undefined if not found\n */\nexport function getFilter(id: string): FilterDefinition | undefined {\n return filters.get(id);\n}\n\n/**\n * Get all registered filter definitions\n * @returns Array of all registered filter definitions\n */\nexport function getAllFilters(): FilterDefinition[] {\n return Array.from(filters.values());\n}\n\n/**\n * NEW: Bulk-register all classes re-exported by the `pixi-filters` bundle.\n * – Keeps bundle size reasonable (tree-shaken in prod)\n * – Lets you use *any* filter without first writing boilerplate\n */\nimport * as PixiFilters from 'pixi-filters';\n\n/**\n * Register all core PixiJS filters if they don't already have custom definitions,\n * but only using the actual custom definitions from their respective files.\n */\nexport function registerCorePixiFilters(): void {\n // Get the filters that are already loaded\n const customFilterIds = getAllFilters().map(f => f.id);\n \n // Get all available PixiJS filters from the pixi-filters package\n type FilterConstructor = new (...args: unknown[]) => unknown\n\n const pixiFilterEntries = Object.entries(PixiFilters) as Array<[string, unknown]>\n\n const pixiFilterClasses = pixiFilterEntries.filter(\n (entry): entry is [string, FilterConstructor] => /Filter$/.test(entry[0]) && typeof entry[1] === 'function'\n );\n \n // Reduce logging in production\n if (import.meta.env.DEV) {\n // Only log filter count, not the entire list\n console.log(`Found ${customFilterIds.length} custom filters and ${pixiFilterClasses.length} PixiJS filters`);\n }\n \n // We'll ONLY register core filters where we DON'T have a custom definition\n // This is intentionally minimalist to ensure we prioritize custom definitions\n let newlyRegisteredCount = 0;\n \n pixiFilterClasses.forEach(([exportName, FilterClass]) => {\n const id = exportName\n .replace(/Filter$/, '')\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .toLowerCase();\n \n // Skip if this filter already has a custom definition\n if (filters.has(id)) {\n return;\n }\n \n // For remaining filters without custom definitions, just provide a minimal registration\n // that just allows the filter to be created but doesn't provide any controls\n // Reduce verbose logging in production\n if (import.meta.env.DEV) {\n console.debug(`Registering minimal entry for ${exportName}`);\n }\n newlyRegisteredCount++;\n \n // Register with minimal information - these won't appear in the UI properly\n // but will be available for debugging or programmatic use\n registerFilter({\n id,\n name: exportName.replace(/Filter$/, ''),\n category: 'unlisted', // Put in a category that won't be shown in UI\n mediaTargets: ['image'],\n defaultParams: {},\n controls: [], // No controls - we don't want to add generic controls\n createFilter: (params = {}) => {\n try {\n // Simply create the filter with params\n return new FilterClass(params);\n } catch (error) {\n console.error(`Error creating filter ${id}:`, error);\n return null;\n }\n },\n });\n });\n \n // Only log in development environment\n if (import.meta.env.DEV && newlyRegisteredCount > 0) {\n console.log(`Registered ${newlyRegisteredCount} additional filters`);\n }\n}\n\n// We will NOT auto-register at module load. \n// Instead, custom filter definitions will be loaded first, then we'll only register missing ones.\n// The actual registration happens when initializeFilterRegistry is called.\n\n/**\n * Get all filters in a specific category\n * @param category The category to retrieve filters for\n * @returns Array of filter definitions in the requested category\n */\nexport function getFiltersByCategory(category: string): FilterDefinition[] {\n const filterIds = categories.get(category) || [];\n return filterIds.map(id => filters.get(id)).filter(Boolean) as FilterDefinition[];\n}\n\n/**\n * Get all filter categories\n * @returns Array of category names\n */\nexport function getAllCategories(): string[] {\n return Array.from(categories.keys());\n}\n\n/**\n * Check if a filter is registered\n * @param id The ID of the filter to check\n * @returns True if the filter is registered, false otherwise\n */\nexport function hasFilter(id: string): boolean {\n return filters.has(id);\n}\n\n/**\n * Remove a filter from the registry.\n * @param id The ID of the filter to remove\n * @returns True if the filter was found and removed\n */\nexport function unregisterFilter(id: string): boolean {\n const definition = filters.get(id);\n if (!definition) {\n return false;\n }\n\n filters.delete(id);\n\n // Remove from category index\n const categoryIds = categories.get(definition.category);\n if (categoryIds) {\n const idx = categoryIds.indexOf(id);\n if (idx !== -1) {\n categoryIds.splice(idx, 1);\n }\n if (categoryIds.length === 0) {\n categories.delete(definition.category);\n }\n }\n\n return true;\n}\n\n/**\n * Check whether a registered filter is compatible with a media target.\n * Unknown filters are treated as incompatible.\n */\nexport function isFilterCompatibleWithMedia(\n id: string,\n target: FilterMediaTarget\n): boolean {\n const definition = filters.get(id);\n if (!definition) {\n return false;\n }\n\n return isMediaCompatible(definition, target);\n}\n\n/**\n * Return all registered filters compatible with the given media target.\n */\nexport function getFiltersByMedia(target: FilterMediaTarget): FilterDefinition[] {\n return Array.from(filters.values()).filter((definition) => isMediaCompatible(definition, target));\n}\n\n/**\n * Get all registered filters with simplified format for UI\n * @returns Array of filter definitions with only UI-relevant properties\n */\nexport function getRegisteredFilters(): Array<{\n id: string;\n name: string;\n category: string;\n controls: ControlDefinition[];\n}> {\n return Array.from(filters.values()).map(filter => ({\n id: filter.id,\n name: filter.name,\n category: filter.category,\n controls: filter.controls\n }));\n}\n\n// Add a debug function to expose filter registry in window\nif (typeof window !== 'undefined') {\n // Store filter list in window for debugging\n (window as any).__DEBUG_FILTERS_LIST = Array.from(filters.keys());\n \n // Expose registry functions for debugging\n (window as any).getAllFilters = getAllFilters;\n (window as any).getFilter = getFilter;\n (window as any).getFiltersByCategory = getFiltersByCategory;\n (window as any).getRegisteredFilters = getRegisteredFilters;\n \n // Update the debug list whenever a new filter is registered\n const originalRegisterFilter = registerFilter;\n (window as any).registerFilter = (definition: FilterDefinition) => {\n const result = originalRegisterFilter(definition);\n (window as any).__DEBUG_FILTERS_LIST = Array.from(filters.keys());\n console.log(`Filter \"${definition.id}\" registered. Total filters: ${filters.size}`);\n return result;\n };\n \n // Remove this console log - it's causing duplicate logging\n // if (process.env.NODE_ENV !== 'production') {\n // console.log(`Registry initialized with ${filters.size} filters`);\n // }\n}\n\n// Add a safety check for initializeFilterRegistry in case it's not working\n// This is a fallback in case the main implementation is facing issues\nif (typeof window !== 'undefined') {\n (window as any).initializeFilterRegistry = (window as any).initializeFilterRegistry || function() {\n console.warn('Using fallback window.initializeFilterRegistry');\n return [];\n };\n}\n","/**\n * Adjustment Filter Definition\n * Controls basic image adjustments like brightness, contrast, saturation, etc.\n */\nimport { registerFilter } from '../registry';\n// Import the AdjustmentFilter directly from the pixi-filters package\nimport * as PixiFilters from 'pixi-filters';\n// Access AdjustmentFilter from the pixi-filters package\nconst { AdjustmentFilter } = PixiFilters;\n\n// Import ColorMatrixFilter as fallback\nimport * as PIXI from 'pixi.js';\n// Access ColorMatrixFilter from pixi.js package\nconst { ColorMatrixFilter } = PIXI;\n\ninterface AdjustmentParams {\n gamma: number;\n saturation: number;\n contrast: number;\n brightness: number;\n red: number;\n green: number;\n blue: number;\n alpha: number;\n}\n\ntype AdjustmentParamKey = keyof AdjustmentParams;\n\nconst DEFAULT_ADJUSTMENT_PARAMS: AdjustmentParams = {\n gamma: 1,\n saturation: 1,\n contrast: 1,\n brightness: 1,\n red: 1,\n green: 1,\n blue: 1,\n alpha: 1,\n};\n\nconst ADJUSTMENT_PARAM_KEYS = new Set<AdjustmentParamKey>([\n 'gamma',\n 'saturation',\n 'contrast',\n 'brightness',\n 'red',\n 'green',\n 'blue',\n 'alpha',\n]);\n\nfunction toFiniteNumber(value: unknown, fallback: number): number {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n\n if (typeof value === 'string') {\n const parsed = Number(value);\n if (Number.isFinite(parsed)) {\n return parsed;\n }\n }\n\n return fallback;\n}\n\nfunction isAdjustmentParamKey(key: string): key is AdjustmentParamKey {\n return ADJUSTMENT_PARAM_KEYS.has(key as AdjustmentParamKey);\n}\n\nfunction normalizeAdjustmentParams(params: Record<string, unknown>): AdjustmentParams {\n return {\n gamma: toFiniteNumber(params.gamma, DEFAULT_ADJUSTMENT_PARAMS.gamma),\n saturation: toFiniteNumber(params.saturation, DEFAULT_ADJUSTMENT_PARAMS.saturation),\n contrast: toFiniteNumber(params.contrast, DEFAULT_ADJUSTMENT_PARAMS.contrast),\n brightness: toFiniteNumber(params.brightness, DEFAULT_ADJUSTMENT_PARAMS.brightness),\n red: toFiniteNumber(params.red, DEFAULT_ADJUSTMENT_PARAMS.red),\n green: toFiniteNumber(params.green, DEFAULT_ADJUSTMENT_PARAMS.green),\n blue: toFiniteNumber(params.blue, DEFAULT_ADJUSTMENT_PARAMS.blue),\n alpha: toFiniteNumber(params.alpha, DEFAULT_ADJUSTMENT_PARAMS.alpha),\n };\n}\n\nfunction applyColorMatrixAdjustments(filter: PIXI.ColorMatrixFilter, params: AdjustmentParams): void {\n filter.reset();\n\n // ColorMatrixFilter operations must be multiplied to compose adjustments.\n filter.brightness(params.brightness, true);\n filter.contrast(params.contrast, true);\n filter.saturate(params.saturation, true);\n}\n\n// Register the adjustment filter\nexport default registerFilter({\n id: 'adjustment',\n name: 'Adjustment',\n category: 'adjust',\n description: 'Adjust basic image properties like brightness, contrast, and saturation',\n \n // Create an instance of the AdjustmentFilter with the provided parameters\n createFilter: (params) => {\n try {\n const normalizedParams = normalizeAdjustmentParams((params ?? {}) as Record<string, unknown>);\n console.log('Creating AdjustmentFilter with params:', normalizedParams);\n \n // Create options object for filter parameters\n const options = { ...normalizedParams };\n \n // Attempt to create AdjustmentFilter first (preferred)\n try {\n const filter = new AdjustmentFilter(options);\n\n type AdjustmentFilterWithUI = typeof filter & {\n _customParams?: AdjustmentParams;\n updateUIParam?: (key: string, value: unknown) => void;\n };\n const filterWithUI = filter as AdjustmentFilterWithUI;\n\n // Add custom updateUIParam method for dynamic updates\n filterWithUI._customParams = { ...normalizedParams };\n filterWithUI.updateUIParam = function updateUIParam(key: string, value: unknown): void {\n try {\n if (!isAdjustmentParamKey(key)) {\n return;\n }\n\n const customParams = this._customParams ?? { ...DEFAULT_ADJUSTMENT_PARAMS };\n const numericValue = toFiniteNumber(value, customParams[key]);\n customParams[key] = numericValue;\n this._customParams = customParams;\n\n const target = this as unknown as Record<string, unknown>;\n if (key in target) {\n target[key] = numericValue;\n }\n } catch (error) {\n console.error(`Error updating AdjustmentFilter parameter ${key}:`, error);\n }\n };\n \n console.log('AdjustmentFilter created successfully');\n return filter;\n } catch (error) {\n console.warn('Failed to create AdjustmentFilter, falling back to ColorMatrixFilter:', error);\n \n // Fall back to ColorMatrixFilter if AdjustmentFilter fails\n const filter = new ColorMatrixFilter();\n\n type ColorMatrixWithUI = typeof filter & {\n _customParams?: AdjustmentParams;\n updateUIParam?: (key: string, value: unknown) => void;\n };\n const filterWithUI = filter as ColorMatrixWithUI;\n\n // Store original parameters\n filterWithUI._customParams = { ...normalizedParams };\n\n // Apply initial adjustments as a composed matrix.\n applyColorMatrixAdjustments(filter, normalizedParams);\n \n // Add custom update method\n filterWithUI.updateUIParam = function updateUIParam(key: string, value: unknown): void {\n try {\n if (!isAdjustmentParamKey(key)) {\n return;\n }\n\n const customParams = this._customParams ?? { ...DEFAULT_ADJUSTMENT_PARAMS };\n const numericValue = toFiniteNumber(value, customParams[key]);\n customParams[key] = numericValue;\n this._customParams = customParams;\n\n applyColorMatrixAdjustments(this, customParams);\n } catch (error) {\n console.error(`Error updating ColorMatrixFilter parameter ${key}:`, error);\n }\n };\n \n console.log('ColorMatrixFilter created as fallback');\n return filter;\n }\n } catch (error) {\n console.error('Failed to create any adjustment filter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n gamma: 1,\n saturation: 1,\n contrast: 1,\n brightness: 1,\n red: 1,\n green: 1,\n blue: 1,\n alpha: 1,\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'brightness',\n type: 'slider',\n label: 'Brightness',\n property: 'brightness',\n min: 0,\n max: 5,\n step: 0.01,\n default: 1,\n },\n {\n id: 'contrast',\n type: 'slider',\n label: 'Contrast',\n property: 'contrast',\n min: 0,\n max: 5,\n step: 0.01,\n default: 1,\n },\n {\n id: 'saturation',\n type: 'slider',\n label: 'Saturation',\n property: 'saturation',\n min: 0,\n max: 5,\n step: 0.01,\n default: 1,\n },\n {\n id: 'gamma',\n type: 'slider',\n label: 'Gamma',\n property: 'gamma',\n min: 0,\n max: 5,\n step: 0.01,\n default: 1,\n },\n {\n id: 'red',\n type: 'slider',\n label: 'Red',\n property: 'red',\n min: 0,\n max: 5,\n step: 0.01,\n default: 1,\n },\n {\n id: 'green',\n type: 'slider',\n label: 'Green',\n property: 'green',\n min: 0,\n max: 5,\n step: 0.01,\n default: 1,\n },\n {\n id: 'blue',\n type: 'slider',\n label: 'Blue',\n property: 'blue',\n min: 0,\n max: 5,\n step: 0.01,\n default: 1,\n },\n {\n id: 'alpha',\n type: 'slider',\n label: 'Alpha',\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1,\n },\n ],\n});\n","/**\n * Advanced Adjustment Filter Definition\n * Provides advanced image adjustment options with a single filter\n */\nimport { registerFilter } from '../registry';\n// Import ColorMatrixFilter directly\nimport * as PIXI from 'pixi.js';\n// Access ColorMatrixFilter class\nconst { ColorMatrixFilter } = PIXI;\n\ninterface AdvancedAdjustmentParams {\n brightness: number;\n contrast: number;\n saturation: number;\n hue: number;\n sepia: number;\n negative: boolean;\n}\n\ntype AdvancedAdjustmentParamKey = keyof AdvancedAdjustmentParams;\n\nconst DEFAULT_ADVANCED_ADJUSTMENT_PARAMS: AdvancedAdjustmentParams = {\n brightness: 1,\n contrast: 1,\n saturation: 1,\n hue: 0,\n sepia: 0,\n negative: false,\n};\n\nconst ADVANCED_ADJUSTMENT_PARAM_KEYS = new Set<AdvancedAdjustmentParamKey>([\n 'brightness',\n 'contrast',\n 'saturation',\n 'hue',\n 'sepia',\n 'negative',\n]);\n\nfunction isAdvancedAdjustmentParamKey(key: string): key is AdvancedAdjustmentParamKey {\n return ADVANCED_ADJUSTMENT_PARAM_KEYS.has(key as AdvancedAdjustmentParamKey);\n}\n\nfunction toFiniteNumber(value: unknown, fallback: number): number {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n\n if (typeof value === 'string') {\n const parsed = Number(value);\n if (Number.isFinite(parsed)) {\n return parsed;\n }\n }\n\n return fallback;\n}\n\nfunction toBoolean(value: unknown, fallback: boolean): boolean {\n if (typeof value === 'boolean') {\n return value;\n }\n\n if (typeof value === 'string') {\n if (value === 'true') {\n return true;\n }\n if (value === 'false') {\n return false;\n }\n }\n\n return fallback;\n}\n\nfunction normalizeAdvancedAdjustmentParams(params: Record<string, unknown>): AdvancedAdjustmentParams {\n return {\n brightness: toFiniteNumber(params.brightness, DEFAULT_ADVANCED_ADJUSTMENT_PARAMS.brightness),\n contrast: toFiniteNumber(params.contrast, DEFAULT_ADVANCED_ADJUSTMENT_PARAMS.contrast),\n saturation: toFiniteNumber(params.saturation, DEFAULT_ADVANCED_ADJUSTMENT_PARAMS.saturation),\n hue: toFiniteNumber(params.hue, DEFAULT_ADVANCED_ADJUSTMENT_PARAMS.hue),\n sepia: toFiniteNumber(params.sepia, DEFAULT_ADVANCED_ADJUSTMENT_PARAMS.sepia),\n negative: toBoolean(params.negative, DEFAULT_ADVANCED_ADJUSTMENT_PARAMS.negative),\n };\n}\n\nfunction applyAdvancedAdjustments(filter: PIXI.ColorMatrixFilter, params: AdvancedAdjustmentParams): void {\n // Reset first so we always apply from a clean identity matrix.\n filter.reset();\n\n if (params.brightness !== 1) {\n filter.brightness(params.brightness, true);\n }\n\n if (params.contrast !== 1) {\n filter.contrast(params.contrast, true);\n }\n\n if (params.saturation !== 1) {\n filter.saturate(params.saturation, true);\n }\n\n if (params.hue !== 0) {\n filter.hue(params.hue, true);\n }\n\n if (params.sepia > 0) {\n filter.sepia(true);\n }\n\n if (params.negative) {\n filter.negative(true);\n }\n}\n\n// Register the advanced adjustment filter\nexport default registerFilter({\n id: 'adjustment-advanced',\n name: 'Advanced Adjustment',\n category: 'adjust',\n description: 'Comprehensive image adjustments including brightness, contrast, saturation, hue, and more',\n \n // Create an instance of the ColorMatrixFilter with the provided parameters\n createFilter: (params) => {\n try {\n const normalizedParams = normalizeAdvancedAdjustmentParams((params ?? {}) as Record<string, unknown>);\n console.log('Creating Advanced Adjustment filter with params:', normalizedParams);\n \n // Create filter instance\n const filter = new ColorMatrixFilter();\n\n type AdvancedFilterWithUI = typeof filter & {\n _customParams?: AdvancedAdjustmentParams;\n updateUIParam?: (key: string, value: unknown) => void;\n };\n const filterWithUI = filter as AdvancedFilterWithUI;\n\n // Store custom parameters for later reference\n filterWithUI._customParams = { ...normalizedParams };\n\n // Apply initial adjustments from full parameter set.\n applyAdvancedAdjustments(filter, normalizedParams);\n \n // Add custom updateUIParam method for dynamic updates\n filterWithUI.updateUIParam = function updateUIParam(key: string, value: unknown): void {\n try {\n if (!isAdvancedAdjustmentParamKey(key)) {\n return;\n }\n\n const customParams = this._customParams ?? { ...DEFAULT_ADVANCED_ADJUSTMENT_PARAMS };\n if (key === 'negative') {\n customParams.negative = toBoolean(value, customParams.negative);\n } else {\n const numericKey = key as Exclude<AdvancedAdjustmentParamKey, 'negative'>;\n customParams[numericKey] = toFiniteNumber(value, customParams[numericKey]);\n }\n\n this._customParams = customParams;\n applyAdvancedAdjustments(this, customParams);\n } catch (error) {\n console.error(`Error updating Advanced Adjustment parameter ${key}:`, error);\n }\n };\n \n console.log('Advanced Adjustment filter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create Advanced Adjustment filter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n brightness: 1,\n contrast: 1,\n saturation: 1,\n hue: 0,\n sepia: 0,\n negative: false\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'brightness',\n type: 'slider',\n label: 'Brightness',\n property: 'brightness',\n min: 0,\n max: 2,\n step: 0.01,\n default: 1,\n },\n {\n id: 'contrast',\n type: 'slider',\n label: 'Contrast',\n property: 'contrast',\n min: 0,\n max: 2,\n step: 0.01,\n default: 1,\n },\n {\n id: 'saturation',\n type: 'slider',\n label: 'Saturation',\n property: 'saturation',\n min: 0,\n max: 2,\n step: 0.01,\n default: 1,\n },\n {\n id: 'hue',\n type: 'slider',\n label: 'Hue Rotation',\n property: 'hue',\n min: 0,\n max: 360,\n step: 1,\n default: 0,\n },\n {\n id: 'sepia',\n type: 'slider',\n label: 'Sepia',\n property: 'sepia',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0,\n },\n {\n id: 'negative',\n type: 'toggle',\n label: 'Negative',\n property: 'negative',\n default: false,\n },\n ],\n});\n","/**\n * Alpha Filter Definition\n * Controls image opacity using PIXI.AlphaFilter.\n *\n * NOTE: Previously used ColorMatrixFilter with an identity matrix, which\n * does not produce visible transparency — ColorMatrixFilter.alpha is a\n * blend ratio between filtered and unfiltered output, so with an identity\n * matrix every value produces identical output.\n */\nimport { registerFilter } from '../registry';\nimport * as PIXI from 'pixi.js';\n\nconst clamp01 = (n: number) => Math.max(0, Math.min(1, n));\n\nexport default registerFilter({\n id: 'alpha',\n name: 'Alpha',\n category: 'adjust',\n description: 'Adjust the opacity of the image',\n\n createFilter: (params) => {\n const alpha = clamp01(params.alpha !== undefined ? Number(params.alpha) : 1);\n\n // AlphaFilter genuinely controls display-object opacity. PIXI v8 accepts\n // either a number or an options object; pass the number directly so we\n // work on any minor version that's installed.\n const filter = new (PIXI as any).AlphaFilter(alpha);\n\n (filter as any).updateUIParam = function (key: string, value: unknown) {\n if (key === 'alpha') {\n this.alpha = clamp01(Number(value));\n }\n };\n\n return filter;\n },\n\n defaultParams: {\n alpha: 1.0,\n },\n\n controls: [\n {\n id: 'alpha',\n type: 'slider',\n label: 'Opacity',\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1.0,\n },\n ],\n});\n","/**\n * Blur Filter Definition\n * Applies a Gaussian blur effect to the image\n * \n * This implementation uses the proper BlurFilter from pixi.js\n * which is compatible with PixiJS v8\n */\nimport { registerFilter } from '../registry';\n// Import PIXI namespace\nimport * as PIXI from 'pixi.js';\n\n// Register the blur filter\nexport default registerFilter({\n id: 'blur',\n name: 'Blur',\n category: 'blur',\n description: 'Apply a smooth blur effect to the entire image',\n \n /**\n * Create an instance of the BlurFilter from pixi.js package\n * This implementation matches the PixiJS example exactly, using 'blur' and 'quality' parameters\n */\n createFilter: (params) => {\n try {\n console.log('Creating BlurFilter with params:', params);\n \n // Create filter with proper options object for v8\n const filter = new PIXI.BlurFilter({\n strength: params.blur || 8,\n quality: params.quality || 4\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n * and provides consistent parameter handling across all filters.\n * \n * @param key The UI parameter name\n * @param value The new value for the parameter\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'blur':\n this.strength = value; // PixiJS BlurFilter uses 'strength' internally\n console.log(`Updated blur to ${this.strength}`);\n break;\n \n case 'quality':\n this.quality = value;\n console.log(`Updated quality to ${this.quality}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('BlurFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create BlurFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n blur: 8,\n quality: 4,\n },\n \n // UI controls for the filter - matching PixiJS example exactly\n controls: [\n {\n id: 'blur',\n type: 'slider',\n label: 'Blur',\n property: 'blur',\n min: 0,\n max: 100,\n step: 0.1,\n default: 8,\n },\n {\n id: 'quality',\n type: 'slider',\n label: 'Quality',\n property: 'quality',\n min: 1,\n max: 10,\n step: 1,\n default: 4,\n },\n ],\n});","/**\n * Color Matrix Filter Definition\n *\n * Applies brightness/contrast/saturation/hue/sepia/negative via PIXI's\n * ColorMatrixFilter. These operations are method calls on the filter\n * instance (not writable properties) and are non-commutative: applying\n * brightness-then-hue produces a different matrix than hue-then-brightness.\n *\n * Every update rebuilds the matrix from reset() in a fixed order so the\n * output is deterministic regardless of which slider was moved last, and\n * so a slider update cannot corrupt the filter by accidentally overwriting\n * one of the methods.\n */\nimport * as PIXI from 'pixi.js';\nimport { registerFilter } from '../registry';\n\ninterface ColorMatrixParams {\n brightness: number;\n contrast: number;\n saturation: number;\n hue: number;\n sepia: boolean;\n negative: boolean;\n}\n\nfunction applyColorMatrixParams(\n filter: PIXI.ColorMatrixFilter,\n params: ColorMatrixParams,\n): void {\n if (typeof (filter as any).reset === 'function') {\n (filter as any).reset();\n }\n\n // Deterministic order — matrix ops don't commute.\n if (params.brightness !== 1) {\n filter.brightness(params.brightness, false);\n }\n if (params.contrast !== 1) {\n filter.contrast(params.contrast, false);\n }\n if (params.saturation !== 1) {\n filter.saturate(params.saturation, false);\n }\n if (params.hue !== 0) {\n filter.hue(params.hue, false);\n }\n if (params.sepia) {\n filter.sepia(false);\n }\n if (params.negative) {\n filter.negative(false);\n }\n}\n\nfunction normalizeParams(raw: Record<string, unknown>): ColorMatrixParams {\n return {\n brightness: Number(raw.brightness ?? 1),\n contrast: Number(raw.contrast ?? 1),\n saturation: Number(raw.saturation ?? 1),\n hue: Number(raw.hue ?? 0),\n sepia: Boolean(raw.sepia),\n negative: Boolean(raw.negative),\n };\n}\n\nexport default registerFilter({\n id: 'color-matrix',\n name: 'Color Matrix',\n category: 'advanced',\n description: 'Advanced color adjustments including sepia, hue rotation, and negative',\n\n createFilter: (params) => {\n const MatrixFilterClass = (PIXI as any).ColorMatrixFilter;\n if (!MatrixFilterClass) return null;\n\n const filter: PIXI.ColorMatrixFilter = new MatrixFilterClass();\n const normalized = normalizeParams(params);\n\n (filter as any)._customParams = { ...normalized };\n applyColorMatrixParams(filter, normalized);\n\n (filter as any).updateUIParam = function (key: string, value: unknown) {\n const stored: ColorMatrixParams = (this as any)._customParams ?? normalizeParams({});\n\n switch (key) {\n case 'brightness':\n case 'contrast':\n case 'saturation':\n case 'hue':\n stored[key] = Number(value);\n break;\n case 'sepia':\n case 'negative':\n stored[key] = Boolean(value);\n break;\n default:\n return;\n }\n\n (this as any)._customParams = stored;\n applyColorMatrixParams(this, stored);\n };\n\n return filter;\n },\n\n defaultParams: {\n brightness: 1,\n contrast: 1,\n saturation: 1,\n hue: 0,\n sepia: false,\n negative: false,\n },\n\n controls: [\n {\n id: 'brightness',\n type: 'slider',\n label: 'Brightness',\n property: 'brightness',\n min: 0,\n max: 5,\n step: 0.1,\n default: 1,\n },\n {\n id: 'contrast',\n type: 'slider',\n label: 'Contrast',\n property: 'contrast',\n min: 0,\n max: 5,\n step: 0.1,\n default: 1,\n },\n {\n id: 'saturation',\n type: 'slider',\n label: 'Saturation',\n property: 'saturation',\n min: 0,\n max: 5,\n step: 0.1,\n default: 1,\n },\n {\n id: 'hue',\n type: 'slider',\n label: 'Hue Rotation',\n property: 'hue',\n min: -180,\n max: 180,\n step: 1,\n default: 0,\n },\n // Sepia is a toggle in phase 1 — PIXI v8's ColorMatrixFilter.sepia()\n // doesn't accept a smooth intensity, so a slider here would be misleading.\n {\n id: 'sepia',\n type: 'toggle',\n label: 'Sepia',\n property: 'sepia',\n default: false,\n },\n {\n id: 'negative',\n type: 'toggle',\n label: 'Negative',\n property: 'negative',\n default: false,\n },\n ],\n});\n","/**\n * Color Overlay Filter Definition\n * Applies a colored overlay to the entire image\n * \n * This implementation uses the proper ColorOverlayFilter from pixi-filters\n * which is compatible with PixiJS v8\n */\nimport { registerFilter } from '../registry';\n// Import from the central package for pixi filters\nimport * as PixiFilters from 'pixi-filters';\n// Access ColorOverlayFilter from the pixi-filters package\nconst { ColorOverlayFilter } = PixiFilters;\n\n// Register the color overlay filter\nexport default registerFilter({\n id: 'colorOverlay',\n name: 'Color Overlay',\n category: 'color',\n description: 'Apply a colored tint or overlay to the entire image',\n \n /**\n * Create an instance of ColorOverlayFilter from pixi-filters package\n * This implementation follows the pattern from ColorGradientFilter, adding\n * proper parameter handling with an updateUIParam method\n */\n createFilter: (params) => {\n try {\n console.log('Creating ColorOverlayFilter with params:', params);\n \n // Parse color string to number if needed\n let colorValue = 0xff0000; // Default red\n if (params.color) {\n if (typeof params.color === 'string') {\n colorValue = parseInt(params.color.replace('#', '0x'), 16);\n } else if (typeof params.color === 'number') {\n colorValue = params.color;\n }\n }\n \n // Create filter with the ColorOverlayFilter from pixi-filters\n // Using the options object syntax for v6+\n console.log('Creating ColorOverlayFilter with options object:', {\n color: colorValue,\n alpha: params.alpha || 0.5\n });\n \n const filter = new ColorOverlayFilter({\n color: colorValue,\n alpha: params.alpha || 0.5\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n * and provides consistent parameter handling across all filters.\n * \n * @param key The UI parameter name\n * @param value The new value for the parameter\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n // IMPORTANT: Must update BOTH the JS property AND the shader uniform\n // The JS property is used for state tracking, but the shader uses uniforms for rendering\n switch (key) {\n case 'color':\n // Convert hex string to number for the color property\n let colorNum: number;\n if (typeof value === 'string') {\n colorNum = parseInt(value.replace('#', '0x'), 16);\n } else {\n colorNum = Number(value);\n }\n this.color = colorNum;\n if (this.uniforms) this.uniforms.uColor = colorNum;\n console.log(`Updated color to ${colorNum}`);\n break;\n\n case 'alpha':\n // Direct alpha update\n this.alpha = Number(value);\n if (this.uniforms) this.uniforms.uAlpha = Number(value);\n console.log(`Updated alpha to ${this.alpha}`);\n break;\n\n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('ColorOverlayFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create ColorOverlayFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n color: '#ff0000',\n alpha: 0.5,\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'color',\n type: 'color',\n label: 'Color',\n property: 'color',\n default: '#ff0000',\n },\n {\n id: 'alpha',\n type: 'slider',\n label: 'Opacity',\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n ],\n});","/**\n * Drop Shadow Filter Definition\n * Applies a drop shadow effect to the image\n */\nimport { registerFilter } from '../registry';\nimport * as filters from 'pixi-filters';\n\n// Register the drop shadow filter\nexport default registerFilter({\n id: 'drop-shadow',\n name: 'Drop Shadow',\n category: 'effects',\n description: 'Add a soft drop shadow to the image',\n \n /**\n * Create an instance of the DropShadowFilter with the provided parameters\n * Using the official pixi-filters implementation\n */\n createFilter: (params) => {\n try {\n // Parse color from hex string\n const color = params.color ? params.color.replace('#', '0x') : '0x000000';\n\n // Create offset object based on distance and angle\n const distance = params.distance !== undefined ? params.distance : 5;\n const angle = params.angle !== undefined ? params.angle : 90;\n const blur = params.blur !== undefined ? params.blur : 2;\n const quality = params.quality !== undefined ? params.quality : 3;\n const offset = {\n x: distance * Math.cos(angle * Math.PI / 180),\n y: distance * Math.sin(angle * Math.PI / 180)\n };\n\n // Create the filter with the official pixi-filters package\n const filter = new filters.DropShadowFilter({\n offset: offset,\n color: parseInt(color, 16),\n alpha: params.alpha !== undefined ? params.alpha : 0.5,\n blur,\n quality,\n shadowOnly: params.shadowOnly !== undefined ? params.shadowOnly : false,\n pixelSize: {\n x: params.pixelSizeX !== undefined ? params.pixelSizeX : 1,\n y: params.pixelSizeY !== undefined ? params.pixelSizeY : 1\n }\n });\n\n // pixi-filters' DropShadowFilter does NOT set a .padding large enough\n // to contain its bleed (blur kernel + offset). Export needs to know the\n // actual reach so it can expand the render canvas. Compute it here and\n // expose it via _exportPadding so PixiRenderer.exportImage can read it.\n //\n // Rule of thumb: blur-kernel reach (blur * quality * 2) + offset magnitude\n // plus a small safety margin. This is the bleed from the SPRITE edge,\n // not the bleed radius around a single point.\n const computePadding = (b: number, q: number, offX: number, offY: number) => {\n const kernel = b * q * 2;\n const mag = Math.sqrt(offX * offX + offY * offY);\n return Math.ceil(kernel + mag + 2);\n };\n (filter as any)._exportPadding = computePadding(blur, quality, offset.x, offset.y);\n // Also set the built-in padding so PIXI's own bounds math doesn't clip\n // the preview at some inner boundary on certain configs.\n filter.padding = Math.max(filter.padding ?? 0, (filter as any)._exportPadding);\n\n // Store custom parameters for later reference\n (filter as any)._customParams = {\n ...params,\n // Also store the calculated offset for use in updateUIParam\n _offset: offset,\n _distance: distance,\n _angle: angle\n };\n\n /**\n * Build a fresh DropShadowFilter sized for export.\n *\n * The user tunes drop-shadow values while looking at the preview, where\n * the image is downscaled to fit the viewport. The same `distance=11`\n * that looks correct on a 600px-wide preview becomes microscopic on a\n * native-size 3224px export. This factory rebuilds the filter with\n * size-dependent params (distance, blur) multiplied by the\n * preview-to-native scale so the saved image visually matches the\n * preview at the user's intended apparent shadow size.\n *\n * Quality is unitless and stays as-is. Color, alpha, shadowOnly are\n * also intensity-only / boolean and don't scale.\n */\n const createScaledForExport = (rawParams: any, scale: number) => {\n const dist = Number(rawParams._distance ?? rawParams.distance ?? 5) * scale;\n const ang = Number(rawParams._angle ?? rawParams.angle ?? 90);\n const blr = Number(rawParams.blur ?? 2) * scale;\n const qual = Number(rawParams.quality ?? 3);\n const off = {\n x: dist * Math.cos(ang * Math.PI / 180),\n y: dist * Math.sin(ang * Math.PI / 180),\n };\n const colorStr = rawParams.color\n ? String(rawParams.color).replace('#', '0x')\n : '0x000000';\n\n const next = new filters.DropShadowFilter({\n offset: off,\n color: parseInt(colorStr, 16),\n alpha: rawParams.alpha !== undefined ? Number(rawParams.alpha) : 0.5,\n blur: blr,\n quality: qual,\n shadowOnly: rawParams.shadowOnly !== undefined ? Boolean(rawParams.shadowOnly) : false,\n pixelSize: {\n x: rawParams.pixelSizeX !== undefined ? Number(rawParams.pixelSizeX) : 1,\n y: rawParams.pixelSizeY !== undefined ? Number(rawParams.pixelSizeY) : 1,\n },\n });\n\n const padding = computePadding(blr, qual, off.x, off.y);\n (next as any)._exportPadding = padding;\n next.padding = Math.max(next.padding ?? 0, padding);\n return next;\n };\n\n /**\n * Hook used by PixiRenderer.exportImage(). Returns a fresh filter\n * instance with size params scaled to native pixels — never mutates\n * the live preview filter.\n */\n (filter as any).createExportFilter = function (options: { previewToNativeScale?: number } = {}) {\n const scale = Number.isFinite(options.previewToNativeScale)\n ? Math.max(1, Number(options.previewToNativeScale))\n : 1;\n const stored = (this as any)._customParams || params;\n return createScaledForExport(stored, scale);\n };\n\n /** Conservative export-time bleed for the renderer to reserve. */\n (filter as any).getExportPadding = function () {\n return Number((this as any)._exportPadding || this.padding || 0);\n };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * Following the pattern from the fix_filters.md document\n */\n const refreshPadding = (f: any) => {\n const off = f._customParams?._offset ?? { x: 0, y: 0 };\n const b = Number(f.blur ?? 0);\n const q = Number(f.quality ?? 1);\n const p = computePadding(b, q, off.x, off.y);\n f._exportPadding = p;\n f.padding = Math.max(f.padding ?? 0, p);\n };\n\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n customParams[key] = value;\n\n switch (key) {\n case 'color':\n if (typeof value === 'string') {\n this.color = parseInt(value.replace('#', '0x'), 16);\n }\n break;\n\n case 'alpha':\n this.alpha = Number(value);\n break;\n\n case 'blur':\n this.blur = Number(value);\n refreshPadding(this);\n break;\n\n case 'quality':\n this.quality = Number(value);\n refreshPadding(this);\n break;\n\n case 'shadowOnly':\n this.shadowOnly = Boolean(value);\n break;\n\n case 'pixelSizeX':\n this.pixelSizeX = Number(value);\n customParams.pixelSizeX = Number(value);\n break;\n\n case 'pixelSizeY':\n this.pixelSizeY = Number(value);\n customParams.pixelSizeY = Number(value);\n break;\n\n case 'distance':\n case 'angle': {\n if (key === 'distance') {\n customParams._distance = Number(value);\n customParams.distance = Number(value);\n } else {\n customParams._angle = Number(value);\n customParams.angle = Number(value);\n }\n const newOffset = {\n x: customParams._distance * Math.cos(customParams._angle * Math.PI / 180),\n y: customParams._distance * Math.sin(customParams._angle * Math.PI / 180),\n };\n customParams._offset = newOffset;\n this.offset = newOffset;\n refreshPadding(this);\n break;\n }\n\n default:\n if (key in this) {\n this[key] = value;\n }\n break;\n }\n\n return true;\n } catch {\n if ((this as any)._customParams) {\n (this as any)._customParams[key] = value;\n }\n return false;\n }\n };\n\n return filter;\n } catch (error) {\n console.error('Failed to create Drop Shadow filter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n alpha: 0.5,\n blur: 2,\n color: '#000000',\n distance: 5,\n angle: 90,\n quality: 3,\n shadowOnly: false,\n pixelSizeX: 1,\n pixelSizeY: 1\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'alpha',\n type: 'slider',\n label: 'Opacity',\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'blur',\n type: 'slider',\n label: 'Blur',\n property: 'blur',\n min: 0,\n max: 20,\n step: 0.1,\n default: 2,\n },\n {\n id: 'color',\n type: 'color',\n label: 'Color',\n property: 'color',\n default: '#000000',\n },\n {\n id: 'distance',\n type: 'slider',\n label: 'Distance',\n property: 'distance',\n min: 0,\n max: 50,\n step: 1,\n default: 5,\n },\n {\n id: 'angle',\n type: 'slider',\n label: 'Angle',\n property: 'angle',\n min: 0,\n max: 360,\n step: 1,\n default: 90,\n },\n {\n id: 'quality',\n type: 'slider',\n label: 'Quality',\n property: 'quality',\n min: 0,\n max: 20,\n step: 1,\n default: 3,\n },\n {\n id: 'shadowOnly',\n type: 'toggle',\n label: 'Shadow Only',\n property: 'shadowOnly',\n default: false,\n },\n {\n id: 'pixelSizeX',\n type: 'slider',\n label: 'Pixel Size X',\n property: 'pixelSizeX',\n min: 0.5,\n max: 8,\n step: 0.5,\n default: 1,\n },\n {\n id: 'pixelSizeY',\n type: 'slider',\n label: 'Pixel Size Y',\n property: 'pixelSizeY',\n min: 0.5,\n max: 8,\n step: 0.5,\n default: 1,\n }\n ],\n});","/**\n * Grayscale Filter Definition\n * Converts image to grayscale with customizable intensity\n * \n * This implementation uses the ColorMatrixFilter from pixi.js\n * to provide a grayscale effect with adjustable intensity.\n */\nimport { registerFilter } from '../registry';\n// Import from pixi.js with namespace\nimport * as PIXI from 'pixi.js';\n// @ts-ignore - Module structure doesn't match TypeScript definitions\nconst { ColorMatrixFilter } = PIXI;;\n\n// Register the grayscale filter\nexport default registerFilter({\n id: 'grayscale',\n name: 'Grayscale',\n category: 'color',\n description: 'Convert the image to black and white with adjustable intensity',\n \n /**\n * Create a ColorMatrixFilter instance configured for grayscale effect with adjustable intensity\n * This implementation follows the pattern from ColorGradientFilter, adding\n * proper parameter handling with an updateUIParam method\n */\n createFilter: (params) => {\n try {\n console.log('Creating grayscale filter with params:', params);\n \n // Create a new ColorMatrixFilter\n const filter = new ColorMatrixFilter();\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n // Apply the initial grayscale effect based on intensity\n const intensity = params.intensity !== undefined ? params.intensity : 1.0;\n applyGrayscaleEffect(filter as any, intensity);\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * This follows the same pattern as ColorOverlayFilter and ColorGradientFilter\n * \n * @param key The UI parameter name\n * @param value The new value for the parameter\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'intensity':\n // Apply grayscale effect with the new intensity\n applyGrayscaleEffect(this, value);\n console.log(`Updated grayscale intensity to ${value}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n this[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('Grayscale filter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create grayscale filter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n intensity: 0.35,\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'intensity',\n type: 'slider',\n label: 'Intensity',\n property: 'intensity',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.35,\n },\n ],\n});\n\n/**\n * Helper function to apply grayscale effect with a specific intensity\n * @param filter The ColorMatrixFilter instance\n * @param intensity The intensity of the grayscale effect (0-1)\n */\nfunction applyGrayscaleEffect(filter: any, intensity: number): void {\n // Reset the matrix to identity (no effect)\n filter.reset();\n\n // Apply grayscale with the specified intensity\n // The greyscale method takes a single parameter for intensity (0-1)\n filter.greyscale(intensity);\n}","/**\n * HSL Adjustment Filter Definition\n * Adjusts hue, saturation, and lightness with fine control\n */\nimport { registerFilter } from '../registry';\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { HslAdjustmentFilter } = PixiFilters;;\n\n// Register the HSL adjustment filter\nexport default registerFilter({\n id: 'hsl-adjustment',\n name: 'HSL Adjustment',\n category: 'color',\n description: 'Control hue, saturation, and lightness independently',\n \n /**\n * Create an instance of the HslAdjustmentFilter with the provided parameters\n * Using the official pixi-filters implementation instead of a custom one\n */\n createFilter: (params) => {\n try {\n console.log('Creating HSL Adjustment filter with params:', params);\n \n // Create a new HslAdjustmentFilter instance from the pixi-filters package\n const filter = new HslAdjustmentFilter({\n hue: params.hue !== undefined ? params.hue : 0,\n saturation: params.saturation !== undefined ? params.saturation : 0,\n lightness: params.lightness !== undefined ? params.lightness : 0, \n colorize: params.colorize !== undefined ? params.colorize : false,\n alpha: params.alpha !== undefined ? params.alpha : 1.0\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * Following the pattern from the fix_filters.md document\n * \n * @param key The UI parameter name\n * @param value The new value for the parameter\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n // IMPORTANT: Must update BOTH the JS property AND the shader uniform\n // The JS property is used for state tracking, but the shader uses uniforms for rendering\n switch (key) {\n case 'hue':\n // The filter handles the degrees to radians conversion internally\n this.hue = Number(value);\n if (this.uniforms) this.uniforms.uHue = Number(value);\n console.log(`Updated hue to ${value}`);\n break;\n\n case 'saturation':\n this.saturation = Number(value);\n if (this.uniforms) this.uniforms.uSaturation = Number(value);\n console.log(`Updated saturation to ${value}`);\n break;\n\n case 'lightness':\n this.lightness = Number(value);\n if (this.uniforms) this.uniforms.uLightness = Number(value);\n console.log(`Updated lightness to ${value}`);\n break;\n\n case 'colorize':\n this.colorize = Boolean(value);\n if (this.uniforms) this.uniforms.uColorize = value ? 1 : 0;\n console.log(`Updated colorize to ${value}`);\n break;\n\n case 'alpha':\n this.alpha = Number(value);\n if (this.uniforms) this.uniforms.uAlpha = Number(value);\n console.log(`Updated alpha to ${value}`);\n break;\n\n // For any other properties, try direct assignment\n default:\n if (key in this) {\n this[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n } catch (error) {\n console.error(`Failed to update parameter ${key} using updateUIParam:`, error);\n \n // Still store the value in customParams even if setting it failed\n if ((this as any)._customParams) {\n (this as any)._customParams[key] = value;\n }\n \n return false;\n }\n };\n \n console.log('HSL Adjustment filter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create HSL Adjustment filter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n hue: 0,\n saturation: 0,\n lightness: 0,\n colorize: false,\n alpha: 1.0\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'hue',\n type: 'slider',\n label: 'Hue',\n property: 'hue',\n min: -180,\n max: 180,\n step: 1,\n default: 0,\n },\n {\n id: 'saturation',\n type: 'slider',\n label: 'Saturation',\n property: 'saturation',\n min: -1,\n max: 1,\n step: 0.01,\n default: 0,\n },\n {\n id: 'lightness',\n type: 'slider',\n label: 'Lightness',\n property: 'lightness',\n min: -1,\n max: 1,\n step: 0.01,\n default: 0,\n },\n {\n id: 'colorize',\n type: 'toggle',\n label: 'Colorize',\n property: 'colorize',\n default: false,\n },\n {\n id: 'alpha',\n type: 'slider',\n label: 'Alpha',\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1.0,\n },\n ],\n});","/**\n * Kawase Blur Filter Definition\n * A much faster blur than Gaussian blur, with similar quality\n * \n * This implementation uses the proper KawaseBlurFilter from pixi-filters\n * which is compatible with PixiJS v8\n */\nimport { registerFilter } from '../registry';\n// Import KawaseBlurFilter directly from pixi-filters\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { KawaseBlurFilter } = PixiFilters;;\n\n// Register the kawase blur filter\nexport default registerFilter({\n id: 'kawase-blur',\n name: 'Kawase Blur',\n category: 'blur',\n description: 'A more optimized blur algorithm that is faster than standard blur',\n \n /**\n * Create an instance of the KawaseBlurFilter from pixi-filters package\n * This implementation follows the pattern from ColorGradientFilter, adding\n * proper parameter handling with an updateUIParam method\n */\n createFilter: (params) => {\n try {\n console.log('Creating KawaseBlurFilter with params:', params);\n \n // Create filter with proper options object for v6+\n const filter = new KawaseBlurFilter({\n strength: params.strength || 4,\n quality: params.quality || 3,\n clamp: params.clamp || false,\n pixelSize: params.pixelSize || 1\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n * and provides consistent parameter handling across all filters.\n * \n * @param key The UI parameter name\n * @param value The new value for the parameter\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'strength':\n this.strength = value;\n console.log(`Updated strength to ${this.strength}`);\n break;\n \n case 'quality':\n this.quality = value;\n console.log(`Updated quality to ${this.quality}`);\n break;\n \n case 'clamp':\n this.clamp = value;\n console.log(`Updated clamp to ${this.clamp}`);\n break;\n \n case 'pixelSize':\n // pixelSize can be set as a single number or as an object with x and y\n if (typeof value === 'number') {\n this.pixelSize = value;\n } else if (typeof value === 'object' && value !== null) {\n if ('x' in value && 'y' in value) {\n this.pixelSize = value;\n }\n }\n console.log(`Updated pixelSize to ${JSON.stringify(this.pixelSize)}`);\n break;\n\n case 'pixelSizeX':\n this.pixelSizeX = value;\n console.log(`Updated pixelSizeX to ${this.pixelSizeX}`);\n break;\n \n case 'pixelSizeY':\n this.pixelSizeY = value;\n console.log(`Updated pixelSizeY to ${this.pixelSizeY}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('KawaseBlurFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create KawaseBlurFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n strength: 4,\n quality: 3,\n clamp: false,\n pixelSize: 1\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'strength',\n type: 'slider',\n label: 'Strength',\n property: 'strength',\n min: 0,\n max: 20,\n step: 0.1,\n default: 4,\n },\n {\n id: 'quality',\n type: 'slider',\n label: 'Quality',\n property: 'quality',\n min: 1,\n max: 20,\n step: 1,\n default: 3,\n },\n {\n id: 'clamp',\n type: 'toggle',\n label: 'Clamp Edges',\n property: 'clamp',\n default: false,\n },\n {\n id: 'pixelSize',\n type: 'slider',\n label: 'Pixel Size',\n property: 'pixelSize',\n min: 0.5,\n max: 10,\n step: 0.5,\n default: 1,\n },\n {\n id: 'pixelSizeX',\n type: 'slider',\n label: 'Pixel Size X',\n property: 'pixelSizeX',\n min: 0,\n max: 10,\n step: 0.1,\n default: 1,\n },\n {\n id: 'pixelSizeY',\n type: 'slider',\n label: 'Pixel Size Y',\n property: 'pixelSizeY',\n min: 0,\n max: 10,\n step: 0.1,\n default: 1,\n },\n ],\n});","/**\n * Motion Blur Filter Definition\n * Applies a directional motion blur effect to the image\n * \n * This implementation uses the proper MotionBlurFilter from pixi-filters\n * which is compatible with PixiJS v8\n */\nimport { registerFilter } from '../registry';\n// Import MotionBlurFilter directly from pixi-filters\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { MotionBlurFilter } = PixiFilters;;\n\n// Register the motion blur filter\nexport default registerFilter({\n id: 'motion-blur',\n name: 'Motion Blur',\n category: 'blur',\n description: 'Creates a directional blur effect simulating motion',\n \n /**\n * Create an instance of the MotionBlurFilter from pixi-filters package\n * This implementation follows the pattern from ColorGradientFilter, adding\n * proper parameter handling with an updateUIParam method\n */\n createFilter: (params) => {\n try {\n console.log('Creating MotionBlurFilter with params:', params);\n \n // Create filter with proper options object for v6+\n const filter = new MotionBlurFilter({\n velocity: { \n x: params.velocityX !== undefined ? params.velocityX : 0, \n y: params.velocityY !== undefined ? params.velocityY : 0 \n },\n kernelSize: params.kernelSize || 5,\n offset: params.offset !== undefined ? params.offset : 0\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n * and provides consistent parameter handling across all filters.\n * \n * @param key The UI parameter name\n * @param value The new value for the parameter\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'velocityX':\n // Update just the X component of the velocity\n this.velocityX = value;\n console.log(`Updated velocityX to ${this.velocityX}`);\n break;\n \n case 'velocityY':\n // Update just the Y component of the velocity\n this.velocityY = value;\n console.log(`Updated velocityY to ${this.velocityY}`);\n break;\n \n case 'kernelSize':\n this.kernelSize = value;\n console.log(`Updated kernelSize to ${this.kernelSize}`);\n break;\n \n case 'offset':\n this.offset = value;\n console.log(`Updated offset to ${this.offset}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('MotionBlurFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create MotionBlurFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n velocityX: 0,\n velocityY: 0,\n kernelSize: 5,\n offset: 0\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'velocityX',\n type: 'slider',\n label: 'Velocity X',\n property: 'velocityX',\n min: -90,\n max: 90,\n step: 1,\n default: 0,\n },\n {\n id: 'velocityY',\n type: 'slider',\n label: 'Velocity Y',\n property: 'velocityY',\n min: -90,\n max: 90,\n step: 1,\n default: 0,\n },\n {\n id: 'kernelSize',\n type: 'select',\n label: 'Kernel Size',\n property: 'kernelSize',\n options: [\n { label: '3', value: 3 },\n { label: '5', value: 5 },\n { label: '7', value: 7 },\n { label: '9', value: 9 },\n { label: '11', value: 11 },\n { label: '13', value: 13 },\n { label: '15', value: 15 },\n { label: '17', value: 17 },\n { label: '19', value: 19 },\n { label: '21', value: 21 },\n { label: '23', value: 23 },\n { label: '25', value: 25 },\n ],\n default: 5,\n },\n {\n id: 'offset',\n type: 'slider',\n label: 'Offset',\n property: 'offset',\n min: -150,\n max: 150,\n step: 1,\n default: 0,\n },\n ],\n});","/**\n * Radial Blur Filter Definition\n * Applies a radial motion blur effect that emanates from a center point\n */\nimport { registerFilter } from '../registry';\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { RadialBlurFilter } = PixiFilters;;\n\n// Register the radial blur filter\nexport default registerFilter({\n id: 'radial-blur',\n name: 'Radial Blur',\n category: 'blur',\n description: 'Creates a circular blur effect emanating from a center point',\n \n // Create an instance of the RadialBlurFilter with the provided parameters\n createFilter: (params) => {\n try {\n // Create filter with options object\n const filter = new RadialBlurFilter({\n angle: params.angle ?? 20,\n center: { x: params.centerX ?? 0, y: params.centerY ?? 0 },\n kernelSize: params.kernelSize ?? 15,\n radius: params.radius ?? 300\n });\n\n // Store custom params for reference\n (filter as any)._customParams = {\n centerX: params.centerX ?? 0,\n centerY: params.centerY ?? 0\n };\n \n // Add custom updateUIParam method for dynamic updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n switch (key) {\n case 'angle':\n this.angle = Number(value);\n break;\n case 'centerX':\n (this as any)._customParams.centerX = Number(value);\n this.center = { \n x: Number(value), \n y: (this as any)._customParams.centerY \n };\n break;\n case 'centerY':\n (this as any)._customParams.centerY = Number(value);\n this.center = { \n x: (this as any)._customParams.centerX, \n y: Number(value) \n };\n break;\n case 'kernelSize':\n this.kernelSize = Number(value);\n break;\n case 'radius':\n this.radius = Number(value);\n break;\n default:\n console.warn(`Unknown parameter for RadialBlurFilter: ${key}`);\n }\n } catch (error) {\n console.error(`Error updating RadialBlurFilter parameter ${key}:`, error);\n }\n };\n \n return filter;\n } catch (error) {\n console.error('Failed to create RadialBlurFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n angle: 20,\n centerX: 0,\n centerY: 0,\n kernelSize: 15,\n radius: 300\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'angle',\n type: 'slider',\n label: 'Angle',\n property: 'angle',\n min: -180,\n max: 180,\n step: 1,\n default: 20,\n },\n {\n id: 'centerX',\n type: 'slider',\n label: 'Center X',\n property: 'centerX',\n min: -1,\n max: 1,\n step: 0.01,\n default: 0,\n },\n {\n id: 'centerY',\n type: 'slider',\n label: 'Center Y',\n property: 'centerY',\n min: -1,\n max: 1,\n step: 0.01,\n default: 0,\n },\n {\n id: 'kernelSize',\n type: 'select',\n label: 'Kernel Size',\n property: 'kernelSize',\n options: [\n { label: '3', value: 3 },\n { label: '5', value: 5 },\n { label: '7', value: 7 },\n { label: '9', value: 9 },\n { label: '11', value: 11 },\n { label: '13', value: 13 },\n { label: '15', value: 15 },\n { label: '17', value: 17 },\n { label: '19', value: 19 },\n { label: '21', value: 21 },\n { label: '23', value: 23 },\n { label: '25', value: 25 },\n ],\n default: 15,\n },\n {\n id: 'radius',\n type: 'slider',\n label: 'Radius',\n property: 'radius',\n min: -1,\n max: 1000,\n step: 10,\n default: 300,\n },\n ],\n});","/**\n * Tilt Shift Filter Definition\n * Creates a depth-of-field effect like a miniature model\n */\nimport { registerFilter } from '../registry';\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { TiltShiftFilter } = PixiFilters;\n\n// Register the tilt shift filter\nexport default registerFilter({\n id: 'tilt-shift',\n name: 'Tilt Shift',\n category: 'blur',\n description: 'Creates a depth-of-field effect simulating miniature photography',\n \n // Create an instance of the TiltShiftFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating TiltShiftFilter with params:', params);\n \n // Ensure parameters have default values if missing\n const blur = typeof params.blur === 'number' ? params.blur : 100;\n const gradientBlur = typeof params.gradientBlur === 'number' ? params.gradientBlur : 600;\n const startX = typeof params.startX === 'number' ? params.startX : 0;\n const startY = typeof params.startY === 'number' ? params.startY : 0.5;\n const endX = typeof params.endX === 'number' ? params.endX : 1;\n const endY = typeof params.endY === 'number' ? params.endY : 0.5;\n \n // Create the filter with proper options\n const filter = new TiltShiftFilter({\n blur: Number(blur),\n gradientBlur: Number(gradientBlur),\n start: { x: Number(startX), y: Number(startY) },\n end: { x: Number(endX), y: Number(endY) }\n });\n \n // Log the actual filter object to see its properties\n console.log('Created TiltShiftFilter instance with properties:', {\n blur: filter.blur,\n gradientBlur: filter.gradientBlur,\n start: filter.start,\n end: filter.end\n });\n \n // Store custom parameters for reference\n (filter as any)._customParams = {\n blur: blur,\n gradientBlur: gradientBlur,\n startX: startX,\n startY: startY,\n endX: endX,\n endY: endY\n };\n \n // Add updateUIParam method for dynamic parameter updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n console.log(`TiltShiftFilter.updateUIParam called: ${key} = ${value}`);\n \n // Force numeric conversion\n const numValue = Number(value);\n \n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = numValue;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'blur':\n this.blur = numValue;\n console.log(`Updated blur to ${this.blur}`);\n break;\n \n case 'gradientBlur':\n this.gradientBlur = numValue;\n console.log(`Updated gradientBlur to ${this.gradientBlur}`);\n break;\n \n case 'startX':\n if (this.start && typeof this.start === 'object') {\n this.start.x = numValue;\n console.log(`Updated startX to ${numValue}`, this.start);\n }\n break;\n \n case 'startY':\n if (this.start && typeof this.start === 'object') {\n this.start.y = numValue;\n console.log(`Updated startY to ${numValue}`, this.start);\n }\n break;\n \n case 'endX':\n if (this.end && typeof this.end === 'object') {\n this.end.x = numValue;\n console.log(`Updated endX to ${numValue}`, this.end);\n }\n break;\n \n case 'endY':\n if (this.end && typeof this.end === 'object') {\n this.end.y = numValue;\n console.log(`Updated endY to ${numValue}`, this.end);\n }\n break;\n \n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = numValue;\n console.log(`Updated ${key} to ${numValue}`);\n } else {\n console.warn(`Unknown parameter for TiltShiftFilter: ${key}`);\n }\n break;\n }\n \n // Log the current state after updates\n console.log('TiltShiftFilter state after update:', {\n blur: this.blur,\n gradientBlur: this.gradientBlur,\n start: this.start,\n end: this.end\n });\n } catch (error) {\n console.error(`Error updating TiltShiftFilter parameter ${key}:`, error);\n }\n };\n \n console.log('TiltShiftFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create TiltShiftFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n blur: 100,\n gradientBlur: 600,\n startX: 0,\n startY: 0.5,\n endX: 1,\n endY: 0.5\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'blur',\n type: 'slider',\n label: 'Blur Strength',\n property: 'blur',\n min: 0,\n max: 200,\n step: 1,\n default: 100,\n },\n {\n id: 'gradientBlur',\n type: 'slider',\n label: 'Gradient Width',\n property: 'gradientBlur',\n min: 0,\n max: 1000,\n step: 10,\n default: 600,\n },\n {\n id: 'startX',\n type: 'slider',\n label: 'Start X',\n property: 'startX',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0,\n },\n {\n id: 'startY',\n type: 'slider',\n label: 'Start Y',\n property: 'startY',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'endX',\n type: 'slider',\n label: 'End X',\n property: 'endX',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1,\n },\n {\n id: 'endY',\n type: 'slider',\n label: 'End Y',\n property: 'endY',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n ],\n});","/**\n * Zoom Blur Filter Definition\n * Creates a radial blur that simulates a camera zoom effect\n * \n * This implementation uses the proper ZoomBlurFilter from pixi-filters\n * which is compatible with PixiJS v8\n */\nimport { registerFilter } from '../registry';\n// Import ZoomBlurFilter directly from pixi-filters\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { ZoomBlurFilter } = PixiFilters;;\n\n// Register the zoom blur filter\nexport default registerFilter({\n id: 'zoom-blur',\n name: 'Zoom Blur',\n category: 'blur',\n description: 'Creates a zoom blur effect from a center point',\n \n /**\n * Create an instance of the ZoomBlurFilter from pixi-filters package\n * This implementation follows the pattern from ColorGradientFilter, adding\n * proper parameter handling with an updateUIParam method\n */\n createFilter: (params) => {\n try {\n console.log('Creating ZoomBlurFilter with params:', params);\n \n // Create filter with proper options object for v6+\n const filter = new ZoomBlurFilter({\n strength: params.strength || 0.1,\n center: { \n x: params.centerX !== undefined ? params.centerX : 0.5, \n y: params.centerY !== undefined ? params.centerY : 0.5 \n },\n innerRadius: params.innerRadius || 80,\n radius: params.radius !== undefined ? params.radius : -1,\n maxKernelSize: params.maxKernelSize || 32\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n * and provides consistent parameter handling across all filters.\n * \n * @param key The UI parameter name\n * @param value The new value for the parameter\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'strength':\n this.strength = value;\n console.log(`Updated strength to ${this.strength}`);\n break;\n \n case 'centerX':\n // Update just the X component of the center point\n this.centerX = value;\n console.log(`Updated centerX to ${this.centerX}`);\n break;\n \n case 'centerY':\n // Update just the Y component of the center point\n this.centerY = value;\n console.log(`Updated centerY to ${this.centerY}`);\n break;\n \n case 'innerRadius':\n this.innerRadius = value;\n console.log(`Updated innerRadius to ${this.innerRadius}`);\n break;\n \n case 'radius':\n this.radius = value;\n console.log(`Updated radius to ${this.radius}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('ZoomBlurFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create ZoomBlurFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n strength: 0.1,\n centerX: 0.5,\n centerY: 0.5,\n innerRadius: 80,\n radius: -1,\n maxKernelSize: 32\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'strength',\n type: 'slider',\n label: 'Strength',\n property: 'strength',\n min: 0,\n max: 0.5,\n step: 0.01,\n default: 0.1,\n },\n {\n id: 'centerX',\n type: 'slider',\n label: 'Center X',\n property: 'centerX',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'centerY',\n type: 'slider',\n label: 'Center Y',\n property: 'centerY',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'innerRadius',\n type: 'slider',\n label: 'Inner Radius',\n property: 'innerRadius',\n min: 0,\n max: 1000,\n step: 1,\n default: 80,\n },\n {\n id: 'radius',\n type: 'slider',\n label: 'Outer Radius',\n property: 'radius',\n min: -1,\n max: 1000,\n step: 10,\n default: -1,\n },\n {\n id: 'maxKernelSize',\n type: 'select',\n label: 'Quality',\n property: 'maxKernelSize',\n options: [\n { label: 'Low', value: 16 },\n { label: 'Medium', value: 32 },\n { label: 'High', value: 48 },\n { label: 'Very High', value: 64 },\n ],\n default: 32,\n },\n ],\n});","/**\n * Color Gradient Filter Definition\n *\n * Applies a linear/radial/conic gradient via pixi-filters' ColorGradientFilter.\n * Supports unlimited color stops with per-stop color/offset/alpha editing,\n * add/remove stop commands, and CSS gradient string parsing.\n *\n * The filter instance exposes:\n * getSerializableParams() - canonical state snapshot for FilterManager sync\n * getDynamicControls() - per-stop control rows for FilterAdjustments UI\n * updateUIParam(key,val) - mutation entry point (static + dynamic + actions)\n * handleButtonAction(act) - thin wrapper for add/remove stop commands\n */\nimport { registerFilter } from '../registry';\nimport * as PixiFilters from 'pixi-filters';\n\nconst { ColorGradientFilter } = PixiFilters as any;\n\ntype HexString = `#${string}`;\n\ninterface ColorStopNum {\n offset: number;\n color: number; // integer RGB\n alpha: number;\n}\n\ninterface ColorStopHex {\n offset: number;\n color: HexString;\n alpha: number;\n}\n\ninterface SerializedParams {\n gradientType: number;\n colorStops: ColorStopHex[];\n angle: number;\n alpha: number;\n maxColors: number;\n replace: boolean;\n cssGradient: string;\n}\n\nfunction hexToInt(hex: string): number {\n return parseInt(hex.replace('#', '0x'), 16);\n}\n\nfunction intToHex(num: number): HexString {\n return ('#' + num.toString(16).padStart(6, '0')) as HexString;\n}\n\nfunction normalizeStopForFilter(stop: { offset: number; color: string | number; alpha: number }): ColorStopNum {\n return {\n offset: Number(stop.offset),\n color: typeof stop.color === 'string' ? hexToInt(stop.color) : Number(stop.color),\n alpha: Number(stop.alpha),\n };\n}\n\nfunction hexStopFromFilter(stop: { offset: number; color: number | string; alpha: number }): ColorStopHex {\n return {\n offset: stop.offset,\n color: typeof stop.color === 'number' ? intToHex(stop.color) : (stop.color as HexString),\n alpha: stop.alpha,\n };\n}\n\nexport default registerFilter({\n id: 'color-gradient',\n name: 'Color Gradient',\n category: 'color',\n description: 'Applies a linear, radial or conic color gradient over the image with multiple color stops',\n\n createFilter: (params) => {\n const incomingStops = (params.colorStops as any[]) || [\n { offset: 0, color: '#ff0000', alpha: 1 },\n { offset: 1, color: '#0000ff', alpha: 1 },\n ];\n\n let stops: ColorStopNum[] = incomingStops.map(normalizeStopForFilter);\n if (stops.length < 2) {\n stops = [\n { offset: 0, color: 0xff0000, alpha: 1 },\n { offset: 1, color: 0x0000ff, alpha: 1 },\n ];\n }\n // Sort on creation — the UI layer avoids re-sorting during a drag.\n stops.sort((a, b) => a.offset - b.offset);\n\n const filter = new ColorGradientFilter({\n type: params.gradientType,\n stops,\n angle: params.angle,\n alpha: params.alpha,\n maxColors: params.maxColors || 0,\n replace: params.replace,\n });\n\n (filter as any)._customParams = {\n cssGradient: params.cssGradient || '',\n };\n\n /**\n * Canonical snapshot for persistence + recreation.\n */\n (filter as any).getSerializableParams = function (): SerializedParams {\n const stopsHex: ColorStopHex[] = Array.isArray(this.stops)\n ? this.stops.map(hexStopFromFilter)\n : [];\n\n return {\n gradientType: this.type,\n colorStops: stopsHex,\n angle: this.angle,\n alpha: this.alpha,\n maxColors: this.maxColors,\n replace: this.replace,\n cssGradient: this._customParams?.cssGradient ?? '',\n };\n };\n\n /**\n * Color stops formatted for UI consumption.\n */\n (filter as any).getColorStopsForUI = function (): ColorStopHex[] {\n if (!Array.isArray(this.stops)) return [];\n return this.stops.map(hexStopFromFilter);\n };\n\n /**\n * Generate one control row per color stop (color, offset, alpha).\n * Called by FilterAdjustments after rendering static controls.\n */\n (filter as any).getDynamicControls = function () {\n const colorStops: ColorStopHex[] = this.getColorStopsForUI();\n\n const controls: Array<{\n id: string;\n type: string;\n label: string;\n property: string;\n default: unknown;\n min?: number;\n max?: number;\n step?: number;\n }> = [];\n\n colorStops.forEach((stop, index) => {\n controls.push({\n id: `colorStop-${index}-color`,\n type: 'color',\n label: `Stop ${index + 1} Color`,\n property: `colorStops[${index}].color`,\n default: stop.color,\n });\n\n controls.push({\n id: `colorStop-${index}-offset`,\n type: 'slider',\n label: `Stop ${index + 1} Position`,\n property: `colorStops[${index}].offset`,\n min: 0,\n max: 1,\n step: 0.01,\n default: stop.offset,\n });\n\n controls.push({\n id: `colorStop-${index}-alpha`,\n type: 'slider',\n label: `Stop ${index + 1} Alpha`,\n property: `colorStops[${index}].alpha`,\n min: 0,\n max: 1,\n step: 0.01,\n default: stop.alpha,\n });\n });\n\n return controls;\n };\n\n /**\n * Thin wrapper so the UI can dispatch named actions without knowing\n * that they're routed through updateUIParam.\n */\n (filter as any).handleButtonAction = function (action: string) {\n if (action === 'addColorStop' || action === 'removeColorStop') {\n this.updateUIParam(action, true);\n }\n };\n\n (filter as any).updateUIParam = function (key: string, value: unknown) {\n const customParams = (this as any)._customParams ?? {};\n (this as any)._customParams = customParams;\n\n switch (key) {\n case 'gradientType':\n this.type = Number(value);\n return;\n\n case 'angle':\n case 'alpha':\n case 'maxColors':\n this[key] = Number(value);\n return;\n\n case 'replace':\n this.replace = Boolean(value);\n return;\n\n case 'addColorStop': {\n const current: ColorStopNum[] = Array.isArray(this.stops) ? [...this.stops] : [];\n const randomColor =\n (Math.floor(Math.random() * 255) << 16) |\n (Math.floor(Math.random() * 255) << 8) |\n Math.floor(Math.random() * 255);\n\n // Rescale existing stops so the new one fits at the tail.\n if (current.length > 0) {\n const scale = 0.8;\n for (const stop of current) {\n stop.offset *= scale;\n }\n }\n current.push({ offset: 1.0, color: randomColor, alpha: 1.0 });\n current.sort((a, b) => a.offset - b.offset);\n this.stops = current;\n return;\n }\n\n case 'removeColorStop': {\n const current: ColorStopNum[] = Array.isArray(this.stops) ? [...this.stops] : [];\n if (current.length > 2) {\n current.pop();\n this.stops = current;\n }\n return;\n }\n\n case 'cssGradient': {\n const str = typeof value === 'string' ? value.trim() : '';\n customParams.cssGradient = str;\n if (!str) return;\n try {\n const parsed = new ColorGradientFilter({ css: str });\n this.type = parsed.type;\n this.angle = parsed.angle;\n this.stops = [...parsed.stops];\n } catch {\n // Silently ignore invalid CSS gradient strings —\n // the user can fix the input and retry.\n }\n return;\n }\n\n case 'colorStops': {\n if (!Array.isArray(value)) return;\n const normalized = (value as any[]).map(normalizeStopForFilter);\n normalized.sort((a, b) => a.offset - b.offset);\n this.stops = normalized;\n return;\n }\n\n default: {\n const dynamicMatch = /^colorStops\\[(\\d+)\\]\\.(offset|color|alpha)$/.exec(key);\n if (dynamicMatch) {\n const [, indexStr, prop] = dynamicMatch;\n const index = Number(indexStr);\n const stops: ColorStopNum[] = Array.isArray(this.stops) ? [...this.stops] : [];\n if (index < 0 || index >= stops.length) return;\n\n if (prop === 'color') {\n stops[index].color =\n typeof value === 'string' ? hexToInt(value) : Number(value);\n } else if (prop === 'offset' || prop === 'alpha') {\n stops[index][prop] = Number(value);\n }\n // IMPORTANT: do NOT sort during offset drag — would re-index\n // controls mid-interaction and swap the row the user is dragging.\n // The UI re-renders after pointer up.\n this.stops = stops;\n }\n }\n }\n };\n\n return filter;\n },\n\n defaultParams: {\n gradientType: 0,\n colorStops: [\n { offset: 0, color: '#ff0000', alpha: 1 },\n { offset: 1, color: '#0000ff', alpha: 1 },\n ],\n cssGradient: '',\n angle: 90,\n alpha: 0.75,\n maxColors: 0,\n replace: false,\n },\n\n controls: [\n {\n id: 'gradientType',\n type: 'select',\n label: 'Gradient Type',\n property: 'gradientType',\n options: [\n { label: 'Linear', value: 0 },\n { label: 'Radial', value: 1 },\n { label: 'Conic', value: 2 },\n ],\n default: 0,\n },\n {\n id: 'angle',\n type: 'slider',\n label: 'Angle',\n property: 'angle',\n min: 0,\n max: 360,\n step: 1,\n default: 90,\n },\n {\n id: 'alpha',\n type: 'slider',\n label: 'Overall Alpha',\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.75,\n },\n {\n id: 'maxColors',\n type: 'slider',\n label: 'Max Colors',\n property: 'maxColors',\n min: 0,\n max: 24,\n step: 1,\n default: 0,\n },\n {\n id: 'replace',\n type: 'toggle',\n label: 'Replace Original Colors',\n property: 'replace',\n default: false,\n },\n {\n id: 'addColorStop',\n type: 'button',\n label: 'Add New Color Stop',\n action: 'addColorStop',\n },\n {\n id: 'removeColorStop',\n type: 'button',\n label: 'Remove Last Color Stop',\n action: 'removeColorStop',\n },\n {\n id: 'cssGradient',\n type: 'text',\n label: 'CSS Gradient',\n property: 'cssGradient',\n default: '',\n placeholder: 'e.g. linear-gradient(to right, red, blue)',\n },\n ],\n});\n","/**\n * Color Map Filter Definition\n * Applies a color transformation based on a reference texture\n */\nimport { registerFilter } from '../registry';\n// Import from the central package for pixi filters\nimport * as PixiFilters from 'pixi-filters';\nimport * as PIXI from 'pixi.js';\n\n// Register the Color Map filter\nexport default registerFilter({\n id: 'color-map',\n name: 'Color Map',\n category: 'color',\n description: 'Maps colors using a reference texture as a lookup table',\n \n // Create an instance of the ColorMapFilter with the provided parameters\n createFilter: (params) => {\n try {\n // Access filter class via direct indexing with type casting to avoid TypeScript errors \n // @ts-ignore - Runtime access of property that TypeScript doesn't know about\n const ColorMapFilterClass = PixiFilters['ColorMapFilter'];\n \n if (!ColorMapFilterClass) {\n console.error('ColorMapFilter not found in pixi-filters package');\n return null;\n }\n \n console.log('Creating ColorMapFilter with params:', params);\n \n // Get the color map texture\n let colorMapTexture = null;\n \n // If texture path is provided, create a new texture\n if (params.texturePath) {\n colorMapTexture = PIXI.Texture.from(params.texturePath);\n } else {\n // Use a default colormap texture\n // This is just a fallback - ideally user should provide their own\n colorMapTexture = PIXI.Texture.from('/examples/filters-main/examples/images/colormap.png');\n }\n \n // Create filter with proper options object\n const filter = new ColorMapFilterClass({\n colorMap: colorMapTexture,\n nearest: params.nearest,\n mix: params.mix\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'texturePath':\n // Update the color map texture\n if (value) {\n this.colorMap = PIXI.Texture.from(value);\n console.log(`Updated colorMap texture to ${value}`);\n }\n break;\n \n case 'mix':\n // Direct mix update\n this.mix = value;\n console.log(`Updated mix to ${this.mix}`);\n break;\n \n case 'nearest':\n // Direct nearest update\n this.nearest = value;\n console.log(`Updated nearest to ${this.nearest}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('ColorMapFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create ColorMapFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n texturePath: '', // User should provide a texture path\n mix: 1, // Mix between original and mapped colors (0-1)\n nearest: false // Whether to use nearest-neighbor sampling for the texture\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'texturePath',\n type: 'select',\n label: 'Color Map',\n property: 'texturePath',\n options: [\n { label: 'Default', value: '/examples/filters-main/examples/images/colormap.png' },\n { label: 'Grayscale', value: '/examples/filters-main/examples/images/colormap-grayscale.png' },\n { label: 'Sepia', value: '/examples/filters-main/examples/images/colormap-sepia.png' },\n // Add more options as needed\n ],\n default: '/examples/filters-main/examples/images/colormap.png',\n },\n {\n id: 'mix',\n type: 'slider',\n label: 'Mix',\n property: 'mix',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1,\n },\n {\n id: 'nearest',\n type: 'toggle',\n label: 'Nearest Neighbor Sampling',\n property: 'nearest',\n default: false,\n }\n ],\n});","/**\n * Color Replace Filter Definition\n * Replaces a specific color in the image with another color\n * \n * This implementation uses the proper ColorReplaceFilter from pixi-filters\n * which is compatible with PixiJS v8\n */\nimport { registerFilter } from '../registry';\n// Import from the central package for pixi filters\nimport * as PixiFilters from 'pixi-filters';\n\n// Access filter class via direct indexing with type casting to avoid TypeScript errors \n// @ts-ignore - Runtime access of property that TypeScript doesn't know about\nconst ColorReplaceFilter = PixiFilters['ColorReplaceFilter'];\n\n// Register the Color Replace filter\nexport default registerFilter({\n id: 'color-replace',\n name: 'Color Replace',\n category: 'color',\n description: 'Replaces a specific color in the image with another color',\n \n /**\n * Create an instance of ColorReplaceFilter from pixi-filters package\n * This implementation follows the pattern from ColorGradientFilter, adding\n * proper parameter handling with an updateUIParam method\n */\n createFilter: (params) => {\n try {\n console.log('Creating ColorReplaceFilter with params:', params);\n \n // Parse hex colors to numbers if they're strings\n let originalColorValue = 0xff0000; // Default red\n if (params.originalColor) {\n if (typeof params.originalColor === 'string') {\n originalColorValue = parseInt(params.originalColor.replace('#', '0x'), 16);\n } else if (typeof params.originalColor === 'number') {\n originalColorValue = params.originalColor;\n }\n }\n \n let targetColorValue = 0x0000ff; // Default blue\n if (params.targetColor) {\n if (typeof params.targetColor === 'string') {\n targetColorValue = parseInt(params.targetColor.replace('#', '0x'), 16);\n } else if (typeof params.targetColor === 'number') {\n targetColorValue = params.targetColor;\n }\n }\n \n // Create filter with proper options object for v6+\n const filter = new ColorReplaceFilter({\n originalColor: originalColorValue,\n targetColor: targetColorValue,\n tolerance: params.tolerance || 0.4\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n * and provides consistent parameter handling across all filters.\n * \n * @param key The UI parameter name\n * @param value The new value for the parameter\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'originalColor':\n // Convert hex string to number for the originalColor property\n if (typeof value === 'string') {\n this.originalColor = parseInt(value.replace('#', '0x'), 16);\n console.log(`Updated originalColor to ${this.originalColor} from ${value}`);\n } else if (typeof value === 'number') {\n this.originalColor = value;\n console.log(`Updated originalColor to ${this.originalColor}`);\n }\n break;\n \n case 'targetColor':\n // Convert hex string to number for the targetColor property\n if (typeof value === 'string') {\n this.targetColor = parseInt(value.replace('#', '0x'), 16);\n console.log(`Updated targetColor to ${this.targetColor} from ${value}`);\n } else if (typeof value === 'number') {\n this.targetColor = value;\n console.log(`Updated targetColor to ${this.targetColor}`);\n }\n break;\n \n case 'tolerance':\n // Direct tolerance update\n this.tolerance = value;\n console.log(`Updated tolerance to ${this.tolerance}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('ColorReplaceFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create ColorReplaceFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n originalColor: '#ff0000', // Red\n targetColor: '#0000ff', // Blue\n tolerance: 0.4 // Match sensitivity\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'originalColor',\n type: 'color',\n label: 'Original Color',\n property: 'originalColor',\n default: '#ff0000',\n },\n {\n id: 'targetColor',\n type: 'color',\n label: 'Target Color',\n property: 'targetColor',\n default: '#0000ff',\n },\n {\n id: 'tolerance',\n type: 'slider',\n label: 'Tolerance',\n property: 'tolerance',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.4,\n }\n ],\n});","/**\n * Multi-Color Replace Filter Definition\n * Replaces multiple colors in the image with different target colors\n * \n * This implementation uses the proper MultiColorReplaceFilter from pixi-filters\n * which is compatible with PixiJS v8\n */\nimport { registerFilter } from '../registry';\n// Import from the central package for pixi filters\nimport * as PixiFilters from 'pixi-filters';\n\n// Access filter class via direct indexing with type casting to avoid TypeScript errors \n// @ts-ignore - Runtime access of property that TypeScript doesn't know about\nconst MultiColorReplaceFilter = PixiFilters['MultiColorReplaceFilter'];\n\n// Register the Multi-Color Replace filter\nexport default registerFilter({\n id: 'multi-color-replace',\n name: 'Multi-Color Replace',\n category: 'color',\n description: 'Replaces multiple colors in the image with different target colors',\n \n /**\n * Create an instance of MultiColorReplaceFilter from pixi-filters package\n * This implementation follows the pattern from ColorGradientFilter, adding\n * proper parameter handling with an updateUIParam method\n */\n createFilter: (params) => {\n try {\n console.log('Creating MultiColorReplaceFilter with params:', params);\n \n // Prepare the replacements array with proper color value conversion\n const replacements = [];\n \n // Add first replacement pair\n if (params.originalColor1 && params.targetColor1) {\n const original = typeof params.originalColor1 === 'string' \n ? parseInt(params.originalColor1.replace('#', '0x'), 16)\n : params.originalColor1;\n const target = typeof params.targetColor1 === 'string'\n ? parseInt(params.targetColor1.replace('#', '0x'), 16)\n : params.targetColor1;\n \n replacements.push([original, target]);\n }\n \n // Add second replacement pair\n if (params.originalColor2 && params.targetColor2) {\n const original = typeof params.originalColor2 === 'string'\n ? parseInt(params.originalColor2.replace('#', '0x'), 16)\n : params.originalColor2;\n const target = typeof params.targetColor2 === 'string'\n ? parseInt(params.targetColor2.replace('#', '0x'), 16)\n : params.targetColor2;\n \n replacements.push([original, target]);\n }\n \n // Add third replacement pair if enabled\n if (params.enableThirdPair && params.originalColor3 && params.targetColor3) {\n const original = typeof params.originalColor3 === 'string'\n ? parseInt(params.originalColor3.replace('#', '0x'), 16)\n : params.originalColor3;\n const target = typeof params.targetColor3 === 'string'\n ? parseInt(params.targetColor3.replace('#', '0x'), 16)\n : params.targetColor3;\n \n replacements.push([original, target]);\n }\n \n // Create filter with PIXI v8 API (constructor takes replacements, epsilon, maxColors)\n const filter = new MultiColorReplaceFilter(\n replacements as any,\n params.tolerance || 0.05,\n 3 // Allow up to 3 color pairs\n );\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n * and provides consistent parameter handling across all filters.\n * \n * @param key The UI parameter name\n * @param value The new value for the parameter\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Create new replacements array if needed\n \n // Process standard color pair updates\n if (key === 'originalColor1' || key === 'targetColor1' || \n key === 'originalColor2' || key === 'targetColor2' ||\n key === 'originalColor3' || key === 'targetColor3' ||\n key === 'enableThirdPair') {\n \n // Create a new replacements array based on current params\n const newReplacements = [];\n \n // Add first replacement pair\n if (customParams.originalColor1 && customParams.targetColor1) {\n const original = typeof customParams.originalColor1 === 'string' \n ? parseInt(customParams.originalColor1.replace('#', '0x'), 16)\n : customParams.originalColor1;\n const target = typeof customParams.targetColor1 === 'string'\n ? parseInt(customParams.targetColor1.replace('#', '0x'), 16)\n : customParams.targetColor1;\n \n newReplacements.push([original, target]);\n }\n \n // Add second replacement pair\n if (customParams.originalColor2 && customParams.targetColor2) {\n const original = typeof customParams.originalColor2 === 'string'\n ? parseInt(customParams.originalColor2.replace('#', '0x'), 16)\n : customParams.originalColor2;\n const target = typeof customParams.targetColor2 === 'string'\n ? parseInt(customParams.targetColor2.replace('#', '0x'), 16)\n : customParams.targetColor2;\n \n newReplacements.push([original, target]);\n }\n \n // Add third replacement pair if enabled\n if (customParams.enableThirdPair && customParams.originalColor3 && customParams.targetColor3) {\n const original = typeof customParams.originalColor3 === 'string'\n ? parseInt(customParams.originalColor3.replace('#', '0x'), 16)\n : customParams.originalColor3;\n const target = typeof customParams.targetColor3 === 'string'\n ? parseInt(customParams.targetColor3.replace('#', '0x'), 16)\n : customParams.targetColor3;\n \n newReplacements.push([original, target]);\n }\n \n // Update the replacements and refresh\n this.replacements = newReplacements;\n this.refresh(); // Apply the changes\n console.log(`Updated replacements for ${key}:`, newReplacements);\n } \n // Handle tolerance updates directly\n else if (key === 'tolerance') {\n this.tolerance = value;\n console.log(`Updated tolerance to ${this.tolerance}`);\n } \n // For any other properties, try direct assignment\n else if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n \n return true;\n };\n \n console.log('MultiColorReplaceFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create MultiColorReplaceFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n originalColor1: '#ff0000', // Red\n targetColor1: '#0000ff', // Blue\n originalColor2: '#00ff00', // Green\n targetColor2: '#ffff00', // Yellow\n enableThirdPair: false,\n originalColor3: '#ff00ff', // Magenta\n targetColor3: '#00ffff', // Cyan\n tolerance: 0.05 // Match sensitivity\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'originalColor1',\n type: 'color',\n label: 'Original Color 1',\n property: 'originalColor1',\n default: '#ff0000',\n },\n {\n id: 'targetColor1',\n type: 'color',\n label: 'Target Color 1',\n property: 'targetColor1',\n default: '#0000ff',\n },\n {\n id: 'originalColor2',\n type: 'color',\n label: 'Original Color 2',\n property: 'originalColor2',\n default: '#00ff00',\n },\n {\n id: 'targetColor2',\n type: 'color',\n label: 'Target Color 2',\n property: 'targetColor2',\n default: '#ffff00',\n },\n {\n id: 'enableThirdPair',\n type: 'toggle',\n label: 'Enable Third Color Pair',\n property: 'enableThirdPair',\n default: false,\n },\n {\n id: 'originalColor3',\n type: 'color',\n label: 'Original Color 3',\n property: 'originalColor3',\n default: '#ff00ff',\n },\n {\n id: 'targetColor3',\n type: 'color',\n label: 'Target Color 3',\n property: 'targetColor3',\n default: '#00ffff',\n },\n {\n id: 'tolerance',\n type: 'slider',\n label: 'Tolerance',\n property: 'tolerance',\n min: 0,\n max: 0.5,\n step: 0.01,\n default: 0.05,\n }\n ],\n});","/**\n * RGB Split Filter Definition\n * Displaces the red, green, and blue channels separately to create a glitch or 3D effect\n */\nimport { registerFilter } from '../registry';\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { RGBSplitFilter } = PixiFilters;;\n\n// Register the RGB Split filter\nexport default registerFilter({\n id: 'rgb-split',\n name: 'RGB Split',\n category: 'color',\n description: 'Shifts the red, green, and blue channels to create a retro 3D or glitch effect',\n \n /**\n * Create an instance of the RGBSplitFilter with the provided parameters\n * Using the official pixi-filters implementation\n */\n createFilter: (params) => {\n try {\n console.log('Creating RGB Split filter with params:', params);\n \n // Create point objects for each channel from the params\n const red = { \n x: params.redX !== undefined ? params.redX : -10, \n y: params.redY !== undefined ? params.redY : 0 \n };\n const green = { \n x: params.greenX !== undefined ? params.greenX : 0, \n y: params.greenY !== undefined ? params.greenY : 10 \n };\n const blue = { \n x: params.blueX !== undefined ? params.blueX : 0, \n y: params.blueY !== undefined ? params.blueY : 0 \n };\n \n // Create the filter with the official pixi-filters package\n const filter = new RGBSplitFilter({\n red,\n green,\n blue\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * Following the pattern from the fix_filters.md document\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'redX':\n this.redX = Number(value);\n console.log(`Updated redX to ${value}`);\n break;\n \n case 'redY':\n this.redY = Number(value);\n console.log(`Updated redY to ${value}`);\n break;\n \n case 'greenX':\n this.greenX = Number(value);\n console.log(`Updated greenX to ${value}`);\n break;\n \n case 'greenY':\n this.greenY = Number(value);\n console.log(`Updated greenY to ${value}`);\n break;\n \n case 'blueX':\n this.blueX = Number(value);\n console.log(`Updated blueX to ${value}`);\n break;\n \n case 'blueY':\n this.blueY = Number(value);\n console.log(`Updated blueY to ${value}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n this[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n } catch (error) {\n console.error(`Failed to update parameter ${key} using updateUIParam:`, error);\n \n // Still store the value in customParams even if setting it failed\n if ((this as any)._customParams) {\n (this as any)._customParams[key] = value;\n }\n \n return false;\n }\n };\n \n console.log('RGB Split filter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create RGB Split filter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n redX: -10,\n redY: 0,\n greenX: 0,\n greenY: 10,\n blueX: 0,\n blueY: 0\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'redX',\n type: 'slider',\n label: 'Red X Offset',\n property: 'redX',\n min: -20,\n max: 20,\n step: 1,\n default: -10,\n },\n {\n id: 'redY',\n type: 'slider',\n label: 'Red Y Offset',\n property: 'redY',\n min: -20,\n max: 20,\n step: 1,\n default: 0,\n },\n {\n id: 'greenX',\n type: 'slider',\n label: 'Green X Offset',\n property: 'greenX',\n min: -20,\n max: 20,\n step: 1,\n default: 0,\n },\n {\n id: 'greenY',\n type: 'slider',\n label: 'Green Y Offset',\n property: 'greenY',\n min: -20,\n max: 20,\n step: 1,\n default: 10,\n },\n {\n id: 'blueX',\n type: 'slider',\n label: 'Blue X Offset',\n property: 'blueX',\n min: -20,\n max: 20,\n step: 1,\n default: 0,\n },\n {\n id: 'blueY',\n type: 'slider',\n label: 'Blue Y Offset',\n property: 'blueY',\n min: -20,\n max: 20,\n step: 1,\n default: 0,\n }\n ],\n});","/**\n * Advanced Bloom Filter Definition\n * Applies a sophisticated bloom effect with fine-grained control over parameters\n */\nimport { registerFilter } from '../registry';\n// Import from the central package for pixi filters\nimport * as PixiFilters from 'pixi-filters';\n// Access AdvancedBloomFilter from the pixi-filters package\nconst { AdvancedBloomFilter } = PixiFilters;\n\n// Register the Advanced Bloom filter\nexport default registerFilter({\n id: 'advanced-bloom',\n name: 'Advanced Bloom',\n category: 'light',\n description: 'Adds a sophisticated bloom/glow effect with fine-grained control',\n \n // Create an instance of the AdvancedBloomFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating AdvancedBloomFilter with params:', params);\n \n // Using PixiJS v8 style options object\n const filter = new AdvancedBloomFilter({\n threshold: params.threshold || 0.5,\n bloomScale: params.bloomScale || 1.0,\n brightness: params.brightness || 1.0,\n blur: params.blur || 8,\n quality: params.quality || 4,\n pixelSize: { \n x: params.pixelSizeX || 1, \n y: params.pixelSizeY || 1 \n }\n });\n \n // Store custom params for reference\n (filter as any)._customParams = {\n pixelSizeX: params.pixelSizeX || 1,\n pixelSizeY: params.pixelSizeY || 1\n };\n \n // Add custom updateUIParam method for dynamic updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = value;\n \n switch (key) {\n case 'threshold':\n this.threshold = Number(value);\n console.log(`Updated threshold to ${this.threshold}`);\n break;\n \n case 'bloomScale':\n this.bloomScale = Number(value);\n console.log(`Updated bloomScale to ${this.bloomScale}`);\n break;\n \n case 'brightness':\n this.brightness = Number(value);\n console.log(`Updated brightness to ${this.brightness}`);\n break;\n \n case 'blur':\n this.blur = Number(value);\n console.log(`Updated blur to ${this.blur}`);\n break;\n \n case 'quality':\n this.quality = Number(value);\n console.log(`Updated quality to ${this.quality}`);\n break;\n \n case 'pixelSizeX':\n customParams.pixelSizeX = Number(value);\n // Need to update the entire pixelSize object\n this.pixelSize = { \n x: Number(value), \n y: customParams.pixelSizeY \n };\n console.log(`Updated pixelSizeX to ${value}`);\n break;\n \n case 'pixelSizeY':\n customParams.pixelSizeY = Number(value);\n // Need to update the entire pixelSize object\n this.pixelSize = { \n x: customParams.pixelSizeX, \n y: Number(value) \n };\n console.log(`Updated pixelSizeY to ${value}`);\n break;\n \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Unknown parameter for AdvancedBloomFilter: ${key}`);\n }\n break;\n }\n } catch (error) {\n console.error(`Error updating AdvancedBloomFilter parameter ${key}:`, error);\n }\n };\n \n console.log('AdvancedBloomFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create AdvancedBloomFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n threshold: 0.5, // Brightness threshold\n bloomScale: 1.0, // Intensity of the bloom effect\n brightness: 1.0, // Overall brightness\n blur: 8, // Blur strength\n quality: 4, // Quality of the blur (higher = better but slower)\n pixelSizeX: 1, // Horizontal pixel size\n pixelSizeY: 1 // Vertical pixel size\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'threshold',\n type: 'slider',\n label: 'Threshold',\n property: 'threshold',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'bloomScale',\n type: 'slider',\n label: 'Bloom Intensity',\n property: 'bloomScale',\n min: 0,\n max: 3,\n step: 0.1,\n default: 1.0,\n },\n {\n id: 'brightness',\n type: 'slider',\n label: 'Brightness',\n property: 'brightness',\n min: 0,\n max: 3,\n step: 0.1,\n default: 1.0,\n },\n {\n id: 'blur',\n type: 'slider',\n label: 'Blur Strength',\n property: 'blur',\n min: 0,\n max: 20,\n step: 1,\n default: 8,\n },\n {\n id: 'quality',\n type: 'slider',\n label: 'Quality',\n property: 'quality',\n min: 1,\n max: 10,\n step: 1,\n default: 4,\n },\n {\n id: 'pixelSizeX',\n type: 'slider',\n label: 'Pixel Size X',\n property: 'pixelSizeX',\n min: 0.5,\n max: 10,\n step: 0.5,\n default: 1,\n },\n {\n id: 'pixelSizeY',\n type: 'slider',\n label: 'Pixel Size Y',\n property: 'pixelSizeY',\n min: 0.5,\n max: 10,\n step: 0.5,\n default: 1,\n }\n ],\n});","/**\n * ASCII Filter Definition\n * Applies an ASCII art effect to the image\n */\nimport { registerFilter } from '../registry';\n// Import from the central PixiFilters export\nimport * as PixiFilters from 'pixi-filters';\n// Define AsciiFilter as a variable to allow fallback implementation\nconst AsciiFilter = (PixiFilters as any).AsciiFilter;\n\n// Register the ASCII filter\nexport default registerFilter({\n id: 'ascii',\n name: 'ASCII',\n category: 'stylize',\n description: 'Convert image to ASCII text characters',\n \n // Create an instance of the AsciiFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating AsciiFilter with params:', params);\n \n // Ensure parameters have default values if missing\n const size = typeof params.size === 'number' ? params.size : 8;\n \n // Convert color string to number if needed\n let color = params.color;\n if (typeof color === 'string' && color.startsWith('#')) {\n color = parseInt(color.replace('#', '0x'), 16);\n }\n \n const replaceColor = params.replaceColor === true;\n \n // Create the filter with proper options\n const filter = new AsciiFilter({\n size: size,\n color: color,\n replaceColor: replaceColor\n });\n \n // Store custom parameters for reference\n (filter as any)._customParams = {\n size: size,\n color: color,\n replaceColor: replaceColor\n };\n \n // Add custom updateUIParam method for dynamic parameter updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n console.log(`AsciiFilter.updateUIParam called: ${key} = ${value}`);\n \n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'size':\n this.size = Number(value);\n console.log(`Updated size to ${this.size}`);\n break;\n \n case 'color':\n // Convert color string to number if needed\n if (typeof value === 'string' && value.startsWith('#')) {\n customParams.color = value;\n this.color = parseInt(value.replace('#', '0x'), 16);\n } else {\n this.color = value;\n }\n console.log(`Updated color to ${this.color}`);\n break;\n \n case 'replaceColor':\n this.replaceColor = Boolean(value);\n console.log(`Updated replaceColor to ${this.replaceColor}`);\n break;\n \n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Unknown parameter for AsciiFilter: ${key}`);\n }\n break;\n }\n } catch (error) {\n console.error(`Error updating AsciiFilter parameter ${key}:`, error);\n }\n };\n \n console.log('AsciiFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create AsciiFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n size: 8,\n color: '#ffffff',\n replaceColor: false\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'size',\n type: 'slider',\n label: 'Character Size',\n property: 'size',\n min: 2,\n max: 20,\n step: 1,\n default: 8,\n },\n {\n id: 'color',\n type: 'color',\n label: 'Character Color',\n property: 'color',\n default: '#ffffff',\n },\n {\n id: 'replaceColor',\n type: 'toggle',\n label: 'Replace Original Colors',\n property: 'replaceColor',\n default: false,\n }\n ],\n});","/**\n * Backdrop Blur Filter Definition\n * Applies a blur effect to the background behind an object\n * \n * IMPORTANT: This filter requires setting useBackBuffer: true in the renderer options,\n * which has been added to the PixiApplication.ts file. It's a special filter that\n * applies a blur to what's behind the objects rather than to the objects themselves.\n */\nimport { registerFilter } from '../registry';\n// Import from the central PixiFilters export\nimport * as PixiFilters from 'pixi-filters';\n// Define BackdropBlurFilter as a variable to allow fallback implementation\nconst BackdropBlurFilter = (PixiFilters as any).BackdropBlurFilter;\n\n// Register the backdrop blur filter\nexport default registerFilter({\n id: 'backdrop-blur',\n name: 'Backdrop Blur',\n category: 'blur',\n description: 'Blurs what is behind the object, creating a glass-like effect',\n \n // Create an instance of the BackdropBlurFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating BackdropBlurFilter with params:', params);\n \n // Create filter with options object\n // This is a special filter - it inherits from BlurFilter but adds a blend pass\n // to apply the blur only to what's behind the object\n const filter = new BackdropBlurFilter({\n // Higher strength values (20-50) make the effect more noticeable\n strength: params.strength || 20, \n quality: params.quality || 4,\n // Lower resolution values (0.2-0.5) can make the effect more visible but less sharp\n resolution: params.resolution || 0.5,\n kernelSize: params.kernelSize || 9\n });\n \n // Store custom params for reference\n (filter as any)._customParams = { ...params };\n \n // Add custom updateUIParam method for dynamic updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = value;\n \n // Handle all supported parameters\n switch (key) {\n case 'strength':\n // Higher strength values will make the effect more visible\n this.strength = Number(value);\n // For this filter, we can also update blur, which is a deprecated alias\n // but might be used internally\n this.blur = Number(value) / 4; // Scale down for blur property\n console.log(`Updated strength to ${this.strength}`);\n break;\n \n case 'quality':\n this.quality = Number(value);\n console.log(`Updated quality to ${this.quality}`);\n break;\n \n case 'resolution':\n // Lower resolution values make the effect more pronounced\n this.resolution = Number(value);\n console.log(`Updated resolution to ${this.resolution}`);\n break;\n \n case 'kernelSize':\n // Larger kernel sizes increase the blur radius and quality\n const kernelSize = Number(value);\n \n // Update both the X and Y kernel sizes\n if (this.blurXFilter && this.blurYFilter) {\n this.blurXFilter.kernelSize = kernelSize;\n this.blurYFilter.kernelSize = kernelSize;\n } else {\n // Fallback for older versions\n (this as any).kernelSize = kernelSize;\n }\n \n console.log(`Updated kernelSize to ${kernelSize}`);\n break;\n \n // For any other properties that might exist directly on the filter\n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Unknown parameter for BackdropBlurFilter: ${key}`);\n }\n break;\n }\n } catch (error) {\n console.error(`Error updating BackdropBlurFilter parameter ${key}:`, error);\n }\n };\n \n // Log successful creation\n console.log('BackdropBlurFilter created successfully');\n \n return filter;\n } catch (error) {\n console.error('Failed to create BackdropBlurFilter:', error);\n return null;\n }\n },\n \n // Default parameter values - optimized for better visibility\n defaultParams: {\n strength: 20, // Higher value for stronger effect\n quality: 4, // Moderate quality for performance\n resolution: 0.5, // Lower resolution makes effect more visible\n kernelSize: 9 // Larger kernel for wider blur\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'strength',\n type: 'slider',\n label: 'Strength',\n property: 'strength',\n min: 0,\n max: 50, // Increased max to allow stronger effects\n step: 1,\n default: 20,\n },\n {\n id: 'quality',\n type: 'slider',\n label: 'Quality',\n property: 'quality',\n min: 1,\n max: 10,\n step: 1,\n default: 4,\n },\n {\n id: 'resolution',\n type: 'slider',\n label: 'Resolution',\n property: 'resolution',\n min: 0.1,\n max: 1, // Reduced max to focus on lower values that show effect better\n step: 0.1,\n default: 0.5,\n },\n {\n id: 'kernelSize',\n type: 'select',\n label: 'Kernel Size',\n property: 'kernelSize',\n options: [\n { label: '5', value: 5 },\n { label: '7', value: 7 },\n { label: '9', value: 9 },\n { label: '11', value: 11 },\n { label: '13', value: 13 },\n { label: '15', value: 15 },\n ],\n default: 9,\n },\n ],\n});","/**\n * Bevel Filter Definition\n * Applies a beveled edge effect to the image\n */\nimport { registerFilter } from '../registry';\n// Import from the central package for pixi filters\nimport * as PixiFilters from 'pixi-filters';\n// Access BevelFilter from the pixi-filters package\nconst { BevelFilter } = PixiFilters;\n\n// Register the Bevel filter\nexport default registerFilter({\n id: 'bevel',\n name: 'Bevel',\n category: 'effects',\n description: 'Add a 3D-like beveled edge effect to the image',\n \n /**\n * Create an instance of the BevelFilter with the provided parameters\n * Using the official pixi-filters implementation\n */\n createFilter: (params) => {\n try {\n console.log('Creating Bevel filter with params:', params);\n \n // Parse colors from hex strings\n const lightColor = params.lightColor ? params.lightColor.replace('#', '0x') : '0xffffff';\n const shadowColor = params.shadowColor ? params.shadowColor.replace('#', '0x') : '0x000000';\n \n // Create the filter with the official pixi-filters package\n const filter = new BevelFilter({\n rotation: params.rotation !== undefined ? params.rotation : 45,\n thickness: params.thickness !== undefined ? params.thickness : 2,\n lightColor: parseInt(lightColor, 16),\n lightAlpha: params.lightAlpha !== undefined ? params.lightAlpha : 0.7,\n shadowColor: parseInt(shadowColor, 16),\n shadowAlpha: params.shadowAlpha !== undefined ? params.shadowAlpha : 0.7\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * Following the pattern from the fix_filters.md document\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'rotation':\n this.rotation = Number(value);\n console.log(`Updated rotation to ${value}`);\n break;\n \n case 'thickness':\n this.thickness = Number(value);\n console.log(`Updated thickness to ${value}`);\n break;\n \n case 'lightColor':\n // Convert hex string to number for the lightColor property\n if (typeof value === 'string') {\n const colorNum = parseInt(value.replace('#', '0x'), 16);\n this.lightColor = colorNum;\n console.log(`Updated lightColor to ${value} (${colorNum})`);\n }\n break;\n \n case 'lightAlpha':\n this.lightAlpha = Number(value);\n console.log(`Updated lightAlpha to ${value}`);\n break;\n \n case 'shadowColor':\n // Convert hex string to number for the shadowColor property\n if (typeof value === 'string') {\n const colorNum = parseInt(value.replace('#', '0x'), 16);\n this.shadowColor = colorNum;\n console.log(`Updated shadowColor to ${value} (${colorNum})`);\n }\n break;\n \n case 'shadowAlpha':\n this.shadowAlpha = Number(value);\n console.log(`Updated shadowAlpha to ${value}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n this[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n } catch (error) {\n console.error(`Failed to update parameter ${key} using updateUIParam:`, error);\n \n // Still store the value in customParams even if setting it failed\n if ((this as any)._customParams) {\n (this as any)._customParams[key] = value;\n }\n \n return false;\n }\n };\n \n console.log('Bevel filter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create Bevel filter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n rotation: 45,\n thickness: 2,\n lightColor: '#ffffff',\n lightAlpha: 0.7,\n shadowColor: '#000000',\n shadowAlpha: 0.7\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'rotation',\n type: 'slider',\n label: 'Angle',\n property: 'rotation',\n min: 0,\n max: 360,\n step: 1,\n default: 45,\n },\n {\n id: 'thickness',\n type: 'slider',\n label: 'Thickness',\n property: 'thickness',\n min: 0,\n max: 10,\n step: 0.1,\n default: 2,\n },\n {\n id: 'lightColor',\n type: 'color',\n label: 'Light Color',\n property: 'lightColor',\n default: '#ffffff',\n },\n {\n id: 'lightAlpha',\n type: 'slider',\n label: 'Light Opacity',\n property: 'lightAlpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.7,\n },\n {\n id: 'shadowColor',\n type: 'color',\n label: 'Shadow Color',\n property: 'shadowColor',\n default: '#000000',\n },\n {\n id: 'shadowAlpha',\n type: 'slider',\n label: 'Shadow Opacity',\n property: 'shadowAlpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.7,\n }\n ],\n});","/**\n * Bloom Filter Definition\n * Creates a glowing effect by emphasizing bright areas\n */\nimport { registerFilter } from '../registry';\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { BloomFilter } = PixiFilters;\n\n// Register the bloom filter\nexport default registerFilter({\n id: 'bloom',\n name: 'Bloom/Glow',\n category: 'light',\n description: 'Add a subtle glow effect to bright areas of the image',\n \n // Create an instance of the BloomFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating BloomFilter with params:', params);\n \n // Ensure parameters have default values if missing\n const strengthX = typeof params.strengthX === 'number' ? params.strengthX : 2;\n const strengthY = typeof params.strengthY === 'number' ? params.strengthY : 2;\n const quality = typeof params.quality === 'number' ? params.quality : 4;\n const resolution = typeof params.resolution === 'number' ? params.resolution : 1;\n const kernelSize = typeof params.kernelSize === 'number' ? params.kernelSize : 5;\n \n // Create the filter with proper options - force cast types to numbers\n const filter = new BloomFilter({\n strength: { \n x: Number(strengthX), \n y: Number(strengthY)\n },\n quality: Number(quality),\n resolution: Number(resolution),\n kernelSize: Number(kernelSize)\n });\n \n // Log the actual filter object to see its properties\n console.log('Created BloomFilter instance with properties:', {\n strength: filter.strength,\n quality: (filter as any).quality,\n resolution: filter.resolution,\n kernelSize: (filter as any).kernelSize\n });\n \n // Store custom parameters for reference\n (filter as any)._customParams = {\n strengthX: strengthX,\n strengthY: strengthY,\n quality: quality,\n resolution: resolution,\n kernelSize: kernelSize\n };\n \n // Add a more direct approach to updateUIParam method for dynamic parameter updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n console.log(`BloomFilter.updateUIParam called: ${key} = ${value}`);\n \n // Force numeric conversion\n const numValue = Number(value);\n \n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = numValue;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'strengthX':\n // Direct property access to ensure the update happens\n if (this.strength && typeof this.strength === 'object') {\n this.strength.x = numValue;\n // Force a refresh of the internal filters\n this._updateStrength?.();\n console.log(`Updated strengthX to ${numValue}`, this.strength);\n } else {\n console.warn('Filter strength property not found or not an object');\n }\n break;\n \n case 'strengthY':\n // Direct property access to ensure the update happens\n if (this.strength && typeof this.strength === 'object') {\n this.strength.y = numValue;\n // Force a refresh of the internal filters\n this._updateStrength?.();\n console.log(`Updated strengthY to ${numValue}`, this.strength);\n } else {\n console.warn('Filter strength property not found or not an object');\n }\n break;\n \n case 'quality':\n (this as any).quality = numValue;\n console.log(`Updated quality to ${(this as any).quality}`);\n break;\n\n case 'resolution':\n this.resolution = numValue;\n console.log(`Updated resolution to ${this.resolution}`);\n break;\n\n case 'kernelSize':\n (this as any).kernelSize = numValue;\n console.log(`Updated kernelSize to ${(this as any).kernelSize}`);\n break;\n \n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = numValue;\n console.log(`Updated ${key} to ${numValue}`);\n } else {\n console.warn(`Unknown parameter for BloomFilter: ${key}`);\n }\n break;\n }\n \n // Log the current state after updates\n console.log('BloomFilter state after update:', {\n strength: this.strength,\n quality: (this as any).quality,\n resolution: this.resolution,\n kernelSize: (this as any).kernelSize\n });\n } catch (error) {\n console.error(`Error updating BloomFilter parameter ${key}:`, error);\n }\n };\n \n console.log('BloomFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create BloomFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n strengthX: 2,\n strengthY: 2,\n quality: 4,\n resolution: 1,\n kernelSize: 5\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'strengthX',\n type: 'slider',\n label: 'Horizontal Strength',\n property: 'strengthX',\n min: 0,\n max: 20,\n step: 0.1,\n default: 2,\n },\n {\n id: 'strengthY',\n type: 'slider',\n label: 'Vertical Strength',\n property: 'strengthY',\n min: 0,\n max: 20,\n step: 0.1,\n default: 2,\n },\n {\n id: 'quality',\n type: 'slider',\n label: 'Quality',\n property: 'quality',\n min: 1,\n max: 10,\n step: 1,\n default: 4,\n },\n {\n id: 'kernelSize',\n type: 'select',\n label: 'Kernel Size',\n property: 'kernelSize',\n options: [\n { label: '5', value: 5 },\n { label: '7', value: 7 },\n { label: '9', value: 9 },\n { label: '11', value: 11 },\n { label: '13', value: 13 },\n { label: '15', value: 15 }\n ],\n default: 5,\n }\n ],\n});","/**\n * Bulge Pinch Filter Definition\n * Creates a bulge or pinch effect in a circular area\n */\nimport { registerFilter } from '../registry';\n// Import the BulgePinchFilter using wildcard import pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { BulgePinchFilter } = PixiFilters;\n\n/**\n * Bulge-pinch paints displaced pixels that can extend up to `radius` past\n * the sprite edge when the effect's center is near the boundary. PIXI's\n * default filter bounds match the sprite rect, so without explicit padding\n * the bulge gets clipped at the image edge. Reserve a ring of `radius`\n * pixels around the sprite for the filter to render into.\n */\nconst computeBulgePadding = (radius: number): number => {\n const r = Math.max(0, Number(radius) || 0);\n return Math.ceil(r + 2);\n};\n\nexport default registerFilter({\n id: 'bulge-pinch',\n name: 'Bulge/Pinch',\n category: 'distortion',\n description: 'Creates a bulge or pinch effect in a circular area',\n\n createFilter: (params) => {\n try {\n const centerX = params.centerX ?? 0.5;\n const centerY = params.centerY ?? 0.5;\n const radius = params.radius ?? 100;\n const strength = params.strength ?? 1;\n\n const filter = new BulgePinchFilter({\n center: { x: centerX, y: centerY },\n radius,\n strength,\n });\n\n // Reserve room for the bulge to extend past the sprite. Setting\n // .padding forces PIXI to allocate a larger filter framebuffer so\n // the effect renders completely instead of clipping at the image\n // edge. Also expose _exportPadding so the renderer's bbox-based\n // trim path knows how far out to scan for non-transparent content.\n const padding = computeBulgePadding(radius);\n filter.padding = Math.max(filter.padding ?? 0, padding);\n (filter as any)._exportPadding = padding;\n\n (filter as any)._customParams = { ...params };\n\n const refreshPadding = (f: any) => {\n const r = Number(f._customParams?.radius ?? f.radius ?? 0);\n const p = computeBulgePadding(r);\n f._exportPadding = p;\n f.padding = Math.max(f.padding ?? 0, p);\n };\n\n (filter as any).updateUIParam = function (key: string, value: any) {\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n customParams[key] = value;\n\n switch (key) {\n case 'centerX':\n if (!this.center) this.center = { x: 0.5, y: 0.5 };\n this.center.x = value;\n break;\n\n case 'centerY':\n if (!this.center) this.center = { x: 0.5, y: 0.5 };\n this.center.y = value;\n break;\n\n case 'radius':\n this.radius = Number(value);\n refreshPadding(this);\n break;\n\n case 'strength':\n this.strength = Number(value);\n break;\n\n default:\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n }\n\n return true;\n };\n\n /**\n * Build a fresh BulgePinchFilter sized for export.\n *\n * The radius value is in render-target pixels. The user tunes it\n * while looking at the preview, where the image is downscaled. To\n * preserve the visual proportions on the native-size export,\n * scale radius by preview-to-native. Same pattern as drop-shadow.\n * (centerX/centerY are unitless 0-1, strength is unitless; they\n * don't scale.)\n */\n (filter as any).createExportFilter = function (options: { previewToNativeScale?: number } = {}) {\n const scale = Number.isFinite(options.previewToNativeScale)\n ? Math.max(1, Number(options.previewToNativeScale))\n : 1;\n const stored = (this as any)._customParams || params;\n\n const scaledRadius = Number(stored.radius ?? 100) * scale;\n const next = new BulgePinchFilter({\n center: {\n x: Number(stored.centerX ?? 0.5),\n y: Number(stored.centerY ?? 0.5),\n },\n radius: scaledRadius,\n strength: Number(stored.strength ?? 1),\n });\n\n const padding = computeBulgePadding(scaledRadius);\n (next as any)._exportPadding = padding;\n next.padding = Math.max(next.padding ?? 0, padding);\n return next;\n };\n\n (filter as any).getExportPadding = function () {\n return Number((this as any)._exportPadding || this.padding || 0);\n };\n\n return filter;\n } catch (error) {\n console.error('Failed to create BulgePinchFilter:', error);\n return null;\n }\n },\n\n defaultParams: {\n centerX: 0.5,\n centerY: 0.5,\n radius: 100,\n strength: 1,\n },\n\n controls: [\n {\n id: 'centerX',\n type: 'slider',\n label: 'Center X',\n property: 'centerX',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'centerY',\n type: 'slider',\n label: 'Center Y',\n property: 'centerY',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'radius',\n type: 'slider',\n label: 'Radius',\n property: 'radius',\n min: 0,\n max: 1000,\n step: 1,\n default: 100,\n },\n {\n id: 'strength',\n type: 'slider',\n label: 'Strength',\n property: 'strength',\n min: -1,\n max: 1,\n step: 0.01,\n default: 1,\n },\n ],\n});\n","/**\n * Convolution Matrix Filter Definition\n * Applies a matrix convolution filter for effects like blur, sharpen, edge detection\n */\nimport { registerFilter } from '../registry';\n// Import from the central package for pixi filters\nimport * as PixiFilters from 'pixi-filters';\n// Access ConvolutionFilter from the pixi-filters package\nconst { ConvolutionFilter } = PixiFilters;\n\n// Predefined convolution matrices for common effects\nconst MATRICES = {\n normal: [0, 0, 0, 0, 1, 0, 0, 0, 0],\n gaussianBlur: [0.045, 0.122, 0.045, 0.122, 0.332, 0.122, 0.045, 0.122, 0.045],\n boxBlur: [1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9],\n edgeDetection: [-1, -1, -1, -1, 8, -1, -1, -1, -1],\n edgeEnhance: [0, 0, 0, -1, 1, 0, 0, 0, 0],\n emboss: [-2, -1, 0, -1, 1, 1, 0, 1, 2],\n sharpen: [0, -1, 0, -1, 5, -1, 0, -1, 0],\n sobelHorizontal: [1, 2, 1, 0, 0, 0, -1, -2, -1],\n sobelVertical: [1, 0, -1, 2, 0, -2, 1, 0, -1],\n};\n\nexport default registerFilter({\n id: 'convolution',\n name: 'Convolution Matrix',\n category: 'effects',\n description: 'Apply custom image effects using matrix convolution',\n \n createFilter: (params) => {\n try {\n console.log('Creating ConvolutionFilter with params:', params);\n \n // Get the appropriate matrix based on the selected preset or use custom values\n let matrix;\n \n if (params.customMatrix) {\n // Create matrix from individual matrix element values\n matrix = [\n params.m00, params.m01, params.m02,\n params.m10, params.m11, params.m12,\n params.m20, params.m21, params.m22\n ];\n } else {\n // Use preset matrix with type safety\n const presetKey = params.preset as keyof typeof MATRICES;\n matrix = MATRICES[presetKey] || MATRICES.normal;\n }\n \n // Create the filter with direct constructor call (PIXI v8 API)\n const filter = new ConvolutionFilter(matrix as any, params.width || 200, params.height || 200);\n\n // Store custom params for UI updates\n (filter as any)._customParams = { ...params };\n \n // Add custom updateUIParam method for UI parameter handling\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store the updated parameter\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n customParams[key] = value;\n \n switch (key) {\n case 'preset':\n // Update matrix from preset\n if (!customParams.customMatrix) {\n const presetKey = value as keyof typeof MATRICES;\n if (MATRICES[presetKey]) {\n this.matrix = MATRICES[presetKey];\n }\n }\n break;\n \n case 'customMatrix':\n // Toggle between preset and custom matrix\n if (value) {\n // Switch to custom matrix - copy current values to individual parameters\n const currentMatrix = this.matrix;\n customParams.m00 = currentMatrix[0];\n customParams.m01 = currentMatrix[1];\n customParams.m02 = currentMatrix[2];\n customParams.m10 = currentMatrix[3];\n customParams.m11 = currentMatrix[4];\n customParams.m12 = currentMatrix[5];\n customParams.m20 = currentMatrix[6];\n customParams.m21 = currentMatrix[7];\n customParams.m22 = currentMatrix[8];\n } else {\n // Switch back to preset\n const presetKey = customParams.preset as keyof typeof MATRICES;\n this.matrix = MATRICES[presetKey] || MATRICES.normal;\n }\n break;\n \n // Handle individual matrix element updates\n case 'm00': case 'm01': case 'm02':\n case 'm10': case 'm11': case 'm12':\n case 'm20': case 'm21': case 'm22':\n if (customParams.customMatrix) {\n // Update the matrix if in custom matrix mode\n const newMatrix = [...this.matrix];\n \n // Map UI parameter to matrix index\n const indices: Record<string, number> = {\n 'm00': 0, 'm01': 1, 'm02': 2,\n 'm10': 3, 'm11': 4, 'm12': 5,\n 'm20': 6, 'm21': 7, 'm22': 8\n };\n \n const idx = indices[key];\n if (idx !== undefined) {\n newMatrix[idx] = value;\n this.matrix = newMatrix;\n }\n }\n break;\n \n case 'width':\n this.width = value;\n break;\n \n case 'height':\n this.height = value;\n break;\n \n default:\n // For any other parameters that might exist directly on the filter\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n }\n };\n \n return filter;\n } catch (error) {\n console.error('Failed to create ConvolutionFilter:', error);\n return null;\n }\n },\n \n defaultParams: {\n preset: 'normal',\n customMatrix: false,\n m00: 0, m01: 0, m02: 0,\n m10: 0, m11: 1, m12: 0,\n m20: 0, m21: 0, m22: 0,\n width: 200,\n height: 200\n },\n \n controls: [\n {\n id: 'preset',\n type: 'select',\n label: 'Effect Preset',\n property: 'preset',\n options: [\n { value: 'normal', label: 'Normal' },\n { value: 'gaussianBlur', label: 'Gaussian Blur' },\n { value: 'boxBlur', label: 'Box Blur' },\n { value: 'edgeDetection', label: 'Edge Detection' },\n { value: 'edgeEnhance', label: 'Edge Enhance' },\n { value: 'emboss', label: 'Emboss' },\n { value: 'sharpen', label: 'Sharpen' },\n { value: 'sobelHorizontal', label: 'Sobel Horizontal' },\n { value: 'sobelVertical', label: 'Sobel Vertical' }\n ],\n default: 'normal'\n },\n {\n id: 'customMatrix',\n type: 'toggle',\n label: 'Use Custom Matrix',\n property: 'customMatrix',\n default: false\n },\n {\n id: 'width',\n type: 'slider',\n label: 'Width',\n property: 'width',\n min: 50,\n max: 500,\n step: 10,\n default: 200\n },\n {\n id: 'height',\n type: 'slider',\n label: 'Height',\n property: 'height',\n min: 50,\n max: 500,\n step: 10,\n default: 200\n },\n {\n id: 'm00',\n type: 'slider',\n label: 'Matrix [0,0]',\n property: 'm00',\n min: -5,\n max: 5,\n step: 0.1,\n default: 0\n },\n {\n id: 'm01',\n type: 'slider',\n label: 'Matrix [0,1]',\n property: 'm01',\n min: -5,\n max: 5,\n step: 0.1,\n default: 0\n },\n {\n id: 'm02',\n type: 'slider',\n label: 'Matrix [0,2]',\n property: 'm02',\n min: -5,\n max: 5,\n step: 0.1,\n default: 0\n },\n {\n id: 'm10',\n type: 'slider',\n label: 'Matrix [1,0]',\n property: 'm10',\n min: -5,\n max: 5,\n step: 0.1,\n default: 0\n },\n {\n id: 'm11',\n type: 'slider',\n label: 'Matrix [1,1]',\n property: 'm11',\n min: -5,\n max: 5,\n step: 0.1,\n default: 1\n },\n {\n id: 'm12',\n type: 'slider',\n label: 'Matrix [1,2]',\n property: 'm12',\n min: -5,\n max: 5,\n step: 0.1,\n default: 0\n },\n {\n id: 'm20',\n type: 'slider',\n label: 'Matrix [2,0]',\n property: 'm20',\n min: -5,\n max: 5,\n step: 0.1,\n default: 0\n },\n {\n id: 'm21',\n type: 'slider',\n label: 'Matrix [2,1]',\n property: 'm21',\n min: -5,\n max: 5,\n step: 0.1,\n default: 0\n },\n {\n id: 'm22',\n type: 'slider',\n label: 'Matrix [2,2]',\n property: 'm22',\n min: -5,\n max: 5,\n step: 0.1,\n default: 0\n }\n ]\n});","/**\n * Cross Hatch Filter Definition\n * Creates a crosshatching effect like in a pencil drawing\n */\nimport { registerFilter } from '../registry';\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { CrossHatchFilter } = PixiFilters;\n\n// Register the CrossHatch filter\nexport default registerFilter({\n id: 'cross-hatch',\n name: 'Cross Hatch',\n category: 'stylize',\n description: 'Creates a crosshatching effect like in a pencil drawing',\n \n // Create an instance of the CrossHatchFilter\n // Note: CrossHatchFilter has NO parameters according to PixiJS examples\n createFilter: (_params) => {\n try {\n console.log('Creating CrossHatchFilter');\n \n // Create the filter - CrossHatchFilter has no constructor parameters\n const filter = new CrossHatchFilter();\n \n // Add a minimal updateUIParam method for consistency\n // Even though CrossHatchFilter has no parameters to update\n (filter as any).updateUIParam = function(key: string, value: any) {\n console.log(`CrossHatchFilter has no configurable parameters. Ignoring: ${key} = ${value}`);\n return true;\n };\n \n console.log('CrossHatchFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create CrossHatchFilter:', error);\n return null;\n }\n },\n \n // No parameters for this filter\n defaultParams: {},\n \n // No UI controls since CrossHatchFilter has no parameters\n controls: [],\n});","/**\n * CRT Screen Filter Definition\n * Simulates an old CRT screen with scan lines and noise\n */\nimport { registerFilter } from '../registry';\nimport * as filters from 'pixi-filters';\n\n// Register the CRT filter\nexport default registerFilter({\n id: 'crt',\n name: 'CRT Screen',\n category: 'stylize',\n description: 'Simulates an old CRT screen with scan lines and noise',\n \n // Create an instance of the CRTFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating CRTFilter with params:', params);\n \n // Ensure parameters have default values\n const options = {\n lineWidth: typeof params.lineWidth === 'number' ? params.lineWidth : 1.0,\n noise: typeof params.noise === 'number' ? params.noise : 0.3,\n curvature: typeof params.curvature === 'number' ? params.curvature : 1.0,\n lineContrast: typeof params.lineContrast === 'number' ? params.lineContrast : 0.25,\n verticalLine: params.verticalLine === true,\n noiseSize: typeof params.noiseSize === 'number' ? params.noiseSize : 1.0,\n vignetting: typeof params.vignetting === 'number' ? params.vignetting : 0.3,\n vignettingAlpha: typeof params.vignettingAlpha === 'number' ? params.vignettingAlpha : 1.0,\n vignettingBlur: typeof params.vignettingBlur === 'number' ? params.vignettingBlur : 0.3,\n time: typeof params.time === 'number' ? params.time : 0.0,\n seed: typeof params.seed === 'number' ? params.seed : Math.random()\n };\n \n // Create the filter with proper options\n const filter = new filters.CRTFilter(options);\n \n // Store custom parameters for reference\n (filter as any)._customParams = { ...options };\n \n // Add custom updateUIParam method for dynamic parameter updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n console.log(`CRTFilter.updateUIParam called: ${key} = ${value}`);\n \n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = value;\n \n // Handle parameter updates based on key with proper type conversion\n switch (key) {\n case 'lineWidth':\n this.lineWidth = Number(value);\n console.log(`Updated lineWidth to ${this.lineWidth}`);\n break;\n \n case 'noise':\n this.noise = Number(value);\n console.log(`Updated noise to ${this.noise}`);\n break;\n \n case 'curvature':\n this.curvature = Number(value);\n console.log(`Updated curvature to ${this.curvature}`);\n break;\n \n case 'lineContrast':\n this.lineContrast = Number(value);\n console.log(`Updated lineContrast to ${this.lineContrast}`);\n break;\n \n case 'verticalLine':\n this.verticalLine = Boolean(value);\n console.log(`Updated verticalLine to ${this.verticalLine}`);\n break;\n \n case 'noiseSize':\n this.noiseSize = Number(value);\n console.log(`Updated noiseSize to ${this.noiseSize}`);\n break;\n \n case 'vignetting':\n this.vignetting = Number(value);\n console.log(`Updated vignetting to ${this.vignetting}`);\n break;\n \n case 'vignettingAlpha':\n this.vignettingAlpha = Number(value);\n console.log(`Updated vignettingAlpha to ${this.vignettingAlpha}`);\n break;\n \n case 'vignettingBlur':\n this.vignettingBlur = Number(value);\n console.log(`Updated vignettingBlur to ${this.vignettingBlur}`);\n break;\n \n case 'time':\n this.time = Number(value);\n console.log(`Updated time to ${this.time}`);\n break;\n \n case 'seed':\n this.seed = Number(value);\n console.log(`Updated seed to ${this.seed}`);\n break;\n \n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Unknown parameter for CRTFilter: ${key}`);\n }\n break;\n }\n \n // Log current state\n console.log('CRTFilter state:', {\n lineWidth: this.lineWidth,\n noise: this.noise,\n curvature: this.curvature,\n verticalLine: this.verticalLine,\n time: this.time\n });\n } catch (error) {\n console.error(`Error updating CRTFilter parameter ${key}:`, error);\n }\n };\n \n console.log('CRTFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create CRTFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n lineWidth: 1.0,\n noise: 0.3,\n curvature: 1.0,\n lineContrast: 0.25,\n verticalLine: false,\n noiseSize: 1.0,\n vignetting: 0.3,\n vignettingAlpha: 1.0,\n vignettingBlur: 0.3,\n time: 0.0,\n seed: 1.0\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'lineWidth',\n type: 'slider',\n label: 'Scan Line Width',\n property: 'lineWidth',\n min: 0,\n max: 5,\n step: 0.1,\n default: 1.0,\n },\n {\n id: 'noise',\n type: 'slider',\n label: 'Noise Amount',\n property: 'noise',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.3,\n },\n {\n id: 'curvature',\n type: 'slider',\n label: 'Screen Curvature',\n property: 'curvature',\n min: 0,\n max: 10,\n step: 0.1,\n default: 1.0,\n },\n {\n id: 'lineContrast',\n type: 'slider',\n label: 'Line Contrast',\n property: 'lineContrast',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.25,\n },\n {\n id: 'verticalLine',\n type: 'toggle',\n label: 'Vertical Lines',\n property: 'verticalLine',\n default: false,\n },\n {\n id: 'noiseSize',\n type: 'slider',\n label: 'Noise Size',\n property: 'noiseSize',\n min: 0.5,\n max: 5,\n step: 0.1,\n default: 1.0,\n },\n {\n id: 'vignetting',\n type: 'slider',\n label: 'Vignette Size',\n property: 'vignetting',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.3,\n },\n {\n id: 'vignettingAlpha',\n type: 'slider',\n label: 'Vignette Opacity',\n property: 'vignettingAlpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1.0,\n },\n {\n id: 'vignettingBlur',\n type: 'slider',\n label: 'Vignette Blur',\n property: 'vignettingBlur',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.3,\n },\n {\n id: 'time',\n type: 'slider',\n label: 'Animation Time',\n property: 'time',\n min: 0,\n max: 10,\n step: 0.1,\n default: 0.0,\n }\n ],\n});","/**\n * Displacement Filter Definition\n * Applies a displacement map effect to distort the image\n */\nimport { registerFilter } from '../registry';\n// Import PIXI namespace\nimport * as PIXI from 'pixi.js';\n\n// Access classes via direct indexing\n// @ts-ignore - Runtime access of property that TypeScript doesn't know about\nconst DisplacementFilter = PIXI['DisplacementFilter']; \n// @ts-ignore - Runtime access of property that TypeScript doesn't know about\nconst Sprite = PIXI['Sprite'];\n// @ts-ignore - Runtime access of property that TypeScript doesn't know about\nconst Texture = PIXI['Texture'];\n\n// Register the Displacement filter\nexport default registerFilter({\n id: 'displacement', // ID must match what the application expects\n name: 'Displacement Map',\n category: 'distortion',\n description: 'Distorts the image using a displacement map texture',\n \n // Create an instance of the DisplacementFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating DisplacementFilter with params:', params);\n \n // The displacement map texture URL (default or from params)\n const mapUrl = params.mapTexture || '/assets/images/displacement_map.png';\n \n // Create a texture from the map URL\n let mapTexture;\n try {\n mapTexture = Texture.from(mapUrl);\n // Set the texture to repeat\n mapTexture.source.addressMode = 'repeat';\n } catch (error) {\n console.error('Failed to load displacement map texture:', error);\n // Create a fallback texture\n const canvas = document.createElement('canvas');\n canvas.width = 256;\n canvas.height = 256;\n const ctx = canvas.getContext('2d');\n if (ctx) {\n // Draw a simple pattern\n ctx.fillStyle = '#ffffff';\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n ctx.fillStyle = '#000000';\n for (let i = 0; i < 10; i++) {\n for (let j = 0; j < 10; j++) {\n if ((i + j) % 2 === 0) {\n ctx.fillRect(i * 25, j * 25, 25, 25);\n }\n }\n }\n }\n mapTexture = Texture.from(canvas);\n }\n \n // Create sprite for the displacement map\n const displacementSprite = new Sprite(mapTexture);\n \n // Create the filter with the sprite and scale\n const filter = new DisplacementFilter(displacementSprite, params.scale || 50);\n \n // Set individual scale components\n filter.scale.x = params.scaleX || 50;\n filter.scale.y = params.scaleY || 50;\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n (filter as any)._displacementSprite = displacementSprite;\n \n /**\n * Custom method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'scaleX':\n this.scale.x = value;\n console.log(`Updated scale.x to ${value}`);\n break;\n \n case 'scaleY':\n this.scale.y = value;\n console.log(`Updated scale.y to ${value}`);\n break;\n \n case 'mapTexture':\n try {\n // Try to update the sprite's texture\n const sprite = (this as any)._displacementSprite;\n if (sprite) {\n const newTexture = Texture.from(value);\n newTexture.source.addressMode = 'repeat';\n sprite.texture = newTexture;\n console.log(`Updated displacement map texture to ${value}`);\n }\n } catch (error) {\n console.error('Failed to update displacement map texture:', error);\n }\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else if (key in this.scale) {\n this.scale[key] = value;\n console.log(`Updated scale.${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('DisplacementFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create DisplacementFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n mapTexture: '/assets/images/displacement_map.png',\n scale: 50,\n scaleX: 50,\n scaleY: 50\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'mapTexture',\n type: 'select',\n label: 'Displacement Map',\n property: 'mapTexture',\n options: [\n { label: 'Default', value: '/assets/images/displacement_map.png' },\n { label: 'Clouds', value: '/assets/images/clouds.png' },\n { label: 'Ripple', value: '/assets/images/ripple.png' }\n ],\n default: '/assets/images/displacement_map.png',\n },\n {\n id: 'scaleX',\n type: 'slider',\n label: 'Scale X',\n property: 'scaleX',\n min: 1,\n max: 200,\n step: 1,\n default: 50,\n },\n {\n id: 'scaleY',\n type: 'slider',\n label: 'Scale Y',\n property: 'scaleY',\n min: 1,\n max: 200,\n step: 1,\n default: 50,\n }\n ],\n});","/**\n * Dot Screen Filter Definition\n * Simulates a halftone printing pattern with dots\n */\nimport { registerFilter } from '../registry';\nimport * as filters from 'pixi-filters';\n\n// Register the Dot Screen filter\nexport default registerFilter({\n id: 'dot',\n name: 'Dot Screen',\n category: 'stylize',\n description: 'Simulates a halftone printing pattern with dots',\n \n // Create an instance of the DotFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating DotFilter with params:', params);\n \n // Ensure parameters have default values\n const options = {\n scale: typeof params.scale === 'number' ? params.scale : 1,\n angle: typeof params.angle === 'number' ? params.angle : 5,\n grayscale: params.grayscale === true\n };\n \n // Create the filter with proper options\n const filter = new filters.DotFilter(options);\n \n // Store custom parameters for reference\n (filter as any)._customParams = { ...options };\n \n // Add custom updateUIParam method for dynamic parameter updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n console.log(`DotFilter.updateUIParam called: ${key} = ${value}`);\n \n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = value;\n \n // Handle parameter updates based on key with proper type conversion\n switch (key) {\n case 'scale':\n this.scale = Number(value);\n console.log(`Updated scale to ${this.scale}`);\n break;\n \n case 'angle':\n this.angle = Number(value);\n console.log(`Updated angle to ${this.angle}`);\n break;\n \n case 'grayscale':\n this.grayscale = Boolean(value);\n console.log(`Updated grayscale to ${this.grayscale}`);\n break;\n \n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Unknown parameter for DotFilter: ${key}`);\n }\n break;\n }\n \n // Log current state\n console.log('DotFilter state:', {\n scale: this.scale,\n angle: this.angle,\n grayscale: this.grayscale\n });\n } catch (error) {\n console.error(`Error updating DotFilter parameter ${key}:`, error);\n }\n };\n \n console.log('DotFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create DotFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n scale: 1,\n angle: 5,\n grayscale: true\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'scale',\n type: 'slider',\n label: 'Dot Scale',\n property: 'scale',\n min: 0.5,\n max: 10,\n step: 0.1,\n default: 1,\n },\n {\n id: 'angle',\n type: 'slider',\n label: 'Dot Angle',\n property: 'angle',\n min: 0,\n max: 10,\n step: 0.1,\n default: 5,\n },\n {\n id: 'grayscale',\n type: 'toggle',\n label: 'Grayscale',\n property: 'grayscale',\n default: true,\n }\n ],\n});","/**\n * Emboss Filter Definition\n * Creates an embossed relief effect using the proper EmbossFilter from pixi-filters\n */\nimport { registerFilter } from '../registry';\n// Import EmbossFilter from pixi-filters\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { EmbossFilter } = PixiFilters;\n\n// Register the Emboss filter\nexport default registerFilter({\n id: 'emboss',\n name: 'Emboss',\n category: 'stylize',\n description: 'Creates an embossed relief effect',\n \n // Create an instance of the Emboss filter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating Emboss filter with params:', params);\n \n // Ensure parameters have default values\n const strength = typeof params.strength === 'number' ? params.strength : 5;\n \n // Use the proper EmbossFilter from pixi-filters\n const filter = new EmbossFilter(strength);\n \n console.log('Created emboss effect with EmbossFilter, strength:', strength);\n \n // Store custom parameters for reference\n (filter as any)._customParams = {\n strength: strength\n };\n \n // Add custom updateUIParam method for dynamic parameter updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n console.log(`Emboss filter updateUIParam called: ${key} = ${value}`);\n \n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = value;\n \n // Handle parameter updates\n switch (key) {\n case 'strength':\n const numValue = Number(value);\n customParams.strength = numValue;\n \n // For EmbossFilter, set the strength property directly\n this.strength = numValue;\n \n console.log(`Updated EmbossFilter strength to ${numValue}`);\n break;\n \n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Unknown parameter for EmbossFilter: ${key}`);\n }\n break;\n }\n } catch (error) {\n console.error(`Error updating emboss filter parameter ${key}:`, error);\n }\n };\n \n console.log('Emboss filter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create emboss filter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n strength: 5\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'strength',\n type: 'slider',\n label: 'Strength',\n property: 'strength',\n min: 0,\n max: 20,\n step: 0.5,\n default: 5,\n }\n ],\n});","/**\n * Glitch Filter Definition\n * Applies digital distortion and glitch effects to images\n */\nimport { registerFilter } from '../registry';\n// Import the GlitchFilter directly from pixi-filters package\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { GlitchFilter } = PixiFilters;;\n\n// Define constants for fill modes\nconst FILL_MODES = {\n TRANSPARENT: 0,\n ORIGINAL: 1,\n LOOP: 2,\n CLAMP: 3,\n MIRROR: 4\n};\n\nexport default registerFilter({\n id: 'glitch',\n name: 'Glitch',\n category: 'effects',\n description: 'Apply digital distortion and glitch effects',\n \n createFilter: (params) => {\n try {\n console.log('Creating GlitchFilter with params:', params);\n \n // Create color offset objects from individual components\n const redOffset = { x: params.redX, y: params.redY };\n const greenOffset = { x: params.greenX, y: params.greenY };\n const blueOffset = { x: params.blueX, y: params.blueY };\n \n // Create the filter with options\n const filter = new GlitchFilter({\n slices: params.slices,\n offset: params.offset,\n direction: params.direction,\n fillMode: params.fillMode,\n seed: params.seed,\n average: params.average,\n minSize: params.minSize,\n sampleSize: params.sampleSize,\n red: redOffset,\n green: greenOffset,\n blue: blueOffset\n });\n \n // Store animation state\n (filter as any).animating = params.animating || false;\n \n // Store custom params for UI updates\n (filter as any)._customParams = { ...params };\n \n // Trigger a refresh to ensure the filter initializes correctly\n if (typeof filter.refresh === 'function') {\n filter.refresh();\n }\n \n // Set up an animation loop for the filter if it's animating\n let animationFrameId: number | null = null;\n \n const animate = () => {\n if ((filter as any).animating) {\n // Update the seed with a random value for animation\n filter.seed = Math.random();\n }\n // Continue the animation loop\n animationFrameId = requestAnimationFrame(animate);\n };\n \n // Start animation if needed\n if ((filter as any).animating) {\n animationFrameId = requestAnimationFrame(animate);\n }\n \n // Method to clean up animation when filter is destroyed\n (filter as any)._stopAnimation = () => {\n if (animationFrameId !== null) {\n cancelAnimationFrame(animationFrameId);\n animationFrameId = null;\n }\n };\n \n /**\n * Add custom updateUIParam method for dynamic UI parameter handling\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store the updated parameter\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n customParams[key] = value;\n \n switch (key) {\n case 'animating':\n // Toggle animation state\n (this as any).animating = value;\n if (value && !animationFrameId) {\n // Start animation if it's not running\n animationFrameId = requestAnimationFrame(animate);\n }\n break;\n \n case 'slices':\n // Ensure slices is an integer\n this.slices = Math.round(value);\n break;\n \n case 'redX':\n case 'redY':\n // Update red offset\n const red = this.red;\n if (key === 'redX') red.x = value;\n else red.y = value;\n this.red = red;\n break;\n \n case 'greenX':\n case 'greenY':\n // Update green offset\n const green = this.green;\n if (key === 'greenX') green.x = value;\n else green.y = value;\n this.green = green;\n break;\n \n case 'blueX':\n case 'blueY':\n // Update blue offset\n const blue = this.blue;\n if (key === 'blueX') blue.x = value;\n else blue.y = value;\n this.blue = blue;\n break;\n \n case 'seed':\n // Only update seed manually if not animating\n if (!(this as any).animating) {\n this.seed = value;\n }\n break;\n \n case 'randomizeSeed':\n // Action button to randomize seed\n if (value && !customParams.animating) {\n this.seed = Math.random();\n }\n break;\n \n case 'refresh':\n // Action button to refresh the filter\n if (value) {\n try {\n this.refresh();\n } catch (e) {\n console.warn('Error refreshing GlitchFilter:', e);\n }\n }\n break;\n \n // Handle direct properties\n case 'offset':\n case 'direction':\n case 'fillMode':\n case 'average':\n case 'minSize':\n case 'sampleSize':\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n \n default:\n // For any other properties that might exist directly on the filter\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n }\n };\n \n return filter;\n } catch (error) {\n console.error('Failed to create GlitchFilter:', error);\n return null;\n }\n },\n \n defaultParams: {\n slices: 10,\n offset: 100,\n direction: 0,\n fillMode: FILL_MODES.LOOP, // LOOP mode looks better for the demo\n seed: 0.5,\n average: false,\n minSize: 8,\n sampleSize: 512,\n redX: 2,\n redY: 2,\n greenX: -10,\n greenY: 4,\n blueX: 10,\n blueY: -4,\n animating: false, // Control for automatic animation\n randomizeSeed: false, // Button trigger for randomizing seed\n refresh: false, // Button trigger for refreshing the filter\n },\n \n controls: [\n {\n id: 'animating',\n type: 'toggle',\n label: 'Animate Automatically',\n property: 'animating',\n default: false\n },\n {\n id: 'slices',\n type: 'slider',\n label: 'Slices',\n property: 'slices',\n min: 2,\n max: 20,\n step: 1,\n default: 10\n },\n {\n id: 'offset',\n type: 'slider',\n label: 'Offset Amount',\n property: 'offset',\n min: -400,\n max: 400,\n step: 1,\n default: 100\n },\n {\n id: 'direction',\n type: 'slider',\n label: 'Direction',\n property: 'direction',\n min: -180,\n max: 180,\n step: 1,\n default: 0\n },\n {\n id: 'fillMode',\n type: 'select',\n label: 'Fill Mode',\n property: 'fillMode',\n options: [\n { value: FILL_MODES.TRANSPARENT, label: 'Transparent' },\n { value: FILL_MODES.ORIGINAL, label: 'Original' },\n { value: FILL_MODES.LOOP, label: 'Loop' },\n { value: FILL_MODES.CLAMP, label: 'Clamp' },\n { value: FILL_MODES.MIRROR, label: 'Mirror' }\n ],\n default: FILL_MODES.LOOP\n },\n {\n id: 'seed',\n type: 'slider',\n label: 'Seed',\n property: 'seed',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5\n },\n {\n id: 'randomizeSeed',\n type: 'button',\n label: 'Randomize Seed',\n action: 'randomizeSeed'\n },\n {\n id: 'refresh',\n type: 'button',\n label: 'Refresh Filter',\n action: 'refresh'\n },\n {\n id: 'average',\n type: 'toggle',\n label: 'Average Slices',\n property: 'average',\n default: false\n },\n // Color channel offsets\n {\n id: 'redX',\n type: 'slider',\n label: 'Red X Offset',\n property: 'redX',\n min: -50,\n max: 50,\n step: 0.5,\n default: 2\n },\n {\n id: 'redY',\n type: 'slider',\n label: 'Red Y Offset',\n property: 'redY',\n min: -50,\n max: 50,\n step: 0.5,\n default: 2\n },\n {\n id: 'greenX',\n type: 'slider',\n label: 'Green X Offset',\n property: 'greenX',\n min: -50,\n max: 50,\n step: 0.5,\n default: -10\n },\n {\n id: 'greenY',\n type: 'slider',\n label: 'Green Y Offset',\n property: 'greenY',\n min: -50,\n max: 50,\n step: 0.5,\n default: 4\n },\n {\n id: 'blueX',\n type: 'slider',\n label: 'Blue X Offset',\n property: 'blueX',\n min: -50,\n max: 50,\n step: 0.5,\n default: 10\n },\n {\n id: 'blueY',\n type: 'slider',\n label: 'Blue Y Offset',\n property: 'blueY',\n min: -50,\n max: 50,\n step: 0.5,\n default: -4\n }\n ]\n});","/**\n * Glow Filter Definition\n * Applies a customizable glow effect around the image\n */\nimport { registerFilter } from '../registry';\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { GlowFilter } = PixiFilters;;\n\n// Register the Glow filter\nexport default registerFilter({\n id: 'glow',\n name: 'Glow',\n category: 'light',\n description: 'Adds a customizable glow effect around the image',\n \n // Create an instance of the GlowFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating GlowFilter with params:', params);\n \n // Parse color from hex string\n const color = parseInt(params.color.replace('#', '0x'), 16);\n \n // Create filter with proper options\n const filter = new GlowFilter({\n distance: params.distance || 10,\n outerStrength: params.outerStrength || 4,\n innerStrength: params.innerStrength || 0,\n color: color,\n alpha: params.alpha ?? 1,\n quality: params.quality || 0.1,\n knockout: params.knockout || false\n });\n \n // Store custom parameters for reference\n (filter as any)._customParams = { \n color: params.color || '#ffffff', \n ...params \n };\n \n // Add custom updateUIParam method for dynamic updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'distance':\n this.distance = Number(value);\n console.log(`Updated distance to ${this.distance}`);\n break;\n \n case 'outerStrength':\n this.outerStrength = Number(value);\n console.log(`Updated outerStrength to ${this.outerStrength}`);\n break;\n \n case 'innerStrength':\n this.innerStrength = Number(value);\n console.log(`Updated innerStrength to ${this.innerStrength}`);\n break;\n \n case 'color':\n // Store the hex color for reference\n customParams.color = value;\n // Convert hex color string to number for the filter\n this.color = parseInt(value.replace('#', '0x'), 16);\n console.log(`Updated color to ${value} (${this.color})`);\n break;\n \n case 'alpha':\n this.alpha = Number(value);\n console.log(`Updated alpha to ${this.alpha}`);\n break;\n \n case 'quality':\n this.quality = Number(value);\n console.log(`Updated quality to ${this.quality}`);\n break;\n \n case 'knockout':\n this.knockout = Boolean(value);\n console.log(`Updated knockout to ${this.knockout}`);\n break;\n \n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Unknown parameter for GlowFilter: ${key}`);\n }\n break;\n }\n } catch (error) {\n console.error(`Error updating GlowFilter parameter ${key}:`, error);\n }\n };\n \n console.log('GlowFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create GlowFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n distance: 10,\n outerStrength: 4,\n innerStrength: 0,\n color: '#ffffff',\n alpha: 1,\n quality: 0.1,\n knockout: false\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'distance',\n type: 'slider',\n label: 'Distance',\n property: 'distance',\n min: 0,\n max: 20,\n step: 1,\n default: 10,\n },\n {\n id: 'outerStrength',\n type: 'slider',\n label: 'Outer Strength',\n property: 'outerStrength',\n min: 0,\n max: 20,\n step: 0.1,\n default: 4,\n },\n {\n id: 'innerStrength',\n type: 'slider',\n label: 'Inner Strength',\n property: 'innerStrength',\n min: 0,\n max: 20,\n step: 0.1,\n default: 0,\n },\n {\n id: 'color',\n type: 'color',\n label: 'Color',\n property: 'color',\n default: '#ffffff',\n },\n {\n id: 'alpha',\n type: 'slider',\n label: 'Alpha',\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1,\n },\n {\n id: 'quality',\n type: 'slider',\n label: 'Quality',\n property: 'quality',\n min: 0.01,\n max: 1,\n step: 0.01,\n default: 0.1,\n },\n {\n id: 'knockout',\n type: 'toggle',\n label: 'Show Glow Only',\n property: 'knockout',\n default: false,\n }\n ],\n});","/**\n * Godray Filter Definition\n * Creates volumetric light-ray effects\n */\nimport { registerFilter } from '../registry';\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { GodrayFilter } = PixiFilters;;\n\n// Register the Godray filter\nexport default registerFilter({\n id: 'godray',\n name: 'Godray',\n category: 'light',\n description: 'Creates volumetric light-ray effects (crepuscular rays)',\n \n // Create an instance of the GodrayFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating GodrayFilter with params:', params);\n \n // Create filter with proper options\n const filter = new GodrayFilter({\n angle: params.angle || 30,\n parallel: params.parallel ?? true,\n center: { \n x: params.centerX || 0, \n y: params.centerY || 0 \n },\n gain: params.gain || 0.5,\n lacunarity: params.lacunarity || 2.5,\n time: params.time || 0,\n alpha: params.alpha || 1\n });\n \n // Store custom parameters for reference\n (filter as any)._customParams = { \n centerX: params.centerX || 0,\n centerY: params.centerY || 0,\n ...params \n };\n \n // Add custom updateUIParam method for dynamic updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'angle':\n this.angle = Number(value);\n console.log(`Updated angle to ${this.angle}`);\n break;\n \n case 'parallel':\n this.parallel = Boolean(value);\n console.log(`Updated parallel to ${this.parallel}`);\n break;\n \n case 'centerX':\n customParams.centerX = Number(value);\n // Need to update the entire center object\n this.center = { \n x: Number(value), \n y: customParams.centerY \n };\n console.log(`Updated centerX to ${value}`);\n break;\n \n case 'centerY':\n customParams.centerY = Number(value);\n // Need to update the entire center object\n this.center = { \n x: customParams.centerX, \n y: Number(value) \n };\n console.log(`Updated centerY to ${value}`);\n break;\n \n case 'gain':\n this.gain = Number(value);\n console.log(`Updated gain to ${this.gain}`);\n break;\n \n case 'lacunarity':\n this.lacunarity = Number(value);\n console.log(`Updated lacunarity to ${this.lacunarity}`);\n break;\n \n case 'time':\n this.time = Number(value);\n console.log(`Updated time to ${this.time}`);\n break;\n \n case 'alpha':\n this.alpha = Number(value);\n console.log(`Updated alpha to ${this.alpha}`);\n break;\n \n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Unknown parameter for GodrayFilter: ${key}`);\n }\n break;\n }\n } catch (error) {\n console.error(`Error updating GodrayFilter parameter ${key}:`, error);\n }\n };\n \n console.log('GodrayFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create GodrayFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n angle: 30,\n parallel: true,\n centerX: 0,\n centerY: 0,\n gain: 0.5,\n lacunarity: 2.5,\n time: 0,\n alpha: 1\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'angle',\n type: 'slider',\n label: 'Angle',\n property: 'angle',\n min: 0,\n max: 360,\n step: 1,\n default: 30,\n },\n {\n id: 'parallel',\n type: 'toggle',\n label: 'Parallel Rays',\n property: 'parallel',\n default: true,\n },\n {\n id: 'centerX',\n type: 'slider',\n label: 'Light Source X',\n property: 'centerX',\n min: -1,\n max: 1,\n step: 0.01,\n default: 0,\n },\n {\n id: 'centerY',\n type: 'slider',\n label: 'Light Source Y',\n property: 'centerY',\n min: -1,\n max: 1,\n step: 0.01,\n default: 0,\n },\n {\n id: 'gain',\n type: 'slider',\n label: 'Gain/Intensity',\n property: 'gain',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'lacunarity',\n type: 'slider',\n label: 'Density',\n property: 'lacunarity',\n min: 0.1,\n max: 10,\n step: 0.1,\n default: 2.5,\n },\n {\n id: 'time',\n type: 'slider',\n label: 'Time',\n property: 'time',\n min: 0,\n max: 10,\n step: 0.1,\n default: 0,\n },\n {\n id: 'alpha',\n type: 'slider',\n label: 'Alpha',\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1,\n }\n ],\n});","/**\n * Lightmap Filter Definition\n * Applies a lighting effect using a reference texture as a light map\n */\nimport { registerFilter } from '../registry';\n// Import packages\nimport * as PixiFilters from 'pixi-filters';\nimport * as PIXI from 'pixi.js';\n\n// Access classes via direct indexing\n// @ts-ignore - Runtime access of property that TypeScript doesn't know about\nconst SimpleLightmapFilter = PixiFilters['SimpleLightmapFilter'];\n// @ts-ignore - Runtime access of property that TypeScript doesn't know about\nconst Texture = PIXI['Texture'];\n\n// Register the Lightmap filter\nexport default registerFilter({\n id: 'lightmap',\n name: 'Lightmap',\n category: 'light',\n description: 'Applies lighting effects using a reference texture as a light map',\n \n // Create an instance of the SimpleLightmapFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating SimpleLightmapFilter with params:', params);\n \n // Ensure we have default values\n const textureType = params.textureType || 'default';\n const colorValue = params.color || '#000000';\n const alphaValue = typeof params.alpha === 'number' ? params.alpha : 1;\n \n // Create canvas for texture generation\n const canvas = document.createElement('canvas');\n canvas.width = 256;\n canvas.height = 256;\n const ctx = canvas.getContext('2d');\n \n if (!ctx) {\n console.error('Could not get 2D context for canvas');\n throw new Error('Canvas 2D context not available');\n }\n \n // Generate a texture based on the selected type\n if (textureType === 'spotlight') {\n // Create a stronger spotlight effect\n ctx.fillStyle = 'black';\n ctx.fillRect(0, 0, 256, 256);\n \n const gradient = ctx.createRadialGradient(128, 128, 5, 128, 128, 80);\n gradient.addColorStop(0, 'white');\n gradient.addColorStop(0.5, 'rgba(255, 255, 255, 0.5)'); // Stronger middle\n gradient.addColorStop(1, 'rgba(0, 0, 0, 0)');\n \n ctx.fillStyle = gradient;\n ctx.beginPath();\n ctx.arc(128, 128, 100, 0, Math.PI * 2);\n ctx.fill();\n \n console.log('Generated spotlight texture with stronger center');\n } else if (textureType === 'softlight') {\n // Create a more pronounced soft light effect\n const gradient = ctx.createLinearGradient(0, 0, 256, 256);\n gradient.addColorStop(0, 'white');\n gradient.addColorStop(0.3, 'rgba(220, 220, 220, 1)');\n gradient.addColorStop(0.7, 'rgba(150, 150, 150, 1)');\n gradient.addColorStop(1, 'rgba(80, 80, 80, 1)');\n \n ctx.fillStyle = gradient;\n ctx.fillRect(0, 0, 256, 256);\n \n console.log('Generated enhanced softlight texture');\n } else {\n // Default - create a more pronounced radial gradient\n const gradient = ctx.createRadialGradient(128, 128, 10, 128, 128, 160);\n gradient.addColorStop(0, 'white');\n gradient.addColorStop(0.3, 'rgba(220, 220, 220, 1)');\n gradient.addColorStop(0.6, 'rgba(150, 150, 150, 1)');\n gradient.addColorStop(1, 'black');\n \n ctx.fillStyle = gradient;\n ctx.fillRect(0, 0, 256, 256);\n \n console.log('Generated enhanced default texture');\n }\n \n // Create a texture from the canvas\n const lightMapTexture = Texture.from(canvas);\n console.log('Created lightmap texture from canvas');\n \n // Parse color from hex string with safer parsing\n let color;\n try {\n // Handle potential bad color input\n if (typeof colorValue === 'string' && colorValue.startsWith('#')) {\n color = parseInt(colorValue.replace('#', '0x'), 16);\n } else {\n color = 0x000000; // Default black\n }\n } catch (e) {\n console.warn('Error parsing color, using default black');\n color = 0x000000;\n }\n \n // Create filter with proper options\n const filter = new SimpleLightmapFilter(lightMapTexture, color, alphaValue);\n \n // Store custom parameters for reference\n (filter as any)._customParams = {\n textureType: textureType,\n color: colorValue,\n alpha: alphaValue\n };\n \n // Add custom updateUIParam method with improved parameter handling\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n console.log(`SimpleLightmapFilter.updateUIParam called: ${key} = ${value}`);\n \n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'textureType':\n customParams.textureType = value;\n \n // Create a new canvas with the selected texture type\n const updateCanvas = document.createElement('canvas');\n updateCanvas.width = 256;\n updateCanvas.height = 256;\n const updateCtx = updateCanvas.getContext('2d');\n \n if (updateCtx) {\n // Generate texture based on type with stronger effects\n if (value === 'spotlight') {\n updateCtx.fillStyle = 'black';\n updateCtx.fillRect(0, 0, 256, 256);\n \n const gradient = updateCtx.createRadialGradient(128, 128, 5, 128, 128, 80);\n gradient.addColorStop(0, 'white');\n gradient.addColorStop(0.5, 'rgba(255, 255, 255, 0.5)');\n gradient.addColorStop(1, 'rgba(0, 0, 0, 0)');\n \n updateCtx.fillStyle = gradient;\n updateCtx.beginPath();\n updateCtx.arc(128, 128, 100, 0, Math.PI * 2);\n updateCtx.fill();\n } else if (value === 'softlight') {\n const gradient = updateCtx.createLinearGradient(0, 0, 256, 256);\n gradient.addColorStop(0, 'white');\n gradient.addColorStop(0.3, 'rgba(220, 220, 220, 1)');\n gradient.addColorStop(0.7, 'rgba(150, 150, 150, 1)');\n gradient.addColorStop(1, 'rgba(80, 80, 80, 1)');\n \n updateCtx.fillStyle = gradient;\n updateCtx.fillRect(0, 0, 256, 256);\n } else {\n const gradient = updateCtx.createRadialGradient(128, 128, 10, 128, 128, 160);\n gradient.addColorStop(0, 'white');\n gradient.addColorStop(0.3, 'rgba(220, 220, 220, 1)');\n gradient.addColorStop(0.6, 'rgba(150, 150, 150, 1)');\n gradient.addColorStop(1, 'black');\n \n updateCtx.fillStyle = gradient;\n updateCtx.fillRect(0, 0, 256, 256);\n }\n \n // Create a new texture\n const newTexture = Texture.from(updateCanvas);\n \n // Update the filter - directly access the property\n this.lightMap = newTexture;\n \n // Force the filter to redraw by invalidating the transform\n if (this.enabled !== undefined) {\n // Toggle enabled to force a redraw\n const wasEnabled = this.enabled;\n this.enabled = false;\n setTimeout(() => {\n this.enabled = wasEnabled;\n }, 0);\n }\n \n console.log(`Updated lightMap texture to ${value} type`);\n }\n break;\n \n case 'color':\n // Store the hex color for reference\n customParams.color = value;\n // Convert hex color string to number for the filter with safe parsing\n try {\n if (typeof value === 'string' && value.startsWith('#')) {\n this.color = parseInt(value.replace('#', '0x'), 16);\n } else {\n this.color = 0x000000; // Default black\n }\n } catch (e) {\n this.color = 0x000000;\n }\n console.log(`Updated color to ${value} (${this.color})`);\n break;\n \n case 'alpha':\n // Directly set the alpha value - this is the intensity of the effect\n this.alpha = Number(value);\n \n // Log the actual value for debugging\n console.log(`Updated alpha to ${this.alpha}, actual filter:`, {\n alpha: this.alpha,\n color: this.color,\n hasLightmap: !!this.lightMap\n });\n break;\n \n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Unknown parameter for SimpleLightmapFilter: ${key}`);\n }\n break;\n }\n } catch (error) {\n console.error(`Error updating SimpleLightmapFilter parameter ${key}:`, error);\n }\n };\n \n // Log the created filter properties for debugging\n console.log('SimpleLightmapFilter created successfully:', {\n alpha: filter.alpha,\n color: filter.color,\n hasLightmap: !!filter.lightMap\n });\n \n return filter;\n } catch (error) {\n console.error('Failed to create SimpleLightmapFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n textureType: 'default',\n color: '#000000', // Ambient color (black typically)\n alpha: 1 // Coefficient for alpha multiplication\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'textureType',\n type: 'select',\n label: 'Light Map Type',\n property: 'textureType',\n options: [\n { label: 'Default', value: 'default' },\n { label: 'Spotlight', value: 'spotlight' },\n { label: 'Soft Light', value: 'softlight' }\n ],\n default: 'default',\n },\n {\n id: 'color',\n type: 'color',\n label: 'Ambient Color',\n property: 'color',\n default: '#000000',\n },\n {\n id: 'alpha',\n type: 'slider',\n label: 'Intensity', // Renamed from Alpha to Intensity for clarity\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1,\n }\n ],\n});","/**\n * Noise Filter Definition\n * Adds random noise to the image\n */\nimport { registerFilter } from '../registry';\n// Import directly from PixiJS (not pixi-filters) as this is a built-in filter\n// Import from pixi.js with namespace\nimport * as PIXI from 'pixi.js';\n// @ts-ignore - Module structure doesn't match TypeScript definitions\nconst { NoiseFilter } = PIXI;;\n\nexport default registerFilter({\n id: 'noise',\n name: 'Noise',\n category: 'effects',\n description: 'Add random noise to the image',\n \n createFilter: (params) => {\n try {\n console.log('Creating NoiseFilter with params:', params);\n \n // Create the filter with direct options\n const filter = new NoiseFilter({\n noise: params.noise || 0.5,\n seed: params.seed || Math.random()\n });\n \n // Store animation state\n (filter as any).animating = params.animating || false;\n \n // Store custom params for UI updates\n (filter as any)._customParams = { ...params };\n \n // Set up animation loop for randomizing seed if animation is enabled\n let animationFrameId: number | null = null;\n \n const animate = () => {\n if ((filter as any).animating) {\n // Update with a new random seed for animation\n filter.seed = Math.random();\n }\n animationFrameId = requestAnimationFrame(animate);\n };\n \n // Start animation if enabled\n if ((filter as any).animating) {\n animationFrameId = requestAnimationFrame(animate);\n }\n \n // Method to clean up animation when filter is destroyed\n (filter as any)._stopAnimation = () => {\n if (animationFrameId !== null) {\n cancelAnimationFrame(animationFrameId);\n animationFrameId = null;\n }\n };\n \n /**\n * Add custom updateUIParam method for UI parameter handling\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store the updated parameter\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n customParams[key] = value;\n \n switch (key) {\n case 'animating':\n // Toggle animation state\n (this as any).animating = value;\n if (value && !animationFrameId) {\n // Start animation if not already running\n animationFrameId = requestAnimationFrame(animate);\n }\n break;\n \n case 'noise':\n // Update noise amount (with validation) - PIXI NoiseFilter expects 0-1 range\n this.noise = Math.max(0, Math.min(1, value));\n break;\n \n case 'seed':\n // Only update seed manually if not animating\n if (!(this as any).animating) {\n this.seed = value;\n }\n break;\n \n case 'randomizeSeed':\n // Button action to randomize seed\n if (value) {\n this.seed = Math.random();\n }\n break;\n \n default:\n // For any other properties that might exist directly on the filter\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n }\n };\n \n return filter;\n } catch (error) {\n console.error('Failed to create NoiseFilter:', error);\n return null;\n }\n },\n \n defaultParams: {\n noise: 0.5,\n seed: 0.5,\n animating: false,\n randomizeSeed: false\n },\n \n controls: [\n {\n id: 'animating',\n type: 'toggle',\n label: 'Animate Noise',\n property: 'animating',\n default: false\n },\n {\n id: 'noise',\n type: 'slider',\n label: 'Noise Amount',\n property: 'noise',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5\n },\n {\n id: 'seed',\n type: 'slider',\n label: 'Random Seed',\n property: 'seed',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5\n },\n {\n id: 'randomizeSeed',\n type: 'button',\n label: 'Randomize Seed',\n action: 'randomizeSeed'\n }\n ]\n});","/**\n * Old Film Filter Definition\n * Applies a vintage film effect with sepia tone, scratches, grain, and vignetting\n */\nimport { registerFilter } from '../registry';\n// Import the OldFilmFilter directly from pixi-filters package\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { OldFilmFilter } = PixiFilters;;\n\nexport default registerFilter({\n id: 'old-film',\n name: 'Old Film',\n category: 'effects',\n description: 'Apply a vintage film effect with scratches and grain',\n \n createFilter: (params) => {\n try {\n console.log('Creating OldFilmFilter with params:', params);\n \n // Create the filter with direct options\n const filter = new OldFilmFilter({\n sepia: params.sepia,\n noise: params.noise,\n noiseSize: params.noiseSize,\n scratch: params.scratch,\n scratchDensity: params.scratchDensity,\n scratchWidth: params.scratchWidth,\n vignetting: params.vignetting,\n vignettingAlpha: params.vignettingAlpha,\n vignettingBlur: params.vignettingBlur,\n seed: params.seed || Math.random()\n });\n \n // Store animation state\n (filter as any).animating = params.animating || false;\n \n // Store custom params for UI updates\n (filter as any)._customParams = { ...params };\n \n // Set up animation loop for randomizing seed if animation is enabled\n let animationFrameId: number | null = null;\n \n const animate = () => {\n if ((filter as any).animating) {\n // Update with a new random seed for animation\n filter.seed = Math.random();\n }\n animationFrameId = requestAnimationFrame(animate);\n };\n \n // Start animation if enabled\n if ((filter as any).animating) {\n animationFrameId = requestAnimationFrame(animate);\n }\n \n // Method to clean up animation when filter is destroyed\n (filter as any)._stopAnimation = () => {\n if (animationFrameId !== null) {\n cancelAnimationFrame(animationFrameId);\n animationFrameId = null;\n }\n };\n \n /**\n * Add custom updateUIParam method for UI parameter handling\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store the updated parameter\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n customParams[key] = value;\n \n switch (key) {\n case 'animating':\n // Toggle animation state\n (this as any).animating = value;\n if (value && !animationFrameId) {\n // Start animation if not already running\n animationFrameId = requestAnimationFrame(animate);\n }\n break;\n \n case 'seed':\n // Only update seed manually if not animating\n if (!(this as any).animating) {\n this.seed = value;\n }\n break;\n \n case 'randomizeSeed':\n // Button action to randomize seed\n if (value) {\n this.seed = Math.random();\n }\n break;\n \n // Direct properties that are part of the OldFilmFilter\n case 'sepia':\n case 'noise':\n case 'noiseSize':\n case 'scratch':\n case 'scratchDensity':\n case 'scratchWidth':\n case 'vignetting':\n case 'vignettingAlpha':\n case 'vignettingBlur':\n // Apply with validation if needed\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n \n default:\n // For any other properties that might exist directly on the filter\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n }\n };\n \n return filter;\n } catch (error) {\n console.error('Failed to create OldFilmFilter:', error);\n return null;\n }\n },\n \n defaultParams: {\n sepia: 0.3,\n noise: 0.3,\n noiseSize: 1,\n scratch: 0.5,\n scratchDensity: 0.3,\n scratchWidth: 1,\n vignetting: 0.3,\n vignettingAlpha: 1,\n vignettingBlur: 0.3,\n seed: 0.5,\n animating: false,\n randomizeSeed: false\n },\n \n controls: [\n {\n id: 'animating',\n type: 'toggle',\n label: 'Animate Film',\n property: 'animating',\n default: false\n },\n {\n id: 'sepia',\n type: 'slider',\n label: 'Sepia Tone',\n property: 'sepia',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.3\n },\n {\n id: 'noise',\n type: 'slider',\n label: 'Noise Amount',\n property: 'noise',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.3\n },\n {\n id: 'noiseSize',\n type: 'slider',\n label: 'Noise Size',\n property: 'noiseSize',\n min: 1,\n max: 10,\n step: 0.1,\n default: 1\n },\n {\n id: 'scratch',\n type: 'slider',\n label: 'Scratch Amount',\n property: 'scratch',\n min: -1,\n max: 1,\n step: 0.01,\n default: 0.5\n },\n {\n id: 'scratchDensity',\n type: 'slider',\n label: 'Scratch Density',\n property: 'scratchDensity',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.3\n },\n {\n id: 'scratchWidth',\n type: 'slider',\n label: 'Scratch Width',\n property: 'scratchWidth',\n min: 1,\n max: 20,\n step: 1,\n default: 1\n },\n {\n id: 'vignetting',\n type: 'slider',\n label: 'Vignette Size',\n property: 'vignetting',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.3\n },\n {\n id: 'vignettingAlpha',\n type: 'slider',\n label: 'Vignette Opacity',\n property: 'vignettingAlpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1\n },\n {\n id: 'vignettingBlur',\n type: 'slider',\n label: 'Vignette Blur',\n property: 'vignettingBlur',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.3\n },\n {\n id: 'seed',\n type: 'slider',\n label: 'Random Seed',\n property: 'seed',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5\n },\n {\n id: 'randomizeSeed',\n type: 'button',\n label: 'Randomize Seed',\n action: 'randomizeSeed'\n }\n ]\n});","/**\n * Outline Filter Definition\n * Adds an outline/stroke around the image\n */\nimport { registerFilter } from '../registry';\n// Import the OutlineFilter directly from pixi-filters package\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { OutlineFilter } = PixiFilters;;\n\nexport default registerFilter({\n id: 'outline',\n name: 'Outline',\n category: 'effects',\n description: 'Add an outline or stroke around the image',\n \n createFilter: (params) => {\n try {\n console.log('Creating OutlineFilter with params:', params);\n \n // Parse color from hex string if needed\n let color = params.color;\n if (typeof color === 'string') {\n color = parseInt(color.replace('#', '0x'), 16);\n }\n \n // Create the filter with direct options\n const filter = new OutlineFilter({\n thickness: params.thickness || 4,\n color: color,\n alpha: params.alpha || 1,\n quality: params.quality || 0.1,\n knockout: params.knockout || false\n });\n \n // Store custom params for UI updates\n (filter as any)._customParams = { ...params };\n \n // Add custom updateUIParam method for UI parameter handling\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store the updated parameter\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n customParams[key] = value;\n \n switch (key) {\n case 'thickness':\n // Apply with validation (non-negative)\n this.thickness = Math.max(0, value);\n break;\n \n case 'color':\n // Handle color in different formats\n if (typeof value === 'string') {\n // Convert hex string to number\n this.color = parseInt(value.replace('#', '0x'), 16);\n customParams.color = value; // Store the string version for UI\n } else {\n // Direct numeric assignment\n this.color = value;\n }\n break;\n \n case 'alpha':\n // Apply with validation (0-1 range)\n this.alpha = Math.max(0, Math.min(1, value));\n break;\n \n case 'quality':\n // Apply with validation (0.01-1 range for performance reasons)\n this.quality = Math.max(0.01, Math.min(1, value));\n break;\n \n case 'knockout':\n // Boolean toggle\n this.knockout = !!value;\n break;\n \n default:\n // For any other properties that might exist directly on the filter\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n }\n };\n \n return filter;\n } catch (error) {\n console.error('Failed to create OutlineFilter:', error);\n return null;\n }\n },\n \n defaultParams: {\n thickness: 4,\n color: '#000000',\n alpha: 1,\n quality: 0.1,\n knockout: false\n },\n \n controls: [\n {\n id: 'thickness',\n type: 'slider',\n label: 'Thickness',\n property: 'thickness',\n min: 0,\n max: 20,\n step: 0.1,\n default: 4\n },\n {\n id: 'color',\n type: 'color',\n label: 'Color',\n property: 'color',\n default: '#000000'\n },\n {\n id: 'alpha',\n type: 'slider',\n label: 'Alpha',\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1\n },\n {\n id: 'quality',\n type: 'slider',\n label: 'Quality',\n property: 'quality',\n min: 0.01,\n max: 1,\n step: 0.01,\n default: 0.1,\n tooltip: 'Higher values give better quality but slower performance'\n },\n {\n id: 'knockout',\n type: 'toggle',\n label: 'Outline Only',\n property: 'knockout',\n default: false,\n tooltip: 'Only show the outline, not the image content'\n }\n ]\n});","/**\n * Pixelate Filter Definition\n * Creates a pixelated mosaic effect by reducing the resolution in specific areas\n */\nimport { registerFilter } from '../registry';\n// Import the PixelateFilter directly from pixi-filters package\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { PixelateFilter } = PixiFilters;;\n\nexport default registerFilter({\n id: 'pixelate',\n name: 'Pixelate',\n category: 'effects',\n description: 'Create a pixelated or mosaic effect',\n \n createFilter: (params) => {\n try {\n console.log('Creating PixelateFilter with params:', params);\n \n // Create the filter with correct parameters\n // If separate X and Y values are provided, use them\n // Otherwise, use a single size value for both dimensions\n const filter = new PixelateFilter(\n params.useUniform \n ? Math.max(4, params.size || 10) \n : [Math.max(4, params.sizeX || 10), Math.max(4, params.sizeY || 10)]\n );\n \n // Store custom params for UI updates\n (filter as any)._customParams = { ...params };\n \n /**\n * Add custom updateUIParam method for UI parameter handling\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store the updated parameter\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n customParams[key] = value;\n \n switch (key) {\n case 'useUniform':\n // Toggle between uniform (single value) or separate x/y values\n customParams.useUniform = value;\n if (value) {\n // Switch to uniform size - use average of X and Y\n const avgSize = Math.round((this.sizeX + this.sizeY) / 2);\n this.size = Math.max(4, avgSize);\n customParams.size = avgSize;\n } else {\n // Switch to separate values - use current size for both\n const currentSize = Array.isArray(this.size) ? this.size[0] : this.size;\n this.sizeX = Math.max(4, currentSize);\n this.sizeY = Math.max(4, currentSize);\n customParams.sizeX = this.sizeX;\n customParams.sizeY = this.sizeY;\n }\n break;\n \n case 'size':\n // Update uniform size (both X and Y the same)\n if (customParams.useUniform) {\n this.size = Math.max(4, value);\n }\n break;\n \n case 'sizeX':\n // Update only X dimension\n if (!customParams.useUniform) {\n this.sizeX = Math.max(4, value);\n }\n break;\n \n case 'sizeY':\n // Update only Y dimension\n if (!customParams.useUniform) {\n this.sizeY = Math.max(4, value);\n }\n break;\n \n default:\n // For any other properties that might exist on the filter\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n }\n };\n \n return filter;\n } catch (error) {\n console.error('Failed to create PixelateFilter:', error);\n return null;\n }\n },\n \n defaultParams: {\n useUniform: true,\n size: 10,\n sizeX: 10,\n sizeY: 10\n },\n \n controls: [\n {\n id: 'useUniform',\n type: 'toggle',\n label: 'Uniform Pixels',\n property: 'useUniform',\n default: true,\n tooltip: 'Use the same size for both X and Y dimensions'\n },\n {\n id: 'size',\n type: 'slider',\n label: 'Pixel Size',\n property: 'size',\n min: 4,\n max: 40,\n step: 1,\n default: 10,\n tooltip: 'Size of the pixels in both dimensions'\n },\n {\n id: 'sizeX',\n type: 'slider',\n label: 'Horizontal Size',\n property: 'sizeX',\n min: 4,\n max: 40,\n step: 1,\n default: 10,\n tooltip: 'Size of the pixels in the horizontal direction'\n },\n {\n id: 'sizeY',\n type: 'slider',\n label: 'Vertical Size',\n property: 'sizeY',\n min: 4,\n max: 40,\n step: 1,\n default: 10,\n tooltip: 'Size of the pixels in the vertical direction'\n }\n ]\n});","/**\n * Reflection Filter Definition\n * Creates a water reflection effect with configurable waves\n */\nimport { registerFilter } from '../registry';\n// Import the ReflectionFilter directly from pixi-filters package\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { ReflectionFilter } = PixiFilters;;\n\n// Register the Reflection filter\nexport default registerFilter({\n id: 'reflection', // ID must match what the application expects\n name: 'Reflection',\n category: 'distortion',\n description: 'Creates a water reflection effect with configurable waves',\n \n // Create an instance of the ReflectionFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating ReflectionFilter with params:', params);\n \n // Extract parameters with defaults\n const options = {\n mirror: params.mirror ?? true,\n boundary: params.boundary ?? 0.5,\n amplitude: new Float32Array([params.amplitudeStart ?? 0, params.amplitudeEnd ?? 20]),\n waveLength: new Float32Array([params.wavelengthStart ?? 30, params.wavelengthEnd ?? 100]),\n alpha: new Float32Array([params.alphaStart ?? 1, params.alphaEnd ?? 1]),\n time: params.time ?? 0\n };\n\n // Create the filter with PixiJS v8 style options object\n const filter = new ReflectionFilter(options as any);\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n // Add an animating flag for potential animation support\n (filter as any).animating = params.animating ?? false;\n \n /**\n * Custom method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'mirror':\n case 'boundary':\n case 'time':\n this[key] = value;\n console.log(`Updated ${key} to ${value}`);\n break;\n \n case 'amplitudeStart':\n if (!Array.isArray(this.amplitude)) {\n this.amplitude = [0, this._customParams.amplitudeEnd || 20];\n }\n this.amplitude[0] = value;\n console.log(`Updated amplitude[0] to ${value}`);\n break;\n \n case 'amplitudeEnd':\n if (!Array.isArray(this.amplitude)) {\n this.amplitude = [this._customParams.amplitudeStart || 0, 20];\n }\n this.amplitude[1] = value;\n console.log(`Updated amplitude[1] to ${value}`);\n break;\n \n case 'wavelengthStart':\n if (!Array.isArray(this.waveLength)) {\n this.waveLength = [30, this._customParams.wavelengthEnd || 100];\n }\n this.waveLength[0] = value;\n console.log(`Updated waveLength[0] to ${value}`);\n break;\n \n case 'wavelengthEnd':\n if (!Array.isArray(this.waveLength)) {\n this.waveLength = [this._customParams.wavelengthStart || 30, 100];\n }\n this.waveLength[1] = value;\n console.log(`Updated waveLength[1] to ${value}`);\n break;\n \n case 'alphaStart':\n if (!Array.isArray(this.alpha)) {\n this.alpha = [1, this._customParams.alphaEnd || 1];\n }\n this.alpha[0] = value;\n console.log(`Updated alpha[0] to ${value}`);\n break;\n \n case 'alphaEnd':\n if (!Array.isArray(this.alpha)) {\n this.alpha = [this._customParams.alphaStart || 1, 1];\n }\n this.alpha[1] = value;\n console.log(`Updated alpha[1] to ${value}`);\n break;\n \n case 'animating':\n (this as any).animating = value;\n console.log(`Updated animating to ${value}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('ReflectionFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create ReflectionFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n mirror: true,\n boundary: 0.5,\n amplitudeStart: 0,\n amplitudeEnd: 20,\n wavelengthStart: 30,\n wavelengthEnd: 100,\n alphaStart: 1,\n alphaEnd: 1,\n time: 0,\n animating: false\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'mirror',\n type: 'toggle',\n label: 'Mirror Image',\n property: 'mirror',\n default: true,\n },\n {\n id: 'boundary',\n type: 'slider',\n label: 'Boundary Line',\n property: 'boundary',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'amplitudeStart',\n type: 'slider',\n label: 'Wave Height (Start)',\n property: 'amplitudeStart',\n min: 0,\n max: 50,\n step: 1,\n default: 0,\n },\n {\n id: 'amplitudeEnd',\n type: 'slider',\n label: 'Wave Height (End)',\n property: 'amplitudeEnd',\n min: 0,\n max: 50,\n step: 1,\n default: 20,\n },\n {\n id: 'wavelengthStart',\n type: 'slider',\n label: 'Wave Length (Start)',\n property: 'wavelengthStart',\n min: 10,\n max: 200,\n step: 1,\n default: 30,\n },\n {\n id: 'wavelengthEnd',\n type: 'slider',\n label: 'Wave Length (End)',\n property: 'wavelengthEnd',\n min: 10,\n max: 200,\n step: 1,\n default: 100,\n },\n {\n id: 'alphaStart',\n type: 'slider',\n label: 'Opacity (Start)',\n property: 'alphaStart',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1,\n },\n {\n id: 'alphaEnd',\n type: 'slider',\n label: 'Opacity (End)',\n property: 'alphaEnd',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1,\n },\n {\n id: 'time',\n type: 'slider',\n label: 'Animation Time',\n property: 'time',\n min: 0,\n max: 10,\n step: 0.1,\n default: 0,\n },\n {\n id: 'animating',\n type: 'toggle',\n label: 'Auto Animate',\n property: 'animating',\n default: false,\n }\n ],\n});","/**\n * Shockwave Filter Definition\n * Creates a rippling shockwave effect\n */\nimport { registerFilter } from '../registry';\n// Import the ShockwaveFilter directly from pixi-filters package\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { ShockwaveFilter } = PixiFilters;;\n\n// Register the Shockwave filter\nexport default registerFilter({\n id: 'shockwave', // ID must match what the application expects\n name: 'Shockwave',\n category: 'distortion',\n description: 'Creates a rippling shockwave or blast wave effect',\n \n // Create an instance of the ShockwaveFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating ShockwaveFilter with params:', params);\n \n // Extract parameters with defaults\n const centerX = params.centerX ?? 0.5;\n const centerY = params.centerY ?? 0.5;\n const center = { x: centerX, y: centerY };\n const amplitude = params.amplitude ?? 30;\n const wavelength = params.wavelength ?? 160;\n const speed = params.speed ?? 500;\n const brightness = params.brightness ?? 1;\n const radius = params.radius ?? -1;\n const time = params.time ?? 0;\n \n // Create the filter with PixiJS v8 style options object\n const filter = new ShockwaveFilter({\n center,\n amplitude,\n wavelength,\n speed,\n brightness,\n radius,\n time\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n // Add an animating flag for potential animation support\n (filter as any).animating = params.animating ?? false;\n \n /**\n * Custom method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'centerX':\n if (!this.center) this.center = { x: 0.5, y: 0.5 };\n this.center.x = value;\n console.log(`Updated center.x to ${value}`);\n break;\n \n case 'centerY':\n if (!this.center) this.center = { x: 0.5, y: 0.5 };\n this.center.y = value;\n console.log(`Updated center.y to ${value}`);\n break;\n \n case 'amplitude':\n case 'wavelength':\n case 'speed':\n case 'brightness':\n case 'radius':\n case 'time':\n this[key] = value;\n console.log(`Updated ${key} to ${value}`);\n break;\n \n case 'animating':\n (this as any).animating = value;\n console.log(`Updated animating to ${value}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('ShockwaveFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create ShockwaveFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n centerX: 0.5,\n centerY: 0.5,\n amplitude: 30,\n wavelength: 160,\n speed: 500,\n brightness: 1,\n radius: -1,\n time: 0,\n animating: false\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'centerX',\n type: 'slider',\n label: 'Center X',\n property: 'centerX',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'centerY',\n type: 'slider',\n label: 'Center Y',\n property: 'centerY',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'amplitude',\n type: 'slider',\n label: 'Amplitude',\n property: 'amplitude',\n min: 0,\n max: 100,\n step: 1,\n default: 30,\n },\n {\n id: 'wavelength',\n type: 'slider',\n label: 'Wavelength',\n property: 'wavelength',\n min: 10,\n max: 500,\n step: 1,\n default: 160,\n },\n {\n id: 'speed',\n type: 'slider',\n label: 'Speed',\n property: 'speed',\n min: 1,\n max: 1000,\n step: 10,\n default: 500,\n },\n {\n id: 'brightness',\n type: 'slider',\n label: 'Brightness',\n property: 'brightness',\n min: 0,\n max: 5,\n step: 0.1,\n default: 1,\n },\n {\n id: 'radius',\n type: 'slider',\n label: 'Max Radius',\n property: 'radius',\n min: -1,\n max: 1000,\n step: 10,\n default: -1,\n },\n {\n id: 'time',\n type: 'slider',\n label: 'Time',\n property: 'time',\n min: 0,\n max: 5,\n step: 0.1,\n default: 0,\n },\n {\n id: 'animating',\n type: 'toggle',\n label: 'Auto Animate',\n property: 'animating',\n default: false,\n }\n ],\n});","/**\n * Simplex Noise Filter Definition\n * Applies procedural noise to create various texture effects\n */\nimport { registerFilter } from '../registry';\n// Import the SimplexNoiseFilter directly from pixi-filters package\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { SimplexNoiseFilter } = PixiFilters;;\n\nexport default registerFilter({\n id: 'simplex-noise',\n name: 'Simplex Noise',\n category: 'effects',\n description: 'Apply procedural noise to create texture effects',\n \n createFilter: (params) => {\n try {\n console.log('Creating SimplexNoiseFilter with params:', params);\n \n // Use params.time for animation if this is enabled\n const zOffset = params.animating ? 0 : (params.offsetZ || 0);\n \n // Create the filter with direct options\n const filter = new SimplexNoiseFilter({\n strength: params.strength,\n noiseScale: params.noiseScale,\n offsetX: params.offsetX,\n offsetY: params.offsetY,\n offsetZ: zOffset,\n step: params.step\n });\n \n // Store animation state\n (filter as any).animating = params.animating || false;\n (filter as any).animationSpeed = params.animationSpeed || 0.01;\n \n // Store custom params for UI updates\n (filter as any)._customParams = { ...params };\n \n // Set up animation loop for changing the Z offset over time\n let animationFrameId: number | null = null;\n let currentTime = 0;\n \n const animate = () => {\n if ((filter as any).animating) {\n // Update the Z offset over time for animation\n currentTime += (filter as any).animationSpeed;\n filter.offsetZ = currentTime;\n }\n animationFrameId = requestAnimationFrame(animate);\n };\n \n // Start animation if enabled\n if ((filter as any).animating) {\n animationFrameId = requestAnimationFrame(animate);\n }\n \n // Method to clean up animation when filter is destroyed\n (filter as any)._stopAnimation = () => {\n if (animationFrameId !== null) {\n cancelAnimationFrame(animationFrameId);\n animationFrameId = null;\n }\n };\n \n /**\n * Add custom updateUIParam method for UI parameter handling\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store the updated parameter\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n customParams[key] = value;\n \n switch (key) {\n case 'animating':\n // Toggle animation state\n (this as any).animating = value;\n if (value && !animationFrameId) {\n // Start animation if not already running\n animationFrameId = requestAnimationFrame(animate);\n }\n break;\n \n case 'animationSpeed':\n // Update animation speed\n (this as any).animationSpeed = value;\n break;\n \n case 'offsetZ':\n // Only update Z offset manually if not animating\n if (!(this as any).animating) {\n this.offsetZ = value;\n }\n break;\n \n case 'randomizeSeed':\n // Randomize all offsets for a new pattern\n if (value) {\n const randomValue = () => Math.random() * 100 - 50;\n this.offsetX = randomValue();\n this.offsetY = randomValue();\n this.offsetZ = randomValue();\n \n // Update stored values\n customParams.offsetX = this.offsetX;\n customParams.offsetY = this.offsetY;\n customParams.offsetZ = this.offsetZ;\n }\n break;\n \n // Direct properties that exist on the filter\n case 'strength':\n case 'noiseScale':\n case 'offsetX':\n case 'offsetY':\n case 'step':\n // Apply with any needed validation\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n \n default:\n // For any other properties that might exist on the filter\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n }\n };\n \n return filter;\n } catch (error) {\n console.error('Failed to create SimplexNoiseFilter:', error);\n return null;\n }\n },\n \n defaultParams: {\n strength: 0.5,\n noiseScale: 10.0,\n offsetX: 0,\n offsetY: 0,\n offsetZ: 0,\n step: -1,\n animating: false,\n animationSpeed: 0.01,\n randomizeSeed: false\n },\n \n controls: [\n {\n id: 'strength',\n type: 'slider',\n label: 'Noise Strength',\n property: 'strength',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5\n },\n {\n id: 'noiseScale',\n type: 'slider',\n label: 'Noise Scale',\n property: 'noiseScale',\n min: 1,\n max: 50,\n step: 0.5,\n default: 10.0\n },\n {\n id: 'offsetX',\n type: 'slider',\n label: 'X Offset',\n property: 'offsetX',\n min: -50,\n max: 50,\n step: 0.5,\n default: 0\n },\n {\n id: 'offsetY',\n type: 'slider',\n label: 'Y Offset',\n property: 'offsetY',\n min: -50,\n max: 50,\n step: 0.5,\n default: 0\n },\n {\n id: 'offsetZ',\n type: 'slider',\n label: 'Z Offset',\n property: 'offsetZ',\n min: -50,\n max: 50,\n step: 0.5,\n default: 0\n },\n {\n id: 'step',\n type: 'slider',\n label: 'Step Threshold',\n property: 'step',\n min: -1,\n max: 1,\n step: 0.01,\n default: -1,\n tooltip: 'Values above 0 create a blocky effect'\n },\n {\n id: 'animating',\n type: 'toggle',\n label: 'Animate Noise',\n property: 'animating',\n default: false\n },\n {\n id: 'animationSpeed',\n type: 'slider',\n label: 'Animation Speed',\n property: 'animationSpeed',\n min: 0.001,\n max: 0.05,\n step: 0.001,\n default: 0.01\n },\n {\n id: 'randomizeSeed',\n type: 'button',\n label: 'Randomize Pattern',\n action: 'randomizeSeed'\n }\n ]\n});","/**\n * Twist Filter Definition\n *\n * Uses pixi-filters' built-in TwistFilter. The previous custom shader\n * worked in PIXI v7 but silently rendered transparent in PIXI v8 because\n * its vertex shader set `vTextureCoord = aPosition`, which isn't how v8's\n * filter pipeline computes texture coordinates.\n *\n * UI keeps normalized [0,1] inputs for centerX/centerY/radius so they're\n * intuitive across any image size. The filter factory converts those to\n * pixel-space offset/radius using the source image dimensions threaded\n * through `params._sourceWidth/_sourceHeight` by FilterManager.\n */\nimport { registerFilter } from '../registry';\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore — pixi-filters lacks first-class TypeScript types here\nconst { TwistFilter } = PixiFilters;\n\nconst computeTwistPadding = (radiusPx: number): number => {\n // Twist displaces pixels within the radius; extend the render area a bit\n // so edge fringes don't clip when the twist center is near the boundary.\n return Math.ceil(Math.max(0, Number(radiusPx) || 0) + 2);\n};\n\ninterface TwistParams {\n centerX?: number;\n centerY?: number;\n /** Radius as a fraction of the smaller image edge, 0-1. */\n radius?: number;\n /** Twist angle in radians. */\n angle?: number;\n _sourceWidth?: number;\n _sourceHeight?: number;\n}\n\nconst buildTwistFilter = (raw: TwistParams, previewToNativeScale = 1) => {\n const width = Math.max(1, Number(raw._sourceWidth ?? 0));\n const height = Math.max(1, Number(raw._sourceHeight ?? 0));\n const minEdge = Math.min(width, height);\n\n const centerX = Number(raw.centerX ?? 0.5);\n const centerY = Number(raw.centerY ?? 0.5);\n const normalizedRadius = Number(raw.radius ?? 0.25);\n const angle = Number(raw.angle ?? 4);\n\n // Normalized (0-1) → pixels. Center is in the filter area's coord space;\n // pixi-filters TwistFilter's offset is in pixels relative to (0,0) of\n // the filter area. We also scale by previewToNativeScale so exports at\n // higher resolution keep the same visual radius.\n const offsetX = centerX * width * previewToNativeScale;\n const offsetY = centerY * height * previewToNativeScale;\n const radiusPx = normalizedRadius * minEdge * previewToNativeScale;\n\n const filter = new TwistFilter({\n offset: { x: offsetX, y: offsetY },\n radius: radiusPx,\n angle,\n });\n\n // Reserve padding so the twist fringe doesn't clip when centered near\n // the sprite edge. Matches the drop-shadow / bulge-pinch pattern.\n const padding = computeTwistPadding(radiusPx);\n filter.padding = Math.max(filter.padding ?? 0, padding);\n (filter as any)._exportPadding = padding;\n\n return filter;\n};\n\nexport default registerFilter({\n id: 'twist',\n name: 'Twist',\n category: 'distortion',\n description: 'Creates a twisting distortion effect around a central point',\n\n createFilter: (params) => {\n try {\n const raw: TwistParams = {\n centerX: params.centerX ?? 0.5,\n centerY: params.centerY ?? 0.5,\n radius: params.radius ?? 0.25,\n angle: params.angle ?? 4,\n _sourceWidth: params._sourceWidth,\n _sourceHeight: params._sourceHeight,\n };\n\n const filter = buildTwistFilter(raw, 1);\n (filter as any)._customParams = { ...raw };\n\n (filter as any).updateUIParam = function (key: string, value: unknown) {\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n customParams[key] = value;\n\n // Twist params are coupled (center → offset in pixels using dims,\n // radius → px using min edge). Recompute all uniforms whenever any\n // slider moves rather than mapping per-key.\n const width = Math.max(1, Number(customParams._sourceWidth ?? 0));\n const height = Math.max(1, Number(customParams._sourceHeight ?? 0));\n const minEdge = Math.min(width, height);\n const centerX = Number(customParams.centerX ?? 0.5);\n const centerY = Number(customParams.centerY ?? 0.5);\n const normalizedRadius = Number(customParams.radius ?? 0.25);\n const angle = Number(customParams.angle ?? 4);\n\n if (this.offset) {\n this.offset.x = centerX * width;\n this.offset.y = centerY * height;\n }\n this.radius = normalizedRadius * minEdge;\n this.angle = angle;\n\n const padding = computeTwistPadding(this.radius);\n (this as any)._exportPadding = padding;\n this.padding = Math.max(this.padding ?? 0, padding);\n return true;\n };\n\n (filter as any).createExportFilter = function (options: { previewToNativeScale?: number } = {}) {\n const scale = Number.isFinite(options.previewToNativeScale)\n ? Math.max(1, Number(options.previewToNativeScale))\n : 1;\n const stored: TwistParams = (this as any)._customParams || raw;\n return buildTwistFilter(stored, scale);\n };\n\n (filter as any).getExportPadding = function () {\n return Number((this as any)._exportPadding || this.padding || 0);\n };\n\n return filter;\n } catch (error) {\n console.error('Failed to create TwistFilter:', error);\n return null;\n }\n },\n\n // Default parameter values — normalized (0-1) for intuitive slider use.\n defaultParams: {\n centerX: 0.5,\n centerY: 0.5,\n radius: 0.25,\n angle: 4,\n },\n\n controls: [\n {\n id: 'angle',\n type: 'slider',\n label: 'Angle',\n property: 'angle',\n min: -10,\n max: 10,\n step: 0.1,\n default: 4,\n tooltip: 'Amount of twisting (positive is clockwise)',\n },\n {\n id: 'radius',\n type: 'slider',\n label: 'Radius',\n property: 'radius',\n min: 0.05,\n max: 0.75,\n step: 0.01,\n default: 0.25,\n tooltip: 'Size of the twist effect (relative to image)',\n },\n {\n id: 'centerX',\n type: 'slider',\n label: 'Center X',\n property: 'centerX',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n tooltip: 'Horizontal position of twist center',\n },\n {\n id: 'centerY',\n type: 'slider',\n label: 'Center Y',\n property: 'centerY',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n tooltip: 'Vertical position of twist center',\n },\n ],\n});\n","/**\n * Vignette Filter Definition\n * Adds a classic darkened border effect to the image\n * \n * NOTE: This is a CUSTOM implementation as pixi-filters does not provide a VignetteFilter.\n * It uses AdjustmentFilter to simulate a vignette effect by manipulating brightness/contrast.\n * This is not a true radial gradient vignette but provides a similar visual effect.\n */\nimport { registerFilter } from '../registry';\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { AdjustmentFilter } = PixiFilters;;\n\n/**\n * Helper to convert a hex color value to RGB array\n */\nfunction hexToRgb(hex: number | string): number[] {\n const parsedHex = typeof hex === 'string' ? parseInt(hex.replace('#', '0x'), 16) : hex;\n return [\n ((parsedHex >> 16) & 0xFF) / 255,\n ((parsedHex >> 8) & 0xFF) / 255,\n (parsedHex & 0xFF) / 255\n ];\n}\n\n/**\n * Simple Vignette implementation using AdjustmentFilter\n * \n * This approach simulates a vignette effect by manipulating\n * brightness, contrast and color tint - it's not a true vignette\n * but provides a similar visual effect using stable filter mechanisms.\n */\nclass VignetteFilter extends AdjustmentFilter {\n private _radius: number = 0.8;\n private _strength: number = 1.0;\n private _colorRgb: number[] = [0, 0, 0];\n private _colorValue: string = '#000000';\n\n constructor(options: { radius?: number; strength?: number; color?: number | string } = {}) {\n // Initialize with default adjustment values\n super({\n brightness: 1.0,\n contrast: 1.0,\n saturation: 1.0,\n alpha: 1.0\n });\n \n this._radius = options.radius ?? 0.8;\n this._strength = options.strength ?? 1.0;\n \n // Parse color\n if (options.color !== undefined) {\n if (typeof options.color === 'string') {\n this._colorValue = options.color;\n this._colorRgb = hexToRgb(options.color);\n } else {\n this._colorValue = '#' + options.color.toString(16).padStart(6, '0');\n this._colorRgb = hexToRgb(options.color);\n }\n }\n \n // Apply the initial vignette effect\n this.updateVignette();\n }\n \n /**\n * Updates the filter parameters to simulate a vignette effect\n */\n private updateVignette(): void {\n // Calculate effect intensity based on radius and strength\n // Radius inversely affects strength (higher radius = less effect)\n const radiusFactor = 1 - (this._radius / 2); // Normalize to 0.5-1 range\n const effectiveStrength = this._strength * radiusFactor;\n \n // Darker with higher strength (0.5-1.0 range to avoid making everything black)\n this.brightness = Math.max(0.5, 1.0 - effectiveStrength * 0.5);\n \n // Increase contrast slightly with strength to emphasize the vignette\n this.contrast = 1.0 + (effectiveStrength * 0.2);\n \n // Apply a slight tint in the color direction\n if (this._colorRgb[0] > 0 || this._colorRgb[1] > 0 || this._colorRgb[2] > 0) {\n // Tint RGB based on color and strength\n // Since AdjustmentFilter doesn't have direct tint properties,\n // we can't apply a true color tint, but we can adjust\n // saturation to hint at the color\n this.saturation = 1.0 - (effectiveStrength * 0.3);\n }\n }\n\n // Properties with getters/setters\n get radius(): number { return this._radius; }\n set radius(value: number) { \n this._radius = Math.max(0.1, Math.min(1.5, value));\n this.updateVignette();\n }\n\n get strength(): number { return this._strength; }\n set strength(value: number) { \n this._strength = Math.max(0, Math.min(2, value));\n this.updateVignette();\n }\n\n get color(): string { return this._colorValue; }\n set color(value: number | string) { \n if (typeof value === 'string') {\n this._colorValue = value;\n this._colorRgb = hexToRgb(value);\n } else {\n this._colorValue = '#' + value.toString(16).padStart(6, '0');\n this._colorRgb = hexToRgb(value);\n }\n this.updateVignette();\n }\n}\n\nexport default registerFilter({\n id: 'vignette',\n name: 'Vignette',\n category: 'effects',\n description: 'Add a classic darkened border effect to the image',\n \n createFilter: (params) => {\n try {\n console.log('Creating VignetteFilter with params:', params);\n \n // Create the custom VignetteFilter implementation\n const filter = new VignetteFilter({\n radius: params.radius || 0.8,\n strength: params.strength || 1.0,\n color: params.color || '#000000'\n });\n \n // Store custom params for UI updates\n (filter as any)._customParams = { ...params };\n \n // Add custom updateUIParam method for UI parameter handling\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store the updated parameter\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n customParams[key] = value;\n \n switch (key) {\n case 'radius':\n // Apply with validation (0.1-1.5 range for visual quality)\n this.radius = Math.max(0.1, Math.min(1.5, value));\n break;\n \n case 'strength':\n // Apply with validation (non-negative)\n this.strength = Math.max(0, value);\n break;\n \n case 'color':\n // Handle color in different formats\n this.color = value;\n // Store the string version for UI if it's a string\n if (typeof value === 'string') {\n customParams.color = value;\n }\n break;\n \n default:\n // For any other properties that might exist directly on the filter\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n }\n };\n \n return filter;\n } catch (error) {\n console.error('Failed to create VignetteFilter:', error);\n return null;\n }\n },\n \n defaultParams: {\n radius: 0.8,\n strength: 1.0,\n color: '#000000'\n },\n \n controls: [\n {\n id: 'radius',\n type: 'slider',\n label: 'Radius',\n property: 'radius',\n min: 0.1,\n max: 1.5,\n step: 0.01,\n default: 0.8,\n tooltip: 'Size of the vignette effect (larger values create a smaller vignette)'\n },\n {\n id: 'strength',\n type: 'slider',\n label: 'Strength',\n property: 'strength',\n min: 0,\n max: 2,\n step: 0.01,\n default: 1.0,\n tooltip: 'Intensity of the vignette effect'\n },\n {\n id: 'color',\n type: 'color',\n label: 'Color',\n property: 'color',\n default: '#000000',\n tooltip: 'Color of the vignette (usually black)'\n }\n ]\n});","/**\n * Filters Module Index\n * Exports all filter-related functionality\n */\n\n// First import the functions so they exist in this module's scope\nimport {\n registerFilter,\n getFilter,\n getAllFilters,\n getFiltersByCategory,\n getAllCategories,\n hasFilter,\n unregisterFilter,\n getFiltersByMedia,\n isFilterCompatibleWithMedia,\n getRegisteredFilters,\n registerCorePixiFilters,\n} from './registry';\n\n// Then re-export them for downstream consumers\nexport {\n registerFilter,\n getFilter,\n getAllFilters,\n getFiltersByCategory,\n getAllCategories,\n hasFilter,\n unregisterFilter,\n getFiltersByMedia,\n isFilterCompatibleWithMedia,\n getRegisteredFilters,\n registerCorePixiFilters,\n};\nexport type { FilterDefinition, ControlDefinition, FilterMediaTarget } from './registry';\n\n// Re-export from factory\nexport {\n createFilterInstance,\n createFilterInstances,\n updateFilterParams,\n} from './factory';\nexport type { FilterInstanceConfig } from './factory';\n\n// Re-export from controlMapping\nexport {\n mapControlTypeToComponent,\n validateControlValue,\n generateDefaultParams,\n convertControlValue,\n} from './controlMapping';\n\n// Import and re-export all filter definitions\n// This ensures all filters are registered when this module is imported\n\n// Basic adjustments\nimport './definitions/adjustment';\nimport './definitions/adjustmentAdvanced';\nimport './definitions/alpha';\nimport './definitions/blur';\nimport './definitions/colorMatrix';\nimport './definitions/colorOverlay';\nimport './definitions/dropShadow';\nimport './definitions/grayscale';\nimport './definitions/hslAdjustment';\n\n// Blur effects\nimport './definitions/kawaseBlur';\nimport './definitions/motionBlur';\nimport './definitions/radialBlur';\nimport './definitions/tiltShift';\nimport './definitions/zoomBlur';\n\n// Color effects\nimport './definitions/colorGradient';\nimport './definitions/colorMap';\nimport './definitions/colorReplace';\nimport './definitions/multiColorReplace';\nimport './definitions/rgbSplit';\n\n// Stylistic effects\nimport './definitions/advancedBloom';\nimport './definitions/ascii';\nimport './definitions/backdropBlur';\nimport './definitions/bevel';\nimport './definitions/bloom';\nimport './definitions/bulgePinch';\nimport './definitions/convolution';\nimport './definitions/crossHatch';\nimport './definitions/crt';\nimport './definitions/displacement';\nimport './definitions/dot';\nimport './definitions/emboss';\nimport './definitions/glitch';\nimport './definitions/glow';\nimport './definitions/godray';\nimport './definitions/lightmap';\nimport './definitions/noise';\nimport './definitions/oldFilm';\nimport './definitions/outline';\nimport './definitions/pixelate';\nimport './definitions/reflection';\nimport './definitions/shockwave';\nimport './definitions/simplexNoise';\nimport './definitions/twist';\nimport './definitions/vignette';\n\n/**\n * Options for initializeFilterRegistry.\n * @property disabled - Filter IDs to remove from the registry after initialization.\n */\ninterface FilterRegistryOptions {\n disabled?: string[];\n}\n\n/**\n * Initialize the filter registry with all available filters.\n *\n * @param options.disabled - Array of filter IDs to remove after registration\n * (e.g., fetched from the server's mediables.pixi_filters.disabled config).\n */\nexport function initializeFilterRegistry(options?: FilterRegistryOptions) {\n try {\n // Just verify functions exist (they should because of proper imports)\n verifyFilterRegistryFunctions();\n\n // Add explicit type annotations to fix TS7034 errors\n let filters: any[] = [];\n let categories: any[] = [];\n\n // First, try to register core filters\n try {\n // Check if any filters have already been registered\n filters = getAllFilters(); // Now we know this function exists\n\n if (filters.length === 0) {\n // Register core filters if none are registered yet\n console.log('No filters found, registering core filters');\n registerCorePixiFilters(); // Now we know this function exists\n }\n } catch (e) {\n console.warn('Error registering core filters:', e);\n }\n\n // Remove disabled filters from the registry\n const disabled = options?.disabled;\n if (Array.isArray(disabled) && disabled.length > 0) {\n let removedCount = 0;\n for (const id of disabled) {\n if (unregisterFilter(id)) {\n removedCount++;\n }\n }\n if (removedCount > 0) {\n console.log(`Removed ${removedCount} disabled filter(s) from registry`);\n }\n }\n\n // Try to get the filters again after registration\n try {\n filters = getAllFilters();\n categories = getAllCategories(); // Now we know this function exists\n } catch (e) {\n console.warn('Error getting filters or categories:', e);\n // Ensure we have valid defaults even after an error\n if (!filters) filters = [] as any[];\n if (!categories) categories = [] as any[];\n }\n\n // Log the initialization status\n console.log(`Filter registry initialized with ${filters.length} filters in ${categories.length} categories`);\n\n // If we have no filters, log a warning\n if (filters.length === 0) {\n console.warn('No filters found in registry. Filter functionality may be limited.');\n }\n\n return filters as any[];\n } catch (error) {\n // Log the error but don't crash\n console.error('Error initializing filter registry:', error);\n\n // Return an empty array to avoid further errors\n return [];\n }\n}\n\n/**\n * Verify that the required filter registry functions exist\n * This is now just for debugging/validation since we're properly importing the functions\n */\nfunction verifyFilterRegistryFunctions() {\n // Just verify functions exist - they should because of the imports\n const missingFunctions = [];\n \n if (typeof getAllFilters !== 'function') missingFunctions.push('getAllFilters');\n if (typeof getAllCategories !== 'function') missingFunctions.push('getAllCategories');\n if (typeof registerCorePixiFilters !== 'function') missingFunctions.push('registerCorePixiFilters');\n \n if (missingFunctions.length > 0) {\n console.warn(`Warning: Some registry functions are still missing: ${missingFunctions.join(', ')}`);\n }\n}\n\n/**\n * Alternative initialization function with a minimal approach\n * Use this if the main initializeFilterRegistry function is having issues\n */\nexport function safeInitializeFilterRegistry() {\n console.warn('Using minimal safeInitializeFilterRegistry implementation');\n \n try {\n // Verify functions exist but don't create fallbacks\n verifyFilterRegistryFunctions();\n \n // Try to use the getAllFilters function to get any existing filters\n const existingFilters = getAllFilters();\n \n if (existingFilters && existingFilters.length > 0) {\n console.log(`Found ${existingFilters.length} existing filters`);\n return Promise.resolve(existingFilters);\n }\n \n // If no existing filters, try one more attempt with registerCorePixiFilters\n try {\n registerCorePixiFilters();\n const registeredFilters = getAllFilters();\n console.log(`Registered ${registeredFilters.length} core filters`);\n return Promise.resolve(registeredFilters);\n } catch (e) {\n console.warn('Error registering core filters:', e);\n }\n \n // If all else fails, return empty array\n console.warn('Filter functionality will be limited');\n return Promise.resolve([]);\n } catch (e) {\n console.error('Error in safeInitializeFilterRegistry:', e);\n return Promise.resolve([]);\n }\n}\n\n/**\n * Simplified factory for creating a minimal filter\n * Returns a no-op filter that won't cause errors but doesn't do anything\n */\nexport function createMinimalFilter(id: string) {\n console.warn(`Creating minimal placeholder filter for: ${id}`);\n \n // Create a more complete filter stub that matches the expected interface\n return {\n id,\n name: id,\n enabled: true,\n // Basic filter methods\n apply: () => {/* No-op */},\n // Properties needed by the UI\n uniforms: {},\n // Custom interface properties\n updateUIParam: (param: string, value: any) => {\n console.log(`Minimal filter ${id} updateUIParam called with ${param}=${value}`);\n return true;\n },\n handleButtonAction: (action: string) => {\n console.log(`Minimal filter ${id} handleButtonAction called with ${action}`);\n return true;\n },\n // Add any other expected properties based on your filter interface\n // This ensures the minimal filter can be used in place of a real filter\n // without causing errors\n reset: () => {/* No-op */},\n // Clone method for deep copying\n clone: () => createMinimalFilter(id),\n // Allow property access with indexing\n [Symbol.toPrimitive]: () => `[Minimal Filter ${id}]`\n };\n}\n"],"names":["EventEmitter","event","callback","listeners","args","wrapper","TEXT_LAYER_FONT_FAMILIES","TEXT_LAYER_BLEND_MODES","DEFAULT_TEXT_BOX","DEFAULT_TEXT_STYLE","DEFAULT_TEXT_EFFECTS","State","key","parts","value","part","old","lastKey","target","filters","filterId","values","crop","_a","document","binding","snapshot","layers","layer","activeLayerId","layerId","index","baseId","existingIds","safeBase","suffix","candidate","filter","expectedLayerId","expected","activeFilters","filterValues","oldSelectedFilter","min","max","fallback","numeric","normalized","box","base","source","style","fontFamily","fontStyle","align","fill","effects","baseEffects","stroke","shadow","glow","backdrop","transform","input","baseText","contentSource","boxSource","_b","styleSource","_c","effectsSource","_d","removedIndex","distance","nextIndex","previousIndex","fromIndex","toIndex","start","end","activeLayer","visible","name","nextName","oldName","sourceLayer","duplicate","oldActiveLayerId","removed","nextActiveLayerId","direction","locked","payload","patch","textPatch","nextLayer","eventName","eventPayload","id","fit","stops","stop","existingIndex","firstSubjectIndex","insertAt","normalizedFill","previousFit","amount","numericAmount","effect","nextActive","enabled","controlId","filterIndex","controls","existing","ctl","prefersDark","createState","TEXT_BLEND_MODES","PixiRenderer","canvas","w","h","_f","_e","timeoutMs","resolve","settled","timeoutId","finish","tex","scale","opts","s","desired","z","container","backgroundColor","options","mountToken","doMount","PIXI","width","height","backgroundAlpha","app","imageUrl","isCurrent","img","settledScale","renderToken","isCurrentRender","subjectAdded","displayObject","factory","layerEntry","opacity","context","imageFilters","combinedFilters","textDisplayObject","imageDisplayObject","texture","allowed","mode","content","wordWrapWidth","fontSize","lineHeight","letterSpacing","fontWeight","textStyle","textObject","mask","effectMask","sourceUrl","url","image","tiled","gradient","radius","radians","centerX","centerY","length","dx","dy","offset","blur","graphics","color","alpha","primitive","kind","padding","x","y","backdropWidth","backdropHeight","rect","sourceWidth","sourceHeight","_g","_h","ownsTexture","degrees","rotation","rawCos","rawSin","cos","sin","srcW","srcH","outW","outH","src","rt","prevTexture","previousFilters","newSprite","format","quality","maxEdge","dontUpscale","maxPixels","previewW","previewH","previewSourceScale","previewToNativeScale","layerDocumentForExport","hasLayerDocumentForExport","exportFilters","f","cloned","totalPadding","p","initialMargin","renderWithMargin","margin","renderW","renderH","exportRoot","exportSprites","addSubjectSprite","exportSprite","addImageLayer","liveDisplayObject","addBackgroundLayer","background","addTextLayer","layerDocument","hasLayerDocument","childCount","scanAlphaBounds","ctx","pixels","threshold","minX","minY","maxX","maxY","stride","rowStride","rowStart","touchesEdge","result","rendered","bounds","retryMargin","retried","retriedBounds","edge","outCanvas","outCtx","dataUrl","blob","dims","prevCenter","chevronLeft","chevronRight","zoomIn","zoomOut","expand","settings","water","colorPalette","sparkles","move","brush","flash","save","close","refresh","rotateCcw","rotateCw","trash","openFolder","checkmark","eye","eyeOff","lockClosed","lockOpen","pencil","text","square","circle","freeform","sunny","moon","film","personOutline","EDITOR_CATEGORIES","icons.settings","icons.water","icons.colorPalette","icons.sparkles","icons.move","icons.flash","icons.film","icons.text","icons.brush","icons.layers","icons.crop","UI_TO_REGISTRY","c","REGISTRY_TO_UI","rc","getRegistryCategoriesForUi","uiCategoryId","FilterManager","state","pixiRenderer","registry","category","registryCategories","seenIds","registryCat","catFilters","path","tokens","obj","i","last","def","controlIds","isDynamicPath","inst","synced","val","action","params","_i","filterState","dimensions","trackInstances","renderFilter","applied","sprite","failedFilters","error","_CropManager","aspect","aspectMap","targetAspect","currentAspect","shape","side","cropRect","spriteWidth","spriteHeight","texWidth","texHeight","fitScale","currentZoom","overflowW","overflowH","pad","targetZoom","zoomForW","zoomForH","now","overlay","cv","cssW","cssH","dpr","thirdW","thirdH","hs","corners","edges","all","hover","size","px","py","near","ax","ay","bx","by","pos","maxW","maxH","stage","prevZoom","scaleX","scaleY","rawTx","rawTy","offsetX","offsetY","cx","cy","g","previousAppliedRect","appliedPixelRect","appliedShape","appliedAspect","pixelRect","__publicField","CropManager","RemoveBgManager","controller","reason","controllers","imageData","request","operationId","sessionKey","sourceHash","formData","response","withSignal","init","e","errorMessage","errorText","resultBlob","endpoint","data","header","mimeMatch","mime","binary","array","reject","reader","char","random","buffer","digest","byte","el","tag","attrs","children","element","child","createSlider","label","step","onChange","formatValue","display","createToggle","checked","labelEl","toggle","slider","createColorPicker","createTextInput","placeholder","onCommit","lastCommitted","commit","next","createSelect","select","opt","option","createButton","className","onClick","icon","disabled","button","iconEl","svg","createIconButton","title","testId","ariaLabel","createChip","active","chip","isActive","Toolbar","editor","leftSection","openBtn","icons.openFolder","centerSection","zoomOutBtn","icons.zoomOut","current","zoomInBtn","icons.zoomIn","fitBtn","icons.expand","rightSection","icons.sunny","icons.moon","removeBgGroup","optionEl","icons.personOutline","resetBtn","icons.refresh","saveBtn","icons.save","closeBtn","icons.close","unsubZoom","unsubTheme","unsubMode","unsubHasImage","unsubProcessing","unsubAvailability","unsubDocument","unsubLayers","unsubActiveLayer","busy","message","zoom","unsub","CATEGORIES","CategoryCarousel","onSelect","icons.chevronLeft","cat","icons.chevronRight","pageCount","dot","categoryId","currentMode","selectedChip","pageIndex","itemWidth","dots","activePage","FilterCarousel","filterManager","onToggle","unsubCat","unsubActive","unsubSelected","selectedFilter","card","isSelected","preview","previewText","willBeActive","icons.checkmark","maxIndex","FilterAdjustments","onReset","onAction","unsubValues","grid","controlEl","instance","dynamicControls","stateKey","controlType","updateKey","type","MobileFilterDrawer","onRemove","headerActions","removeBtn","MobileActiveFilters","check","SHAPES","icons.freeform","icons.square","icons.circle","ASPECT_RATIOS","ROTATION_PRESETS","normalizeAngle","angle","CropControls","cropManager","shapeSection","shapeRow","currentShape","aspectRow","actionRow","cancelBtn","applyBtn","section","quickRow","rotateLeft","icons.rotateCcw","rotateRight","icons.rotateCw","rotateHalf","rotateThreeQuarter","presetRow","preset","arbitrary","inputRow","reset","unsubShape","unsubAspect","unsubRotation","delta","rawValue","rounded","shapeId","aspectId","lockAspect","ActiveFiltersPanel","onClearAll","onUpdateValue","clearAllBtn","item","headerRow","actions","icons.trash","summaryEl","DEFAULT_PRESET","PRESETS","getPreset","found","normalizeRotationAngle","shortestRotationDelta","from","to","VanillaImageEditor","resolvedPreset","presetOverrides","toolbarContainer","canvasSection","filterLayout","leftColumn","rightColumn","resizeTimer","file","previousUrl","imageSource","loadVersion","ownedObjectUrl","loaded","restoredFilterId","filterDef","REGISTRY_CATEGORY_MAP","objectUrl","exported","link","appliedRect","interactiveRect","wasCropping","isDark","theme","previewRequest","previewContext","available","currentImageData","textEl","_j","_k","_l","categories","isMediaCompatible","definition","registerFilter","getFilter","getAllFilters","registerCorePixiFilters","PixiFilters","entry","exportName","FilterClass","getFiltersByCategory","getAllCategories","hasFilter","unregisterFilter","categoryIds","idx","isFilterCompatibleWithMedia","getRegisteredFilters","originalRegisterFilter","AdjustmentFilter","ColorMatrixFilter","DEFAULT_ADJUSTMENT_PARAMS","ADJUSTMENT_PARAM_KEYS","toFiniteNumber","parsed","isAdjustmentParamKey","normalizeAdjustmentParams","applyColorMatrixAdjustments","normalizedParams","filterWithUI","customParams","numericValue","DEFAULT_ADVANCED_ADJUSTMENT_PARAMS","ADVANCED_ADJUSTMENT_PARAM_KEYS","isAdvancedAdjustmentParamKey","toBoolean","normalizeAdvancedAdjustmentParams","applyAdvancedAdjustments","numericKey","clamp01","n","applyColorMatrixParams","normalizeParams","raw","MatrixFilterClass","stored","ColorOverlayFilter","colorValue","colorNum","computePadding","b","q","offX","offY","kernel","mag","createScaledForExport","rawParams","dist","ang","blr","qual","off","colorStr","refreshPadding","newOffset","intensity","applyGrayscaleEffect","HslAdjustmentFilter","KawaseBlurFilter","MotionBlurFilter","RadialBlurFilter","TiltShiftFilter","gradientBlur","startX","startY","endX","endY","numValue","ZoomBlurFilter","ColorGradientFilter","hexToInt","hex","intToHex","num","normalizeStopForFilter","hexStopFromFilter","a","stopsHex","colorStops","randomColor","str","dynamicMatch","indexStr","prop","ColorMapFilterClass","colorMapTexture","ColorReplaceFilter","originalColorValue","targetColorValue","MultiColorReplaceFilter","replacements","original","newReplacements","RGBSplitFilter","red","green","blue","AdvancedBloomFilter","AsciiFilter","replaceColor","BackdropBlurFilter","kernelSize","BevelFilter","lightColor","shadowColor","BloomFilter","strengthX","strengthY","resolution","BulgePinchFilter","computeBulgePadding","r","strength","scaledRadius","ConvolutionFilter","MATRICES","matrix","presetKey","currentMatrix","newMatrix","CrossHatchFilter","_params","DisplacementFilter","Sprite","Texture","mapUrl","mapTexture","j","displacementSprite","newTexture","EmbossFilter","GlitchFilter","FILL_MODES","redOffset","greenOffset","blueOffset","animationFrameId","animate","GlowFilter","GodrayFilter","SimpleLightmapFilter","textureType","alphaValue","lightMapTexture","updateCanvas","updateCtx","wasEnabled","NoiseFilter","OldFilmFilter","OutlineFilter","PixelateFilter","avgSize","currentSize","ReflectionFilter","ShockwaveFilter","center","amplitude","wavelength","speed","brightness","time","SimplexNoiseFilter","zOffset","currentTime","randomValue","TwistFilter","computeTwistPadding","radiusPx","buildTwistFilter","minEdge","normalizedRadius","hexToRgb","parsedHex","VignetteFilter","radiusFactor","effectiveStrength","initializeFilterRegistry","removedCount"],"mappings":"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"}
|