md-face-engine 1.0.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-BGSZMMvf.js","sources":["../src/core/filters/wrinkles.js","../src/core/filters/brightness.js","../src/core/filters/spots.js","../src/core/filters/acne.js","../src/core/filters/firmness.js","../src/core/filters/index.js","../src/core/config/FilterConfigManager.js","../src/core/webgl/buildWebglConfigForProduct.js","../src/license/token.js","../src/MartidermEngine.js","../src/client.js"],"sourcesContent":["export default {\n key: 'wrinkles',\n label: 'Arrugas',\n defaults: { intensity: 0.5, sigma: 4, brightness: 0 },\n deep: {\n smooth: { enabled: true, radius: 8, passes: 4, opacity: 0.7 },\n brightness: { enabled: true, value: 10 },\n contrast: { enabled: true, value: 1.03 },\n warmth: { enabled: true, rPlus: 8, bMinus: 5, alpha: 0.3 },\n toneUnify: { enabled: true, threshold: 12, mix: 0.4 },\n blemish: { enabled: true, microBlur: 3, alpha: 0.4 },\n contourLift: { enabled: true, lift: 0.06, shade: 0.04, feather: 20 }\n }\n}\n","export default {\n key: 'brightness',\n label: 'Luminosidad',\n defaults: { intensity: 0, sigma: 0, brightness: 0.07 },\n deep: {\n smooth: { enabled: true, radius: 5, passes: 3, opacity: 0.5 },\n brightness: { enabled: true, value: 18 },\n contrast: { enabled: true, value: 1.15 },\n warmth: { enabled: true, rPlus: 12, bMinus: 8, alpha: 0.45 },\n toneUnify: { enabled: true, threshold: 10, mix: 0.3 },\n blemish: { enabled: true, microBlur: 2, alpha: 0.3 },\n contourLift: { enabled: true, lift: 0.12, shade: 0.08, feather: 18 }\n }\n}\n","export default {\n key: 'spots',\n label: 'Manchas/Tono',\n defaults: { intensity: 0.65, sigma: 5, brightness: 0.05 },\n deep: {\n smooth: { enabled: true, radius: 6, passes: 3, opacity: 0.6 },\n brightness: { enabled: true, value: 12 },\n contrast: { enabled: true, value: 1.08 },\n warmth: { enabled: true, rPlus: 7, bMinus: 4, alpha: 0.3 },\n toneUnify: { enabled: true, threshold: 8, mix: 0.6 },\n blemish: { enabled: true, microBlur: 4, alpha: 0.5 },\n contourLift: { enabled: true, lift: 0.08, shade: 0.06, feather: 16 }\n }\n}\n","export default {\n key: 'acne',\n label: 'Acné',\n defaults: { intensity: 0.55, sigma: 3.4, brightness: 0.1 },\n deep: {\n smooth: { enabled: true, radius: 7, passes: 4, opacity: 0.65 },\n brightness: { enabled: true, value: 8 },\n contrast: { enabled: true, value: 1.02 },\n warmth: { enabled: true, rPlus: 6, bMinus: 3, alpha: 0.25 },\n toneUnify: { enabled: true, threshold: 10, mix: 0.5 },\n blemish: { enabled: true, microBlur: 5, alpha: 0.7 },\n contourLift: { enabled: true, lift: 0.06, shade: 0.04, feather: 20 }\n }\n}\n","export default {\n key: 'firmness',\n label: 'Firmeza',\n defaults: { intensity: 0.7, sigma: 2, brightness: 0 },\n deep: {\n smooth: { enabled: true, radius: 3, passes: 2, opacity: 0.3 },\n brightness: { enabled: true, value: 6 },\n contrast: { enabled: true, value: 1.12 },\n warmth: { enabled: true, rPlus: 5, bMinus: 3, alpha: 0.2 },\n toneUnify: { enabled: true, threshold: 18, mix: 0.2 },\n blemish: { enabled: false, microBlur: 1, alpha: 0.1 },\n contourLift: { enabled: true, lift: 0.15, shade: 0.12, feather: 12 }\n }\n}\n","import wrinkles from './wrinkles'\nimport brightness from './brightness'\nimport spots from './spots'\nimport acne from './acne'\nimport firmness from './firmness'\n\nexport const FILTERS = {\n wrinkles,\n brightness,\n spots,\n acne,\n firmness,\n}\n\nexport function getFilter(key) {\n return FILTERS[key] || null\n}\n\nexport const FILTER_ORDER = ['wrinkles','brightness','spots','acne','firmness']\n","/**\n * FilterConfigManager - Servicio para gestionar configuraciones de filtros por producto\n * \n * Funcionalidades:\n * - Almacenamiento persistente de configuraciones de filtros\n * - Gestión de configuraciones por producto\n * - Sistema de autenticación para administradores\n * - Backup y restauración de configuraciones\n * - Valores predeterminados para filtros\n */\n\n// Configuraciones predeterminadas para cada tipo de filtro (alineadas con beautyFilters)\nconst DEFAULT_FILTER_CONFIG = {\n // 1) Arrugas → Suavizado de piel\n smooth: {\n enabled: true,\n intensity: 36, // referencia visual\n radius: 4,\n passes: 2,\n opacity: 0.4\n },\n // 2) Piel apagada → Brillo\n brightness: {\n enabled: true,\n intensity: 91, // referencia visual\n value: 8\n },\n // Ajuste de contraste general\n contrast: {\n enabled: true,\n intensity: 10,\n value: 1.05\n },\n // Tono cálido / glow\n warmth: {\n enabled: true,\n intensity: 20,\n rPlus: 6,\n bMinus: 4,\n alpha: 0.25\n },\n // 2) Manchas → Unificar tono\n toneUnify: {\n enabled: true,\n intensity: 65, // referencia visual\n threshold: 15,\n mix: 0.25\n },\n // 5) Acné → Reducir imperfecciones\n blemish: {\n enabled: true,\n intensity: 35, // referencia visual\n microBlur: 2,\n alpha: 0.25\n },\n // 3) Firmeza → Lifting y contouring\n contourLift: {\n enabled: true,\n intensity: 24, // referencia visual\n lift: 0.08,\n shade: 0.06,\n feather: 15\n },\n // Extras\n highlights: {\n enabled: false,\n intensity: 10\n },\n shadows: {\n enabled: false,\n intensity: 5\n }\n};\n\n// Presets por preocupación de piel\nconst CONCERN_PRESETS = {\n arrugas: {\n smooth: { enabled: true, intensity: 36, radius: 6, passes: 3, opacity: 0.6 },\n contourLift: { enabled: true, intensity: 20, lift: 0.06, shade: 0.05, feather: 18 }\n },\n manchas: {\n toneUnify: { enabled: true, intensity: 65, threshold: 14, mix: 0.35 },\n brightness: { enabled: true, intensity: 20, value: 10 }\n },\n firmeza: {\n contourLift: { enabled: true, intensity: 24, lift: 0.08, shade: 0.06, feather: 20 },\n contrast: { enabled: true, intensity: 12, value: 1.07 }\n },\n luminosidad: {\n brightness: { enabled: true, intensity: 91, value: 12 },\n warmth: { enabled: true, intensity: 25, rPlus: 8, bMinus: 5, alpha: 0.3 }\n },\n acne: {\n blemish: { enabled: true, intensity: 35, microBlur: 3, alpha: 0.35 },\n toneUnify: { enabled: true, intensity: 40, threshold: 16, mix: 0.3 }\n }\n};\n\n// Configuraciones específicas por categoría de producto (usando categorías reales)\nconst CATEGORY_PRESETS = {\n // Antiaging: foco en arrugas y firmeza\n antiaging: {\n smooth: { enabled: true, intensity: 36, radius: 6, passes: 3, opacity: 0.6 },\n contourLift: { enabled: true, intensity: 24, lift: 0.07, shade: 0.05, feather: 18 },\n brightness: { enabled: true, intensity: 20, value: 10 },\n warmth: { enabled: true, intensity: 22, rPlus: 7, bMinus: 5, alpha: 0.28 }\n },\n // Manchas / pigmentación: foco en unificar tono y luminosidad\n manchas: {\n toneUnify: { enabled: true, intensity: 65, threshold: 14, mix: 0.35 },\n brightness: { enabled: true, intensity: 25, value: 10 },\n warmth: { enabled: false }\n },\n // Hidratación: suavizado ligero y glow moderado\n hidratacion: {\n smooth: { enabled: true, intensity: 25, radius: 3, passes: 2, opacity: 0.35 },\n brightness: { enabled: true, intensity: 18, value: 8 },\n warmth: { enabled: true, intensity: 15, rPlus: 5, bMinus: 3, alpha: 0.2 }\n },\n // Acné: foco en reducción de imperfecciones y tono uniforme\n acne: {\n blemish: { enabled: true, intensity: 35, microBlur: 3, alpha: 0.35 },\n toneUnify: { enabled: true, intensity: 40, threshold: 16, mix: 0.3 },\n brightness: { enabled: false }\n }\n};\n\nclass FilterConfigManager {\n constructor(options = {}) {\n this.storageKey = 'martiderm_filter_configs';\n this.authKey = 'martiderm_admin_auth';\n this.backupKey = 'martiderm_config_backup';\n this.products = Array.isArray(options.products) ? options.products : [];\n this.init();\n }\n\n /**\n * Inicializa el gestor de configuraciones\n */\n init() {\n // Verificar si existen configuraciones guardadas\n const savedConfigs = this.loadConfigurations();\n if ((!savedConfigs || Object.keys(savedConfigs).length === 0) && this.products.length > 0) {\n this.initializeDefaultConfigurations();\n }\n }\n\n setProducts(products = []) {\n this.products = Array.isArray(products) ? products : [];\n const savedConfigs = this.loadConfigurations();\n if ((!savedConfigs || Object.keys(savedConfigs).length === 0) && this.products.length > 0) {\n this.initializeDefaultConfigurations();\n }\n }\n\n /**\n * Inicializa configuraciones predeterminadas para todos los productos\n */\n initializeDefaultConfigurations() {\n try {\n const configs = {};\n this.products.forEach(product => {\n configs[product.id] = this.generateProductConfig(product);\n });\n this.saveConfigurations(configs);\n } catch (error) {\n console.error('Error inicializando configuraciones:', error);\n }\n }\n\n /**\n * Genera configuración específica para un producto\n */\n generateProductConfig(product) {\n const baseConfig = { ...DEFAULT_FILTER_CONFIG };\n const categoryPreset = CATEGORY_PRESETS[product.category];\n \n if (categoryPreset) {\n // Aplicar presets específicos de la categoría\n Object.keys(categoryPreset).forEach(filterType => {\n if (baseConfig[filterType]) {\n baseConfig[filterType] = {\n ...baseConfig[filterType],\n ...categoryPreset[filterType]\n };\n }\n });\n }\n\n // Aplicar presets por preocupaciones del producto (si existen)\n if (product.targetConcerns && Array.isArray(product.targetConcerns)) {\n product.targetConcerns.forEach(concern => {\n const preset = CONCERN_PRESETS[concern];\n if (preset) {\n Object.keys(preset).forEach(filterType => {\n if (baseConfig[filterType]) {\n baseConfig[filterType] = {\n ...baseConfig[filterType],\n ...preset[filterType]\n };\n }\n });\n }\n });\n }\n \n return {\n productId: product.id,\n productName: product.name,\n category: product.category,\n filters: baseConfig,\n lastModified: new Date().toISOString(),\n version: '1.0'\n };\n }\n\n /**\n * Obtiene la configuración de filtros para un producto específico\n */\n getProductConfig(productId) {\n const configs = this.loadConfigurations();\n return configs[productId] || null;\n }\n\n /**\n * Guarda la configuración de filtros para un producto\n */\n saveProductConfig(productId, config) {\n const configs = this.loadConfigurations();\n configs[productId] = {\n ...config,\n lastModified: new Date().toISOString()\n };\n this.saveConfigurations(configs);\n return true;\n }\n\n /**\n * Obtiene todas las configuraciones\n */\n getAllConfigurations() {\n return this.loadConfigurations();\n }\n\n /**\n * Carga configuraciones desde localStorage\n */\n loadConfigurations() {\n try {\n const saved = localStorage.getItem(this.storageKey);\n return saved ? JSON.parse(saved) : {};\n } catch (error) {\n console.error('Error cargando configuraciones:', error);\n return {};\n }\n }\n\n /**\n * Guarda configuraciones en localStorage\n */\n saveConfigurations(configs) {\n try {\n localStorage.setItem(this.storageKey, JSON.stringify(configs));\n // Crear backup automático\n this.createBackup(configs);\n return true;\n } catch (error) {\n console.error('Error guardando configuraciones:', error);\n return false;\n }\n }\n\n /**\n * Crea un backup de las configuraciones\n */\n createBackup(configs = null) {\n try {\n const configsToBackup = configs || this.loadConfigurations();\n const backup = {\n timestamp: new Date().toISOString(),\n configurations: configsToBackup,\n version: '1.0'\n };\n localStorage.setItem(this.backupKey, JSON.stringify(backup));\n return true;\n } catch (error) {\n console.error('Error creando backup:', error);\n return false;\n }\n }\n\n /**\n * Restaura configuraciones desde backup\n */\n restoreFromBackup() {\n try {\n const backup = localStorage.getItem(this.backupKey);\n if (backup) {\n const backupData = JSON.parse(backup);\n this.saveConfigurations(backupData.configurations);\n return true;\n }\n return false;\n } catch (error) {\n console.error('Error restaurando backup:', error);\n return false;\n }\n }\n\n /**\n * Exporta configuraciones para descarga\n */\n exportConfigurations() {\n const configs = this.loadConfigurations();\n const exportData = {\n timestamp: new Date().toISOString(),\n configurations: configs,\n version: '1.0'\n };\n return JSON.stringify(exportData, null, 2);\n }\n\n /**\n * Importa configuraciones desde archivo\n */\n importConfigurations(jsonData) {\n try {\n const importData = JSON.parse(jsonData);\n if (importData.configurations) {\n this.saveConfigurations(importData.configurations);\n return true;\n }\n return false;\n } catch (error) {\n console.error('Error importando configuraciones:', error);\n return false;\n }\n }\n\n /**\n * Resetea configuraciones a valores predeterminados\n */\n resetToDefaults() {\n try {\n localStorage.removeItem(this.storageKey);\n this.initializeDefaultConfigurations();\n return true;\n } catch (error) {\n console.error('Error reseteando configuraciones:', error);\n return false;\n }\n }\n\n /**\n * Estado de autenticación del administrador\n */\n isAuthenticated() {\n try {\n const raw = localStorage.getItem(this.authKey);\n if (!raw) return false;\n const data = JSON.parse(raw);\n return !!data?.authenticated;\n } catch (e) {\n return false;\n }\n }\n\n /**\n * Autentica al administrador con credenciales simples de demo\n */\n authenticateAdmin(username, password) {\n // Credenciales de prueba visibles en AdminAuth\n const validUser = username === 'admin';\n const validPass = password === 'martiderm2024';\n if (validUser && validPass) {\n const session = {\n authenticated: true,\n username,\n token: `adm-${Date.now()}`,\n lastLogin: new Date().toISOString()\n };\n localStorage.setItem(this.authKey, JSON.stringify(session));\n return { success: true, username };\n }\n return { success: false, error: 'Credenciales inválidas' };\n }\n\n /**\n * Obtiene información del usuario autenticado\n */\n getAuthenticatedUser() {\n try {\n const raw = localStorage.getItem(this.authKey);\n if (!raw) return null;\n const data = JSON.parse(raw);\n if (data?.authenticated) {\n return { username: data.username };\n }\n return null;\n } catch (e) {\n return null;\n }\n }\n\n /**\n * Cierra sesión del administrador\n */\n logout() {\n try {\n localStorage.removeItem(this.authKey);\n return true;\n } catch (e) {\n return false;\n }\n }\n\n /**\n * Compatibilidad: método singular usado por AdminPanel\n */\n exportConfiguration() {\n return this.exportConfigurations();\n }\n}\n\nexport default new FilterConfigManager();\n\n// Exportar también la clase para testing\nexport { FilterConfigManager, DEFAULT_FILTER_CONFIG, CATEGORY_PRESETS };\n","import { FILTERS } from '../filters/index.js';\nimport filterConfigManager from '../config/FilterConfigManager.js';\n\nexport function buildWebglConfigForProduct(product) {\n const pc = filterConfigManager.getProductConfig(product.id) || {};\n const lockedType = product.filterType || (pc.webglConfig && pc.webglConfig.filterType) || 'wrinkles';\n const defaults = (FILTERS[lockedType] && FILTERS[lockedType].defaults) || { intensity: 0.5, sigma: 4, brightness: 0 };\n const deep = (FILTERS[lockedType] && FILTERS[lockedType].deep) || {};\n const base = {\n filterType: lockedType,\n intensity: (product.defaultIntensity !== undefined) ? product.defaultIntensity : defaults.intensity,\n sigma: (product.defaultSigma !== undefined) ? product.defaultSigma : defaults.sigma,\n brightness: (product.defaultBrightness !== undefined) ? product.defaultBrightness : defaults.brightness,\n contrast: typeof deep.contrast?.value === 'number' ? deep.contrast.value : 1.0,\n warmthR: typeof deep.warmth?.rPlus === 'number' ? deep.warmth.rPlus : 0,\n warmthB: typeof deep.warmth?.bMinus === 'number' ? deep.warmth.bMinus : 0,\n warmthA: typeof deep.warmth?.alpha === 'number' ? deep.warmth.alpha : 0,\n };\n const adminCfg = pc.webglConfig || {};\n return { ...base, ...adminCfg, filterType: lockedType };\n}\n\nexport default buildWebglConfigForProduct;\n","const TOKEN_PREFIX = 'mdfe_';\nconst PRODUCT_CODE = 'md-face-engine';\nconst LICENSE_SECRET = 'md-face-engine-license-v1';\n\nfunction hashToken(value) {\n let hash = 5381;\n for (let i = 0; i < value.length; i += 1) {\n hash = ((hash << 5) + hash) + value.charCodeAt(i);\n hash &= 0xffffffff;\n }\n return (hash >>> 0).toString(16).padStart(8, '0');\n}\n\nfunction decodeBase64Url(value) {\n const normalized = value.replace(/-/g, '+').replace(/_/g, '/');\n const padding = normalized.length % 4;\n const padded = padding ? normalized + '='.repeat(4 - padding) : normalized;\n return atob(padded);\n}\n\nexport function validateLicenseToken(token, options = {}) {\n const { now = Date.now() } = options;\n\n if (!token || typeof token !== 'string') {\n return { valid: false, reason: 'Token vacío o inválido' };\n }\n\n if (!token.startsWith(TOKEN_PREFIX)) {\n return { valid: false, reason: 'Prefijo de token inválido' };\n }\n\n const raw = token.slice(TOKEN_PREFIX.length);\n const parts = raw.split('.');\n if (parts.length !== 2) {\n return { valid: false, reason: 'Formato de token inválido' };\n }\n\n const [payloadPart, signature] = parts;\n const expected = hashToken(`${payloadPart}.${LICENSE_SECRET}`);\n if (signature !== expected) {\n return { valid: false, reason: 'Firma de licencia inválida' };\n }\n\n let payload;\n try {\n payload = JSON.parse(decodeBase64Url(payloadPart));\n } catch (_err) {\n return { valid: false, reason: 'Payload de licencia inválido' };\n }\n\n if (payload.productCode !== PRODUCT_CODE) {\n return { valid: false, reason: 'Licencia de otro producto' };\n }\n\n if (typeof payload.exp !== 'number' || payload.exp < now) {\n return { valid: false, reason: 'Licencia vencida' };\n }\n\n return { valid: true, reason: null, payload };\n}\n\nexport { TOKEN_PREFIX, PRODUCT_CODE };\n","import { FILTERS, FILTER_ORDER, getFilter, filterConfigManager, buildWebglConfigForProduct } from './core/index.js';\nimport { validateLicenseToken, PRODUCT_CODE } from './license/token.js';\n\nexport class MdFaceEngine {\n constructor() {\n this.license = null;\n this.activated = false;\n }\n\n activate(token) {\n const result = validateLicenseToken(token);\n\n if (!result.valid) {\n this.license = null;\n this.activated = false;\n throw new Error(`Licencia inválida: ${result.reason}`);\n }\n\n this.license = result.payload;\n this.activated = true;\n return result.payload;\n }\n\n isActivated() {\n return this.activated;\n }\n\n assertActivated() {\n if (!this.activated) {\n throw new Error('md-face-engine no está activado. Configura VITE_MD_FACE_ENGINE_TOKEN.');\n }\n }\n\n getLicense() {\n this.assertActivated();\n return this.license;\n }\n\n getProductCode() {\n return PRODUCT_CODE;\n }\n\n getFilterRegistry() {\n this.assertActivated();\n return FILTERS;\n }\n\n getFilterOrder() {\n this.assertActivated();\n return FILTER_ORDER;\n }\n\n getFilter(key) {\n this.assertActivated();\n return getFilter(key);\n }\n\n getFilterConfigManager() {\n this.assertActivated();\n return filterConfigManager;\n }\n\n buildWebglConfigForProduct(product) {\n this.assertActivated();\n return buildWebglConfigForProduct(product);\n }\n}\n\nexport { MdFaceEngine as MartidermEngine };\nexport default MdFaceEngine;\n","import MdFaceEngine from './MartidermEngine.js';\n\nexport function createMdFaceEngineClient({ token, products = [] } = {}) {\n if (!token) {\n throw new Error('Falta token de licencia para activar md-face-engine.');\n }\n\n const engine = new MdFaceEngine();\n engine.activate(token);\n engine.assertActivated();\n\n const filterConfigManager = engine.getFilterConfigManager();\n if (Array.isArray(products)) {\n filterConfigManager.setProducts(products);\n }\n\n return {\n engine,\n FILTERS: engine.getFilterRegistry(),\n FILTER_ORDER: engine.getFilterOrder(),\n getFilter: (key) => engine.getFilter(key),\n filterConfigManager,\n buildWebglConfigForProduct: (product) => engine.buildWebglConfigForProduct(product)\n };\n}\n"],"names":["filterConfigManager"],"mappings":"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"}
@@ -0,0 +1,619 @@
1
+ "use strict";
2
+ const wrinkles = {
3
+ key: "wrinkles",
4
+ label: "Arrugas",
5
+ defaults: { intensity: 0.5, sigma: 4, brightness: 0 },
6
+ deep: {
7
+ smooth: { enabled: true, radius: 8, passes: 4, opacity: 0.7 },
8
+ brightness: { enabled: true, value: 10 },
9
+ contrast: { enabled: true, value: 1.03 },
10
+ warmth: { enabled: true, rPlus: 8, bMinus: 5, alpha: 0.3 },
11
+ toneUnify: { enabled: true, threshold: 12, mix: 0.4 },
12
+ blemish: { enabled: true, microBlur: 3, alpha: 0.4 },
13
+ contourLift: { enabled: true, lift: 0.06, shade: 0.04, feather: 20 }
14
+ }
15
+ };
16
+ const brightness = {
17
+ key: "brightness",
18
+ label: "Luminosidad",
19
+ defaults: { intensity: 0, sigma: 0, brightness: 0.07 },
20
+ deep: {
21
+ smooth: { enabled: true, radius: 5, passes: 3, opacity: 0.5 },
22
+ brightness: { enabled: true, value: 18 },
23
+ contrast: { enabled: true, value: 1.15 },
24
+ warmth: { enabled: true, rPlus: 12, bMinus: 8, alpha: 0.45 },
25
+ toneUnify: { enabled: true, threshold: 10, mix: 0.3 },
26
+ blemish: { enabled: true, microBlur: 2, alpha: 0.3 },
27
+ contourLift: { enabled: true, lift: 0.12, shade: 0.08, feather: 18 }
28
+ }
29
+ };
30
+ const spots = {
31
+ key: "spots",
32
+ label: "Manchas/Tono",
33
+ defaults: { intensity: 0.65, sigma: 5, brightness: 0.05 },
34
+ deep: {
35
+ smooth: { enabled: true, radius: 6, passes: 3, opacity: 0.6 },
36
+ brightness: { enabled: true, value: 12 },
37
+ contrast: { enabled: true, value: 1.08 },
38
+ warmth: { enabled: true, rPlus: 7, bMinus: 4, alpha: 0.3 },
39
+ toneUnify: { enabled: true, threshold: 8, mix: 0.6 },
40
+ blemish: { enabled: true, microBlur: 4, alpha: 0.5 },
41
+ contourLift: { enabled: true, lift: 0.08, shade: 0.06, feather: 16 }
42
+ }
43
+ };
44
+ const acne = {
45
+ key: "acne",
46
+ label: "Acné",
47
+ defaults: { intensity: 0.55, sigma: 3.4, brightness: 0.1 },
48
+ deep: {
49
+ smooth: { enabled: true, radius: 7, passes: 4, opacity: 0.65 },
50
+ brightness: { enabled: true, value: 8 },
51
+ contrast: { enabled: true, value: 1.02 },
52
+ warmth: { enabled: true, rPlus: 6, bMinus: 3, alpha: 0.25 },
53
+ toneUnify: { enabled: true, threshold: 10, mix: 0.5 },
54
+ blemish: { enabled: true, microBlur: 5, alpha: 0.7 },
55
+ contourLift: { enabled: true, lift: 0.06, shade: 0.04, feather: 20 }
56
+ }
57
+ };
58
+ const firmness = {
59
+ key: "firmness",
60
+ label: "Firmeza",
61
+ defaults: { intensity: 0.7, sigma: 2, brightness: 0 },
62
+ deep: {
63
+ smooth: { enabled: true, radius: 3, passes: 2, opacity: 0.3 },
64
+ brightness: { enabled: true, value: 6 },
65
+ contrast: { enabled: true, value: 1.12 },
66
+ warmth: { enabled: true, rPlus: 5, bMinus: 3, alpha: 0.2 },
67
+ toneUnify: { enabled: true, threshold: 18, mix: 0.2 },
68
+ blemish: { enabled: false, microBlur: 1, alpha: 0.1 },
69
+ contourLift: { enabled: true, lift: 0.15, shade: 0.12, feather: 12 }
70
+ }
71
+ };
72
+ const FILTERS = {
73
+ wrinkles,
74
+ brightness,
75
+ spots,
76
+ acne,
77
+ firmness
78
+ };
79
+ function getFilter(key) {
80
+ return FILTERS[key] || null;
81
+ }
82
+ const FILTER_ORDER = ["wrinkles", "brightness", "spots", "acne", "firmness"];
83
+ const DEFAULT_FILTER_CONFIG = {
84
+ // 1) Arrugas → Suavizado de piel
85
+ smooth: {
86
+ enabled: true,
87
+ intensity: 36,
88
+ // referencia visual
89
+ radius: 4,
90
+ passes: 2,
91
+ opacity: 0.4
92
+ },
93
+ // 2) Piel apagada → Brillo
94
+ brightness: {
95
+ enabled: true,
96
+ intensity: 91,
97
+ // referencia visual
98
+ value: 8
99
+ },
100
+ // Ajuste de contraste general
101
+ contrast: {
102
+ enabled: true,
103
+ intensity: 10,
104
+ value: 1.05
105
+ },
106
+ // Tono cálido / glow
107
+ warmth: {
108
+ enabled: true,
109
+ intensity: 20,
110
+ rPlus: 6,
111
+ bMinus: 4,
112
+ alpha: 0.25
113
+ },
114
+ // 2) Manchas → Unificar tono
115
+ toneUnify: {
116
+ enabled: true,
117
+ intensity: 65,
118
+ // referencia visual
119
+ threshold: 15,
120
+ mix: 0.25
121
+ },
122
+ // 5) Acné → Reducir imperfecciones
123
+ blemish: {
124
+ enabled: true,
125
+ intensity: 35,
126
+ // referencia visual
127
+ microBlur: 2,
128
+ alpha: 0.25
129
+ },
130
+ // 3) Firmeza → Lifting y contouring
131
+ contourLift: {
132
+ enabled: true,
133
+ intensity: 24,
134
+ // referencia visual
135
+ lift: 0.08,
136
+ shade: 0.06,
137
+ feather: 15
138
+ },
139
+ // Extras
140
+ highlights: {
141
+ enabled: false,
142
+ intensity: 10
143
+ },
144
+ shadows: {
145
+ enabled: false,
146
+ intensity: 5
147
+ }
148
+ };
149
+ const CONCERN_PRESETS = {
150
+ arrugas: {
151
+ smooth: { enabled: true, intensity: 36, radius: 6, passes: 3, opacity: 0.6 },
152
+ contourLift: { enabled: true, intensity: 20, lift: 0.06, shade: 0.05, feather: 18 }
153
+ },
154
+ manchas: {
155
+ toneUnify: { enabled: true, intensity: 65, threshold: 14, mix: 0.35 },
156
+ brightness: { enabled: true, intensity: 20, value: 10 }
157
+ },
158
+ firmeza: {
159
+ contourLift: { enabled: true, intensity: 24, lift: 0.08, shade: 0.06, feather: 20 },
160
+ contrast: { enabled: true, intensity: 12, value: 1.07 }
161
+ },
162
+ luminosidad: {
163
+ brightness: { enabled: true, intensity: 91, value: 12 },
164
+ warmth: { enabled: true, intensity: 25, rPlus: 8, bMinus: 5, alpha: 0.3 }
165
+ },
166
+ acne: {
167
+ blemish: { enabled: true, intensity: 35, microBlur: 3, alpha: 0.35 },
168
+ toneUnify: { enabled: true, intensity: 40, threshold: 16, mix: 0.3 }
169
+ }
170
+ };
171
+ const CATEGORY_PRESETS = {
172
+ // Antiaging: foco en arrugas y firmeza
173
+ antiaging: {
174
+ smooth: { enabled: true, intensity: 36, radius: 6, passes: 3, opacity: 0.6 },
175
+ contourLift: { enabled: true, intensity: 24, lift: 0.07, shade: 0.05, feather: 18 },
176
+ brightness: { enabled: true, intensity: 20, value: 10 },
177
+ warmth: { enabled: true, intensity: 22, rPlus: 7, bMinus: 5, alpha: 0.28 }
178
+ },
179
+ // Manchas / pigmentación: foco en unificar tono y luminosidad
180
+ manchas: {
181
+ toneUnify: { enabled: true, intensity: 65, threshold: 14, mix: 0.35 },
182
+ brightness: { enabled: true, intensity: 25, value: 10 },
183
+ warmth: { enabled: false }
184
+ },
185
+ // Hidratación: suavizado ligero y glow moderado
186
+ hidratacion: {
187
+ smooth: { enabled: true, intensity: 25, radius: 3, passes: 2, opacity: 0.35 },
188
+ brightness: { enabled: true, intensity: 18, value: 8 },
189
+ warmth: { enabled: true, intensity: 15, rPlus: 5, bMinus: 3, alpha: 0.2 }
190
+ },
191
+ // Acné: foco en reducción de imperfecciones y tono uniforme
192
+ acne: {
193
+ blemish: { enabled: true, intensity: 35, microBlur: 3, alpha: 0.35 },
194
+ toneUnify: { enabled: true, intensity: 40, threshold: 16, mix: 0.3 },
195
+ brightness: { enabled: false }
196
+ }
197
+ };
198
+ class FilterConfigManager {
199
+ constructor(options = {}) {
200
+ this.storageKey = "martiderm_filter_configs";
201
+ this.authKey = "martiderm_admin_auth";
202
+ this.backupKey = "martiderm_config_backup";
203
+ this.products = Array.isArray(options.products) ? options.products : [];
204
+ this.init();
205
+ }
206
+ /**
207
+ * Inicializa el gestor de configuraciones
208
+ */
209
+ init() {
210
+ const savedConfigs = this.loadConfigurations();
211
+ if ((!savedConfigs || Object.keys(savedConfigs).length === 0) && this.products.length > 0) {
212
+ this.initializeDefaultConfigurations();
213
+ }
214
+ }
215
+ setProducts(products = []) {
216
+ this.products = Array.isArray(products) ? products : [];
217
+ const savedConfigs = this.loadConfigurations();
218
+ if ((!savedConfigs || Object.keys(savedConfigs).length === 0) && this.products.length > 0) {
219
+ this.initializeDefaultConfigurations();
220
+ }
221
+ }
222
+ /**
223
+ * Inicializa configuraciones predeterminadas para todos los productos
224
+ */
225
+ initializeDefaultConfigurations() {
226
+ try {
227
+ const configs = {};
228
+ this.products.forEach((product) => {
229
+ configs[product.id] = this.generateProductConfig(product);
230
+ });
231
+ this.saveConfigurations(configs);
232
+ } catch (error) {
233
+ console.error("Error inicializando configuraciones:", error);
234
+ }
235
+ }
236
+ /**
237
+ * Genera configuración específica para un producto
238
+ */
239
+ generateProductConfig(product) {
240
+ const baseConfig = { ...DEFAULT_FILTER_CONFIG };
241
+ const categoryPreset = CATEGORY_PRESETS[product.category];
242
+ if (categoryPreset) {
243
+ Object.keys(categoryPreset).forEach((filterType) => {
244
+ if (baseConfig[filterType]) {
245
+ baseConfig[filterType] = {
246
+ ...baseConfig[filterType],
247
+ ...categoryPreset[filterType]
248
+ };
249
+ }
250
+ });
251
+ }
252
+ if (product.targetConcerns && Array.isArray(product.targetConcerns)) {
253
+ product.targetConcerns.forEach((concern) => {
254
+ const preset = CONCERN_PRESETS[concern];
255
+ if (preset) {
256
+ Object.keys(preset).forEach((filterType) => {
257
+ if (baseConfig[filterType]) {
258
+ baseConfig[filterType] = {
259
+ ...baseConfig[filterType],
260
+ ...preset[filterType]
261
+ };
262
+ }
263
+ });
264
+ }
265
+ });
266
+ }
267
+ return {
268
+ productId: product.id,
269
+ productName: product.name,
270
+ category: product.category,
271
+ filters: baseConfig,
272
+ lastModified: (/* @__PURE__ */ new Date()).toISOString(),
273
+ version: "1.0"
274
+ };
275
+ }
276
+ /**
277
+ * Obtiene la configuración de filtros para un producto específico
278
+ */
279
+ getProductConfig(productId) {
280
+ const configs = this.loadConfigurations();
281
+ return configs[productId] || null;
282
+ }
283
+ /**
284
+ * Guarda la configuración de filtros para un producto
285
+ */
286
+ saveProductConfig(productId, config) {
287
+ const configs = this.loadConfigurations();
288
+ configs[productId] = {
289
+ ...config,
290
+ lastModified: (/* @__PURE__ */ new Date()).toISOString()
291
+ };
292
+ this.saveConfigurations(configs);
293
+ return true;
294
+ }
295
+ /**
296
+ * Obtiene todas las configuraciones
297
+ */
298
+ getAllConfigurations() {
299
+ return this.loadConfigurations();
300
+ }
301
+ /**
302
+ * Carga configuraciones desde localStorage
303
+ */
304
+ loadConfigurations() {
305
+ try {
306
+ const saved = localStorage.getItem(this.storageKey);
307
+ return saved ? JSON.parse(saved) : {};
308
+ } catch (error) {
309
+ console.error("Error cargando configuraciones:", error);
310
+ return {};
311
+ }
312
+ }
313
+ /**
314
+ * Guarda configuraciones en localStorage
315
+ */
316
+ saveConfigurations(configs) {
317
+ try {
318
+ localStorage.setItem(this.storageKey, JSON.stringify(configs));
319
+ this.createBackup(configs);
320
+ return true;
321
+ } catch (error) {
322
+ console.error("Error guardando configuraciones:", error);
323
+ return false;
324
+ }
325
+ }
326
+ /**
327
+ * Crea un backup de las configuraciones
328
+ */
329
+ createBackup(configs = null) {
330
+ try {
331
+ const configsToBackup = configs || this.loadConfigurations();
332
+ const backup = {
333
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
334
+ configurations: configsToBackup,
335
+ version: "1.0"
336
+ };
337
+ localStorage.setItem(this.backupKey, JSON.stringify(backup));
338
+ return true;
339
+ } catch (error) {
340
+ console.error("Error creando backup:", error);
341
+ return false;
342
+ }
343
+ }
344
+ /**
345
+ * Restaura configuraciones desde backup
346
+ */
347
+ restoreFromBackup() {
348
+ try {
349
+ const backup = localStorage.getItem(this.backupKey);
350
+ if (backup) {
351
+ const backupData = JSON.parse(backup);
352
+ this.saveConfigurations(backupData.configurations);
353
+ return true;
354
+ }
355
+ return false;
356
+ } catch (error) {
357
+ console.error("Error restaurando backup:", error);
358
+ return false;
359
+ }
360
+ }
361
+ /**
362
+ * Exporta configuraciones para descarga
363
+ */
364
+ exportConfigurations() {
365
+ const configs = this.loadConfigurations();
366
+ const exportData = {
367
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
368
+ configurations: configs,
369
+ version: "1.0"
370
+ };
371
+ return JSON.stringify(exportData, null, 2);
372
+ }
373
+ /**
374
+ * Importa configuraciones desde archivo
375
+ */
376
+ importConfigurations(jsonData) {
377
+ try {
378
+ const importData = JSON.parse(jsonData);
379
+ if (importData.configurations) {
380
+ this.saveConfigurations(importData.configurations);
381
+ return true;
382
+ }
383
+ return false;
384
+ } catch (error) {
385
+ console.error("Error importando configuraciones:", error);
386
+ return false;
387
+ }
388
+ }
389
+ /**
390
+ * Resetea configuraciones a valores predeterminados
391
+ */
392
+ resetToDefaults() {
393
+ try {
394
+ localStorage.removeItem(this.storageKey);
395
+ this.initializeDefaultConfigurations();
396
+ return true;
397
+ } catch (error) {
398
+ console.error("Error reseteando configuraciones:", error);
399
+ return false;
400
+ }
401
+ }
402
+ /**
403
+ * Estado de autenticación del administrador
404
+ */
405
+ isAuthenticated() {
406
+ try {
407
+ const raw = localStorage.getItem(this.authKey);
408
+ if (!raw) return false;
409
+ const data = JSON.parse(raw);
410
+ return !!(data == null ? void 0 : data.authenticated);
411
+ } catch (e) {
412
+ return false;
413
+ }
414
+ }
415
+ /**
416
+ * Autentica al administrador con credenciales simples de demo
417
+ */
418
+ authenticateAdmin(username, password) {
419
+ const validUser = username === "admin";
420
+ const validPass = password === "martiderm2024";
421
+ if (validUser && validPass) {
422
+ const session = {
423
+ authenticated: true,
424
+ username,
425
+ token: `adm-${Date.now()}`,
426
+ lastLogin: (/* @__PURE__ */ new Date()).toISOString()
427
+ };
428
+ localStorage.setItem(this.authKey, JSON.stringify(session));
429
+ return { success: true, username };
430
+ }
431
+ return { success: false, error: "Credenciales inválidas" };
432
+ }
433
+ /**
434
+ * Obtiene información del usuario autenticado
435
+ */
436
+ getAuthenticatedUser() {
437
+ try {
438
+ const raw = localStorage.getItem(this.authKey);
439
+ if (!raw) return null;
440
+ const data = JSON.parse(raw);
441
+ if (data == null ? void 0 : data.authenticated) {
442
+ return { username: data.username };
443
+ }
444
+ return null;
445
+ } catch (e) {
446
+ return null;
447
+ }
448
+ }
449
+ /**
450
+ * Cierra sesión del administrador
451
+ */
452
+ logout() {
453
+ try {
454
+ localStorage.removeItem(this.authKey);
455
+ return true;
456
+ } catch (e) {
457
+ return false;
458
+ }
459
+ }
460
+ /**
461
+ * Compatibilidad: método singular usado por AdminPanel
462
+ */
463
+ exportConfiguration() {
464
+ return this.exportConfigurations();
465
+ }
466
+ }
467
+ const filterConfigManager = new FilterConfigManager();
468
+ function buildWebglConfigForProduct(product) {
469
+ var _a, _b, _c, _d;
470
+ const pc = filterConfigManager.getProductConfig(product.id) || {};
471
+ const lockedType = product.filterType || pc.webglConfig && pc.webglConfig.filterType || "wrinkles";
472
+ const defaults = FILTERS[lockedType] && FILTERS[lockedType].defaults || { intensity: 0.5, sigma: 4, brightness: 0 };
473
+ const deep = FILTERS[lockedType] && FILTERS[lockedType].deep || {};
474
+ const base = {
475
+ filterType: lockedType,
476
+ intensity: product.defaultIntensity !== void 0 ? product.defaultIntensity : defaults.intensity,
477
+ sigma: product.defaultSigma !== void 0 ? product.defaultSigma : defaults.sigma,
478
+ brightness: product.defaultBrightness !== void 0 ? product.defaultBrightness : defaults.brightness,
479
+ contrast: typeof ((_a = deep.contrast) == null ? void 0 : _a.value) === "number" ? deep.contrast.value : 1,
480
+ warmthR: typeof ((_b = deep.warmth) == null ? void 0 : _b.rPlus) === "number" ? deep.warmth.rPlus : 0,
481
+ warmthB: typeof ((_c = deep.warmth) == null ? void 0 : _c.bMinus) === "number" ? deep.warmth.bMinus : 0,
482
+ warmthA: typeof ((_d = deep.warmth) == null ? void 0 : _d.alpha) === "number" ? deep.warmth.alpha : 0
483
+ };
484
+ const adminCfg = pc.webglConfig || {};
485
+ return { ...base, ...adminCfg, filterType: lockedType };
486
+ }
487
+ const TOKEN_PREFIX = "mdfe_";
488
+ const PRODUCT_CODE = "md-face-engine";
489
+ const LICENSE_SECRET = "md-face-engine-license-v1";
490
+ function hashToken(value) {
491
+ let hash = 5381;
492
+ for (let i = 0; i < value.length; i += 1) {
493
+ hash = (hash << 5) + hash + value.charCodeAt(i);
494
+ hash &= 4294967295;
495
+ }
496
+ return (hash >>> 0).toString(16).padStart(8, "0");
497
+ }
498
+ function decodeBase64Url(value) {
499
+ const normalized = value.replace(/-/g, "+").replace(/_/g, "/");
500
+ const padding = normalized.length % 4;
501
+ const padded = padding ? normalized + "=".repeat(4 - padding) : normalized;
502
+ return atob(padded);
503
+ }
504
+ function validateLicenseToken(token, options = {}) {
505
+ const { now = Date.now() } = options;
506
+ if (!token || typeof token !== "string") {
507
+ return { valid: false, reason: "Token vacío o inválido" };
508
+ }
509
+ if (!token.startsWith(TOKEN_PREFIX)) {
510
+ return { valid: false, reason: "Prefijo de token inválido" };
511
+ }
512
+ const raw = token.slice(TOKEN_PREFIX.length);
513
+ const parts = raw.split(".");
514
+ if (parts.length !== 2) {
515
+ return { valid: false, reason: "Formato de token inválido" };
516
+ }
517
+ const [payloadPart, signature] = parts;
518
+ const expected = hashToken(`${payloadPart}.${LICENSE_SECRET}`);
519
+ if (signature !== expected) {
520
+ return { valid: false, reason: "Firma de licencia inválida" };
521
+ }
522
+ let payload;
523
+ try {
524
+ payload = JSON.parse(decodeBase64Url(payloadPart));
525
+ } catch (_err) {
526
+ return { valid: false, reason: "Payload de licencia inválido" };
527
+ }
528
+ if (payload.productCode !== PRODUCT_CODE) {
529
+ return { valid: false, reason: "Licencia de otro producto" };
530
+ }
531
+ if (typeof payload.exp !== "number" || payload.exp < now) {
532
+ return { valid: false, reason: "Licencia vencida" };
533
+ }
534
+ return { valid: true, reason: null, payload };
535
+ }
536
+ class MdFaceEngine {
537
+ constructor() {
538
+ this.license = null;
539
+ this.activated = false;
540
+ }
541
+ activate(token) {
542
+ const result = validateLicenseToken(token);
543
+ if (!result.valid) {
544
+ this.license = null;
545
+ this.activated = false;
546
+ throw new Error(`Licencia inválida: ${result.reason}`);
547
+ }
548
+ this.license = result.payload;
549
+ this.activated = true;
550
+ return result.payload;
551
+ }
552
+ isActivated() {
553
+ return this.activated;
554
+ }
555
+ assertActivated() {
556
+ if (!this.activated) {
557
+ throw new Error("md-face-engine no está activado. Configura VITE_MD_FACE_ENGINE_TOKEN.");
558
+ }
559
+ }
560
+ getLicense() {
561
+ this.assertActivated();
562
+ return this.license;
563
+ }
564
+ getProductCode() {
565
+ return PRODUCT_CODE;
566
+ }
567
+ getFilterRegistry() {
568
+ this.assertActivated();
569
+ return FILTERS;
570
+ }
571
+ getFilterOrder() {
572
+ this.assertActivated();
573
+ return FILTER_ORDER;
574
+ }
575
+ getFilter(key) {
576
+ this.assertActivated();
577
+ return getFilter(key);
578
+ }
579
+ getFilterConfigManager() {
580
+ this.assertActivated();
581
+ return filterConfigManager;
582
+ }
583
+ buildWebglConfigForProduct(product) {
584
+ this.assertActivated();
585
+ return buildWebglConfigForProduct(product);
586
+ }
587
+ }
588
+ function createMdFaceEngineClient({ token, products = [] } = {}) {
589
+ if (!token) {
590
+ throw new Error("Falta token de licencia para activar md-face-engine.");
591
+ }
592
+ const engine = new MdFaceEngine();
593
+ engine.activate(token);
594
+ engine.assertActivated();
595
+ const filterConfigManager2 = engine.getFilterConfigManager();
596
+ if (Array.isArray(products)) {
597
+ filterConfigManager2.setProducts(products);
598
+ }
599
+ return {
600
+ engine,
601
+ FILTERS: engine.getFilterRegistry(),
602
+ FILTER_ORDER: engine.getFilterOrder(),
603
+ getFilter: (key) => engine.getFilter(key),
604
+ filterConfigManager: filterConfigManager2,
605
+ buildWebglConfigForProduct: (product) => engine.buildWebglConfigForProduct(product)
606
+ };
607
+ }
608
+ exports.CATEGORY_PRESETS = CATEGORY_PRESETS;
609
+ exports.DEFAULT_FILTER_CONFIG = DEFAULT_FILTER_CONFIG;
610
+ exports.FILTERS = FILTERS;
611
+ exports.FILTER_ORDER = FILTER_ORDER;
612
+ exports.FilterConfigManager = FilterConfigManager;
613
+ exports.MdFaceEngine = MdFaceEngine;
614
+ exports.buildWebglConfigForProduct = buildWebglConfigForProduct;
615
+ exports.createMdFaceEngineClient = createMdFaceEngineClient;
616
+ exports.filterConfigManager = filterConfigManager;
617
+ exports.getFilter = getFilter;
618
+ exports.validateLicenseToken = validateLicenseToken;
619
+ //# sourceMappingURL=client-DimGdJ4Y.cjs.map