(function () { var scriptFile = new File($.fileName); var scriptDir = scriptFile.parent.fsName.replace(/\\/g, "/"); $.global.PRLB_SCRIPT_DIR = scriptDir; function labT(key, fallback) { if (typeof i18n !== "undefined" && i18n && typeof i18n.t === "function") { var translated = i18n.t(key); if (translated && translated !== key) { return translated; } } return fallback || key; } function labF(key, params, fallback) { var message = labT(key, fallback || key); if (!params) return message; for (var name in params) { if (params.hasOwnProperty(name)) { var token = "{" + name + "}"; var value = String(params[name]); while (message.indexOf(token) !== -1) { message = message.replace(token, value); } } } return message; } function loadLabI18n() { try { function tryLoad(relBin, relJsx) { var bin = new File(scriptDir + "/" + relBin); var jsx = new File(scriptDir + "/" + relJsx); if (bin.exists) { $.evalFile(bin); return true; } if (jsx.exists) { $.evalFile(jsx); return true; } return false; } tryLoad("lib/i18n/en_us.jsxbin", "lib/i18n/en_us.jsx"); tryLoad("lib/i18n/es_hn.jsxbin", "lib/i18n/es_hn.jsx"); tryLoad("lib/07_i18n.jsxbin", "lib/07_i18n.jsx"); tryLoad("lib/02_settings.jsxbin", "lib/02_settings.jsx"); if (typeof i18n !== "undefined" && i18n && typeof i18n.init === "function") { var uiLanguage = "en_us"; try { var prefsFile = null; if (typeof settingsManager !== "undefined" && settingsManager && settingsManager.getUserPreferencesPath) { prefsFile = settingsManager.getUserPreferencesPath(); } if (prefsFile && prefsFile.exists && prefsFile.open("r")) { var prefsContent = prefsFile.read(); prefsFile.close(); var langMatch = prefsContent.match(/"uiLanguage"\s*:\s*"([^"]+)"/); if (langMatch && langMatch[1]) { uiLanguage = String(langMatch[1]); } } } catch (langErr) { } i18n.init(uiLanguage); } } catch (i18nErr) { } } loadLabI18n(); function logToFile(message) { try { function getGmt6Date() { var now = new Date(); var offsetMs = -6 * 60 * 60 * 1000; return new Date(now.getTime() + offsetMs); } function formatGmt6Timestamp(d) { function pad(n) { return (n < 10) ? ("0" + n) : String(n); } return d.getUTCFullYear() + "-" + pad(d.getUTCMonth() + 1) + "-" + pad(d.getUTCDate()) + " " + pad(d.getUTCHours()) + ":" + pad(d.getUTCMinutes()) + ":" + pad(d.getUTCSeconds()) + " GMT-06"; } function sanitizeLogMessage(msg) { if (msg === null || msg === undefined) return ""; try { var out = String(msg); if (!out || out === "null" || out === "undefined") return ""; var winPathRe = new RegExp("[A-Za-z]:[\\\\/][^\\r\\n]*", "g"); out = out.replace(winPathRe, ""); var macUsersRe = new RegExp("\\\\/Users\\\\/[^\\r\\n]*", "g"); var macVolumesRe = new RegExp("\\\\/Volumes\\\\/[^\\r\\n]*", "g"); out = out.replace(macUsersRe, ""); out = out.replace(macVolumesRe, ""); return out; } catch (e) { return "[Log sanitization error]"; } } var now = getGmt6Date(); var year = now.getUTCFullYear(); var month = ("0" + (now.getUTCMonth() + 1)).slice(-2); var day = ("0" + now.getUTCDate()).slice(-2); var dateFolderName = year + "-" + month + "-" + day; var dateFolder = null; if (typeof settingsManager !== "undefined" && settingsManager && typeof settingsManager.getProofLabLogsDir === "function") { dateFolder = settingsManager.getProofLabLogsDir(); } if (!dateFolder) { return; } var logFileName = dateFolderName + "_laboratory.txt"; var logFile = new File(dateFolder.fsName + "/" + logFileName); logFile.encoding = "UTF-8"; if (logFile.open("a")) { var timestamp = formatGmt6Timestamp(now); logFile.writeln("\n\n================================================================================"); logFile.writeln("LABORATORY EXECUTION LOG"); logFile.writeln("Time: " + timestamp); logFile.writeln("================================================================================"); logFile.writeln(""); if (message !== null && message !== undefined) { try { var sanitized = sanitizeLogMessage(message); if (sanitized !== null && sanitized !== undefined) { logFile.write(sanitized); } } catch (e) { logFile.write("[Log sanitization failed: " + String(e) + "]"); } } logFile.writeln(""); logFile.writeln("================================================================================"); logFile.close(); } } catch (e) { $.writeln("[LABORATORY][ERROR] Failed to write log: " + e.toString()); } } try { if (!app.documents.length) { alert(labT("ui.laboratory.error.open_document_first", "Please open a document before running Laboratory.")); return; } var doc = app.activeDocument; if (!doc) { alert(labT("ui.laboratory.error.no_active_document", "No active document.")); return; } if (!doc.artboards || doc.artboards.length === 0) { alert(labT("ui.laboratory.error.no_artboards", "The document has no artboards.\n\nPlease add at least one artboard to the document before running Laboratory.")); return; } var logMessages = []; logMessages.push("[START] Laboratory execution started"); logMessages.push("[DOC] Document: " + doc.name); var isProduction = true; var loggerBin = new File(scriptDir + "/lib/00_logger.jsxbin"); var loggerJsx = new File(scriptDir + "/lib/00_logger.jsx"); if (loggerBin.exists) { $.evalFile(loggerBin); } else if (loggerJsx.exists) { $.evalFile(loggerJsx); isProduction = false; } else { alert(labF("ui.laboratory.error.logger_module_not_found", { binPath: loggerBin.fsName, jsxPath: loggerJsx.fsName }, "Error: Logger module not found.\n\n" + "Tried:\n" + " - {binPath}\n" + " - {jsxPath}\n\n" + "No JSXBIN files found. Please contact your administrator.")); return; } var versionBin = new File(scriptDir + "/lib/06_versioning.jsxbin"); var versionJsx = new File(scriptDir + "/lib/06_versioning.jsx"); if (versionBin.exists) { $.evalFile(versionBin); } else if (versionJsx.exists) { $.evalFile(versionJsx); isProduction = false; } var jsonBin = new File(scriptDir + "/lib/01_json_polyfill.jsxbin"); var jsonJsx = new File(scriptDir + "/lib/01_json_polyfill.jsx"); if (jsonBin.exists) { $.evalFile(jsonBin); } else if (jsonJsx.exists) { $.evalFile(jsonJsx); isProduction = false; } else { alert(labF("ui.laboratory.error.json_module_not_found", { binPath: jsonBin.fsName, jsxPath: jsonJsx.fsName }, "Error: JSON polyfill module not found.\n\n" + "Tried:\n" + " - {binPath}\n" + " - {jsxPath}\n\n" + "No JSXBIN files found. Please contact your administrator.")); return; } var securityBinPre = new File(scriptDir + "/lib/05_security.jsxbin"); var securityJsxPre = new File(scriptDir + "/lib/05_security.jsx"); if (securityBinPre.exists) { $.evalFile(securityBinPre); } else if (securityJsxPre.exists) { $.evalFile(securityJsxPre); isProduction = false; } else { alert(labF("ui.laboratory.error.security_module_not_found", { binPath: securityBinPre.fsName, jsxPath: securityJsxPre.fsName }, "Error: Security module not found.\n\n" + "Tried:\n" + " - {binPath}\n" + " - {jsxPath}\n\n" + "No JSXBIN files found. Please contact your administrator.")); return; } $.global.PRLB_PRODUCTION = isProduction; loadLabI18n(); if (typeof security === "undefined" || !security.check) { alert(labT("ui.laboratory.security.module_unavailable_access_denied", "Security module not available. Access denied.")); return; } var securityResult = security.check(); if (!securityResult.ok) { security.showActivationError(securityResult.machineID); if (isProduction) { logMessages.push("[ERROR] Access denied - Machine ID: "); } else { logMessages.push("[ERROR] Access denied - Machine ID: " + securityResult.machineID); } logToFile(logMessages.join("\n")); return; } if (isProduction) { logMessages.push("[SECURITY] License check passed - Machine ID: "); } else { logMessages.push("[SECURITY] License check passed - Machine ID: " + securityResult.machineID); } var licenseRole = "UNKNOWN"; if (typeof security !== "undefined" && security.getRoleFromLicense) { licenseRole = security.getRoleFromLicense(); } var devModeActive = false; if (typeof security !== "undefined" && security.checkDevelopmentMode) { devModeActive = security.checkDevelopmentMode(); if (devModeActive) { logMessages.push("[MODE] Development mode active (bypasses role check)"); } } var activeABIndex = doc.artboards.getActiveArtboardIndex(); if (activeABIndex < 0 || activeABIndex >= doc.artboards.length) { alert(labT("ui.laboratory.error.no_active_artboard", "No active artboard found.\n\nPlease select an artboard before running Laboratory.")); return; } var activeAB = doc.artboards[activeABIndex]; logMessages.push("[ARTBOARD] Active artboard: " + activeAB.name + " (index: " + activeABIndex + ")"); var selection = doc.selection; var selectionCount = selection ? selection.length : 0; logMessages.push("[SELECTION] Selected items: " + selectionCount); logMessages.push(""); logMessages.push("[PHASE 1] Checking artboard structure..."); var needsFix = false; var fixIssues = []; var requiredGlobalLayer = "$_Global_AB" + activeABIndex; var requiredPerArtLayer = "$_PerArt_AB" + activeABIndex; var requiredTextFramesLayer = "$_Text_Frames"; var hasGlobalLayer = false; var hasPerArtLayer = false; var hasTextFramesLayer = false; for (var i = 0; i < doc.layers.length; i++) { var layerName = doc.layers[i].name; if (layerName === requiredGlobalLayer) hasGlobalLayer = true; if (layerName === requiredPerArtLayer) hasPerArtLayer = true; if (layerName === requiredTextFramesLayer) hasTextFramesLayer = true; } if (!hasGlobalLayer) { needsFix = true; fixIssues.push("Missing layer: " + requiredGlobalLayer); } if (!hasPerArtLayer) { needsFix = true; fixIssues.push("Missing layer: " + requiredPerArtLayer); } if (!hasTextFramesLayer) { needsFix = true; fixIssues.push("Missing layer: " + requiredTextFramesLayer); } var allowFixStructure = true; if (needsFix) { logMessages.push("[FIX] Issues found:"); for (var i = 0; i < fixIssues.length; i++) { logMessages.push(" - " + fixIssues[i]); } if (allowFixStructure) { logMessages.push("[FIX] Executing FixStructure to repair..."); var fixStructureBin = new File(scriptDir + "/FixStructure.jsxbin"); var fixStructureJsx = new File(scriptDir + "/FixStructure.jsx"); if (fixStructureBin.exists) { $.evalFile(fixStructureBin); logMessages.push("[FIX] FixStructure.jsxbin executed successfully"); } else if (fixStructureJsx.exists) { $.evalFile(fixStructureJsx); logMessages.push("[FIX] FixStructure.jsx executed successfully"); } else { logMessages.push("[ERROR] FixStructure script not found"); logToFile(logMessages.join("\n")); alert(labT("ui.laboratory.error.fixstructure_not_found", "Laboratory Error:\n\nFixStructure script not found.")); return; } } } else { logMessages.push("[OK] Structure is valid, no fixes needed"); } logMessages.push(""); logMessages.push("[PHASE 2] Setting mode based on license role..."); var uiMode = "USER"; // Default to USER for safety if (devModeActive) { uiMode = "ADMIN"; // Dev mode gets full access } else if (licenseRole === "ADMIN") { uiMode = "ADMIN"; } else { uiMode = "USER"; // USER or unknown -> USER mode } $.global.PRLB_MODE = uiMode; logMessages.push("[MODE] UI Mode: " + $.global.PRLB_MODE + " (License Role: " + licenseRole + (devModeActive ? ", Dev Mode Active" : "") + ")"); logMessages.push(""); logMessages.push("[PHASE 3] Executing ProofLab..."); $.global.PRLB_LABORATORY_MODE = true; $.global.PRLB_APPLY_SUCCESS = false; // Reset flag before execution var proofLabBin = new File(scriptDir + "/ProofLab.jsxbin"); var proofLabJsx = new File(scriptDir + "/ProofLab.jsx"); if (proofLabBin.exists) { $.evalFile(proofLabBin); } else if (proofLabJsx.exists) { $.evalFile(proofLabJsx); $.global.PRLB_PRODUCTION = false; // Using .jsx = dev mode } else { logMessages.push("[ERROR] ProofLab script not found"); logToFile(logMessages.join("\n")); alert(labF("ui.laboratory.error.prooflab_not_found", { binPath: proofLabBin.fsName, jsxPath: proofLabJsx.fsName }, "Error: ProofLab script not found.\n\n" + "Tried:\n" + " - {binPath}\n" + " - {jsxPath}\n\n" + "No JSXBIN files found. Please contact your administrator.")); return; } var applySuccess = $.global.PRLB_APPLY_SUCCESS === true; delete $.global.PRLB_APPLY_SUCCESS; // Clean up flag if (!applySuccess) { logMessages.push("[CANCELLED] ProofLab was closed without applying (user cancelled or error)"); logMessages.push("[END] Laboratory execution stopped - no swatch panel opened"); logToFile(logMessages.join("\n")); return; // Don't open swatch panel } var lastTemplate = $.global.PRLB_LAST_TEMPLATE; if (lastTemplate) { logMessages.push("[TEMPLATE] " + lastTemplate); delete $.global.PRLB_LAST_TEMPLATE; } var lastApplyMode = $.global.PRLB_LAST_APPLY_MODE; if (lastApplyMode) { logMessages.push("[APPLY_MODE] " + lastApplyMode); delete $.global.PRLB_LAST_APPLY_MODE; } logMessages.push("[SUCCESS] ProofLab applied successfully"); logMessages.push(""); logMessages.push("[PHASE 3] Opening Swatch Settings panel..."); var swatchLauncher = new File(scriptDir + "/SwatchesSettingsLauncher.jsx"); if (swatchLauncher.exists) { $.evalFile(swatchLauncher); logMessages.push("[SUCCESS] Swatch panel opened successfully"); } else { logMessages.push("[WARN] SwatchesSettingsLauncher.jsx not found"); } logMessages.push(""); logMessages.push("[END] Laboratory execution completed"); logToFile(logMessages.join("\n")); } catch (e) { var errorLog = "[ERROR] Laboratory execution failed: " + e.toString(); if (e.line) errorLog += "\n[ERROR] Line: " + e.line; if (e.stack) errorLog += "\n[ERROR] Stack: " + e.stack; logToFile(errorLog); alert(labF("ui.laboratory.error.generic", { error: e.toString() }, "Laboratory Error:\n\n{error}")); } })();