diff --git a/packages/media/dist-in/commands/background-remove-bria.js b/packages/media/dist-in/commands/background-remove-bria.js index c7bbb5e7..516984fe 100644 --- a/packages/media/dist-in/commands/background-remove-bria.js +++ b/packages/media/dist-in/commands/background-remove-bria.js @@ -48,6 +48,10 @@ export const defaultOptions = (yargs) => { describe: 'Preserve alpha channel from input image', type: 'boolean', default: true + }).option('jpg', { + describe: 'Convert PNG output to JPG format and delete PNG', + type: 'boolean', + default: false }); }; export const command = 'background:remove:bria'; @@ -69,6 +73,7 @@ export async function handler(argv) { options.sync = argv.sync; options.contentModeration = argv.contentModeration; options.preserveAlpha = argv.preserveAlpha; + options.jpg = argv.jpg; logger.info("Removing background with Bria AI options:", { sync: options.sync, contentModeration: options.contentModeration, @@ -78,4 +83,4 @@ export async function handler(argv) { await briaBackgroundRemove(options); } cli.command(command, desc, builder, handler); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFja2dyb3VuZC1yZW1vdmUtYnJpYS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21tYW5kcy9iYWNrZ3JvdW5kLXJlbW92ZS1icmlhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUNsRCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBQ3BDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDL0IsT0FBTyxFQUNILFFBQVEsRUFDUixRQUFRLEVBQ1gsTUFBTSxZQUFZLENBQUE7QUFFbkIsT0FBTyxFQUNILG9CQUFvQixFQUV2QixNQUFNLCtDQUErQyxDQUFBO0FBRXRELE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRyxDQUFDLEtBQWUsRUFBRSxFQUFFO0lBQzlDLE9BQU8sS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUU7UUFDdkIsUUFBUSxFQUFFLGtCQUFrQjtRQUM1QixZQUFZLEVBQUUsSUFBSTtLQUNyQixDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRTtRQUNiLFFBQVEsRUFBRSxrQkFBa0I7S0FDL0IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUU7UUFDZixPQUFPLEVBQUUsS0FBSztRQUNkLFFBQVEsRUFBRSxnQ0FBZ0M7UUFDMUMsSUFBSSxFQUFFLFNBQVM7S0FDbEIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUU7UUFDYixPQUFPLEVBQUUsS0FBSztRQUNkLFFBQVEsRUFBRSx5Q0FBeUM7UUFDbkQsSUFBSSxFQUFFLFNBQVM7S0FDbEIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUU7UUFDYixPQUFPLEVBQUUsS0FBSztRQUNkLFFBQVEsRUFBRSx3QkFBd0I7UUFDbEMsSUFBSSxFQUFFLFNBQVM7S0FDbEIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUU7UUFDakIs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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFja2dyb3VuZC1yZW1vdmUtYnJpYS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21tYW5kcy9iYWNrZ3JvdW5kLXJlbW92ZS1icmlhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUNsRCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBQ3BDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDL0IsT0FBTyxFQUNILFFBQVEsRUFDUixRQUFRLEVBQ1gsTUFBTSxZQUFZLENBQUE7QUFFbkIsT0FBTyxFQUNILG9CQUFvQixFQUV2QixNQUFNLCtDQUErQyxDQUFBO0FBRXRELE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRyxDQUFDLEtBQWUsRUFBRSxFQUFFO0lBQzlDLE9BQU8sS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUU7UUFDdkIsUUFBUSxFQUFFLGtCQUFrQjtRQUM1QixZQUFZLEVBQUUsSUFBSTtLQUNyQixDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRTtRQUNiLFFBQVEsRUFBRSxrQkFBa0I7S0FDL0IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUU7UUFDZixPQUFPLEVBQUUsS0FBSztRQUNkLFFBQVEsRUFBRSxnQ0FBZ0M7UUFDMUMsSUFBSSxFQUFFLFNBQVM7S0FDbEIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUU7UUFDYixPQUFPLEVBQUUsS0FBSztRQUNkLFFBQVEsRUFBRSx5Q0FBeUM7UUFDbkQsSUFBSSxFQUFFLFNBQVM7S0FDbEIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUU7UUFDYixPQUFPLEVBQUUsS0FBSztRQUNkLFFBQVEsRUFBRSx3QkFBd0I7UUFDbEMsSUFBSSxFQUFFLFNBQVM7S0FDbEIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUU7UUFDakIs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 \ No newline at end of file diff --git a/packages/media/dist-in/commands/register-commands.d.ts b/packages/media/dist-in/commands/register-commands.d.ts new file mode 100644 index 00000000..72f381b0 --- /dev/null +++ b/packages/media/dist-in/commands/register-commands.d.ts @@ -0,0 +1,6 @@ +import * as CLI from 'yargs'; +export declare const defaultOptions: (yargs: CLI.Argv) => any; +export declare const command = "register-commands"; +export declare const desc = "Register all pm-media commands in Salamander menu"; +export declare const builder: (yargs: CLI.Argv) => any; +export declare function handler(argv: CLI.Arguments): Promise; diff --git a/packages/media/dist-in/commands/register-commands.js b/packages/media/dist-in/commands/register-commands.js new file mode 100644 index 00000000..a2170b31 --- /dev/null +++ b/packages/media/dist-in/commands/register-commands.js @@ -0,0 +1,218 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import { logger } from '../index.js'; +import { cli } from '../cli.js'; +import { defaults } from '../_cli.js'; +import { WindowsRegistry } from '../lib/salamander/index.js'; +export const defaultOptions = (yargs) => { + return yargs.option('group', { + describe: 'Group name to register commands under', + type: 'string', + default: 'Media' + }).option('dry', { + default: false, + describe: 'Show what would be registered without actually registering', + type: 'boolean' + }).option('force', { + default: false, + describe: 'Force register even if command already exists', + type: 'boolean' + }).option('logLevel', { + describe: 'Log level : warn, info, debug, error', + type: 'string', + default: 'info' + }); +}; +export const command = 'register-commands'; +export const desc = 'Register all pm-media commands in Salamander menu'; +export const builder = defaultOptions; +// Basic command mappings - users can extend these as needed +const COMMAND_MAPPINGS = { + 'resize': { + name: 'Resize Images', + command: 'pm-media', + args: 'resize --alt=true --logLevel=info --src=\"$(FullName)/**/*.+(&{IMAGES})\" --dst=\"&{SRC_DIR}/&{SRC_NAME}_resized.&{SRC_EXT}\"', + description: 'Resize images' + }, + 'watermark': { + name: 'Add Watermark', + command: 'pm-media', + args: 'watermark --alt=true --logLevel=info --src=\"$(FullName)/**/*.+(&{IMAGES})\" --watermark=\"&{POLYMECH-ROOT}/nordin-ex/branding/polymech-saw-ex.svg\" --dst=\"&{SRC_DIR}/&{SRC_NAME}_watermarked.&{SRC_EXT}\"', + description: 'Add watermark to images' + }, + 'background-remove': { + name: 'Remove Background', + command: 'pm-media', + args: 'background:remove --alt=true --logLevel=info --src=\"$(FullName)/**/*.+(&{IMAGES})\" --dst=\"&{SRC_DIR}/&{SRC_NAME}_bg_removed.&{SRC_EXT}\"', + description: 'Remove background from images' + }, + 'background-remove-bria': { + name: 'Remove Background (Bria AI)', + command: 'pm-media', + args: 'background:remove:bria --alt=true --logLevel=info --src=\"$(FullName)/**/*.+(&{IMAGES})\" --dst=\"&{SRC_DIR}/&{SRC_NAME}_bria_bg_removed.&{SRC_EXT}\"', + description: 'Remove background using Bria AI' + }, + 'convert': { + name: 'Convert Format', + command: 'pm-media', + args: 'convert --alt=true --logLevel=info --src=\"$(FullName)/**/*.+(&{IMAGES})\" --dst=\"&{SRC_DIR}/&{SRC_NAME}_converted.jpg\"', + description: 'Convert image format' + }, + 'pdf2jpg': { + name: 'PDF to JPG', + command: 'pm-media', + args: 'pdf2jpg --alt=true --logLevel=info --src=\"$(FullName)/**/*.pdf\" --dst=\"&{SRC_DIR}/&{SRC_NAME}_page.jpg\"', + description: 'Convert PDF pages to JPG images' + }, + 'svg2jpg': { + name: 'SVG to JPG', + command: 'pm-media', + args: 'svg2jpg --alt=true --logLevel=info --src=\"$(FullName)/**/*.svg\" --dst=\"&{SRC_DIR}/&{SRC_NAME}.jpg\"', + description: 'Convert SVG to JPG' + }, + 'crop-foreground': { + name: 'Crop Foreground', + command: 'pm-media', + args: 'crop-foreground --alt=true --logLevel=info --src=\"$(FullName)/**/*.+(&{IMAGES})\" --dst=\"&{SRC_DIR}/&{SRC_NAME}_cropped.&{SRC_EXT}\"', + description: 'Crop to foreground content' + } +}; +async function getAvailableCommands() { + const commandsDir = path.join(process.cwd(), 'src', 'commands'); + const files = fs.readdirSync(commandsDir); + return files + .filter(file => file.endsWith('.ts') && + file !== 'salamander.ts' && + file !== 'register-commands.ts') + .map(file => file.replace('.ts', '')) + .filter(cmd => COMMAND_MAPPINGS[cmd]); // Only include commands we have mappings for +} +export async function handler(argv) { + defaults(); + logger.settings.minLevel = argv.logLevel; + const options = { + group: argv.group, + dry: argv.dry, + force: argv.force + }; + try { + logger.info('Scanning available pm-media commands...'); + const availableCommands = await getAvailableCommands(); + logger.info(`Found ${availableCommands.length} commands: ${availableCommands.join(', ')}`); + if (options.dry) { + logger.info('\n=== DRY RUN - Commands that would be registered ==='); + for (const cmdName of availableCommands) { + const cmdInfo = COMMAND_MAPPINGS[cmdName]; + logger.info(`\nCommand: ${cmdName}`); + logger.info(` Name: ${cmdInfo.name}`); + logger.info(` Args: ${cmdInfo.args}`); + logger.info(` Group: ${options.group}`); + } + return; + } + // Check which commands already exist + logger.info('Checking existing registry entries...'); + const existingEntries = await WindowsRegistry.listAllMenuEntries(); + const existingCommandNames = existingEntries + .filter(entry => entry.type === 'command') // Only commands, not submenus + .map(entry => entry.name); + logger.info(`Found ${existingCommandNames.length} existing menu entries`); + let registeredCount = 0; + let skippedCount = 0; + // Check if the target group exists, create it if it doesn't + const groupExists = existingEntries.some(entry => entry.type === 'submenu' && entry.name === options.group); + let groupInsertionPoint; + if (!groupExists) { + logger.info(`Creating group: ${options.group}`); + // Get the starting index for the new submenu + groupInsertionPoint = await WindowsRegistry.getNextMenuIndex(); + // Create the group submenu start + const groupStartValues = { + 'Item Name': options.group, + 'Command': '', + 'Arguments': '', + 'Initial Directory': '', + 'Execute Through Shell': 'dword:00000000', + 'Close Shell Window': 'dword:00000000', + 'Open Shell Window': 'dword:00000000', + 'Icon': '', + 'Type': 'dword:00000001', + 'Show In Toolbar': 'dword:00000001' + }; + await WindowsRegistry.writeMenuEntry(groupInsertionPoint, groupStartValues); + logger.info(`✓ Created group start: ${options.group} at index ${groupInsertionPoint}`); + // Increment for the first command slot + groupInsertionPoint++; + } + else { + logger.info(`Group '${options.group}' already exists`); + groupInsertionPoint = await WindowsRegistry.findGroupInsertionPoint(options.group); + } + for (const cmdName of availableCommands) { + const cmdInfo = COMMAND_MAPPINGS[cmdName]; + // Check if command already exists + const exists = existingCommandNames.some(name => name.toLowerCase().includes(cmdInfo.name.toLowerCase()) || + cmdInfo.name.toLowerCase().includes(name.toLowerCase())); + if (exists && !options.force) { + logger.info(`Skipping '${cmdInfo.name}' - already exists (use --force to override)`); + skippedCount++; + continue; + } + logger.info(`Registering: ${cmdInfo.name}`); + try { + // Build registry values for the command + const values = { + 'Item Name': cmdInfo.name, + 'Command': cmdInfo.command, + 'Arguments': cmdInfo.args, + 'Initial Directory': '$(FullPath)', + 'Execute Through Shell': 'dword:00000001', + 'Close Shell Window': 'dword:00000001', + 'Open Shell Window': 'dword:00000001', + 'Icon': '', + 'Type': 'dword:00000000', + 'Show In Toolbar': 'dword:00000001' + }; + await WindowsRegistry.writeMenuEntry(groupInsertionPoint, values); + registeredCount++; + logger.info(`✓ Registered: ${cmdInfo.name} at index ${groupInsertionPoint}`); + // Increment insertion point for next command to insert them sequentially within the group + groupInsertionPoint++; + } + catch (error) { + logger.error(`Failed to register '${cmdInfo.name}':`, error); + } + } + // If we created a new group and registered commands, add the submenu end + if (!groupExists && registeredCount > 0) { + const groupEndValues = { + 'Item Name': '(Submenu End)', + 'Command': '', + 'Arguments': '', + 'Initial Directory': '', + 'Execute Through Shell': 'dword:00000000', + 'Close Shell Window': 'dword:00000000', + 'Open Shell Window': 'dword:00000000', + 'Icon': '', + 'Type': 'dword:00000002', + 'Show In Toolbar': 'dword:00000000' + }; + await WindowsRegistry.writeMenuEntry(groupInsertionPoint, groupEndValues); + logger.info(`✓ Created group end at index ${groupInsertionPoint}`); + } + logger.info(`\n=== Registration Complete ===`); + logger.info(`Registered: ${registeredCount} commands`); + logger.info(`Skipped: ${skippedCount} commands`); + logger.info(`Total available: ${availableCommands.length} commands`); + if (registeredCount > 0) { + logger.info('\nCommands have been registered in Salamander\'s User Menu.'); + logger.info('Restart Salamander to see the new menu entries.'); + } + } + catch (error) { + logger.error('Failed to register commands:', error); + process.exit(1); + } +} +cli.command(command, desc, builder, handler); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaXN0ZXItY29tbWFuZHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tbWFuZHMvcmVnaXN0ZXItY29tbWFuZHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxLQUFLLEVBQUUsTUFBTSxJQUFJLENBQUE7QUFDeEIsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUE7QUFDNUIsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUNwQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQy9CLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFDckMsT0FBTyxFQUFtQyxlQUFlLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQTtBQUU3RixNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxLQUFlLEVBQUUsRUFBRTtJQUM5QyxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFO1FBQ3pCLFFBQVEsRUFBRSx1Q0FBdUM7UUFDakQsSUFBSSxFQUFFLFFBQVE7UUFDZCxPQUFPLEVBQUUsT0FBTztLQUNuQixDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRTtRQUNiLE9BQU8sRUFBRSxLQUFLO1FBQ2QsUUFBUSxFQUFFLDREQUE0RDtRQUN0RSxJQUFJLEVBQUUsU0FBUztLQUNsQixDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRTtRQUNmLE9BQU8sRUFBRSxLQUFLO1FBQ2QsUUFBUSxFQUFFLCtDQUErQztRQUN6RCxJQUFJLEVBQUUsU0FBUztLQUNsQixDQUFDLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRTtRQUNsQixRQUFRLEVBQUUsc0NBQXNDO1FBQ2hELElBQUksRUFBRSxRQUFRO1FBQ2QsT0FBTyxFQUFFLE1BQU07S0FDbEIsQ0FBQyxDQUFBO0FBQ04sQ0FBQyxDQUFBO0FBRUQsTUFBTSxDQUFDLE1BQU0sT0FBTyxHQUFHLG1CQUFtQixDQUFB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 \ No newline at end of file diff --git a/packages/media/dist-in/commands/register-explorer.d.ts b/packages/media/dist-in/commands/register-explorer.d.ts new file mode 100644 index 00000000..d3bb969f --- /dev/null +++ b/packages/media/dist-in/commands/register-explorer.d.ts @@ -0,0 +1,6 @@ +import * as CLI from 'yargs'; +export declare const defaultOptions: (yargs: CLI.Argv) => any; +export declare const command = "register-explorer"; +export declare const desc = "Register pm-media commands in Windows Explorer context menu for image files"; +export declare const builder: (yargs: CLI.Argv) => any; +export declare function handler(argv: CLI.Arguments): Promise; diff --git a/packages/media/dist-in/commands/register-explorer.js b/packages/media/dist-in/commands/register-explorer.js new file mode 100644 index 00000000..b8fb198e --- /dev/null +++ b/packages/media/dist-in/commands/register-explorer.js @@ -0,0 +1,204 @@ +import { logger } from '../index.js'; +import { cli } from '../cli.js'; +import { defaults } from '../_cli.js'; +import regedit from 'regedit'; +export const defaultOptions = (yargs) => { + return yargs.option('group', { + describe: 'Group name for the context menu items', + type: 'string', + default: 'PM-Media' + }).option('unregister', { + default: false, + describe: 'Remove the shell extensions from Explorer', + type: 'boolean' + }).option('dry', { + default: false, + describe: 'Show what would be registered without actually doing it', + type: 'boolean' + }).option('logLevel', { + describe: 'Log level : warn, info, debug, error', + type: 'string', + default: 'info' + }); +}; +export const command = 'register-explorer'; +export const desc = 'Register pm-media commands in Windows Explorer context menu for image files'; +export const builder = defaultOptions; +// Image file extensions to register with +const IMAGE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.webp', '.svg']; +// Command mappings for Explorer context menu +const EXPLORER_COMMANDS = [ + { + name: 'Convert to JPG', + command: 'pm-media', + args: 'convert --alt=true --logLevel=info --src="%1" --dst="%~dpn1_converted.jpg"' + }, + { + name: 'Resize Image', + command: 'pm-media', + args: 'resize --alt=true --logLevel=info --src="%1" --dst="%~dpn1_resized%~x1"' + }, + { + name: 'Add Watermark', + command: 'pm-media', + args: 'watermark --alt=true --logLevel=info --src="%1" --watermark="&{POLYMECH-ROOT}/nordin-ex/branding/polymech-saw-ex.svg" --dst="%~dpn1_watermarked%~x1"' + }, + { + name: 'Remove Background', + command: 'pm-media', + args: 'background:remove --alt=true --logLevel=info --src="%1" --dst="%~dpn1_bg_removed%~x1"' + } +]; +/** + * Generate registry entries for Windows Explorer shell extensions + */ +function generateExplorerRegistryEntries(groupName) { + const entries = []; + for (const ext of IMAGE_EXTENSIONS) { + const extKey = `HKCU\\Software\\Classes\\${ext}`; + // For each command, create the shell extension entries + for (let i = 0; i < EXPLORER_COMMANDS.length; i++) { + const cmd = EXPLORER_COMMANDS[i]; + const cmdKey = `${extKey}\\shell\\${groupName}\\shell\\${cmd.name.replace(/\s+/g, '')}`; + // Command display name + entries.push({ + keyPath: cmdKey, + valueName: '', + value: cmd.name, + type: 'REG_SZ' + }); + // Command execution + entries.push({ + keyPath: `${cmdKey}\\command`, + valueName: '', + value: `${cmd.command} ${cmd.args}`, + type: 'REG_SZ' + }); + } + // Set the group submenu display name + entries.push({ + keyPath: `${extKey}\\shell\\${groupName}`, + valueName: '', + value: groupName, + type: 'REG_SZ' + }); + // Set submenu position (optional) + entries.push({ + keyPath: `${extKey}\\shell\\${groupName}`, + valueName: 'Position', + value: 'Middle', + type: 'REG_SZ' + }); + } + return entries; +} +/** + * Write registry entries for Explorer shell extensions + */ +async function writeExplorerRegistryEntries(entries) { + const promisified = regedit.promisified; + for (const entry of entries) { + try { + // Create the key if it doesn't exist + await promisified.createKey([entry.keyPath]); + // Write the value using correct regedit format + // For default values, use empty string as key name + const valueName = entry.valueName || ''; + const valuesToWrite = { + [entry.keyPath]: { + [valueName]: { + value: entry.value, + type: entry.type + } + } + }; + await promisified.putValue(valuesToWrite); + logger.debug(`✓ Created registry entry: ${entry.keyPath} = ${entry.value}`); + } + catch (error) { + logger.error(`Failed to create registry entry ${entry.keyPath}:`, error); + logger.error(`Entry details:`, { + keyPath: entry.keyPath, + valueName: entry.valueName, + value: entry.value, + type: entry.type + }); + } + } +} +/** + * Remove registry entries for Explorer shell extensions + */ +async function removeExplorerRegistryEntries(groupName) { + const promisified = regedit.promisified; + for (const ext of IMAGE_EXTENSIONS) { + const extKey = `HKCU\\Software\\Classes\\${ext}`; + const groupKey = `${extKey}\\shell\\${groupName}`; + try { + // Check if the key exists + const result = await promisified.list([groupKey]); + if (result[groupKey].exists) { + await promisified.deleteKey([groupKey]); + logger.info(`✓ Removed shell extension for ${ext}`); + } + } + catch (error) { + logger.debug(`Could not remove key ${groupKey}:`, error); + } + } +} +export async function handler(argv) { + defaults(); + logger.settings.minLevel = argv.logLevel; + const options = { + group: argv.group, + unregister: argv.unregister, + dry: argv.dry + }; + if (process.platform !== 'win32') { + logger.error('Windows Explorer shell extensions are only supported on Windows'); + process.exit(1); + } + try { + if (options.unregister) { + logger.info(`Removing Explorer shell extensions for group: ${options.group}`); + if (options.dry) { + logger.info('\n=== DRY RUN - Extensions that would be removed ==='); + for (const ext of IMAGE_EXTENSIONS) { + logger.info(` ${ext} files: Remove "${options.group}" context menu`); + } + return; + } + await removeExplorerRegistryEntries(options.group); + logger.info(`✓ Successfully removed Explorer shell extensions for: ${options.group}`); + } + else { + logger.info(`Registering Explorer shell extensions for group: ${options.group}`); + logger.info(`Target file types: ${IMAGE_EXTENSIONS.join(', ')}`); + const entries = generateExplorerRegistryEntries(options.group); + if (options.dry) { + logger.info('\n=== DRY RUN - Extensions that would be registered ==='); + for (const ext of IMAGE_EXTENSIONS) { + logger.info(`\n${ext} files:`); + for (const cmd of EXPLORER_COMMANDS) { + logger.info(` → ${cmd.name}: ${cmd.command} ${cmd.args}`); + } + } + logger.info(`\nTotal registry entries: ${entries.length}`); + return; + } + await writeExplorerRegistryEntries(entries); + logger.info(`\n=== Registration Complete ===`); + logger.info(`Registered ${EXPLORER_COMMANDS.length} commands for ${IMAGE_EXTENSIONS.length} file types`); + logger.info(`Total registry entries created: ${entries.length}`); + logger.info('\nExplorer context menu entries have been registered.'); + logger.info('You may need to restart Explorer.exe to see the changes.'); + } + } + catch (error) { + logger.error('Failed to register/unregister Explorer shell extensions:', error); + process.exit(1); + } +} +cli.command(command, desc, builder, handler); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaXN0ZXItZXhwbG9yZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tbWFuZHMvcmVnaXN0ZXItZXhwbG9yZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUNwQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQy9CLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFDckMsT0FBTyxPQUFvRCxNQUFNLFNBQVMsQ0FBQTtBQUUxRSxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxLQUFlLEVBQUUsRUFBRTtJQUM5QyxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFO1FBQ3pCLFFBQVEsRUFBRSx1Q0FBdUM7UUFDakQsSUFBSSxFQUFFLFFBQVE7UUFDZCxPQUFPLEVBQUUsVUFBVTtLQUN0QixDQUFDLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRTtRQUNwQixPQUFPLEVBQUUsS0FBSztRQUNkLFFBQVEsRUFBRSwyQ0FBMkM7UUFDckQsSUFBSSxFQUFFLFNBQVM7S0FDbEIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUU7UUFDYixPQUFPLEVBQUUsS0FBSztRQUNkLFFBQVEsRUFBRSx5REFBeUQ7UUFDbkUsSUFBSSxFQUFFLFNBQVM7S0FDbEIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUU7UUFDbEIsUUFBUSxFQUFFLHNDQUFzQztRQUNoRCxJQUFJLEVBQUUsUUFBUTtRQUNkLE9BQU8sRUFBRSxNQUFNO0tBQ2xCLENBQUMsQ0FBQTtBQUNOLENBQUMsQ0FBQTtBQUVELE1BQU0sQ0FBQyxNQUFNLE9BQU8sR0FBRyxtQkFBbUIsQ0FBQTtBQUMxQyxNQUFNLENBQUMsTUFBTSxJQUFJLEdBQUcsNkVBQTZFLENBQUE7QUFDakcsTUFBTSxDQUFDLE1BQU0sT0FBTyxHQUFHLGNBQWMsQ0FB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 \ No newline at end of file diff --git a/packages/media/dist-in/commands/salamander.d.ts b/packages/media/dist-in/commands/salamander.d.ts new file mode 100644 index 00000000..6a199925 --- /dev/null +++ b/packages/media/dist-in/commands/salamander.d.ts @@ -0,0 +1,6 @@ +import * as CLI from 'yargs'; +export declare const defaultOptions: (yargs: CLI.Argv) => any; +export declare const command = "salamander"; +export declare const desc = "Generate Salamander file manager menu entries from JSON configuration"; +export declare const builder: (yargs: CLI.Argv) => any; +export declare function handler(argv: CLI.Arguments): Promise; diff --git a/packages/media/dist-in/commands/salamander.js b/packages/media/dist-in/commands/salamander.js new file mode 100644 index 00000000..4a8e5735 --- /dev/null +++ b/packages/media/dist-in/commands/salamander.js @@ -0,0 +1,247 @@ +import * as path from 'path'; +import { logger } from '../index.js'; +import { cli } from '../cli.js'; +import { sanitize, defaults } from '../_cli.js'; +import SalamanderMenuGenerator, { SalamanderMenuGeneratorRegistry } from '../lib/salamander/index.js'; +export const defaultOptions = (yargs) => { + return yargs.option('config', { + describe: 'JSON configuration file path', + type: 'string' + }).option('output', { + describe: 'Output registry file path', + type: 'string' + }).option('existing', { + describe: 'Path to existing registry file to parse for insertion point', + type: 'string' + }).option('group', { + describe: 'Group name to insert items into (e.g., "Media")', + type: 'string' + }).option('startIndex', { + describe: 'Starting menu index (overrides auto-detection)', + type: 'number' + }).option('debug', { + default: false, + describe: 'Enable internal debug messages', + type: 'boolean' + }).option('verbose', { + default: false, + describe: 'Show internal messages', + type: 'boolean' + }).option('logLevel', { + describe: 'Log level : warn, info, debug, error', + type: 'string', + default: 'info' + }).option('registry', { + describe: 'Apply directly to Windows registry (Windows only)', + type: 'boolean', + default: false + }).option('list', { + describe: 'List current menu entries from registry', + type: 'boolean', + default: false + }).option('remove', { + describe: 'Remove menu entries from registry', + type: 'boolean', + default: false + }).option('name', { + describe: 'Menu item name', + type: 'string' + }).option('command', { + describe: 'Command to execute', + type: 'string' + }).option('args', { + describe: 'Command arguments', + type: 'string' + }).option('workingDir', { + describe: 'Working directory for command execution', + type: 'string', + default: '$(FullPath)' + }).option('icon', { + describe: 'Icon path for menu item', + type: 'string', + default: '' + }).option('executeThoughShell', { + describe: 'Execute command through shell', + type: 'boolean', + default: true + }).option('closeShellWindow', { + describe: 'Close shell window after execution', + type: 'boolean', + default: false + }).option('openShellWindow', { + describe: 'Open shell window during execution', + type: 'boolean', + default: true + }).option('showInToolbar', { + describe: 'Show item in toolbar', + type: 'boolean', + default: true + }); +}; +export const command = 'salamander'; +export const desc = 'Generate Salamander file manager menu entries from JSON configuration'; +export const builder = defaultOptions; +export async function handler(argv) { + defaults(); + const options = sanitize(argv); + logger.settings.minLevel = options.logLevel; + try { + // Handle listing current menu entries + if (argv.list) { + if (process.platform !== 'win32') { + logger.error('Registry listing is only supported on Windows'); + process.exit(1); + } + logger.info('Current Salamander menu entries:'); + const entries = await SalamanderMenuGeneratorRegistry.listCurrentMenuEntries(); + for (const entry of entries) { + const typeStr = entry.type === 'submenu' ? '(submenu)' : + entry.type === 'submenu-end' ? '(submenu end)' : '(command)'; + const cmdStr = entry.command ? ` → ${entry.command}` : ''; + logger.info(` [${entry.index}] ${entry.name} ${typeStr}${cmdStr}`); + } + return; + } + let config; + // Check if we're using individual command line options or JSON config + if (argv.name && argv.command) { + // Create config from command line options + logger.info('Creating menu entry from command line options'); + config = { + baseKey: 'HKCU\\Software\\Altap\\Altap Salamander 4.0\\User Menu', + startIndex: 1, + items: [{ + name: argv.name, + command: argv.command, + arguments: argv.args || '', + initialDirectory: argv.workingDir, + executeThoughShell: argv.executeThoughShell, + closeShellWindow: argv.closeShellWindow, + openShellWindow: argv.openShellWindow, + icon: argv.icon, + showInToolbar: argv.showInToolbar + }] + }; + } + else if (argv.config) { + // Load configuration from JSON + const configPath = argv.config; + logger.info(`Loading configuration from: ${configPath}`); + config = SalamanderMenuGenerator.loadFromJson(configPath); + } + else { + logger.error('Either --config file or --name and --command options are required'); + process.exit(1); + } + // Determine starting index + let startIndex = argv.startIndex; + if (!startIndex) { + if (argv.registry && process.platform === 'win32') { + // Use registry to determine insertion point + if (argv.group) { + startIndex = await SalamanderMenuGeneratorRegistry.autoDetectInsertionPoint(argv.group); + logger.info(`Found insertion point for group "${argv.group}": index ${startIndex}`); + } + else { + startIndex = await SalamanderMenuGeneratorRegistry.autoDetectInsertionPoint(); + logger.info(`Detected next available index: ${startIndex}`); + } + } + else if (argv.existing) { + const existingPath = argv.existing; + if (argv.group) { + startIndex = SalamanderMenuGenerator.findInsertionPoint(existingPath, argv.group); + logger.info(`Found insertion point for group "${argv.group}": index ${startIndex}`); + } + else { + const maxIndex = SalamanderMenuGenerator.parseExistingRegistry(existingPath); + startIndex = maxIndex + 1; + logger.info(`Detected next available index: ${startIndex}`); + } + } + else { + startIndex = config.startIndex || 1; + logger.info(`Using configured start index: ${startIndex}`); + } + } + // Update config with determined start index + config.startIndex = startIndex; + // Handle direct registry operations + if (argv.registry) { + if (process.platform !== 'win32') { + logger.error('Direct registry operations are only supported on Windows'); + process.exit(1); + } + const generator = new SalamanderMenuGeneratorRegistry(config); + if (argv.remove) { + logger.info('Removing menu entries from registry...'); + await generator.removeFromRegistry(); + logger.info('Menu entries removed successfully'); + } + else { + logger.info('Applying menu entries to registry...'); + await generator.applyToRegistry(); + logger.info('Menu entries applied successfully'); + logger.info('Restart Salamander to see the new menu items'); + } + // Show summary + const entries = generator.generateRegistryEntries(); + logger.info(`Processed ${entries.length} menu entries`); + if (options.verbose) { + logger.info('Processed entries:'); + for (const entry of entries) { + const itemName = entry.values['"Item Name"']; + const type = entry.values['"Type"']; + const typeStr = type === 'dword:00000001' ? '(submenu)' : + type === 'dword:00000002' ? '(submenu end)' : '(command)'; + logger.info(` ${itemName} ${typeStr}`); + } + } + return; + } + // Generate .reg file + const generator = new SalamanderMenuGenerator(config); + // Generate output path if not specified + let outputPath = argv.output; + if (!outputPath) { + if (argv.config) { + const configPath = argv.config; + const configDir = path.dirname(configPath); + const configName = path.basename(configPath, '.json'); + outputPath = path.join(configDir, `${configName}-salamander-menu.reg`); + } + else { + outputPath = `salamander-menu-${argv.name?.toString().toLowerCase().replace(/\s+/g, '-') || 'item'}.reg`; + } + } + logger.info(`Generating registry file: ${outputPath}`); + // Generate and save registry file + generator.saveRegistryFile(outputPath); + // Generate summary + const entries = generator.generateRegistryEntries(); + logger.info(`Successfully generated ${entries.length} menu entries`); + if (options.verbose) { + logger.info('Generated entries:'); + for (const entry of entries) { + const itemName = entry.values['"Item Name"']; + const type = entry.values['"Type"']; + const typeStr = type === 'dword:00000001' ? '(submenu)' : + type === 'dword:00000002' ? '(submenu end)' : '(command)'; + logger.info(` ${itemName} ${typeStr}`); + } + } + logger.info(`\nTo apply the menu entries:`); + logger.info(`1. Double-click the generated .reg file: ${outputPath}`); + logger.info(`2. Confirm the registry import in Windows`); + logger.info(`3. Restart Salamander to see the new menu items`); + } + catch (error) { + logger.error(`Failed to generate Salamander menu:`, error.message); + if (options.debug) { + logger.error(error.stack); + } + process.exit(1); + } +} +cli.command(command, desc, builder, handler); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2FsYW1hbmRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21tYW5kcy9zYWxhbWFuZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBQzVCLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFDcEMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUMvQixPQUFPLEVBQ0gsUUFBUSxFQUNSLFFBQVEsRUFDWCxNQUFNLFlBQVksQ0FBQTtBQUVuQixPQUFPLHVCQUF1QixFQUFFLEVBQXdCLCtCQUErQixFQUFtQixNQUFNLDRCQUE0QixDQUFBO0FBRTVJLE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRyxDQUFDLEtBQWUsRUFBRSxFQUFFO0lBQzlDLE9BQU8sS0FBSyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUU7UUFDMUIsUUFBUSxFQUFFLDhCQUE4QjtRQUN4QyxJQUFJLEVBQUUsUUFBUTtLQUNqQixDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRTtRQUNoQixRQUFRLEVBQUUsMkJBQTJCO1FBQ3JDLElBQUksRUFBRSxRQUFRO0tBQ2pCLENBQUMsQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFO1FBQ2xCLFFBQVEsRUFBRSw2REFBNkQ7UUFDdkUsSUFBSSxFQUFFLFFBQVE7S0FDakIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUU7UUFDZixRQUFRLEVBQUUsaURBQWlEO1FBQzNELElBQUksRUFBRSxRQUFRO0tBQ2pCLENBQUMsQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFO1FBQ3BCLFFBQVEsRUFBRSxnREFBZ0Q7UUFDMUQsSUFBSSxFQUFFLFFBQVE7S0FDakIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUU7UUFDZixPQUFPLEVBQUUsS0FBSztRQUNkLFFBQVEsRUFBRSxnQ0FBZ0M7UUFDMUMsSUFBSSxFQUFFLFNB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 \ No newline at end of file diff --git a/packages/media/dist-in/lib/media/images/background-remove-bria.d.ts b/packages/media/dist-in/lib/media/images/background-remove-bria.d.ts index 6259f9fd..519b501c 100644 --- a/packages/media/dist-in/lib/media/images/background-remove-bria.d.ts +++ b/packages/media/dist-in/lib/media/images/background-remove-bria.d.ts @@ -4,6 +4,7 @@ export interface BriaBackgroundRemoveOptions extends IOptions { sync?: boolean; contentModeration?: boolean; preserveAlpha?: boolean; + jpg?: boolean; } export declare function removeBriaBackground(inputPath: string, outputPath: string, options: BriaBackgroundRemoveOptions): Promise; export declare const briaBackgroundRemove: (options: BriaBackgroundRemoveOptions) => Promise<{ diff --git a/packages/media/dist-in/lib/media/images/background-remove-bria.js b/packages/media/dist-in/lib/media/images/background-remove-bria.js index 2a1a9058..48dd02e3 100644 --- a/packages/media/dist-in/lib/media/images/background-remove-bria.js +++ b/packages/media/dist-in/lib/media/images/background-remove-bria.js @@ -1,5 +1,6 @@ import * as fs from 'fs'; import * as path from 'path'; +import sharp from 'sharp'; import pMap from 'p-map'; import { logger } from '../../../index.js'; import { targets } from '../../index.js'; @@ -20,6 +21,25 @@ async function downloadImageFromUrl(imageUrl, outputPath) { mkdir(path.dirname(outputPath)); fs.writeFileSync(outputPath, buffer); } +// Convert PNG to JPG while preserving rotation and metadata +async function convertPngToJpg(pngPath, jpgPath) { + try { + await sharp(pngPath) + .jpeg({ + quality: 95, + progressive: true + }) + .withMetadata() // Preserve EXIF data including rotation + .toFile(jpgPath); + // Delete the temporary PNG file + fs.unlinkSync(pngPath); + logger.debug(`Converted PNG to JPG and cleaned up: ${pngPath} → ${jpgPath}`); + } + catch (error) { + logger.error(`Failed to convert PNG to JPG: ${error.message}`); + throw error; + } +} export async function removeBriaBackground(inputPath, outputPath, options) { try { if (!options.apiKey) { @@ -60,8 +80,18 @@ export async function removeBriaBackground(inputPath, outputPath, options) { if (result.result_url || result.image_res) { // Download the processed image (Bria API uses result_url) const imageUrl = result.result_url || result.image_res; - await downloadImageFromUrl(imageUrl, outputPath); - logger.info(`Background removed: ${inputPath} → ${outputPath}`); + if (options.jpg && path.extname(outputPath).toLowerCase() === '.jpg') { + // If JPG conversion is requested and output is JPG, download as PNG first then convert + const tempPngPath = outputPath.replace(/\.jpe?g$/i, '_temp.png'); + await downloadImageFromUrl(imageUrl, tempPngPath); + await convertPngToJpg(tempPngPath, outputPath); + logger.info(`Background removed and converted to JPG: ${inputPath} → ${outputPath}`); + } + else { + // Standard PNG output + await downloadImageFromUrl(imageUrl, outputPath); + logger.info(`Background removed: ${inputPath} → ${outputPath}`); + } } else { throw new Error('No image result returned from Bria API'); @@ -105,4 +135,4 @@ export const briaBackgroundRemove = async (options) => { return []; } }; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFja2dyb3VuZC1yZW1vdmUtYnJpYS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvbWVkaWEvaW1hZ2VzL2JhY2tncm91bmQtcmVtb3ZlLWJyaWEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDekIsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxJQUFJLE1BQU0sT0FBTyxDQUFDO0FBQ3pCLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUUzQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDekMsT0FBTyxFQUFFLElBQUksSUFBSSxLQUFLLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQVNqRCx5Q0FBeUM7QUFDekMsU0FBUyxhQUFhLENBQUMsUUFBZ0I7SUFDckMsT0FBTyxFQUFFLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ25DLENBQUM7QUFFRCwyQ0FBMkM7QUFDM0MsS0FBSyxVQUFVLG9CQUFvQixDQUFDLFFBQWdCLEVBQUUsVUFBa0I7SUFDdEUsTUFBTSxRQUFRLEdBQUcsTUFBTSxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDdkMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUNqQixNQUFNLElBQUksS0FBSyxDQUFDLDZCQUE2QixRQUFRLENBQUMsTUFBTSxJQUFJLFFBQVEsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO0lBQ3pGLENBQUM7SUFFRCxNQUFNLFdBQVcsR0FBRyxNQUFNLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNqRCxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBRXhDLGlDQUFpQztJQUNqQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFV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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFja2dyb3VuZC1yZW1vdmUtYnJpYS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvbWVkaWEvaW1hZ2VzL2JhY2tncm91bmQtcmVtb3ZlLWJyaWEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDekIsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQzFCLE9BQU8sSUFBSSxNQUFNLE9BQU8sQ0FBQztBQUN6QixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFM0MsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSxJQUFJLElBQUksS0FBSyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFVakQseUNBQXlDO0FBQ3pDLFNBQVMsYUFBYSxDQUFDLFFBQWdCO0lBQ3JDLE9BQU8sRUFBRSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNuQyxDQUFDO0FBRUQsMkNBQTJDO0FBQzNDLEtBQUssVUFBVSxvQkFBb0IsQ0FBQyxRQUFnQixFQUFFLFVBQWtCO0lBQ3RFLE1BQU0sUUFBUSxHQUFHLE1BQU0sS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3ZDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyw2QkFBNkIsUUFBUSxDQUFDLE1BQU0sSUFBSSxRQUFRLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztJQUN6RixDQUFDO0lBRUQsTUFBTSxXQUFXLEdBQUcsTUFBTSxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDakQsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUV4QyxpQ0FBaUM7SUFDakMsS0FB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 \ No newline at end of file diff --git a/packages/media/dist-in/lib/salamander/index.d.ts b/packages/media/dist-in/lib/salamander/index.d.ts new file mode 100644 index 00000000..7d46feb7 --- /dev/null +++ b/packages/media/dist-in/lib/salamander/index.d.ts @@ -0,0 +1,130 @@ +export interface SalamanderMenuItem { + name: string; + command?: string; + arguments?: string; + initialDirectory?: string; + executeThoughShell?: boolean; + closeShellWindow?: boolean; + openShellWindow?: boolean; + icon?: string; + showInToolbar?: boolean; + type?: 'command' | 'submenu' | 'submenu-end'; + children?: SalamanderMenuItem[]; +} +export interface SalamanderMenuConfig { + baseKey: string; + startIndex: number; + items: SalamanderMenuItem[]; +} +export interface RegistryEntry { + key: string; + values: Record; +} +export declare class SalamanderMenuGenerator { + private config; + private baseKey; + constructor(config: SalamanderMenuConfig); + /** + * Parse existing registry file to find the highest menu index + */ + static parseExistingRegistry(registryPath: string): number; + /** + * Generate registry entries from menu configuration + */ + generateRegistryEntries(): RegistryEntry[]; + /** + * Convert menu item to registry values + */ + private itemToRegistryValues; + /** + * Escape arguments for registry format + */ + private escapeArguments; + /** + * Generate registry file content + */ + generateRegistryFile(): string; + /** + * Save registry file to disk + */ + saveRegistryFile(outputPath: string): void; + /** + * Load menu configuration from JSON file + */ + static loadFromJson(jsonPath: string): SalamanderMenuConfig; + /** + * Find insertion point in existing registry + */ + static findInsertionPoint(registryPath: string, groupName?: string): number; +} +/** + * Windows Registry helper for direct registry operations using regedit package + */ +export declare class WindowsRegistry { + private static isWindows; + private static ensureRegedit; + /** + * Read all User Menu entries from registry + */ + static readUserMenuEntries(baseKey?: string): Promise>; + /** + * Read specific menu entry by index + */ + static readMenuEntry(index: number, baseKey?: string): Promise>; + /** + * Get all existing menu indices + */ + static getExistingMenuIndices(baseKey?: string): Promise; + /** + * Get next available menu index + */ + static getNextMenuIndex(baseKey?: string): Promise; + /** + * Find insertion point for a specific group + */ + static findGroupInsertionPoint(groupName: string, baseKey?: string): Promise; + /** + * Write registry values for a menu entry + */ + static writeMenuEntry(index: number, values: Record, baseKey?: string): Promise; + /** + * Delete a menu entry + */ + static deleteMenuEntry(index: number, baseKey?: string): Promise; + /** + * List all menu entries with their details + */ + static listAllMenuEntries(baseKey?: string): Promise>; +} +/** + * Extended Salamander Menu Generator with direct registry support + */ +export declare class SalamanderMenuGeneratorRegistry extends SalamanderMenuGenerator { + /** + * Apply menu configuration directly to Windows registry + */ + applyToRegistry(): Promise; + /** + * Remove menu entries from Windows registry + */ + removeFromRegistry(): Promise; + /** + * Auto-detect insertion point from Windows registry + */ + static autoDetectInsertionPoint(groupName?: string): Promise; + /** + * List current menu entries from registry + */ + static listCurrentMenuEntries(): Promise>; +} +export default SalamanderMenuGenerator; diff --git a/packages/media/dist-in/lib/salamander/index.js b/packages/media/dist-in/lib/salamander/index.js new file mode 100644 index 00000000..065a009e --- /dev/null +++ b/packages/media/dist-in/lib/salamander/index.js @@ -0,0 +1,403 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import regedit from 'regedit'; +const promisified = regedit.promisified; +export class SalamanderMenuGenerator { + config; + baseKey = 'HKEY_CURRENT_USER\\Software\\Altap\\Altap Salamander 4.0\\User Menu'; + constructor(config) { + this.config = config; + if (config.baseKey) { + this.baseKey = config.baseKey; + } + } + /** + * Parse existing registry file to find the highest menu index + */ + static parseExistingRegistry(registryPath) { + if (!fs.existsSync(registryPath)) { + return 0; + } + const content = fs.readFileSync(registryPath, 'utf8'); + const lines = content.split('\n'); + let maxIndex = 0; + for (const line of lines) { + const match = line.match(/\\User Menu\\(\d+)\]/); + if (match) { + const index = parseInt(match[1], 10); + if (index > maxIndex) { + maxIndex = index; + } + } + } + return maxIndex; + } + /** + * Generate registry entries from menu configuration + */ + generateRegistryEntries() { + const entries = []; + let currentIndex = this.config.startIndex; + const processItems = (items, isSubMenu = false) => { + for (const item of items) { + if (item.children && item.children.length > 0) { + // Submenu start + entries.push({ + key: `[${this.baseKey}\\${currentIndex}]`, + values: this.itemToRegistryValues(item, 'submenu') + }); + currentIndex++; + // Process children + processItems(item.children, true); + // Submenu end + entries.push({ + key: `[${this.baseKey}\\${currentIndex}]`, + values: { + '"Item Name"': '"(Submenu End)"', + '"Command"': '""', + '"Arguments"': '""', + '"Initial Directory"': '""', + '"Execute Through Shell"': 'dword:00000000', + '"Close Shell Window"': 'dword:00000000', + '"Open Shell Window"': 'dword:00000000', + '"Icon"': '""', + '"Type"': 'dword:00000002', + '"Show In Toolbar"': 'dword:00000000' + } + }); + currentIndex++; + } + else { + // Regular command + entries.push({ + key: `[${this.baseKey}\\${currentIndex}]`, + values: this.itemToRegistryValues(item, 'command') + }); + currentIndex++; + } + } + }; + processItems(this.config.items); + return entries; + } + /** + * Convert menu item to registry values + */ + itemToRegistryValues(item, type) { + const values = { + '"Item Name"': `"${item.name}"`, + '"Command"': `"${item.command || ''}"`, + '"Arguments"': `"${this.escapeArguments(item.arguments || '')}"`, + '"Initial Directory"': `"${item.initialDirectory || ''}"`, + '"Execute Through Shell"': item.executeThoughShell !== false ? 'dword:00000001' : 'dword:00000000', + '"Close Shell Window"': item.closeShellWindow === true ? 'dword:00000001' : 'dword:00000000', + '"Open Shell Window"': item.openShellWindow !== false ? 'dword:00000001' : 'dword:00000000', + '"Icon"': `"${item.icon || ''}"`, + '"Type"': type === 'submenu' ? 'dword:00000001' : 'dword:00000000', + '"Show In Toolbar"': item.showInToolbar !== false ? 'dword:00000001' : 'dword:00000000' + }; + return values; + } + /** + * Escape arguments for registry format + */ + escapeArguments(args) { + return args + .replace(/\\/g, '\\\\') // Escape backslashes + .replace(/"/g, '\\\\"'); // Escape quotes + } + /** + * Generate registry file content + */ + generateRegistryFile() { + const entries = this.generateRegistryEntries(); + let content = 'REGEDIT4\n\n'; + for (const entry of entries) { + content += `${entry.key}\n`; + for (const [key, value] of Object.entries(entry.values)) { + content += `${key}=${value}\n`; + } + content += '\n'; + } + return content; + } + /** + * Save registry file to disk + */ + saveRegistryFile(outputPath) { + const content = this.generateRegistryFile(); + // Ensure output directory exists + const dir = path.dirname(outputPath); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } + fs.writeFileSync(outputPath, content, 'utf8'); + } + /** + * Load menu configuration from JSON file + */ + static loadFromJson(jsonPath) { + if (!fs.existsSync(jsonPath)) { + throw new Error(`JSON configuration file not found: ${jsonPath}`); + } + const content = fs.readFileSync(jsonPath, 'utf8'); + return JSON.parse(content); + } + /** + * Find insertion point in existing registry + */ + static findInsertionPoint(registryPath, groupName) { + if (!fs.existsSync(registryPath)) { + return 1; // Start at index 1 if no existing registry + } + const maxIndex = this.parseExistingRegistry(registryPath); + if (!groupName) { + return maxIndex + 1; + } + // Find group and insert before submenu end + const content = fs.readFileSync(registryPath, 'utf8'); + const lines = content.split('\n'); + let inTargetGroup = false; + let groupStartIndex = -1; + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + // Check for menu entry + const menuMatch = line.match(/\\User Menu\\(\d+)\]/); + if (menuMatch) { + const index = parseInt(menuMatch[1], 10); + // Look for item name in next few lines + for (let j = i + 1; j < Math.min(i + 10, lines.length); j++) { + const nameLine = lines[j]; + if (nameLine.includes('"Item Name"')) { + const nameMatch = nameLine.match(/"Item Name"="([^"]+)"/); + if (nameMatch) { + const itemName = nameMatch[1]; + if (itemName === groupName) { + inTargetGroup = true; + groupStartIndex = index; + } + else if (itemName === '(Submenu End)' && inTargetGroup) { + return index; // Insert before submenu end + } + } + break; + } + } + } + } + return maxIndex + 1; // Fallback to end + } +} +/** + * Windows Registry helper for direct registry operations using regedit package + */ +export class WindowsRegistry { + static isWindows() { + return process.platform === 'win32' && promisified !== null; + } + static ensureRegedit() { + if (!this.isWindows()) { + throw new Error('Registry operations are only supported on Windows with regedit package installed'); + } + } + /** + * Read all User Menu entries from registry + */ + static async readUserMenuEntries(baseKey = 'HKCU\\Software\\Altap\\Altap Salamander 4.0\\User Menu') { + this.ensureRegedit(); + try { + const result = await promisified.list([baseKey]); + return result[baseKey] || { exists: false, keys: [], values: {} }; + } + catch (error) { + return { exists: false, keys: [], values: {} }; + } + } + /** + * Read specific menu entry by index + */ + static async readMenuEntry(index, baseKey = 'HKCU\\Software\\Altap\\Altap Salamander 4.0\\User Menu') { + this.ensureRegedit(); + const keyPath = `${baseKey}\\${index}`; + try { + const result = await promisified.list([keyPath]); + return result[keyPath] || { exists: false, keys: [], values: {} }; + } + catch (error) { + return { exists: false, keys: [], values: {} }; + } + } + /** + * Get all existing menu indices + */ + static async getExistingMenuIndices(baseKey = 'HKCU\\Software\\Altap\\Altap Salamander 4.0\\User Menu') { + this.ensureRegedit(); + const menuData = await this.readUserMenuEntries(baseKey); + if (!menuData.exists) { + return []; + } + return menuData.keys + .map((key) => parseInt(key, 10)) + .filter((index) => !isNaN(index)) + .sort((a, b) => a - b); + } + /** + * Get next available menu index + */ + static async getNextMenuIndex(baseKey = 'HKCU\\Software\\Altap\\Altap Salamander 4.0\\User Menu') { + const indices = await this.getExistingMenuIndices(baseKey); + return indices.length > 0 ? Math.max(...indices) + 1 : 1; + } + /** + * Find insertion point for a specific group + */ + static async findGroupInsertionPoint(groupName, baseKey = 'HKCU\\Software\\Altap\\Altap Salamander 4.0\\User Menu') { + this.ensureRegedit(); + const indices = await this.getExistingMenuIndices(baseKey); + let inTargetGroup = false; + for (const index of indices) { + const entry = await this.readMenuEntry(index, baseKey); + if (entry.exists && entry.values['Item Name']) { + const itemName = entry.values['Item Name'].value; + if (itemName === groupName) { + inTargetGroup = true; + } + else if (itemName === '(Submenu End)' && inTargetGroup) { + return index; // Insert before submenu end + } + } + } + return await this.getNextMenuIndex(baseKey); // Fallback to end + } + /** + * Write registry values for a menu entry + */ + static async writeMenuEntry(index, values, baseKey = 'HKCU\\Software\\Altap\\Altap Salamander 4.0\\User Menu') { + this.ensureRegedit(); + const keyPath = `${baseKey}\\${index}`; + // First create the key + await promisified.createKey([keyPath]); + // Then write the values + const valuesToWrite = {}; + valuesToWrite[keyPath] = {}; + for (const [valueName, valueData] of Object.entries(values)) { + const cleanValueName = valueName.replace(/"/g, ''); + let cleanValueData = String(valueData); + let valueType = 'REG_SZ'; + if (cleanValueData.startsWith('dword:')) { + valueType = 'REG_DWORD'; + cleanValueData = parseInt(cleanValueData.replace('dword:', ''), 16).toString(); + } + else { + cleanValueData = cleanValueData.replace(/"/g, ''); + } + valuesToWrite[keyPath][cleanValueName] = { + value: cleanValueData, + type: valueType + }; + } + await promisified.putValue(valuesToWrite); + } + /** + * Delete a menu entry + */ + static async deleteMenuEntry(index, baseKey = 'HKCU\\Software\\Altap\\Altap Salamander 4.0\\User Menu') { + this.ensureRegedit(); + const keyPath = `${baseKey}\\${index}`; + try { + await promisified.deleteKey([keyPath]); + } + catch (error) { + // Key might not exist, ignore error + } + } + /** + * List all menu entries with their details + */ + static async listAllMenuEntries(baseKey = 'HKCU\\Software\\Altap\\Altap Salamander 4.0\\User Menu') { + const indices = await this.getExistingMenuIndices(baseKey); + const entries = []; + for (const index of indices) { + const entry = await this.readMenuEntry(index, baseKey); + if (entry.exists && entry.values['Item Name']) { + const name = entry.values['Item Name'].value; + const type = entry.values['Type'] ? entry.values['Type'].value : 0; + const command = entry.values['Command'] ? entry.values['Command'].value : ''; + let typeString = 'command'; + if (type === 1 || type === '0x00000001') + typeString = 'submenu'; + if (type === 2 || type === '0x00000002') + typeString = 'submenu-end'; + entries.push({ + index, + name, + type: typeString, + command: command || undefined + }); + } + } + return entries; + } +} +/** + * Extended Salamander Menu Generator with direct registry support + */ +export class SalamanderMenuGeneratorRegistry extends SalamanderMenuGenerator { + /** + * Apply menu configuration directly to Windows registry + */ + async applyToRegistry() { + if (process.platform !== 'win32') { + throw new Error('Direct registry operations are only supported on Windows'); + } + const entries = this.generateRegistryEntries(); + for (const entry of entries) { + // Extract menu index from key + const keyMatch = entry.key.match(/\\User Menu\\(\d+)\]/); + if (!keyMatch) + continue; + const menuIndex = parseInt(keyMatch[1], 10); + await WindowsRegistry.writeMenuEntry(menuIndex, entry.values); + } + } + /** + * Remove menu entries from Windows registry + */ + async removeFromRegistry() { + if (process.platform !== 'win32') { + throw new Error('Direct registry operations are only supported on Windows'); + } + const entries = this.generateRegistryEntries(); + // Remove in reverse order to avoid index issues + for (let i = entries.length - 1; i >= 0; i--) { + const entry = entries[i]; + const keyMatch = entry.key.match(/\\User Menu\\(\d+)\]/); + if (keyMatch) { + const menuIndex = parseInt(keyMatch[1], 10); + await WindowsRegistry.deleteMenuEntry(menuIndex); + } + } + } + /** + * Auto-detect insertion point from Windows registry + */ + static async autoDetectInsertionPoint(groupName) { + if (process.platform !== 'win32') { + throw new Error('Registry operations are only supported on Windows'); + } + if (groupName) { + return await WindowsRegistry.findGroupInsertionPoint(groupName); + } + else { + return await WindowsRegistry.getNextMenuIndex(); + } + } + /** + * List current menu entries from registry + */ + static async listCurrentMenuEntries() { + return await WindowsRegistry.listAllMenuEntries(); + } +} +export default SalamanderMenuGenerator; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3NhbGFtYW5kZXIvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDekIsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxPQUFPLE1BQU0sU0FBUyxDQUFDO0FBRTlCLE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUM7QUEyQnhDLE1BQU0sT0FBTyx1QkFBdUI7SUFHZDtJQUZaLE9BQU8sR0FBVyxxRUFBcUUsQ0FBQztJQUVoRyxZQUFvQixNQUE0QjtRQUE1QixXQUFNLEdBQU4sTUFBTSxDQUFzQjtRQUM5QyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUM7UUFDaEMsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxZQUFvQjtRQUMvQyxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1lBQ2pDLE9BQU8sQ0FBQyxDQUFDO1FBQ1gsQ0FBQztRQUVELE1BQU0sT0FBTyxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3RELE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbEMsSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDO1FBRWpCLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7WUFDekIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1lBQ2pELElBQUksS0FBSyxFQUFFLENBQUM7Z0JBQ1YsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDckMsSUFBSSxLQUFLLEdBQUcsUUFBUSxFQUFFLENBQUM7b0JBQ3JCLFFBQVEsR0FBRyxLQUFLLENBQUM7Z0JBQ25CLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7SUFFRDs7T0FFRztJQUNILHVCQUF1QjtRQUNyQixNQUFNLE9BQU8sR0FBb0IsRUFBRSxDQUFDO1FBQ3BDLElBQUksWUFBWSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDO1FBRTFDLE1BQU0sWUFBWSxHQUFHLENBQUMsS0FBMkIsRUFBRSxTQUFTLEdBQUcsS0FBSyxFQUFFLEVBQUU7WUFDdEUsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztnQkFDekIsSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO29CQUM5QyxnQkFBZ0I7b0JBQ2hCLE9BQU8sQ0FBQyxJQUFJLENBQUM7d0JBQ1gsR0FBRyxFQUFFLElBQUksSUFBSSxDQUFDLE9BQU8sS0FBSyxZQUFZLEdBQUc7d0JBQ3pDLE1BQU0sRUFBRSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQztxQkFDbkQsQ0FBQyxDQUFDO29CQUNILFlBQVksRUFBRSxDQUFDO29CQUVmLG1CQUFtQjtvQkFDbkIsWUFBWSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7b0JBRWxDLGNBQWM7b0JBQ2QsT0FBTyxDQUFDLElBQUksQ0FBQzt3QkFDWCxHQUFHLEVBQUUsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLFlBQVksR0FBRzt3QkFDekMsTUFBTSxFQUFFOzRCQUNOLGFBQWEsRUFBRSxpQkFBaUI7NEJBQ2hDLFdBQVcsRUFBRSxJQUFJOzRCQUNqQixhQUFhLEVBQUUsSUFBSTs0QkFDbkIscUJBQXFCLEVBQUUsSUFBSTs0QkFDM0IseUJBQXlCLEVBQUUsZ0JBQWdCOzRCQUMzQyxzQkFBc0IsRUFBRSxnQkFBZ0I7NEJBQ3hDLHFCQUFxQixFQUFFLGdCQUFnQjs0QkFDdkMsUUFBUSxFQUFFLElBQUk7NEJBQ2QsUUFBUSxFQUFFLGdCQUFnQjs0QkFDMUIsbUJBQW1CLEVBQUUsZ0JBQWdCO3lCQUN0QztxQkFDRixDQUFDLENBQUM7b0JBQ0gsWUFBWSxFQUFFLENBQUM7Z0JBQ2pCLENBQUM7cUJBQU0sQ0FBQztvQkFDTixrQkFBa0I7b0JBQ2xCLE9BQU8sQ0FBQyxJQUFJLENBQUM7d0JBQ1gsR0FBRyxFQUFFLElBQUksSUFBSSxDQUFDLE9BQU8sS0FBSyxZQUFZLEdBQUc7d0JBQ3pDLE1BQU0sRUFBRSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQztxQkFDbkQsQ0FBQyxDQUFDO29CQUNILFlBQVksRUFBRSxDQUFDO2dCQUNqQixDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUMsQ0FBQztRQUVGLFlBQVksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2hDLE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFRDs7T0FFRztJQUNLLG9CQUFvQixDQUFDLElBQXdCLEVBQUUsSUFBMkI7UUFDaEYsTUFBTSxNQUFNLEdBQW9DO1lBQzlDLGFBQWEsRUFBRSxJQUFJLElBQUksQ0FBQyxJQUFJLEdBQUc7WUFDL0IsV0FBVyxFQUFFLElBQUksSUFBSSxDQUFDLE9BQU8sSUFBSSxFQUFFLEdBQUc7WUFDdEMsYUFBYSxFQUFFLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLEVBQUUsQ0FBQyxHQUFHO1lBQ2hFLHFCQUFxQixFQUFFLElBQUksSUFBSSxDQUFDLGdCQUFnQixJQUFJLEVBQUUsR0FBRztZQUN6RCx5QkFBeUIsRUFBRSxJQUFJLENBQUMsa0JBQWtCLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCO1lBQ2xHLHNCQUFzQixFQUFFLElBQUksQ0FBQyxnQkFBZ0IsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxnQkFBZ0I7WUFDNUYscUJBQXFCLEVBQUUsSUFBSSxDQUFDLGVBQWUsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxnQkFBZ0I7WUFDM0YsUUFBUSxFQUFFLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxFQUFFLEdBQUc7WUFDaEMsUUFBUSxFQUFFLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxnQkFBZ0I7WUFDbEUsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLGFBQWEsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxnQkFBZ0I7U0FDeEYsQ0FBQztRQUVGLE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRDs7T0FFRztJQUNLLGVBQWUsQ0FBQyxJQUFZO1FBQ2xDLE9BQU8sSUFBSTthQUNSLE9BQU8sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUUscUJBQXFCO2FBQzdDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxnQkFBZ0I7SUFDN0MsQ0FBQztJQUVEOztPQUVHO0lBQ0gsb0JBQW9CO1FBQ2xCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBQy9DLElBQUksT0FBTyxHQUFHLGNBQWMsQ0FBQztRQUU3QixLQUFLLE1BQU0sS0FBSyxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQzVCLE9BQU8sSUFBSSxHQUFHLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQztZQUU1QixLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztnQkFDeEQsT0FBTyxJQUFJLEdBQUcsR0FBRyxJQUFJLEtBQUssSUFBSSxDQUFDO1lBQ2pDLENBQUM7WUFFRCxPQUFPLElBQUksSUFBSSxDQUFDO1FBQ2xCLENBQUM7UUFFRCxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxnQkFBZ0IsQ0FBQyxVQUFrQjtRQUNqQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUU1QyxpQ0FBaUM7UUFDakMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3hCLEVBQUUsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDekMsQ0FBQztRQUVELEVBQUUsQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsWUFBWSxDQUFDLFFBQWdCO1FBQ2xDLElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDN0IsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQ0FBc0MsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUNwRSxDQUFDO1FBRUQsTUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDbEQsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBeUIsQ0FBQztJQUNyRCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsa0JBQWtCLENBQUMsWUFBb0IsRUFBRSxTQUFrQjtRQUNoRSxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1lBQ2pDLE9BQU8sQ0FBQyxDQUFDLENBQUMsMkNBQTJDO1FBQ3ZELENBQUM7UUFFRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsWUFBWSxDQUFDLENBQUM7UUFFMUQsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ2YsT0FBTyxRQUFRLEdBQUcsQ0FBQyxDQUFDO1FBQ3RCLENBQUM7UUFFRCwyQ0FBMkM7UUFDM0MsTUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDdEQsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVsQyxJQUFJLGFBQWEsR0FBRyxLQUFLLENBQUM7UUFDMUIsSUFBSSxlQUFlLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFekIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUN0QyxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFdEIsdUJBQXVCO1lBQ3ZCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCLENBQUMsQ0FBQztZQUNyRCxJQUFJLFNBQVMsRUFBRSxDQUFDO2dCQUNkLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBRXpDLHVDQUF1QztnQkFDdkMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7b0JBQzVELE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDMUIsSUFBSSxRQUFRLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUM7d0JBQ3JDLE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsdUJBQXVCLENBQUMsQ0FBQzt3QkFDMUQsSUFBSSxTQUFTLEVBQUUsQ0FBQzs0QkFDZCxNQUFNLFFBQVEsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7NEJBRTlCLElBQUksUUFBUSxLQUFLLFNBQVMsRUFBRSxDQUFDO2dDQUMzQixhQUFhLEdBQUcsSUFBSSxDQUFDO2dDQUNyQixlQUFlLEdBQUcsS0FBSyxDQUFDOzRCQUMxQixDQUFDO2lDQUFNLElBQUksUUFBUSxLQUFLLGVBQWUsSUFBSSxhQUFhLEVBQUUsQ0FBQztnQ0FDekQsT0FBTyxLQUFLLENBQUMsQ0FBQyw0QkFBNEI7NEJBQzVDLENBQUM7d0JBQ0gsQ0FBQzt3QkFDRCxNQUFNO29CQUNSLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxRQUFRLEdBQUcsQ0FBQyxDQUFDLENBQUMsa0JBQWtCO0lBQ3pDLENBQUM7Q0FDRjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGVBQWU7SUFDbEIsTUFBTSxDQUFDLFNBQVM7UUFDdEIsT0FBTyxPQUFPLENBQUMsUUFBUSxLQUFLLE9BQU8sSUFBSSxXQUFXLEtBQUssSUFBSSxDQUFDO0lBQzlELENBQUM7SUFFTyxNQUFNLENBQUMsYUFBYTtRQUMxQixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUM7WUFDdEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxrRkFBa0YsQ0FBQyxDQUFDO1FBQ3RHLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLG1CQUFtQixDQUFDLFVBQWtCLHdEQUF3RDtRQUN6RyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFFckIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUNqRCxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLENBQUM7UUFDcEUsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUNqRCxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsS0FBYSxFQUFFLFVBQWtCLHdEQUF3RDtRQUNsSCxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFFckIsTUFBTSxPQUFPLEdBQUcsR0FBRyxPQUFPLEtBQUssS0FBSyxFQUFFLENBQUM7UUFDdkMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUNqRCxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLENBQUM7UUFDcEUsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUNqRCxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxVQUFrQix3REFBd0Q7UUFDNUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBRXJCLE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3pELElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDckIsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDO1FBRUQsT0FBTyxRQUFRLENBQUMsSUFBSTthQUNqQixHQUFHLENBQUMsQ0FBQyxHQUFXLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7YUFDdkMsTUFBTSxDQUFDLENBQUMsS0FBYSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUN4QyxJQUFJLENBQUMsQ0FBQyxDQUFTLEVBQUUsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUVEOztPQUVHO0lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFrQix3REFBd0Q7UUFDdEcsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDM0QsT0FBTyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsdUJBQXVCLENBQUMsU0FBaUIsRUFBRSxVQUFrQix3REFBd0Q7UUFDaEksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBRXJCLE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRTNELElBQUksYUFBYSxHQUFHLEtBQUssQ0FBQztRQUUxQixLQUFLLE1BQU0sS0FBSyxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQzVCLE1BQU0sS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFFdkQsSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztnQkFDOUMsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxLQUFLLENBQUM7Z0JBRWpELElBQUksUUFBUSxLQUFLLFNBQVMsRUFBRSxDQUFDO29CQUMzQixhQUFhLEdBQUcsSUFBSSxDQUFDO2dCQUN2QixDQUFDO3FCQUFNLElBQUksUUFBUSxLQUFLLGVBQWUsSUFBSSxhQUFhLEVBQUUsQ0FBQztvQkFDekQsT0FBTyxLQUFLLENBQUMsQ0FBQyw0QkFBNEI7Z0JBQzVDLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxrQkFBa0I7SUFDakUsQ0FBQztJQUVEOztPQUVHO0lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsS0FBYSxFQUFFLE1BQTJCLEVBQUUsVUFBa0Isd0RBQXdEO1FBQ2hKLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUVyQixNQUFNLE9BQU8sR0FBRyxHQUFHLE9BQU8sS0FBSyxLQUFLLEVBQUUsQ0FBQztRQUV2Qyx1QkFBdUI7UUFDdkIsTUFBTSxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUV2Qyx3QkFBd0I7UUFDeEIsTUFBTSxhQUFhLEdBQXdCLEVBQUUsQ0FBQztRQUM5QyxhQUFhLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBRTVCLEtBQUssTUFBTSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDNUQsTUFBTSxjQUFjLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDbkQsSUFBSSxjQUFjLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ3ZDLElBQUksU0FBUyxHQUFHLFFBQVEsQ0FBQztZQUV6QixJQUFJLGNBQWMsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztnQkFDeEMsU0FBUyxHQUFHLFdBQVcsQ0FBQztnQkFDeEIsY0FBYyxHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNqRixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sY0FBYyxHQUFHLGNBQWMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ3BELENBQUM7WUFFRCxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsY0FBYyxDQUFDLEdBQUc7Z0JBQ3ZDLEtBQUssRUFBRSxjQUFjO2dCQUNyQixJQUFJLEVBQUUsU0FBUzthQUNoQixDQUFDO1FBQ0osQ0FBQztRQUVELE1BQU0sV0FBVyxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxLQUFhLEVBQUUsVUFBa0Isd0RBQXdEO1FBQ3BILElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUVyQixNQUFNLE9BQU8sR0FBRyxHQUFHLE9BQU8sS0FBSyxLQUFLLEVBQUUsQ0FBQztRQUV2QyxJQUFJLENBQUM7WUFDSCxNQUFNLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ3pDLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2Ysb0NBQW9DO1FBQ3RDLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFVBQWtCLHdEQUF3RDtRQUN4RyxNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMzRCxNQUFNLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFFbkIsS0FBSyxNQUFNLEtBQUssSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUM1QixNQUFNLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBRXZELElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7Z0JBQzlDLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsS0FBSyxDQUFDO2dCQUM3QyxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNuRSxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUU3RSxJQUFJLFVBQVUsR0FBRyxTQUFTLENBQUM7Z0JBQzNCLElBQUksSUFBSSxLQUFLLENBQUMsSUFBSSxJQUFJLEtBQUssWUFBWTtvQkFBRSxVQUFVLEdBQUcsU0FBUyxDQUFDO2dCQUNoRSxJQUFJLElBQUksS0FBSyxDQUFDLElBQUksSUFBSSxLQUFLLFlBQVk7b0JBQUUsVUFBVSxHQUFHLGFBQWEsQ0FBQztnQkFFcEUsT0FBTyxDQUFDLElBQUksQ0FBQztvQkFDWCxLQUFLO29CQUNMLElBQUk7b0JBQ0osSUFBSSxFQUFFLFVBQVU7b0JBQ2hCLE9BQU8sRUFBRSxPQUFPLElBQUksU0FBUztpQkFDOUIsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0NBQ0Y7QUFFRDs7R0FFRztBQUNILE1BQU0sT0FBTywrQkFBZ0MsU0FBUSx1QkFBdUI7SUFFMUU7O09BRUc7SUFDSCxLQUFLLENBQUMsZUFBZTtRQUNuQixJQUFJLE9BQU8sQ0FBQyxRQUFRLEtBQUssT0FBTyxFQUFFLENBQUM7WUFDakMsTUFBTSxJQUFJLEtBQUssQ0FBQywwREFBMEQsQ0FBQyxDQUFDO1FBQzlFLENBQUM7UUFFRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztRQUUvQyxLQUFLLE1BQU0sS0FBSyxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQzVCLDhCQUE4QjtZQUM5QixNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1lBQ3pELElBQUksQ0FBQyxRQUFRO2dCQUFFLFNBQVM7WUFFeEIsTUFBTSxTQUFTLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUU1QyxNQUFNLGVBQWUsQ0FBQyxjQUFjLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNoRSxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLGtCQUFrQjtRQUN0QixJQUFJLE9BQU8sQ0FBQyxRQUFRLEtBQUssT0FBTyxFQUFFLENBQUM7WUFDakMsTUFBTSxJQUFJLEtBQUssQ0FBQywwREFBMEQsQ0FBQyxDQUFDO1FBQzlFLENBQUM7UUFFRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztRQUUvQyxnREFBZ0Q7UUFDaEQsS0FBSyxJQUFJLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDN0MsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3pCLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUM7WUFDekQsSUFBSSxRQUFRLEVBQUUsQ0FBQztnQkFDYixNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUM1QyxNQUFNLGVBQWUsQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDbkQsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLHdCQUF3QixDQUFDLFNBQWtCO1FBQ3RELElBQUksT0FBTyxDQUFDLFFBQVEsS0FBSyxPQUFPLEVBQUUsQ0FBQztZQUNqQyxNQUFNLElBQUksS0FBSyxDQUFDLG1EQUFtRCxDQUFDLENBQUM7UUFDdkUsQ0FBQztRQUVELElBQUksU0FBUyxFQUFFLENBQUM7WUFDZCxPQUFPLE1BQU0sZUFBZSxDQUFDLHVCQUF1QixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2xFLENBQUM7YUFBTSxDQUFDO1lBQ04sT0FBTyxNQUFNLGVBQWUsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ2xELENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLHNCQUFzQjtRQUNqQyxPQUFPLE1BQU0sZUFBZSxDQUFDLGtCQUFrQixFQUFFLENBQUM7SUFDcEQsQ0FBQztDQUNGO0FBRUQsZUFBZSx1QkFBdUIsQ0FBQyJ9 \ No newline at end of file diff --git a/packages/media/dist-in/main.d.ts b/packages/media/dist-in/main.d.ts index a8a06eb8..3bf1036c 100644 --- a/packages/media/dist-in/main.d.ts +++ b/packages/media/dist-in/main.d.ts @@ -5,3 +5,6 @@ import './commands/watermark.js'; import './commands/background-remove.js'; import './commands/background-remove-bria.js'; import './commands/crop-foreground.js'; +import './commands/salamander.js'; +import './commands/register-commands.js'; +import './commands/register-explorer.js'; diff --git a/packages/media/dist-in/main.js b/packages/media/dist-in/main.js index 00c1fd13..46b29369 100644 --- a/packages/media/dist-in/main.js +++ b/packages/media/dist-in/main.js @@ -8,6 +8,9 @@ import './commands/watermark.js'; import './commands/background-remove.js'; import './commands/background-remove-bria.js'; import './commands/crop-foreground.js'; +import './commands/salamander.js'; +import './commands/register-commands.js'; +import './commands/register-explorer.js'; const argv = cli.argv; if (argv.h || argv.help) { cli.showHelp(); @@ -16,4 +19,4 @@ if (argv.h || argv.help) { else if (argv.v || argv.version) { process.exit(); } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9tYWluLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFDQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQUMsUUFBUSxFQUFFLENBQUE7QUFFaEQsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQUU5QixPQUFPLHNCQUFzQixDQUFBO0FBQzdCLE9BQU8sdUJBQXVCLENBQUE7QUFDOUIsT0FBTyx5QkFBeUIsQ0FBQTtBQUNoQyxPQUFPLGlDQUFpQyxDQUFBO0FBQ3hDLE9BQU8sc0NBQXNDLENBQUE7QUFDN0MsT0FBTywrQkFBK0IsQ0FBQTtBQUV0QyxNQUFNLElBQUksR0FBUSxHQUFHLENBQUMsSUFBSSxDQUFDO0FBRTNCLElBQUksSUFBSSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDdEIsR0FBRyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ2YsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO0FBQ25CLENBQUM7S0FBTSxJQUFJLElBQUksQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2hDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUNuQixDQUFDIn0= \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9tYWluLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFDQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQUMsUUFBUSxFQUFFLENBQUE7QUFFaEQsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQUU5QixPQUFPLHNCQUFzQixDQUFBO0FBQzdCLE9BQU8sdUJBQXVCLENBQUE7QUFDOUIsT0FBTyx5QkFBeUIsQ0FBQTtBQUNoQyxPQUFPLGlDQUFpQyxDQUFBO0FBQ3hDLE9BQU8sc0NBQXNDLENBQUE7QUFDN0MsT0FBTywrQkFBK0IsQ0FBQTtBQUN0QyxPQUFPLDBCQUEwQixDQUFBO0FBQ2pDLE9BQU8saUNBQWlDLENBQUE7QUFDeEMsT0FBTyxpQ0FBaUMsQ0FBQTtBQUV4QyxNQUFNLElBQUksR0FBUSxHQUFHLENBQUMsSUFBSSxDQUFDO0FBRTNCLElBQUksSUFBSSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDdEIsR0FBRyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ2YsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO0FBQ25CLENBQUM7S0FBTSxJQUFJLElBQUksQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2hDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUNuQixDQUFDIn0= \ No newline at end of file diff --git a/packages/media/integration/salamander-menu-sample.json b/packages/media/integration/salamander-menu-sample.json new file mode 100644 index 00000000..7fef3555 --- /dev/null +++ b/packages/media/integration/salamander-menu-sample.json @@ -0,0 +1,52 @@ +{ + "baseKey": "HKEY_CURRENT_USER\\Software\\Altap\\Altap Salamander 4.0\\User Menu", + "startIndex": 5, + "items": [ + { + "name": "Background Remove (Bria)", + "command": "pm-media", + "arguments": "background:remove:bria --alt=true --logLevel=info --src=\\\"$(FullName)/**/*.+(&{IMAGES})\\\" --dst=\\\"&{SRC_DIR}/&{SRC_NAME}_nobg.png\\\" --jpg", + "initialDirectory": "$(FullPath)", + "executeThoughShell": true, + "closeShellWindow": false, + "openShellWindow": true, + "icon": "", + "showInToolbar": true + }, + { + "name": "Convert Tools", + "children": [ + { + "name": "To WebP", + "command": "pm-media", + "arguments": "convert --alt=true --logLevel=info --src=\\\"$(FullName)/**/*.+(&{IMAGES})\\\" --dst=\\\"&{SRC_DIR}/&{SRC_NAME}.webp\\\"", + "initialDirectory": "$(FullPath)", + "executeThoughShell": true, + "closeShellWindow": true, + "openShellWindow": true, + "showInToolbar": true + }, + { + "name": "To PNG", + "command": "pm-media", + "arguments": "convert --alt=true --logLevel=info --src=\\\"$(FullName)/**/*.+(&{IMAGES})\\\" --dst=\\\"&{SRC_DIR}/&{SRC_NAME}.png\\\"", + "initialDirectory": "$(FullPath)", + "executeThoughShell": true, + "closeShellWindow": true, + "openShellWindow": true, + "showInToolbar": true + } + ] + }, + { + "name": "PDF to Images", + "command": "pm-media", + "arguments": "pdf2jpg --alt=true --logLevel=info --src=\\\"$(FullName)\\\" --dst=\\\"&{SRC_DIR}/&{SRC_NAME}\\\"", + "initialDirectory": "$(FullPath)", + "executeThoughShell": true, + "closeShellWindow": false, + "openShellWindow": true, + "showInToolbar": true + } + ] +} diff --git a/packages/media/package-lock.json b/packages/media/package-lock.json index 63aa1504..7ce72334 100644 --- a/packages/media/package-lock.json +++ b/packages/media/package-lock.json @@ -25,6 +25,7 @@ "mupdf": "^1.3.3", "novita-sdk": "^1.0.37", "p-map": "^7.0.3", + "regedit": "^5.1.4", "replicate": "^1.0.1", "sharp": "^0.34.2", "tslog": "^4.9.3", @@ -2207,7 +2208,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -3205,6 +3205,12 @@ ], "license": "BSD-3-Clause" }, + "node_modules/if-async": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/if-async/-/if-async-3.7.4.tgz", + "integrity": "sha512-BFEH2mZyeF6KZKaKLVPZ0wMjIiWOdjvZ7zbx8ENec0qfZhJwKFbX/4jKM5LTKyJEc/GOqUKiiJ2IFKT9yWrZqA==", + "license": "MIT" + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -3615,7 +3621,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/mupdf": { @@ -4011,6 +4016,18 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/regedit": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/regedit/-/regedit-5.1.4.tgz", + "integrity": "sha512-3VQ8BY2unUdl4nSx19QAn+pUlkqJhRbIsQc0zciWIVmELLXQLIHvdytUfcI56XYJZj3r9rkb7NTKxkQaXSYnow==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "if-async": "^3.7.4", + "stream-slicer": "0.0.6", + "through2": "^0.6.3" + } + }, "node_modules/replicate": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/replicate/-/replicate-1.0.1.tgz", @@ -4333,6 +4350,12 @@ "dev": true, "license": "MIT" }, + "node_modules/stream-slicer": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stream-slicer/-/stream-slicer-0.0.6.tgz", + "integrity": "sha512-QsY0LbweYE5L+e+iBQgtkM5WUIf7+kCMA/m2VULv8rEEDDnlDPsPvOHH4nli6uaZOKQEt64u65h0l/eeZo7lCw==", + "license": "MIT" + }, "node_modules/strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", @@ -4542,6 +4565,40 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "license": "MIT" }, + "node_modules/through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg==", + "license": "MIT", + "dependencies": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "node_modules/through2/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "license": "MIT" + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "license": "MIT" + }, "node_modules/timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", @@ -6298,7 +6355,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "dev": true, "requires": { "ms": "^2.1.3" } @@ -6969,6 +7025,11 @@ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, + "if-async": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/if-async/-/if-async-3.7.4.tgz", + "integrity": "sha512-BFEH2mZyeF6KZKaKLVPZ0wMjIiWOdjvZ7zbx8ENec0qfZhJwKFbX/4jKM5LTKyJEc/GOqUKiiJ2IFKT9yWrZqA==" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -7248,8 +7309,7 @@ "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "mupdf": { "version": "1.26.2", @@ -7494,6 +7554,17 @@ "string_decoder": "^1.3.0" } }, + "regedit": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/regedit/-/regedit-5.1.4.tgz", + "integrity": "sha512-3VQ8BY2unUdl4nSx19QAn+pUlkqJhRbIsQc0zciWIVmELLXQLIHvdytUfcI56XYJZj3r9rkb7NTKxkQaXSYnow==", + "requires": { + "debug": "^4.1.0", + "if-async": "^3.7.4", + "stream-slicer": "0.0.6", + "through2": "^0.6.3" + } + }, "replicate": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/replicate/-/replicate-1.0.1.tgz", @@ -7703,6 +7774,11 @@ "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", "dev": true }, + "stream-slicer": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stream-slicer/-/stream-slicer-0.0.6.tgz", + "integrity": "sha512-QsY0LbweYE5L+e+iBQgtkM5WUIf7+kCMA/m2VULv8rEEDDnlDPsPvOHH4nli6uaZOKQEt64u65h0l/eeZo7lCw==" + }, "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", @@ -7858,6 +7934,38 @@ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg==", + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + } + } + }, "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", diff --git a/packages/media/package.json b/packages/media/package.json index 7d027be5..fe5631b7 100644 --- a/packages/media/package.json +++ b/packages/media/package.json @@ -29,6 +29,7 @@ "mupdf": "^1.3.3", "novita-sdk": "^1.0.37", "p-map": "^7.0.3", + "regedit": "^5.1.4", "replicate": "^1.0.1", "sharp": "^0.34.2", "tslog": "^4.9.3", diff --git a/packages/media/salamander-menu-watermark.reg b/packages/media/salamander-menu-watermark.reg new file mode 100644 index 00000000..054ae55c --- /dev/null +++ b/packages/media/salamander-menu-watermark.reg @@ -0,0 +1,14 @@ +REGEDIT4 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\1] +"Item Name"="Watermark" +"Command"="pm-media" +"Arguments"="watermark --src=\\" \\ --registry --group Media" +"Initial Directory"="$(FullPath)" +"Execute Through Shell"=dword:00000001 +"Close Shell Window"=dword:00000000 +"Open Shell Window"=dword:00000001 +"Icon"="" +"Type"=dword:00000000 +"Show In Toolbar"=dword:00000001 + diff --git a/packages/media/src/commands/background-remove-bria.ts b/packages/media/src/commands/background-remove-bria.ts index 39f44fc4..d3c39f9c 100644 --- a/packages/media/src/commands/background-remove-bria.ts +++ b/packages/media/src/commands/background-remove-bria.ts @@ -57,6 +57,10 @@ export const defaultOptions = (yargs: CLI.Argv) => { describe: 'Preserve alpha channel from input image', type: 'boolean', default: true + }).option('jpg', { + describe: 'Convert PNG output to JPG format and delete PNG', + type: 'boolean', + default: false }) } @@ -83,6 +87,7 @@ export async function handler(argv: CLI.Arguments) { options.sync = argv.sync as boolean; options.contentModeration = argv.contentModeration as boolean; options.preserveAlpha = argv.preserveAlpha as boolean; + options.jpg = argv.jpg as boolean; logger.info("Removing background with Bria AI options:", { sync: options.sync, diff --git a/packages/media/src/commands/register-commands.ts b/packages/media/src/commands/register-commands.ts new file mode 100644 index 00000000..40747e34 --- /dev/null +++ b/packages/media/src/commands/register-commands.ts @@ -0,0 +1,260 @@ +import * as CLI from 'yargs' +import * as fs from 'fs' +import * as path from 'path' +import { logger } from '../index.js' +import { cli } from '../cli.js' +import { defaults } from '../_cli.js' +import { SalamanderMenuGeneratorRegistry, WindowsRegistry } from '../lib/salamander/index.js' + +export const defaultOptions = (yargs: CLI.Argv) => { + return yargs.option('group', { + describe: 'Group name to register commands under', + type: 'string', + default: 'Media' + }).option('dry', { + default: false, + describe: 'Show what would be registered without actually registering', + type: 'boolean' + }).option('force', { + default: false, + describe: 'Force register even if command already exists', + type: 'boolean' + }).option('logLevel', { + describe: 'Log level : warn, info, debug, error', + type: 'string', + default: 'info' + }) +} + +export const command = 'register-commands' +export const desc = 'Register all pm-media commands in Salamander menu' +export const builder = defaultOptions + +interface CommandInfo { + name: string + command: string + args: string + description: string +} + +// Basic command mappings - users can extend these as needed +const COMMAND_MAPPINGS: Record = { + 'resize': { + name: 'Resize Images', + command: 'pm-media', + args: 'resize --alt=true --logLevel=info --src=\"$(FullName)/**/*.+(&{IMAGES})\" --dst=\"&{SRC_DIR}/&{SRC_NAME}_resized.&{SRC_EXT}\"', + description: 'Resize images' + }, + 'watermark': { + name: 'Add Watermark', + command: 'pm-media', + args: 'watermark --alt=true --logLevel=info --src=\"$(FullName)/**/*.+(&{IMAGES})\" --watermark=\"&{POLYMECH-ROOT}/nordin-ex/branding/polymech-saw-ex.svg\" --dst=\"&{SRC_DIR}/&{SRC_NAME}_watermarked.&{SRC_EXT}\"', + description: 'Add watermark to images' + }, + 'background-remove': { + name: 'Remove Background', + command: 'pm-media', + args: 'background:remove --alt=true --logLevel=info --src=\"$(FullName)/**/*.+(&{IMAGES})\" --dst=\"&{SRC_DIR}/&{SRC_NAME}_bg_removed.&{SRC_EXT}\"', + description: 'Remove background from images' + }, + 'background-remove-bria': { + name: 'Remove Background (Bria AI)', + command: 'pm-media', + args: 'background:remove:bria --alt=true --logLevel=info --src=\"$(FullName)/**/*.+(&{IMAGES})\" --dst=\"&{SRC_DIR}/&{SRC_NAME}_bria_bg_removed.&{SRC_EXT}\"', + description: 'Remove background using Bria AI' + }, + 'convert': { + name: 'Convert Format', + command: 'pm-media', + args: 'convert --alt=true --logLevel=info --src=\"$(FullName)/**/*.+(&{IMAGES})\" --dst=\"&{SRC_DIR}/&{SRC_NAME}_converted.jpg\"', + description: 'Convert image format' + }, + 'pdf2jpg': { + name: 'PDF to JPG', + command: 'pm-media', + args: 'pdf2jpg --alt=true --logLevel=info --src=\"$(FullName)/**/*.pdf\" --dst=\"&{SRC_DIR}/&{SRC_NAME}_page.jpg\"', + description: 'Convert PDF pages to JPG images' + }, + 'svg2jpg': { + name: 'SVG to JPG', + command: 'pm-media', + args: 'svg2jpg --alt=true --logLevel=info --src=\"$(FullName)/**/*.svg\" --dst=\"&{SRC_DIR}/&{SRC_NAME}.jpg\"', + description: 'Convert SVG to JPG' + }, + 'crop-foreground': { + name: 'Crop Foreground', + command: 'pm-media', + args: 'crop-foreground --alt=true --logLevel=info --src=\"$(FullName)/**/*.+(&{IMAGES})\" --dst=\"&{SRC_DIR}/&{SRC_NAME}_cropped.&{SRC_EXT}\"', + description: 'Crop to foreground content' + } +} + +async function getAvailableCommands(): Promise { + const commandsDir = path.join(process.cwd(), 'src', 'commands') + const files = fs.readdirSync(commandsDir) + + return files + .filter(file => file.endsWith('.ts') && + file !== 'salamander.ts' && + file !== 'register-commands.ts') + .map(file => file.replace('.ts', '')) + .filter(cmd => COMMAND_MAPPINGS[cmd]) // Only include commands we have mappings for +} + +export async function handler(argv: CLI.Arguments) { + defaults() + logger.settings.minLevel = argv.logLevel as any + + const options = { + group: argv.group as string, + dry: argv.dry as boolean, + force: argv.force as boolean + } + + try { + logger.info('Scanning available pm-media commands...') + const availableCommands = await getAvailableCommands() + logger.info(`Found ${availableCommands.length} commands: ${availableCommands.join(', ')}`) + + if (options.dry) { + logger.info('\n=== DRY RUN - Commands that would be registered ===') + for (const cmdName of availableCommands) { + const cmdInfo = COMMAND_MAPPINGS[cmdName] + logger.info(`\nCommand: ${cmdName}`) + logger.info(` Name: ${cmdInfo.name}`) + logger.info(` Args: ${cmdInfo.args}`) + logger.info(` Group: ${options.group}`) + } + return + } + + // Check which commands already exist + logger.info('Checking existing registry entries...') + const existingEntries = await WindowsRegistry.listAllMenuEntries() + const existingCommandNames = existingEntries + .filter(entry => entry.type === 'command') // Only commands, not submenus + .map(entry => entry.name) + + logger.info(`Found ${existingCommandNames.length} existing menu entries`) + + let registeredCount = 0 + let skippedCount = 0 + + // Check if the target group exists, create it if it doesn't + const groupExists = existingEntries.some(entry => + entry.type === 'submenu' && entry.name === options.group + ) + + let groupInsertionPoint: number + + if (!groupExists) { + logger.info(`Creating group: ${options.group}`) + + // Get the starting index for the new submenu + groupInsertionPoint = await WindowsRegistry.getNextMenuIndex() + + // Create the group submenu start + const groupStartValues = { + 'Item Name': options.group, + 'Command': '', + 'Arguments': '', + 'Initial Directory': '', + 'Execute Through Shell': 'dword:00000000', + 'Close Shell Window': 'dword:00000000', + 'Open Shell Window': 'dword:00000000', + 'Icon': '', + 'Type': 'dword:00000001', + 'Show In Toolbar': 'dword:00000001' + } + + await WindowsRegistry.writeMenuEntry(groupInsertionPoint, groupStartValues) + logger.info(`✓ Created group start: ${options.group} at index ${groupInsertionPoint}`) + + // Increment for the first command slot + groupInsertionPoint++ + } else { + logger.info(`Group '${options.group}' already exists`) + groupInsertionPoint = await WindowsRegistry.findGroupInsertionPoint(options.group) + } + + for (const cmdName of availableCommands) { + const cmdInfo = COMMAND_MAPPINGS[cmdName] + + // Check if command already exists + const exists = existingCommandNames.some(name => + name.toLowerCase().includes(cmdInfo.name.toLowerCase()) || + cmdInfo.name.toLowerCase().includes(name.toLowerCase()) + ) + + if (exists && !options.force) { + logger.info(`Skipping '${cmdInfo.name}' - already exists (use --force to override)`) + skippedCount++ + continue + } + + logger.info(`Registering: ${cmdInfo.name}`) + + try { + // Build registry values for the command + const values = { + 'Item Name': cmdInfo.name, + 'Command': cmdInfo.command, + 'Arguments': cmdInfo.args, + 'Initial Directory': '$(FullPath)', + 'Execute Through Shell': 'dword:00000001', + 'Close Shell Window': 'dword:00000001', + 'Open Shell Window': 'dword:00000001', + 'Icon': '', + 'Type': 'dword:00000000', + 'Show In Toolbar': 'dword:00000001' + } + + await WindowsRegistry.writeMenuEntry(groupInsertionPoint, values) + + registeredCount++ + logger.info(`✓ Registered: ${cmdInfo.name} at index ${groupInsertionPoint}`) + + // Increment insertion point for next command to insert them sequentially within the group + groupInsertionPoint++ + + } catch (error) { + logger.error(`Failed to register '${cmdInfo.name}':`, error) + } + } + + // If we created a new group and registered commands, add the submenu end + if (!groupExists && registeredCount > 0) { + const groupEndValues = { + 'Item Name': '(Submenu End)', + 'Command': '', + 'Arguments': '', + 'Initial Directory': '', + 'Execute Through Shell': 'dword:00000000', + 'Close Shell Window': 'dword:00000000', + 'Open Shell Window': 'dword:00000000', + 'Icon': '', + 'Type': 'dword:00000002', + 'Show In Toolbar': 'dword:00000000' + } + + await WindowsRegistry.writeMenuEntry(groupInsertionPoint, groupEndValues) + logger.info(`✓ Created group end at index ${groupInsertionPoint}`) + } + + logger.info(`\n=== Registration Complete ===`) + logger.info(`Registered: ${registeredCount} commands`) + logger.info(`Skipped: ${skippedCount} commands`) + logger.info(`Total available: ${availableCommands.length} commands`) + + if (registeredCount > 0) { + logger.info('\nCommands have been registered in Salamander\'s User Menu.') + logger.info('Restart Salamander to see the new menu entries.') + } + + } catch (error) { + logger.error('Failed to register commands:', error) + process.exit(1) + } +} + +cli.command(command, desc, builder, handler) diff --git a/packages/media/src/commands/register-explorer.ts b/packages/media/src/commands/register-explorer.ts new file mode 100644 index 00000000..5b4e60ba --- /dev/null +++ b/packages/media/src/commands/register-explorer.ts @@ -0,0 +1,240 @@ +import * as CLI from 'yargs' +import { logger } from '../index.js' +import { cli } from '../cli.js' +import { defaults } from '../_cli.js' +import regedit, { RegistryItemPutCollection, REG_SZ_Value } from 'regedit' + +export const defaultOptions = (yargs: CLI.Argv) => { + return yargs.option('group', { + describe: 'Group name for the context menu items', + type: 'string', + default: 'PM-Media' + }).option('unregister', { + default: false, + describe: 'Remove the shell extensions from Explorer', + type: 'boolean' + }).option('dry', { + default: false, + describe: 'Show what would be registered without actually doing it', + type: 'boolean' + }).option('logLevel', { + describe: 'Log level : warn, info, debug, error', + type: 'string', + default: 'info' + }) +} + +export const command = 'register-explorer' +export const desc = 'Register pm-media commands in Windows Explorer context menu for image files' +export const builder = defaultOptions + +// Image file extensions to register with +const IMAGE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.webp', '.svg'] + +// Command mappings for Explorer context menu +const EXPLORER_COMMANDS = [ + { + name: 'Convert to JPG', + command: 'pm-media', + args: 'convert --alt=true --logLevel=info --src="%1" --dst="%~dpn1_converted.jpg"' + }, + { + name: 'Resize Image', + command: 'pm-media', + args: 'resize --alt=true --logLevel=info --src="%1" --dst="%~dpn1_resized%~x1"' + }, + { + name: 'Add Watermark', + command: 'pm-media', + args: 'watermark --alt=true --logLevel=info --src="%1" --watermark="&{POLYMECH-ROOT}/nordin-ex/branding/polymech-saw-ex.svg" --dst="%~dpn1_watermarked%~x1"' + }, + { + name: 'Remove Background', + command: 'pm-media', + args: 'background:remove --alt=true --logLevel=info --src="%1" --dst="%~dpn1_bg_removed%~x1"' + } +] + +interface ExplorerRegistryEntry { + keyPath: string + valueName: string + value: string + type: 'REG_SZ' | 'REG_DWORD' +} + +/** + * Generate registry entries for Windows Explorer shell extensions + */ +function generateExplorerRegistryEntries(groupName: string): ExplorerRegistryEntry[] { + const entries: ExplorerRegistryEntry[] = [] + + for (const ext of IMAGE_EXTENSIONS) { + const extKey = `HKCU\\Software\\Classes\\${ext}` + + // For each command, create the shell extension entries + for (let i = 0; i < EXPLORER_COMMANDS.length; i++) { + const cmd = EXPLORER_COMMANDS[i] + const cmdKey = `${extKey}\\shell\\${groupName}\\shell\\${cmd.name.replace(/\s+/g, '')}` + + // Command display name + entries.push({ + keyPath: cmdKey, + valueName: '', + value: cmd.name, + type: 'REG_SZ' + }) + + // Command execution + entries.push({ + keyPath: `${cmdKey}\\command`, + valueName: '', + value: `${cmd.command} ${cmd.args}`, + type: 'REG_SZ' + }) + } + + // Set the group submenu display name + entries.push({ + keyPath: `${extKey}\\shell\\${groupName}`, + valueName: '', + value: groupName, + type: 'REG_SZ' + }) + + // Set submenu position (optional) + entries.push({ + keyPath: `${extKey}\\shell\\${groupName}`, + valueName: 'Position', + value: 'Middle', + type: 'REG_SZ' + }) + } + + return entries +} + +/** + * Write registry entries for Explorer shell extensions + */ +async function writeExplorerRegistryEntries(entries: ExplorerRegistryEntry[]): Promise { + const promisified = regedit.promisified + + for (const entry of entries) { + try { + // Create the key if it doesn't exist + await promisified.createKey([entry.keyPath]) + + // Write the value using correct regedit format + // For default values, use empty string as key name + const valueName = entry.valueName || '' + const valuesToWrite: RegistryItemPutCollection = { + [entry.keyPath]: { + [valueName]: { + value: entry.value, + type: entry.type as 'REG_SZ' + } + } + } + + await promisified.putValue(valuesToWrite) + logger.debug(`✓ Created registry entry: ${entry.keyPath} = ${entry.value}`) + + } catch (error) { + logger.error(`Failed to create registry entry ${entry.keyPath}:`, error) + logger.error(`Entry details:`, { + keyPath: entry.keyPath, + valueName: entry.valueName, + value: entry.value, + type: entry.type + }) + } + } +} + +/** + * Remove registry entries for Explorer shell extensions + */ +async function removeExplorerRegistryEntries(groupName: string): Promise { + const promisified = regedit.promisified + + for (const ext of IMAGE_EXTENSIONS) { + const extKey = `HKCU\\Software\\Classes\\${ext}` + const groupKey = `${extKey}\\shell\\${groupName}` + + try { + // Check if the key exists + const result = await promisified.list([groupKey]) + if (result[groupKey].exists) { + await promisified.deleteKey([groupKey]) + logger.info(`✓ Removed shell extension for ${ext}`) + } + } catch (error) { + logger.debug(`Could not remove key ${groupKey}:`, error) + } + } +} + +export async function handler(argv: CLI.Arguments) { + defaults() + logger.settings.minLevel = argv.logLevel as any + + const options = { + group: argv.group as string, + unregister: argv.unregister as boolean, + dry: argv.dry as boolean + } + + if (process.platform !== 'win32') { + logger.error('Windows Explorer shell extensions are only supported on Windows') + process.exit(1) + } + + try { + if (options.unregister) { + logger.info(`Removing Explorer shell extensions for group: ${options.group}`) + + if (options.dry) { + logger.info('\n=== DRY RUN - Extensions that would be removed ===') + for (const ext of IMAGE_EXTENSIONS) { + logger.info(` ${ext} files: Remove "${options.group}" context menu`) + } + return + } + + await removeExplorerRegistryEntries(options.group) + logger.info(`✓ Successfully removed Explorer shell extensions for: ${options.group}`) + + } else { + logger.info(`Registering Explorer shell extensions for group: ${options.group}`) + logger.info(`Target file types: ${IMAGE_EXTENSIONS.join(', ')}`) + + const entries = generateExplorerRegistryEntries(options.group) + + if (options.dry) { + logger.info('\n=== DRY RUN - Extensions that would be registered ===') + for (const ext of IMAGE_EXTENSIONS) { + logger.info(`\n${ext} files:`) + for (const cmd of EXPLORER_COMMANDS) { + logger.info(` → ${cmd.name}: ${cmd.command} ${cmd.args}`) + } + } + logger.info(`\nTotal registry entries: ${entries.length}`) + return + } + + await writeExplorerRegistryEntries(entries) + + logger.info(`\n=== Registration Complete ===`) + logger.info(`Registered ${EXPLORER_COMMANDS.length} commands for ${IMAGE_EXTENSIONS.length} file types`) + logger.info(`Total registry entries created: ${entries.length}`) + logger.info('\nExplorer context menu entries have been registered.') + logger.info('You may need to restart Explorer.exe to see the changes.') + } + + } catch (error) { + logger.error('Failed to register/unregister Explorer shell extensions:', error) + process.exit(1) + } +} + +cli.command(command, desc, builder, handler) diff --git a/packages/media/src/commands/salamander.ts b/packages/media/src/commands/salamander.ts new file mode 100644 index 00000000..a3688abe --- /dev/null +++ b/packages/media/src/commands/salamander.ts @@ -0,0 +1,270 @@ +import * as CLI from 'yargs' +import * as path from 'path' +import { logger } from '../index.js' +import { cli } from '../cli.js' +import { + sanitize, + defaults +} from '../_cli.js' + +import SalamanderMenuGenerator, { SalamanderMenuConfig, SalamanderMenuGeneratorRegistry, WindowsRegistry } from '../lib/salamander/index.js' + +export const defaultOptions = (yargs: CLI.Argv) => { + return yargs.option('config', { + describe: 'JSON configuration file path', + type: 'string' + }).option('output', { + describe: 'Output registry file path', + type: 'string' + }).option('existing', { + describe: 'Path to existing registry file to parse for insertion point', + type: 'string' + }).option('group', { + describe: 'Group name to insert items into (e.g., "Media")', + type: 'string' + }).option('startIndex', { + describe: 'Starting menu index (overrides auto-detection)', + type: 'number' + }).option('debug', { + default: false, + describe: 'Enable internal debug messages', + type: 'boolean' + }).option('verbose', { + default: false, + describe: 'Show internal messages', + type: 'boolean' + }).option('logLevel', { + describe: 'Log level : warn, info, debug, error', + type: 'string', + default: 'info' + }).option('registry', { + describe: 'Apply directly to Windows registry (Windows only)', + type: 'boolean', + default: false + }).option('list', { + describe: 'List current menu entries from registry', + type: 'boolean', + default: false + }).option('remove', { + describe: 'Remove menu entries from registry', + type: 'boolean', + default: false + }).option('name', { + describe: 'Menu item name', + type: 'string' + }).option('command', { + describe: 'Command to execute', + type: 'string' + }).option('args', { + describe: 'Command arguments', + type: 'string' + }).option('workingDir', { + describe: 'Working directory for command execution', + type: 'string', + default: '$(FullPath)' + }).option('icon', { + describe: 'Icon path for menu item', + type: 'string', + default: '' + }).option('executeThoughShell', { + describe: 'Execute command through shell', + type: 'boolean', + default: true + }).option('closeShellWindow', { + describe: 'Close shell window after execution', + type: 'boolean', + default: false + }).option('openShellWindow', { + describe: 'Open shell window during execution', + type: 'boolean', + default: true + }).option('showInToolbar', { + describe: 'Show item in toolbar', + type: 'boolean', + default: true + }) +} + +export const command = 'salamander'; +export const desc = 'Generate Salamander file manager menu entries from JSON configuration'; +export const builder = defaultOptions; + +export async function handler(argv: CLI.Arguments) { + defaults() + const options = sanitize(argv) + logger.settings.minLevel = options.logLevel as any + + try { + // Handle listing current menu entries + if (argv.list) { + if (process.platform !== 'win32') { + logger.error('Registry listing is only supported on Windows'); + process.exit(1); + } + + logger.info('Current Salamander menu entries:'); + const entries = await SalamanderMenuGeneratorRegistry.listCurrentMenuEntries(); + + for (const entry of entries) { + const typeStr = entry.type === 'submenu' ? '(submenu)' : + entry.type === 'submenu-end' ? '(submenu end)' : '(command)'; + const cmdStr = entry.command ? ` → ${entry.command}` : ''; + logger.info(` [${entry.index}] ${entry.name} ${typeStr}${cmdStr}`); + } + return; + } + + let config: SalamanderMenuConfig; + + // Check if we're using individual command line options or JSON config + if (argv.name && argv.command) { + // Create config from command line options + logger.info('Creating menu entry from command line options'); + + config = { + baseKey: 'HKCU\\Software\\Altap\\Altap Salamander 4.0\\User Menu', + startIndex: 1, + items: [{ + name: argv.name as string, + command: argv.command as string, + arguments: argv.args as string || '', + initialDirectory: argv.workingDir as string, + executeThoughShell: argv.executeThoughShell as boolean, + closeShellWindow: argv.closeShellWindow as boolean, + openShellWindow: argv.openShellWindow as boolean, + icon: argv.icon as string, + showInToolbar: argv.showInToolbar as boolean + }] + }; + } else if (argv.config) { + // Load configuration from JSON + const configPath = argv.config as string; + logger.info(`Loading configuration from: ${configPath}`); + config = SalamanderMenuGenerator.loadFromJson(configPath); + } else { + logger.error('Either --config file or --name and --command options are required'); + process.exit(1); + } + + // Determine starting index + let startIndex = argv.startIndex as number; + + if (!startIndex) { + if (argv.registry && process.platform === 'win32') { + // Use registry to determine insertion point + if (argv.group) { + startIndex = await SalamanderMenuGeneratorRegistry.autoDetectInsertionPoint(argv.group as string); + logger.info(`Found insertion point for group "${argv.group}": index ${startIndex}`); + } else { + startIndex = await SalamanderMenuGeneratorRegistry.autoDetectInsertionPoint(); + logger.info(`Detected next available index: ${startIndex}`); + } + } else if (argv.existing) { + const existingPath = argv.existing as string; + + if (argv.group) { + startIndex = SalamanderMenuGenerator.findInsertionPoint(existingPath, argv.group as string); + logger.info(`Found insertion point for group "${argv.group}": index ${startIndex}`); + } else { + const maxIndex = SalamanderMenuGenerator.parseExistingRegistry(existingPath); + startIndex = maxIndex + 1; + logger.info(`Detected next available index: ${startIndex}`); + } + } else { + startIndex = config.startIndex || 1; + logger.info(`Using configured start index: ${startIndex}`); + } + } + + // Update config with determined start index + config.startIndex = startIndex; + + // Handle direct registry operations + if (argv.registry) { + if (process.platform !== 'win32') { + logger.error('Direct registry operations are only supported on Windows'); + process.exit(1); + } + + const generator = new SalamanderMenuGeneratorRegistry(config); + + if (argv.remove) { + logger.info('Removing menu entries from registry...'); + await generator.removeFromRegistry(); + logger.info('Menu entries removed successfully'); + } else { + logger.info('Applying menu entries to registry...'); + await generator.applyToRegistry(); + logger.info('Menu entries applied successfully'); + logger.info('Restart Salamander to see the new menu items'); + } + + // Show summary + const entries = generator.generateRegistryEntries(); + logger.info(`Processed ${entries.length} menu entries`); + + if (options.verbose) { + logger.info('Processed entries:'); + for (const entry of entries) { + const itemName = entry.values['"Item Name"'] as string; + const type = entry.values['"Type"'] as string; + const typeStr = type === 'dword:00000001' ? '(submenu)' : + type === 'dword:00000002' ? '(submenu end)' : '(command)'; + logger.info(` ${itemName} ${typeStr}`); + } + } + + return; + } + + // Generate .reg file + const generator = new SalamanderMenuGenerator(config); + + // Generate output path if not specified + let outputPath = argv.output as string; + if (!outputPath) { + if (argv.config) { + const configPath = argv.config as string; + const configDir = path.dirname(configPath); + const configName = path.basename(configPath, '.json'); + outputPath = path.join(configDir, `${configName}-salamander-menu.reg`); + } else { + outputPath = `salamander-menu-${argv.name?.toString().toLowerCase().replace(/\s+/g, '-') || 'item'}.reg`; + } + } + + logger.info(`Generating registry file: ${outputPath}`); + + // Generate and save registry file + generator.saveRegistryFile(outputPath); + + // Generate summary + const entries = generator.generateRegistryEntries(); + logger.info(`Successfully generated ${entries.length} menu entries`); + + if (options.verbose) { + logger.info('Generated entries:'); + for (const entry of entries) { + const itemName = entry.values['"Item Name"'] as string; + const type = entry.values['"Type"'] as string; + const typeStr = type === 'dword:00000001' ? '(submenu)' : + type === 'dword:00000002' ? '(submenu end)' : '(command)'; + logger.info(` ${itemName} ${typeStr}`); + } + } + + logger.info(`\nTo apply the menu entries:`); + logger.info(`1. Double-click the generated .reg file: ${outputPath}`); + logger.info(`2. Confirm the registry import in Windows`); + logger.info(`3. Restart Salamander to see the new menu items`); + + } catch (error) { + logger.error(`Failed to generate Salamander menu:`, error.message); + if (options.debug) { + logger.error(error.stack); + } + process.exit(1); + } +} + +cli.command(command, desc, builder, handler) diff --git a/packages/media/src/lib/media/images/background-remove-bria.ts b/packages/media/src/lib/media/images/background-remove-bria.ts index 64f3ae27..1888b1e8 100644 --- a/packages/media/src/lib/media/images/background-remove-bria.ts +++ b/packages/media/src/lib/media/images/background-remove-bria.ts @@ -1,5 +1,6 @@ import * as fs from 'fs'; import * as path from 'path'; +import sharp from 'sharp'; import pMap from 'p-map'; import { logger } from '../../../index.js'; import { IOptions } from '../../../types.js'; @@ -11,6 +12,7 @@ export interface BriaBackgroundRemoveOptions extends IOptions { sync?: boolean; contentModeration?: boolean; preserveAlpha?: boolean; + jpg?: boolean; } // Read image file as buffer for Bria API @@ -34,6 +36,27 @@ async function downloadImageFromUrl(imageUrl: string, outputPath: string): Promi fs.writeFileSync(outputPath, buffer); } +// Convert PNG to JPG while preserving rotation and metadata +async function convertPngToJpg(pngPath: string, jpgPath: string): Promise { + try { + await sharp(pngPath) + .jpeg({ + quality: 95, + progressive: true + }) + .withMetadata() // Preserve EXIF data including rotation + .toFile(jpgPath); + + // Delete the temporary PNG file + fs.unlinkSync(pngPath); + + logger.debug(`Converted PNG to JPG and cleaned up: ${pngPath} → ${jpgPath}`); + } catch (error) { + logger.error(`Failed to convert PNG to JPG: ${error.message}`); + throw error; + } +} + export async function removeBriaBackground( inputPath: string, outputPath: string, @@ -89,8 +112,18 @@ export async function removeBriaBackground( if (result.result_url || result.image_res) { // Download the processed image (Bria API uses result_url) const imageUrl = result.result_url || result.image_res; - await downloadImageFromUrl(imageUrl, outputPath); - logger.info(`Background removed: ${inputPath} → ${outputPath}`); + + if (options.jpg && path.extname(outputPath).toLowerCase() === '.jpg') { + // If JPG conversion is requested and output is JPG, download as PNG first then convert + const tempPngPath = outputPath.replace(/\.jpe?g$/i, '_temp.png'); + await downloadImageFromUrl(imageUrl, tempPngPath); + await convertPngToJpg(tempPngPath, outputPath); + logger.info(`Background removed and converted to JPG: ${inputPath} → ${outputPath}`); + } else { + // Standard PNG output + await downloadImageFromUrl(imageUrl, outputPath); + logger.info(`Background removed: ${inputPath} → ${outputPath}`); + } } else { throw new Error('No image result returned from Bria API'); } diff --git a/packages/media/src/lib/salamander/index.ts b/packages/media/src/lib/salamander/index.ts new file mode 100644 index 00000000..b44f1dad --- /dev/null +++ b/packages/media/src/lib/salamander/index.ts @@ -0,0 +1,496 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import regedit from 'regedit'; + +const promisified = regedit.promisified; + +export interface SalamanderMenuItem { + name: string; + command?: string; + arguments?: string; + initialDirectory?: string; + executeThoughShell?: boolean; + closeShellWindow?: boolean; + openShellWindow?: boolean; + icon?: string; + showInToolbar?: boolean; + type?: 'command' | 'submenu' | 'submenu-end'; + children?: SalamanderMenuItem[]; +} + +export interface SalamanderMenuConfig { + baseKey: string; + startIndex: number; + items: SalamanderMenuItem[]; +} + +export interface RegistryEntry { + key: string; + values: Record; +} + +export class SalamanderMenuGenerator { + private baseKey: string = 'HKEY_CURRENT_USER\\Software\\Altap\\Altap Salamander 4.0\\User Menu'; + + constructor(private config: SalamanderMenuConfig) { + if (config.baseKey) { + this.baseKey = config.baseKey; + } + } + + /** + * Parse existing registry file to find the highest menu index + */ + static parseExistingRegistry(registryPath: string): number { + if (!fs.existsSync(registryPath)) { + return 0; + } + + const content = fs.readFileSync(registryPath, 'utf8'); + const lines = content.split('\n'); + let maxIndex = 0; + + for (const line of lines) { + const match = line.match(/\\User Menu\\(\d+)\]/); + if (match) { + const index = parseInt(match[1], 10); + if (index > maxIndex) { + maxIndex = index; + } + } + } + + return maxIndex; + } + + /** + * Generate registry entries from menu configuration + */ + generateRegistryEntries(): RegistryEntry[] { + const entries: RegistryEntry[] = []; + let currentIndex = this.config.startIndex; + + const processItems = (items: SalamanderMenuItem[], isSubMenu = false) => { + for (const item of items) { + if (item.children && item.children.length > 0) { + // Submenu start + entries.push({ + key: `[${this.baseKey}\\${currentIndex}]`, + values: this.itemToRegistryValues(item, 'submenu') + }); + currentIndex++; + + // Process children + processItems(item.children, true); + + // Submenu end + entries.push({ + key: `[${this.baseKey}\\${currentIndex}]`, + values: { + '"Item Name"': '"(Submenu End)"', + '"Command"': '""', + '"Arguments"': '""', + '"Initial Directory"': '""', + '"Execute Through Shell"': 'dword:00000000', + '"Close Shell Window"': 'dword:00000000', + '"Open Shell Window"': 'dword:00000000', + '"Icon"': '""', + '"Type"': 'dword:00000002', + '"Show In Toolbar"': 'dword:00000000' + } + }); + currentIndex++; + } else { + // Regular command + entries.push({ + key: `[${this.baseKey}\\${currentIndex}]`, + values: this.itemToRegistryValues(item, 'command') + }); + currentIndex++; + } + } + }; + + processItems(this.config.items); + return entries; + } + + /** + * Convert menu item to registry values + */ + private itemToRegistryValues(item: SalamanderMenuItem, type: 'command' | 'submenu'): Record { + const values: Record = { + '"Item Name"': `"${item.name}"`, + '"Command"': `"${item.command || ''}"`, + '"Arguments"': `"${this.escapeArguments(item.arguments || '')}"`, + '"Initial Directory"': `"${item.initialDirectory || ''}"`, + '"Execute Through Shell"': item.executeThoughShell !== false ? 'dword:00000001' : 'dword:00000000', + '"Close Shell Window"': item.closeShellWindow === true ? 'dword:00000001' : 'dword:00000000', + '"Open Shell Window"': item.openShellWindow !== false ? 'dword:00000001' : 'dword:00000000', + '"Icon"': `"${item.icon || ''}"`, + '"Type"': type === 'submenu' ? 'dword:00000001' : 'dword:00000000', + '"Show In Toolbar"': item.showInToolbar !== false ? 'dword:00000001' : 'dword:00000000' + }; + + return values; + } + + /** + * Escape arguments for registry format + */ + private escapeArguments(args: string): string { + return args + .replace(/\\/g, '\\\\') // Escape backslashes + .replace(/"/g, '\\\\"'); // Escape quotes + } + + /** + * Generate registry file content + */ + generateRegistryFile(): string { + const entries = this.generateRegistryEntries(); + let content = 'REGEDIT4\n\n'; + + for (const entry of entries) { + content += `${entry.key}\n`; + + for (const [key, value] of Object.entries(entry.values)) { + content += `${key}=${value}\n`; + } + + content += '\n'; + } + + return content; + } + + /** + * Save registry file to disk + */ + saveRegistryFile(outputPath: string): void { + const content = this.generateRegistryFile(); + + // Ensure output directory exists + const dir = path.dirname(outputPath); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } + + fs.writeFileSync(outputPath, content, 'utf8'); + } + + /** + * Load menu configuration from JSON file + */ + static loadFromJson(jsonPath: string): SalamanderMenuConfig { + if (!fs.existsSync(jsonPath)) { + throw new Error(`JSON configuration file not found: ${jsonPath}`); + } + + const content = fs.readFileSync(jsonPath, 'utf8'); + return JSON.parse(content) as SalamanderMenuConfig; + } + + /** + * Find insertion point in existing registry + */ + static findInsertionPoint(registryPath: string, groupName?: string): number { + if (!fs.existsSync(registryPath)) { + return 1; // Start at index 1 if no existing registry + } + + const maxIndex = this.parseExistingRegistry(registryPath); + + if (!groupName) { + return maxIndex + 1; + } + + // Find group and insert before submenu end + const content = fs.readFileSync(registryPath, 'utf8'); + const lines = content.split('\n'); + + let inTargetGroup = false; + let groupStartIndex = -1; + + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + + // Check for menu entry + const menuMatch = line.match(/\\User Menu\\(\d+)\]/); + if (menuMatch) { + const index = parseInt(menuMatch[1], 10); + + // Look for item name in next few lines + for (let j = i + 1; j < Math.min(i + 10, lines.length); j++) { + const nameLine = lines[j]; + if (nameLine.includes('"Item Name"')) { + const nameMatch = nameLine.match(/"Item Name"="([^"]+)"/); + if (nameMatch) { + const itemName = nameMatch[1]; + + if (itemName === groupName) { + inTargetGroup = true; + groupStartIndex = index; + } else if (itemName === '(Submenu End)' && inTargetGroup) { + return index; // Insert before submenu end + } + } + break; + } + } + } + } + + return maxIndex + 1; // Fallback to end + } +} + +/** + * Windows Registry helper for direct registry operations using regedit package + */ +export class WindowsRegistry { + private static isWindows(): boolean { + return process.platform === 'win32' && promisified !== null; + } + + private static ensureRegedit(): void { + if (!this.isWindows()) { + throw new Error('Registry operations are only supported on Windows with regedit package installed'); + } + } + + /** + * Read all User Menu entries from registry + */ + static async readUserMenuEntries(baseKey: string = 'HKCU\\Software\\Altap\\Altap Salamander 4.0\\User Menu'): Promise> { + this.ensureRegedit(); + + try { + const result = await promisified.list([baseKey]); + return result[baseKey] || { exists: false, keys: [], values: {} }; + } catch (error) { + return { exists: false, keys: [], values: {} }; + } + } + + /** + * Read specific menu entry by index + */ + static async readMenuEntry(index: number, baseKey: string = 'HKCU\\Software\\Altap\\Altap Salamander 4.0\\User Menu'): Promise> { + this.ensureRegedit(); + + const keyPath = `${baseKey}\\${index}`; + try { + const result = await promisified.list([keyPath]); + return result[keyPath] || { exists: false, keys: [], values: {} }; + } catch (error) { + return { exists: false, keys: [], values: {} }; + } + } + + /** + * Get all existing menu indices + */ + static async getExistingMenuIndices(baseKey: string = 'HKCU\\Software\\Altap\\Altap Salamander 4.0\\User Menu'): Promise { + this.ensureRegedit(); + + const menuData = await this.readUserMenuEntries(baseKey); + if (!menuData.exists) { + return []; + } + + return menuData.keys + .map((key: string) => parseInt(key, 10)) + .filter((index: number) => !isNaN(index)) + .sort((a: number, b: number) => a - b); + } + + /** + * Get next available menu index + */ + static async getNextMenuIndex(baseKey: string = 'HKCU\\Software\\Altap\\Altap Salamander 4.0\\User Menu'): Promise { + const indices = await this.getExistingMenuIndices(baseKey); + return indices.length > 0 ? Math.max(...indices) + 1 : 1; + } + + /** + * Find insertion point for a specific group + */ + static async findGroupInsertionPoint(groupName: string, baseKey: string = 'HKCU\\Software\\Altap\\Altap Salamander 4.0\\User Menu'): Promise { + this.ensureRegedit(); + + const indices = await this.getExistingMenuIndices(baseKey); + + let inTargetGroup = false; + + for (const index of indices) { + const entry = await this.readMenuEntry(index, baseKey); + + if (entry.exists && entry.values['Item Name']) { + const itemName = entry.values['Item Name'].value; + + if (itemName === groupName) { + inTargetGroup = true; + } else if (itemName === '(Submenu End)' && inTargetGroup) { + return index; // Insert before submenu end + } + } + } + + return await this.getNextMenuIndex(baseKey); // Fallback to end + } + + /** + * Write registry values for a menu entry + */ + static async writeMenuEntry(index: number, values: Record, baseKey: string = 'HKCU\\Software\\Altap\\Altap Salamander 4.0\\User Menu'): Promise { + this.ensureRegedit(); + + const keyPath = `${baseKey}\\${index}`; + + // First create the key + await promisified.createKey([keyPath]); + + // Then write the values + const valuesToWrite: Record = {}; + valuesToWrite[keyPath] = {}; + + for (const [valueName, valueData] of Object.entries(values)) { + const cleanValueName = valueName.replace(/"/g, ''); + let cleanValueData = String(valueData); + let valueType = 'REG_SZ'; + + if (cleanValueData.startsWith('dword:')) { + valueType = 'REG_DWORD'; + cleanValueData = parseInt(cleanValueData.replace('dword:', ''), 16).toString(); + } else { + cleanValueData = cleanValueData.replace(/"/g, ''); + } + + valuesToWrite[keyPath][cleanValueName] = { + value: cleanValueData, + type: valueType + }; + } + + await promisified.putValue(valuesToWrite); + } + + /** + * Delete a menu entry + */ + static async deleteMenuEntry(index: number, baseKey: string = 'HKCU\\Software\\Altap\\Altap Salamander 4.0\\User Menu'): Promise { + this.ensureRegedit(); + + const keyPath = `${baseKey}\\${index}`; + + try { + await promisified.deleteKey([keyPath]); + } catch (error) { + // Key might not exist, ignore error + } + } + + /** + * List all menu entries with their details + */ + static async listAllMenuEntries(baseKey: string = 'HKCU\\Software\\Altap\\Altap Salamander 4.0\\User Menu'): Promise> { + const indices = await this.getExistingMenuIndices(baseKey); + const entries = []; + + for (const index of indices) { + const entry = await this.readMenuEntry(index, baseKey); + + if (entry.exists && entry.values['Item Name']) { + const name = entry.values['Item Name'].value; + const type = entry.values['Type'] ? entry.values['Type'].value : 0; + const command = entry.values['Command'] ? entry.values['Command'].value : ''; + + let typeString = 'command'; + if (type === 1 || type === '0x00000001') typeString = 'submenu'; + if (type === 2 || type === '0x00000002') typeString = 'submenu-end'; + + entries.push({ + index, + name, + type: typeString, + command: command || undefined + }); + } + } + + return entries; + } +} + +/** + * Extended Salamander Menu Generator with direct registry support + */ +export class SalamanderMenuGeneratorRegistry extends SalamanderMenuGenerator { + + /** + * Apply menu configuration directly to Windows registry + */ + async applyToRegistry(): Promise { + if (process.platform !== 'win32') { + throw new Error('Direct registry operations are only supported on Windows'); + } + + const entries = this.generateRegistryEntries(); + + for (const entry of entries) { + // Extract menu index from key + const keyMatch = entry.key.match(/\\User Menu\\(\d+)\]/); + if (!keyMatch) continue; + + const menuIndex = parseInt(keyMatch[1], 10); + + await WindowsRegistry.writeMenuEntry(menuIndex, entry.values); + } + } + + /** + * Remove menu entries from Windows registry + */ + async removeFromRegistry(): Promise { + if (process.platform !== 'win32') { + throw new Error('Direct registry operations are only supported on Windows'); + } + + const entries = this.generateRegistryEntries(); + + // Remove in reverse order to avoid index issues + for (let i = entries.length - 1; i >= 0; i--) { + const entry = entries[i]; + const keyMatch = entry.key.match(/\\User Menu\\(\d+)\]/); + if (keyMatch) { + const menuIndex = parseInt(keyMatch[1], 10); + await WindowsRegistry.deleteMenuEntry(menuIndex); + } + } + } + + /** + * Auto-detect insertion point from Windows registry + */ + static async autoDetectInsertionPoint(groupName?: string): Promise { + if (process.platform !== 'win32') { + throw new Error('Registry operations are only supported on Windows'); + } + + if (groupName) { + return await WindowsRegistry.findGroupInsertionPoint(groupName); + } else { + return await WindowsRegistry.getNextMenuIndex(); + } + } + + /** + * List current menu entries from registry + */ + static async listCurrentMenuEntries(): Promise> { + return await WindowsRegistry.listAllMenuEntries(); + } +} + +export default SalamanderMenuGenerator; diff --git a/packages/media/src/main.ts b/packages/media/src/main.ts index f0c51907..b03abc08 100644 --- a/packages/media/src/main.ts +++ b/packages/media/src/main.ts @@ -9,6 +9,9 @@ import './commands/watermark.js' import './commands/background-remove.js' import './commands/background-remove-bria.js' import './commands/crop-foreground.js' +import './commands/salamander.js' +import './commands/register-commands.js' +import './commands/register-explorer.js' const argv: any = cli.argv; diff --git a/packages/media/src/ref/config_sal_min.reg b/packages/media/src/ref/config_sal_min.reg new file mode 100644 index 00000000..ef7363a7 --- /dev/null +++ b/packages/media/src/ref/config_sal_min.reg @@ -0,0 +1,3453 @@ +REGEDIT4 + +[-HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0] + +[HKEY_CURRENT_USER\Software] + +[HKEY_CURRENT_USER\Software\Altap] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Alternative Viewers] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Alternative Viewers\1] +"Masks"="*.*" +"Type"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Colors] +"Color Scheme"=dword:00000000 +"Focus Active Normal"=dword:01000000 +"Focus Active Selected"=dword:01000000 +"Focus Inactive Normal"=dword:00808080 +"Focus Inactive Selected"=dword:00808080 +"Focus Bk Inactive Normal"=dword:01ffffff +"Focus Bk Inactive Selected"=dword:01ffffff +"Item Fg Normal"=dword:01000000 +"Item Fg Selected"=dword:000000ff +"Item Fg Focused"=dword:01000000 +"Item Fg Focused and Selected"=dword:000000ff +"Item Fg Highlight"=dword:01000000 +"Item Bk Normal"=dword:01ffffff +"Item Bk Selected"=dword:01ffffff +"Item Bk Focused"=dword:00e8e8e8 +"Item Bk Focused and Selected"=dword:00e8e8e8 +"Item Bk Highlight"=dword:01000000 +"Icon Blend Selected"=dword:018080ff +"Icon Blend Focused"=dword:00808080 +"Icon Blend Focused and Selected"=dword:000000ff +"Progress Fg Normal"=dword:01c00000 +"Progress Fg Selected"=dword:01ffffff +"Progress Bk Normal"=dword:01ffffff +"Progress Bk Selected"=dword:01c00000 +"Hot Panel"=dword:01ff0000 +"Hot Active"=dword:01808080 +"Hot Inactive"=dword:01808080 +"Active Caption Fg"=dword:01ffffff +"Active Caption Bk"=dword:01800000 +"Inactive Caption Fg"=dword:01ffffff +"Inactive Caption Bk"=dword:01808080 +"Thumbnail Frame Normal"=dword:00c0c0c0 +"Thumbnail Frame Selected"=dword:000000ff +"Thumbnail Frame Focused"=dword:00000000 +"Thumbnail Frame Focused and Selected"=dword:00000080 +"Viewer Fg Normal"=dword:01000000 +"Viewer Bk Normal"=dword:01ffffff +"Viewer Fg Selected"=dword:01ffffff +"Viewer Bk Selected"=dword:01000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Colors\Panel Items Hilighting] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Colors\Panel Items Hilighting\1] +"Masks"="*.*" +"Attributes"=dword:00000800 +"Valid Attributes"=dword:00000800 +"Item Fg Normal"=dword:00ff0000 +"Item Fg Selected"=dword:010000ff +"Item Fg Focused"=dword:00ff0000 +"Item Fg Focused and Selected"=dword:010000ff +"Item Fg Highlight"=dword:01ff0000 +"Item Bk Normal"=dword:01ffffff +"Item Bk Selected"=dword:01ffffff +"Item Bk Focused"=dword:01e8e8e8 +"Item Bk Focused and Selected"=dword:01e8e8e8 +"Item Bk Highlight"=dword:01e9e9e9 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Colors\Panel Items Hilighting\2] +"Masks"="*.*" +"Attributes"=dword:00004000 +"Valid Attributes"=dword:00004000 +"Item Fg Normal"=dword:000d8f13 +"Item Fg Selected"=dword:010000ff +"Item Fg Focused"=dword:000d8f13 +"Item Fg Focused and Selected"=dword:010000ff +"Item Fg Highlight"=dword:010d8f13 +"Item Bk Normal"=dword:01ffffff +"Item Bk Selected"=dword:01ffffff +"Item Bk Focused"=dword:01e8e8e8 +"Item Bk Focused and Selected"=dword:01e8e8e8 +"Item Bk Highlight"=dword:01e9e9e9 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration] +"Menu Index"=dword:00000000 +"Menu Break"=dword:00000001 +"Menu Width"=dword:00000001 +"ToolBar Index"=dword:00000001 +"ToolBar Break"=dword:00000001 +"ToolBar Width"=dword:00000001 +"PluginsBar Index"=dword:00000002 +"PluginsBar Break"=dword:00000001 +"PluginsBar Width"=dword:00000001 +"User Menu Index"=dword:00000003 +"User Menu Break"=dword:00000001 +"User Menu Width"=dword:00000001 +"User Menu Labels"=dword:00000001 +"Hot Paths Index"=dword:00000004 +"Hot Paths Break"=dword:00000001 +"Hot Paths Width"=dword:00000001 +"Drive Bar Index"=dword:00000002 +"Drive Bar Break"=dword:00000001 +"Drive Bar Width"=dword:00000001 +"Grips Visible"=dword:00000001 +"File Name Format"=dword:00000004 +"Size Format"=dword:00000000 +"Select/Deselect Directories"=dword:00000000 +"Copy Find Text"=dword:00000001 +"Clear Readonly Attribute"=dword:00000001 +"Primary Context Menu"=dword:00000001 +"Hide Hidden and System Files and Directories"=dword:00000000 +"Use Recycle Bin"=dword:00000000 +"Use Recycle Bin For"="*.txt;*.doc" +"Save Configuration On Exit"=dword:00000001 +"Show Errors In Find Files"=dword:00000000 +"Show Full Row In Find Files"=dword:00000000 +"Use Speeker Beep"=dword:00000001 +"Close Shell Window"=dword:00000000 +"Right Panel Focused"=dword:00000000 +"Always On Top"=dword:00000000 +"Sort Uses Locale"=dword:00000001 +"Sort Detects Numbers"=dword:00000001 +"Sort Newer On Top"=dword:00000000 +"Sort Dirs By Name"=dword:00000000 +"Sort Dirs By Ext"=dword:00000000 +"Save History"=dword:00000001 +"Save Working Dirs"=dword:00000000 +"Enable CmdLine History"=dword:00000001 +"Save CmdLine History"=dword:00000001 +"Only One Instance"=dword:00000000 +"Status Area"=dword:00000000 +"Full Row Select"=dword:00000000 +"Full Row Highlight"=dword:00000001 +"Use Icon Tincture"=dword:00000001 +"Show Panel Caption"=dword:00000001 +"Show Panel Zoom"=dword:00000001 +"Single Click"=dword:00000000 +"Information Line Content"="$(FileName): $(FileSize), $(FileDate), $(FileTime), $(FileAttributes), $(FileDOSName)" +"If Path Is Inaccessible Go To My Docs"=dword:00000001 +"If Path Is Inaccessible Go To"="" +"Auto Configurate Hot Paths"=dword:00000001 +"Speed Limit"=dword:00100000 +"Quick Search Enter Alt"=dword:00000000 +"Change Drive Show My Documents"=dword:00000001 +"Change Drive Show Cloud Storages"=dword:00000001 +"Change Drive Show Another"=dword:00000001 +"Change Drive Network"=dword:00000001 +"Search File Content"=dword:00000001 +"Plugins.ver Version (x64)"=dword:00000000 +"Plugins.ver Version (x86)"=dword:00000000 +"Use salopen.exe"=dword:00000000 +"Netware Fast Dir Move"=dword:00000000 +"Async Copy Alg On Network"=dword:00000001 +"Reload Environment Variables"=dword:00000001 +"Quick Rename Select All"=dword:00000000 +"Edit New File Select All"=dword:00000001 +"Use Shift For GoTo HotPath"=dword:00000001 +"Language"="english.slg" +"Use Alternate Language for Plugins"=dword:00000000 +"Alternate Language for Plugins"="" +"Language Changed"=dword:00000000 +"Show Splash Screen"=dword:00000001 +"Conversion Table"="westeuro" +"Skill Level"=dword:00000002 +"Title bar show path"=dword:00000001 +"Title bar mode"=dword:00000000 +"Title bar prefix"=dword:00000000 +"Title bar prefix text"="ADMIN" +"Main window icon index"=dword:00000000 +"Click to Quick Rename"=dword:00000001 +"Visible Drives"=dword:03ffffff +"Separated Drives"=dword:00000000 +"Compare By Time"=dword:00000001 +"Compare By Size"=dword:00000001 +"Compare By Content"=dword:00000000 +"Compare By Attr"=dword:00000000 +"Compare By Subdirs"=dword:00000000 +"Compare By Subdirs Attr"=dword:00000000 +"Compare One Panel Dirs"=dword:00000000 +"Compare More Options"=dword:00000000 +"Compare Ignore Files"=dword:00000000 +"Compare Ignore Dirs"=dword:00000000 +"Compare Ignore Files Masks"="" +"Compare Ignore Dirs Masks"="" +"Thumbnail Size"=dword:0000005e +"Keep Plugins Sorted"=dword:00000001 +"Show Translation Is Incomplete"=dword:00000001 +"Enable Custom Icon Overlays"=dword:00000001 +"Disabled Custom Icon Overlays"="" +"Edit New File Use Default"=dword:00000000 +"Edit New File Default"="" +"Top ToolBar"="11,14,15,70,-1,40,56,-1,30,31,32,-1,41,42,18,27,55,33,-1,3,34,35,20,19,-1,43,46,49" +"Middle ToolBar"="2,3,17,21,22,23,72,26,24,25,27,55,28,29,30,31,32,33" +"Left ToolBar"="36" +"Right ToolBar"="51" +"Show Top ToolBar"=dword:00000001 +"Show Plugins Bar"=dword:00000000 +"Show Middle ToolBar"=dword:00000000 +"Show User Menu ToolBar"=dword:00000000 +"Hot Paths Bar"=dword:00000000 +"Show Drive Bar"=dword:00000001 +"Show Drive Bar2"=dword:00000000 +"Show Bottom ToolBar"=dword:00000001 +"Use Time Resolution"=dword:00000001 +"Time Resolution"=dword:00000002 +"Ignore DST Shifts"=dword:00000000 +"Use DragDrop Min Time"=dword:00000001 +"DragDrop Min Time"=dword:000001f4 +"Last Focused Page"=dword:0000000e +"Configuration Height"=dword:000001f1 +"Viewers And Editors Expanded"=dword:00000001 +"Packers And Unpackers Expanded"=dword:00000000 +"Command Line"=dword:00000001 +"Command Line Focused"=dword:00000000 +"Use Custom Panel Font"=dword:00000000 +"Panel Font"="Segoe UI,-12,400,0,1,0,0,5,0" +"Make File List Name"="" +"Make File List Append"=dword:00000000 +"Make File List Destination"=dword:00000000 +"Start Trace Server"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\ChangeDir History] +"1"="C:\\Users\\zx\\Desktop\\polymech" +"2"="C:\\Users\\zx\\.platformio\\packages\\framework-arduinoespressif32\\cores" +"3"="C:\\Users\\zx\\.platformio\\packages\\tool-mklittlefs\\" +"4"="c:\\Users\\zx\\AppData\\Roaming\\Cursor\\User\\globalStorage\\llvm-vs-code-extensions.vscode-clangd\\" +"5"="C:\\Users\\zx\\Desktop\\osr\\products\\products\\sheetpress\\cassandra-edczmax-rc2\\cad\\" +"6"="C:\\Users\\zx\\Desktop\\osr\\products\\products\\sheetpress\\cassandra-edczmax-rc2\\cad\\3" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Command History] +"1"="c" +"2"="cc" +"3"="cx" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Confirmation] +"Files or Dirs Del"=dword:00000001 +"Non-empty Dir Del"=dword:00000000 +"File Overwrite"=dword:00000001 +"Directory Overwrite"=dword:00000000 +"SH File Del"=dword:00000001 +"SH Dir Del"=dword:00000000 +"SH File Overwrite"=dword:00000001 +"NTFS Compress and Uncompress"=dword:00000001 +"NTFS Encrypt and Decrypt"=dword:00000001 +"Drag and Drop"=dword:00000000 +"Close Archive"=dword:00000001 +"Close Find"=dword:00000001 +"Stop Find"=dword:00000001 +"Create Target Path"=dword:00000001 +"Always on Top"=dword:00000001 +"Close Salamander"=dword:00000000 +"Send Email"=dword:00000001 +"Add To Archive"=dword:00000001 +"Create Dir"=dword:00000001 +"Change Dir TC"=dword:00000001 +"Show Names To Compare"=dword:00000001 +"DST Shifts Ignored"=dword:00000001 +"DST Shifts Occured"=dword:00000001 +"Copy Move Options Not Supported"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Convert History] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Copy History] +"1"="C:\\Users\\zx\\Desktop\\polymech\\polymech-mono\\packages\\media\\src\\ref\\*.*" +"2"="C:\\Users\\zx\\Desktop\\osr\\products\\rosa\\2025\\08\\cidepa\\*.*" +"3"="C:\\Users\\zx\\Desktop\\polymech\\polymech-mono\\packages\\bot\\src\\*.*" +"4"="C:\\Users\\zx\\Desktop\\osr\\osr-oa-bot\\src\\*.*" +"5"="C:\\Users\\zx\\Desktop\\polymech\\polymech-mono\\packages\\bot\\src\\commands\\*.*" +"6"="C:\\Users\\zx\\Desktop\\polymech\\polymech-mono\\packages\\bot\\*.*" +"7"="C:\\Users\\zx\\Desktop\\osr\\*.*" +"8"="C:\\Users\\zx\\Desktop\\polymech\\polymech-mono\\packages\\media\\tests\\images\\watermark-add\\*.*" +"9"="C:\\Users\\zx\\Desktop\\polymech\\polymech-fw-apps\\elz-rc3\\lib\\polymech-base\\src\\components\\*.*" +"10"="C:\\Users\\zx\\Desktop\\polymech\\nordin-ex\\*.*" +"11"="C:\\Users\\zx\\Desktop\\social\\233\\*.*" +"12"="C:\\Users\\zx\\Desktop\\polymech\\polymech-mono\\packages\\ai-tools\\src\\lib\\tools\\*.*" +"13"="C:\\Users\\zx\\Desktop\\polymech\\polymech-fw-apps\\elz-rc3\\scripts\\delta\\*.*" +"14"="C:\\Users\\zx\\Desktop\\polymech\\polymech-mono\\packages\\media\\tests\\pdf\\*.*" +"15"="C:\\Users\\zx\\Desktop\\clients\\plastiq\\followip\\*.*" +"16"="C:\\Users\\zx\\Desktop\\polymech\\polymech-fw-apps\\vendor\\delta\\*.*" +"17"="C:\\Users\\zx\\Desktop\\polymech\\polymech-fw-apps\\vendor\\*.*" +"18"="C:\\Users\\zx\\Desktop\\polymech\\fw-backups\\elzm-rc2\\*.*" +"19"="C:\\Users\\zx\\Desktop\\cs-2\\manuals\\*.*" +"20"="C:\\Users\\zx\\Desktop\\social\\231\\*.*" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Copy Move Options] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Create Directory History] +"1"="ref" +"2"="cidepa" +"3"="08" +"4"="bot" +"5"="logos" +"6"="branding" +"7"="watermark-add" +"8"="nordin-ex" +"9"="1" +"10"="delta" +"11"="elzm-rc2" +"12"="manuals" +"13"="test" +"14"="app" +"15"="thomas-traels" +"16"="340" +"17"="229" +"18"="scripts" +"19"="sel" +"20"="228" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Drive Special Settings] +"Floppy Automatic Refresh"=dword:00000001 +"Floppy Simple Icons"=dword:00000001 +"Removable Automatic Refresh"=dword:00000001 +"Removable Simple Icons"=dword:00000000 +"Fixed Automatic Refresh"=dword:00000001 +"Fixed Simple Icons"=dword:00000000 +"Remote Automatic Refresh"=dword:00000001 +"Remote Simple Icons"=dword:00000000 +"Remote Do Not Refresh on Activation"=dword:00000000 +"CDROM Automatic Refresh"=dword:00000001 +"CDROM Simple Icons"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Edit New History] +"1"="overview" +"2"="ex45.md" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\File List History] +"1"="$(FileName)$(CRLF)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Filter History] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Find Ignore] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Find Ignore\1] +"Path"="\\System Volume Information" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Find Ignore\2] +"Path"="Local Settings\\Temporary Internet Files" +"Enabled"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Find Options] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Grep History] +"1"="arduino-esp32" +"2"="espressif/arduino-esp32" +"3"="const char" +"4"="va_start" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Look In History] +"1"="C:\\Users\\zx\\Desktop\\osr\\products\\products\\sheetpress\\cassandra-edczmax-rc2" +"2"="C:\\Users\\zx\\Desktop\\osr\\products\\rosa" +"3"="C:\\Users\\zx\\Desktop\\osr\\products\\products\\sheetpress\\components" +"4"="C:\\Users\\zx\\Desktop\\osr\\products\\products\\sheetpress\\cassandra-edczmax-rc2\\cad" +"5"="C:\\Users\\zx\\Desktop\\polymech\\polymech-fw-apps" +"6"="C:\\Users\\zx\\.platformio" +"7"="C:\\Espressif\\frameworks\\esp-idf-v5.3.1\\examples" +"8"="C:\\Espressif" +"9"="C:\\Users\\zx\\Desktop\\osr\\products\\nc" +"10"="C:\\Users\\zx\\Desktop\\polymech\\polymech-fw-apps\\cassandra-rc2\\.pio\\libdeps\\waveshare\\eModbus\\src" +"11"="C:\\Users\\zx\\Desktop\\osr\\products\\products\\products\\poly-mech" +"12"="C:\\Program Files" +"13"="E:\\Users\\mc007\\Desktop" +"14"="E:\\Users\\mc007\\Desktop\\ph3\\temp" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Named History] +"1"="cover" +"2"="blank" +"3"="bracket" +"4"="inter" +"5"="bugs*" +"6"="xtensa-esp32s3-elf-stri" +"7"="platform.py" +"8"="*.sh" +"9"="*.*" +"10"="idf.py" +"11"="face" +"12"="docs.sh" +"13"="drawer" +"14"="drawers" +"15"="eDrawings.Interop.EModelViewControl.dll" +"16"="*.reg" +"17"="node_modules" +"18"="pio.exe" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Quick Rename History] +"1"="Global-650-Default-RC2.SLDASM" +"2"="gSPC-650-Default-RC2-Dual.SLDASM" +"3"="EDC-650-320_HG20-40_x6.dxf" +"4"="EDC-650-322_HG20-40Side_x12.dxf" +"5"="EDC-650-323_HG20-40Flange_x12.dxf" +"6"="EDC-650-324_HG20-40RodM_x6.dxf" +"7"="EDC-650-720_GroundPlate_x1.dxf" +"8"="EDC-650-450_FlexInterConnect_x8.dxf" +"9"="EDC-650-616_OutletPanelBlank_x2.dxf" +"10"="EDC-650-612_SidePanelBlank_x4.dxf" +"11"="EDC-650-612_SidePanel_x4.dxf" +"12"="EDC-650-610_FrontPanelBlank_x2.dxf" +"13"="EDC-650-610_FrontPanel_x2.dxf" +"14"="EDC-650-525_Belt_x2.dxf" +"15"="EDC-650-403_MountPlate_x4.dxf" +"16"="EDC-650-403_MountPlate_x.dxf" +"17"="laser_" +"18"="watermark.ts" +"19"="watermark-rm.ts" +"20"="DeltaTypesEx.h" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Select History] +"1"="*.png" +"2"="*.jpg" +"3"="*.arw" +"4"="*.jph" +"5"="*.jpw" +"6"="*.gz" +"7"="*.js" +"8"="*.lnk" +"9"="*.md" +"10"="*.x_t" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Viewer History] +"1"="pdf" +"2"="onFinished" +"3"="PlotBase::onFinished" +"4"="joystick" +"5"="src" +"6"="cassandra" +"7"="const char" +"8"="Exporteren naar CSV" +"9"="loop(" +"10"="mb_tcp_base_address" +"11"="getRegistersHandler" +"12"="signalplot" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Configuration\Working Directories] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Custom Colors] +"1"=dword:00ffffff +"2"=dword:00ffffff +"3"=dword:00ffffff +"4"=dword:00ffffff +"5"=dword:00ffffff +"6"=dword:00ffffff +"7"=dword:00ffffff +"8"=dword:00ffffff +"9"=dword:00ffffff +"10"=dword:00ffffff +"11"=dword:00ffffff +"12"=dword:00ffffff +"13"=dword:00ffffff +"14"=dword:00ffffff +"15"=dword:00ffffff +"16"=dword:00ffffff + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Default Directories] +"C"="C:\\Users\\zx\\Desktop\\polymech\\polymech-mono\\packages\\media\\src\\ref" +"G"="G:\\My Drive\\sec" +"E"="E:\\latest\\desktop\\osr" +"D"="D:\\DCIM\\100MSDCF" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Editors] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Editors\1] +"Masks"="*.*" +"Command"="notepad.exe" +"Arguments"="\"$(Name)\"" +"Initial Directory"="$(FullPath)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Find Dialog Window] +"Left"=dword:00000780 +"Right"=dword:0000093d +"Top"=dword:00000022 +"Bottom"=dword:000001f4 +"Show"=dword:00000003 +"Name Width"=dword:000000fa + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Hot Paths] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Hot Paths\10] +"Name"="C:\\Users\\zx\\Desktop\\polymech\\polymech-mono\\packages\\kbot" +"Path"="C:\\Users\\zx\\Desktop\\polymech\\polymech-mono\\packages\\kbot" +"Visible"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Hot Paths\11] +"Name"="C:\\Users\\zx\\Desktop\\polymech\\polymech-fw-apps" +"Path"="C:\\Users\\zx\\Desktop\\polymech\\polymech-fw-apps" +"Visible"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Hot Paths\12] +"Name"="C:\\Users\\zx\\Desktop\\osr\\products\\products\\products\\poly-mech" +"Path"="C:\\Users\\zx\\Desktop\\osr\\products\\products\\products\\poly-mech" +"Visible"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Hot Paths\2] +"Name"="C:\\Users\\zx\\Desktop" +"Path"="C:\\Users\\zx\\Desktop" +"Visible"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Hot Paths\3] +"Name"="C:\\Users\\zx\\Desktop\\polymech" +"Path"="C:\\Users\\zx\\Desktop\\polymech" +"Visible"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Hot Paths\5] +"Name"="C:\\Users\\zx\\Desktop\\osr\\products" +"Path"="C:\\Users\\zx\\Desktop\\osr\\products" +"Visible"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Hot Paths\8] +"Name"="C:\\Users\\zx\\Desktop\\polymech\\nordin-ex" +"Path"="C:\\Users\\zx\\Desktop\\polymech\\nordin-ex" +"Visible"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Hot Paths\9] +"Name"="C:\\Users\\zx\\Desktop\\osr" +"Path"="C:\\Users\\zx\\Desktop\\osr" +"Visible"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Left Panel] +"Header Line"=dword:00000001 +"Path"="C:\\Users\\zx\\Desktop\\polymech\\polymech-mono\\packages\\media\\src\\ref" +"View Type"=dword:00000002 +"Sort Type"=dword:00000000 +"Reverse Sort"=dword:00000000 +"Directory Line"=dword:00000001 +"Status Line"=dword:00000001 +"Enable Filter"=dword:00000000 +"Filter"="*.*" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers] +"Simple Icons In Archives"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Archive Association] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Archive Association\1] +"Extension List"="zip;pk3;jar" +"Packer Supported"=dword:00000001 +"Packer Index"=dword:ffffffff +"Unpacker Index"=dword:ffffffff + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Archive Association\10] +"Extension List"="7z" +"Packer Supported"=dword:00000001 +"Packer Index"=dword:fffffffb +"Unpacker Index"=dword:fffffffb + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Archive Association\11] +"Extension List"="ena" +"Packer Supported"=dword:00000001 +"Packer Index"=dword:fffffff5 +"Unpacker Index"=dword:fffffff5 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Archive Association\12] +"Extension List"="cab" +"Packer Supported"=dword:00000000 +"Packer Index"=dword:ffffffff +"Unpacker Index"=dword:ffffffea + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Archive Association\13] +"Extension List"="ima" +"Packer Supported"=dword:00000000 +"Packer Index"=dword:ffffffff +"Unpacker Index"=dword:ffffffe7 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Archive Association\14] +"Extension List"="iso;isz;nrg;bin;img;pdi;cdi;cif;ncd;c2d;mdf;dmg" +"Packer Supported"=dword:00000000 +"Packer Index"=dword:ffffffff +"Unpacker Index"=dword:ffffffe6 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Archive Association\15] +"Extension List"="eml;b64;uue;xxe;hqx;ntx;cnm" +"Packer Supported"=dword:00000000 +"Packer Index"=dword:ffffffff +"Unpacker Index"=dword:ffffffe4 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Archive Association\2] +"Extension List"="j" +"Packer Supported"=dword:00000001 +"Packer Index"=dword:00000000 +"Unpacker Index"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Archive Association\3] +"Extension List"="rar;r##" +"Packer Supported"=dword:00000001 +"Packer Index"=dword:00000001 +"Unpacker Index"=dword:ffffffe3 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Archive Association\4] +"Extension List"="arj;a##" +"Packer Supported"=dword:00000001 +"Packer Index"=dword:00000009 +"Unpacker Index"=dword:ffffffeb + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Archive Association\5] +"Extension List"="lzh;lha;lzs" +"Packer Supported"=dword:00000001 +"Packer Index"=dword:00000003 +"Unpacker Index"=dword:ffffffe5 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Archive Association\6] +"Extension List"="uc2" +"Packer Supported"=dword:00000001 +"Packer Index"=dword:00000004 +"Unpacker Index"=dword:00000004 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Archive Association\7] +"Extension List"="ace;c##" +"Packer Supported"=dword:00000001 +"Packer Index"=dword:0000000a +"Unpacker Index"=dword:0000000a + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Archive Association\8] +"Extension List"="pak" +"Packer Supported"=dword:00000001 +"Packer Index"=dword:fffffffd +"Unpacker Index"=dword:fffffffd + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Archive Association\9] +"Extension List"="tgz;tbz;taz;tar;gz;bz;bz2;z;rpm;cpio;deb" +"Packer Supported"=dword:00000000 +"Packer Index"=dword:ffffffff +"Unpacker Index"=dword:fffffffe + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers] +"Use Another Panel"=dword:00000000 +"Preffered"=dword:00000002 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\1] +"Type"=dword:fffffff5 +"Title"="Encrypt (Plugin)" +"Ext"="ena" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\10] +"Type"=dword:00000000 +"Title"="ARJ to 1.44MB volumes (External Win32, tested with v3.00c)" +"Ext"="arj" +"Support Long Names"=dword:00000001 +"Need ANSI List"=dword:00000000 +"Copy Command"="$(Arj32bitExecutable)" +"Copy Arguments"="a -pav1440 \"$(ArchiveFullName)\" !\"$(ListFullName)\"" +"Support Move"=dword:00000001 +"Move Command"="$(Arj32bitExecutable)" +"Move Arguments"="m -pav1440 \"$(ArchiveFullName)\" !\"$(ListFullName)\"" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\11] +"Type"=dword:00000000 +"Title"="ACE (External Win32, tested with v1.2b)" +"Ext"="ace" +"Support Long Names"=dword:00000001 +"Need ANSI List"=dword:00000001 +"Copy Command"="$(Ace32bitExecutable)" +"Copy Arguments"="a \"$(ArchiveFullName)\" @\"$(ListFullName)\"" +"Support Move"=dword:00000001 +"Move Command"="$(Ace32bitExecutable)" +"Move Arguments"="m \"$(ArchiveFullName)\" @\"$(ListFullName)\"" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\12] +"Type"=dword:00000000 +"Title"="ACE to 1.44MB volumes (External Win32, tested with v1.2b)" +"Ext"="ace" +"Support Long Names"=dword:00000001 +"Need ANSI List"=dword:00000001 +"Copy Command"="$(Ace32bitExecutable)" +"Copy Arguments"="a -v1440 \"$(ArchiveFullName)\" @\"$(ListFullName)\"" +"Support Move"=dword:00000001 +"Move Command"="$(Ace32bitExecutable)" +"Move Arguments"="m -v1440 \"$(ArchiveFullName)\" @\"$(ListFullName)\"" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\13] +"Type"=dword:00000000 +"Title"="ARJ (External DOS, tested with v2.60)" +"Ext"="arj" +"Support Long Names"=dword:00000000 +"Need ANSI List"=dword:00000000 +"Copy Command"="$(Arj16bitExecutable)" +"Copy Arguments"="a -pa $(ArchiveDOSFullName) !$(ListDOSFullName)" +"Support Move"=dword:00000001 +"Move Command"="$(Arj16bitExecutable)" +"Move Arguments"="m -pa $(ArchiveDOSFullName) !$(ListDOSFullName)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\14] +"Type"=dword:00000000 +"Title"="ARJ to 1.44MB volumes (External DOS, tested with v2.60)" +"Ext"="arj" +"Support Long Names"=dword:00000000 +"Need ANSI List"=dword:00000000 +"Copy Command"="$(Arj16bitExecutable)" +"Copy Arguments"="a -pav1440 $(ArchiveDOSFullName) !$(ListDOSFullName)" +"Support Move"=dword:00000001 +"Move Command"="$(Arj16bitExecutable)" +"Move Arguments"="m -pav1440 $(ArchiveDOSFullName) !$(ListDOSFullName)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\15] +"Type"=dword:00000000 +"Title"="LHA (External DOS, tested with v2.55)" +"Ext"="lzh" +"Support Long Names"=dword:00000000 +"Need ANSI List"=dword:00000000 +"Copy Command"="$(Lha16bitExecutable)" +"Copy Arguments"="a -m -p -a -l1 -x1 -c $(ArchiveDOSFullName) @$(ListDOSFullName)" +"Support Move"=dword:00000001 +"Move Command"="$(Lha16bitExecutable)" +"Move Arguments"="m -m -p -a -l1 -x1 -c $(ArchiveDOSFullName) @$(ListDOSFullName)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\16] +"Type"=dword:00000000 +"Title"="UC2 (External DOS, tested with v2r3PRO)" +"Ext"="uc2" +"Support Long Names"=dword:00000000 +"Need ANSI List"=dword:00000000 +"Copy Command"="$(UC216bitExecutable)" +"Copy Arguments"="A !SYSHID=ON ##\\ $(ArchiveDOSFullName) @$(ListDOSFullName)" +"Support Move"=dword:00000001 +"Move Command"="$(UC216bitExecutable)" +"Move Arguments"="AM !SYSHID=ON ##\\ $(ArchiveDOSFullName) @$(ListDOSFullName)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\17] +"Type"=dword:00000000 +"Title"="ACE (External DOS, tested with v1.2b)" +"Ext"="ace" +"Support Long Names"=dword:00000000 +"Need ANSI List"=dword:00000000 +"Copy Command"="$(Ace16bitExecutable)" +"Copy Arguments"="a $(ArchiveDOSFullName) @$(ListDOSFullName)" +"Support Move"=dword:00000001 +"Move Command"="$(Ace16bitExecutable)" +"Move Arguments"="m $(ArchiveDOSFullName) @$(ListDOSFullName)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\18] +"Type"=dword:00000000 +"Title"="ACE to 1.44MB volumes (External DOS, tested with v1.2b)" +"Ext"="ace" +"Support Long Names"=dword:00000000 +"Need ANSI List"=dword:00000000 +"Copy Command"="$(Ace16bitExecutable)" +"Copy Arguments"="a -v1440 $(ArchiveDOSFullName) @$(ListDOSFullName)" +"Support Move"=dword:00000001 +"Move Command"="$(Ace16bitExecutable)" +"Move Arguments"="m -v1440 $(ArchiveDOSFullName) @$(ListDOSFullName)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\19] +"Type"=dword:00000000 +"Title"="JAR (External DOS, tested with v1.02)" +"Ext"="j" +"Support Long Names"=dword:00000000 +"Need ANSI List"=dword:00000000 +"Copy Command"="$(Jar16bitExecutable)" +"Copy Arguments"="a $(ArchiveDOSFullName) !$(ListDOSFullName)" +"Support Move"=dword:00000001 +"Move Command"="$(Jar16bitExecutable)" +"Move Arguments"="m $(ArchiveDOSFullName) !$(ListDOSFullName)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\2] +"Type"=dword:fffffffb +"Title"="7-Zip (Plugin)" +"Ext"="7z" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\20] +"Type"=dword:00000000 +"Title"="JAR to 1.44MB volumes (External DOS, tested with v1.02)" +"Ext"="j" +"Support Long Names"=dword:00000000 +"Need ANSI List"=dword:00000000 +"Copy Command"="$(Jar16bitExecutable)" +"Copy Arguments"="a -v1440 $(ArchiveDOSFullName) !$(ListDOSFullName)" +"Support Move"=dword:00000001 +"Move Command"="$(Jar16bitExecutable)" +"Move Arguments"="m -v1440 $(ArchiveDOSFullName) !$(ListDOSFullName)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\21] +"Type"=dword:00000000 +"Title"="RAR (External DOS, tested with v2.50)" +"Ext"="rar" +"Support Long Names"=dword:00000000 +"Need ANSI List"=dword:00000000 +"Copy Command"="$(Rar16bitExecutable)" +"Copy Arguments"="a $(ArchiveDOSFullName) @$(ListDOSFullName)" +"Support Move"=dword:00000001 +"Move Command"="$(Rar16bitExecutable)" +"Move Arguments"="m $(ArchiveDOSFullName) @$(ListDOSFullName)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\22] +"Type"=dword:00000000 +"Title"="RAR to 1.44MB volumes (External DOS, tested with v2.50)" +"Ext"="rar" +"Support Long Names"=dword:00000000 +"Need ANSI List"=dword:00000000 +"Copy Command"="$(Rar16bitExecutable)" +"Copy Arguments"="a -v1440 $(ArchiveDOSFullName) @$(ListDOSFullName)" +"Support Move"=dword:00000001 +"Move Command"="$(Rar16bitExecutable)" +"Move Arguments"="m -v1440 $(ArchiveDOSFullName) @$(ListDOSFullName)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\23] +"Type"=dword:00000000 +"Title"="PKZIP (External Win32, tested with v2.50)" +"Ext"="zip" +"Support Long Names"=dword:00000001 +"Need ANSI List"=dword:00000001 +"Copy Command"="$(Zip32bitExecutable)" +"Copy Arguments"="-add -nozipextension -path -attr \"$(ArchiveFullName)\" @\"$(ListFullName)\"" +"Support Move"=dword:00000001 +"Move Command"="$(Zip32bitExecutable)" +"Move Arguments"="-add -nozipextension -move -path -attr \"$(ArchiveFullName)\" @\"$(ListFullName)\"" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\24] +"Type"=dword:00000000 +"Title"="PKZIP (External DOS, tested with v2.04g)" +"Ext"="zip" +"Support Long Names"=dword:00000000 +"Need ANSI List"=dword:00000000 +"Copy Command"="$(Zip16bitExecutable)" +"Copy Arguments"="-P -whs $(ArchiveDOSFullName) @$(ListDOSFullName)" +"Support Move"=dword:00000001 +"Move Command"="$(Zip16bitExecutable)" +"Move Arguments"="-m -P -whs $(ArchiveDOSFullName) @$(ListDOSFullName)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\3] +"Type"=dword:ffffffff +"Title"="ZIP (Plugin)" +"Ext"="zip" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\4] +"Type"=dword:fffffffd +"Title"="PAK (Plugin)" +"Ext"="pak" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\5] +"Type"=dword:00000000 +"Title"="JAR (External Win32, tested with v1.02)" +"Ext"="j" +"Support Long Names"=dword:00000001 +"Need ANSI List"=dword:00000000 +"Copy Command"="$(Jar32bitExecutable)" +"Copy Arguments"="a \"$(ArchiveFullName)\" !\"$(ListFullName)\"" +"Support Move"=dword:00000001 +"Move Command"="$(Jar32bitExecutable)" +"Move Arguments"="m \"$(ArchiveFullName)\" !\"$(ListFullName)\"" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\6] +"Type"=dword:00000000 +"Title"="JAR to 1.44MB volumes (External Win32, tested with v1.02)" +"Ext"="j" +"Support Long Names"=dword:00000001 +"Need ANSI List"=dword:00000000 +"Copy Command"="$(Jar32bitExecutable)" +"Copy Arguments"="a -v1440 \"$(ArchiveFullName)\" !\"$(ListFullName)\"" +"Support Move"=dword:00000001 +"Move Command"="$(Jar32bitExecutable)" +"Move Arguments"="m -v1440 \"$(ArchiveFullName)\" !\"$(ListFullName)\"" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\7] +"Type"=dword:00000000 +"Title"="RAR (External Win32, tested with v2.50)" +"Ext"="rar" +"Support Long Names"=dword:00000001 +"Need ANSI List"=dword:00000000 +"Copy Command"="$(Rar32bitExecutable)" +"Copy Arguments"="a -scol \"$(ArchiveFullName)\" @\"$(ListFullName)\"" +"Support Move"=dword:00000001 +"Move Command"="$(Rar32bitExecutable)" +"Move Arguments"="m -scol \"$(ArchiveFullName)\" @\"$(ListFullName)\"" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\8] +"Type"=dword:00000000 +"Title"="RAR to 1.44MB volumes (External Win32, tested with v2.50)" +"Ext"="rar" +"Support Long Names"=dword:00000001 +"Need ANSI List"=dword:00000000 +"Copy Command"="$(Rar32bitExecutable)" +"Copy Arguments"="a -scol -v1440 \"$(ArchiveFullName)\" @\"$(ListFullName)\"" +"Support Move"=dword:00000001 +"Move Command"="$(Rar32bitExecutable)" +"Move Arguments"="m -scol -v1440 \"$(ArchiveFullName)\" @\"$(ListFullName)\"" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Packers\9] +"Type"=dword:00000000 +"Title"="ARJ (External Win32, tested with v3.00c)" +"Ext"="arj" +"Support Long Names"=dword:00000001 +"Need ANSI List"=dword:00000000 +"Copy Command"="$(Arj32bitExecutable)" +"Copy Arguments"="a -pa \"$(ArchiveFullName)\" !\"$(ListFullName)\"" +"Support Move"=dword:00000001 +"Move Command"="$(Arj32bitExecutable)" +"Move Arguments"="m -pa \"$(ArchiveFullName)\" !\"$(ListFullName)\"" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers] +"Use Another Panel"=dword:00000000 +"Use Subdir Name By Archive"=dword:00000000 +"Preffered"=dword:0000000a + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\1] +"Type"=dword:ffffffe3 +"Title"="UnRAR (Plugin)" +"Ext"="*.rar;*.r##" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\10] +"Type"=dword:fffffffb +"Title"="7-Zip (Plugin)" +"Ext"="*.7z" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\11] +"Type"=dword:ffffffff +"Title"="ZIP (Plugin)" +"Ext"="*.zip;*.pk3;*.jar" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\12] +"Type"=dword:fffffffd +"Title"="PAK (Plugin)" +"Ext"="*.pak" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\13] +"Type"=dword:fffffffe +"Title"="TAR (Plugin)" +"Ext"="*.tar;*.tgz;*.tbz;*.taz;*.tar.gz;*.tar.bz;*.tar.bz2;*.tar.z;*_tar.gz;*_tar.bz;*_tar.bz2;*_tar.z;*_tar_gz;*_tar_bz;*_tar_bz2;*_tar_z;*.tar_gz;*.tar_bz;*.tar_bz2;*.tar_z;*.gz;*.bz;*.bz2;*.z;*.rpm;*.cpio;*.deb" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\14] +"Type"=dword:00000000 +"Title"="JAR (External Win32, tested with v1.02)" +"Ext"="*.j" +"Support Long Names"=dword:00000001 +"Need ANSI List"=dword:00000000 +"Extract Command"="$(Jar32bitExecutable)" +"Extract Arguments"="x -jyc \"$(ArchiveFullName)\" !\"$(ListFullName)\"" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\15] +"Type"=dword:00000000 +"Title"="RAR (External Win32, tested with v2.50)" +"Ext"="*.rar" +"Support Long Names"=dword:00000001 +"Need ANSI List"=dword:00000000 +"Extract Command"="$(Rar32bitExecutable)" +"Extract Arguments"="x -scol \"$(ArchiveFullName)\" @\"$(ListFullName)\"" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\16] +"Type"=dword:00000000 +"Title"="ARJ (External Win32, tested with v3.00c)" +"Ext"="*.arj" +"Support Long Names"=dword:00000001 +"Need ANSI List"=dword:00000000 +"Extract Command"="$(Arj32bitExecutable)" +"Extract Arguments"="x -va -jyc \"$(ArchiveFullName)\" !\"$(ListFullName)\"" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\17] +"Type"=dword:00000000 +"Title"="ACE (External Win32, tested with v1.2b)" +"Ext"="*.ace" +"Support Long Names"=dword:00000001 +"Need ANSI List"=dword:00000001 +"Extract Command"="$(Ace32bitExecutable)" +"Extract Arguments"="x \"$(ArchiveFullName)\" @\"$(ListFullName)\"" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\18] +"Type"=dword:00000000 +"Title"="ARJ (External DOS, tested with v2.60)" +"Ext"="*.arj" +"Support Long Names"=dword:00000000 +"Need ANSI List"=dword:00000000 +"Extract Command"="$(Arj16bitExecutable)" +"Extract Arguments"="x -va -jyc $(ArchiveDOSFullName) !$(ListDOSFullName)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\19] +"Type"=dword:00000000 +"Title"="LHA (External DOS, tested with v2.55)" +"Ext"="*.lzh" +"Support Long Names"=dword:00000000 +"Need ANSI List"=dword:00000000 +"Extract Command"="$(Lha16bitExecutable)" +"Extract Arguments"="x -a -l1 -c $(ArchiveDOSFullName) @$(ListDOSFullName)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\2] +"Type"=dword:ffffffe4 +"Title"="UnMIME (Plugin)" +"Ext"="*.eml;*.b64;*.uue;*.xxe;*.hqx;*.ntx;*.cnm" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\20] +"Type"=dword:00000000 +"Title"="UC2 (External DOS, tested with v2r3PRO)" +"Ext"="*.uc2" +"Support Long Names"=dword:00000000 +"Need ANSI List"=dword:00000000 +"Extract Command"="$(UC216bitExecutable)" +"Extract Arguments"="ESF $(ArchiveDOSFullName) @$(ListDOSFullName)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\21] +"Type"=dword:00000000 +"Title"="ACE (External DOS, tested with v1.2b)" +"Ext"="*.ace" +"Support Long Names"=dword:00000000 +"Need ANSI List"=dword:00000000 +"Extract Command"="$(Ace16bitExecutable)" +"Extract Arguments"="x $(ArchiveDOSFullName) @$(ListDOSFullName)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\22] +"Type"=dword:00000000 +"Title"="JAR (External DOS, tested with v1.02)" +"Ext"="*.j" +"Support Long Names"=dword:00000000 +"Need ANSI List"=dword:00000000 +"Extract Command"="$(Jar16bitExecutable)" +"Extract Arguments"="x -jyc $(ArchiveDOSFullName) !$(ListDOSFullName)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\23] +"Type"=dword:00000000 +"Title"="RAR (External DOS, tested with v2.50)" +"Ext"="*.rar" +"Support Long Names"=dword:00000000 +"Need ANSI List"=dword:00000000 +"Extract Command"="$(Rar16bitExecutable)" +"Extract Arguments"="x $(ArchiveDOSFullName) @$(ListDOSFullName)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\24] +"Type"=dword:00000000 +"Title"="PKZIP (External Win32, tested with v2.50)" +"Ext"="*.zip;*.pk3;*.jar" +"Support Long Names"=dword:00000001 +"Need ANSI List"=dword:00000001 +"Extract Command"="$(Zip32bitExecutable)" +"Extract Arguments"="-ext -nozipextension -directories -path \"$(ArchiveFullName)\" @\"$(ListFullName)\"" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\25] +"Type"=dword:00000000 +"Title"="PKUNZIP (External DOS, tested with v2.04g)" +"Ext"="*.zip" +"Support Long Names"=dword:00000000 +"Need ANSI List"=dword:00000000 +"Extract Command"="$(Unzip16bitExecutable)" +"Extract Arguments"="-d -Jhrs $(ArchiveDOSFullName) @$(ListDOSFullName)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\3] +"Type"=dword:ffffffe5 +"Title"="UnLHA (Plugin)" +"Ext"="*.lzh;*.lha;*.lzs" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\4] +"Type"=dword:ffffffe6 +"Title"="UnISO (Plugin)" +"Ext"="*.iso;*.isz;*.nrg;*.bin;*.img;*.pdi;*.cdi;*.cif;*.ncd;*.c2d;*.mdf;*.dmg" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\5] +"Type"=dword:ffffffe7 +"Title"="UnFAT (Plugin)" +"Ext"="*.ima" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\6] +"Type"=dword:ffffffe9 +"Title"="UnCHM (Plugin)" +"Ext"="*.chm" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\7] +"Type"=dword:ffffffea +"Title"="UnCAB (Plugin)" +"Ext"="*.cab" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\8] +"Type"=dword:ffffffeb +"Title"="UnARJ (Plugin)" +"Ext"="*.arj;*.a##" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Custom Unpackers\9] +"Type"=dword:fffffff5 +"Title"="Decrypt (Plugin)" +"Ext"="*.ena" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Predefined Packers] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Predefined Packers\1] +"Packer UID"=dword:00000001 +"Packer Executable"="jar32" +"Use Packer Executable To Unpack"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Predefined Packers\10] +"Packer UID"=dword:0000000a +"Packer Executable"="arj32" +"Use Packer Executable To Unpack"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Predefined Packers\11] +"Packer UID"=dword:0000000b +"Packer Executable"="ace32" +"Use Packer Executable To Unpack"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Predefined Packers\12] +"Packer UID"=dword:0000000c +"Packer Executable"="ace" +"Use Packer Executable To Unpack"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Predefined Packers\2] +"Packer UID"=dword:00000002 +"Packer Executable"="rar" +"Use Packer Executable To Unpack"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Predefined Packers\3] +"Packer UID"=dword:00000003 +"Packer Executable"="arj" +"Use Packer Executable To Unpack"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Predefined Packers\4] +"Packer UID"=dword:00000004 +"Packer Executable"="lha" +"Use Packer Executable To Unpack"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Predefined Packers\5] +"Packer UID"=dword:00000005 +"Packer Executable"="uc" +"Use Packer Executable To Unpack"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Predefined Packers\6] +"Packer UID"=dword:00000006 +"Packer Executable"="jar16" +"Use Packer Executable To Unpack"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Predefined Packers\7] +"Packer UID"=dword:00000007 +"Packer Executable"="rar" +"Use Packer Executable To Unpack"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Predefined Packers\8] +"Packer UID"=dword:00000008 +"Packer Executable"="pkzip25" +"Use Packer Executable To Unpack"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Packers & Unpackers\Predefined Packers\9] +"Packer UID"=dword:00000009 +"Packer Executable"="pkzip" +"Use Packer Executable To Unpack"=dword:00000000 +"Unpacker Executable"="pkunzip" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Password Manager] +"Use Master Password"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\1] +"Name"="ZIP" +"DLL"="zip\\zip.spl" +"Version"="1.39" +"Copyright"="Copyright © 1999-2019 ALTAP" +"Extensions"="zip;pk3;pk4;jar" +"Description"="Create, browse, and extract ZIP archives." +"Configuration Key"="ZIP" +"FS Name"="" +"Functions"=dword:0000003f +"HomePage"="www.altap.cz" +"PluginIconList"=hex:89,50,4e,47,0d,0a,1a,0a,00,00,00,0d,49,48,44,52,00,00,00,\ + 10,00,00,00,10,08,06,00,00,00,1f,f3,ff,61,00,00,00,b5,49,44,41,54,78,9c,95,\ + 92,cb,11,c5,20,08,00,39,d8,51,7a,b2,8e,77,b2,07,7b,a2,20,6f,bc,48,40,fc,11,\ + 27,71,f6,90,51,17,10,80,c0,16,00,91,c7,78,e6,c7,f0,ff,b0,91,1f,2e,34,a2,10,\ + 42,20,3d,87,44,8e,40,cc,33,b7,b3,49,66,20,a5,44,1e,16,f5,91,54,50,b8,44,c8,\ + 82,52,0a,d9,27,47,11,9a,40,25,5b,54,10,23,0c,cc,82,be,d4,e1,0d,2c,03,8b,5c,\ + c1,bc,0a,dc,37,a8,17,e7,0c,76,02,37,83,3e,7a,bd,58,c9,71,14,ec,a2,73,06,de,\ + 86,a2,97,fb,0e,68,17,f8,11,4f,11,f4,72,44,67,4e,7a,c1,db,24,b6,9a,bd,49,7c,\ + ed,b5,1c,3e,0a,4e,8b,33,ec,47,3e,2f,4d,3a,08,c0,4a,d3,2c,3e,0a,d6,d2,fe,62,\ + 31,12,86,9c,44,db,ed,00,00,00,00,49,45,4e,44,ae,42,60,82 +"PluginIconIndex"=dword:00000000 +"SubmenuIconIndex"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\1\Menu] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\1\Menu\1] +"State"=dword:ffffffff +"ID"=dword:00000004 +"Name"="Archive &Comment..." +"Skill"=dword:00000006 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\1\Menu\2] +"State"=dword:ffffffff +"ID"=dword:00000001 +"Name"="Create &Self-Extracting Archive (.exe)..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\1\Menu\3] +"State"=dword:ffffffff +"ID"=dword:00000003 +"Name"="&Test Archive" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\10] +"Name"="DiskMap" +"DLL"="diskmap\\diskmap.spl" +"Version"="1.12" +"Copyright"="Copyright © 2009-2019 Ondrej Zarevucky" +"Extensions"="" +"Description"="Displays a treemap of files on your disk." +"Configuration Key"="DISKMAP" +"FS Name"="" +"Functions"=dword:00000020 +"HomePage"="www.altap.cz" +"PluginIconList"=hex:89,50,4e,47,0d,0a,1a,0a,00,00,00,0d,49,48,44,52,00,00,00,\ + 10,00,00,00,10,08,06,00,00,00,1f,f3,ff,61,00,00,02,97,49,44,41,54,78,9c,cd,\ + 92,5b,48,d3,01,14,c6,67,d0,05,22,88,c8,85,3e,29,b8,9c,36,a5,87,c8,a9,69,b6,\ + 09,41,9a,97,6d,48,3d,09,5d,24,7a,70,8a,58,e1,2a,73,2d,72,cb,bc,ad,bf,53,4c,\ + c1,9c,b7,4d,ff,db,6c,ba,72,ae,bc,ce,91,4e,b7,a1,2e,97,8e,a6,a1,91,90,37,34,\ + 93,dc,d7,ac,a7,1e,5a,d1,53,07,0e,9c,87,f3,fd,0e,df,e1,a3,50,fe,cb,0a,0c,08,\ + 08,64,46,c7,5e,8b,3f,7b,ee,26,33,32,ea,a2,bf,9f,df,fe,bf,12,06,07,07,fb,24,\ + 27,27,27,de,93,91,43,43,8e,4f,b6,b7,0b,eb,53,7d,36,97,5d,f4,e8,89,81,4a,f5,\ + f5,ff,23,e0,74,4c,4c,40,81,b4,fe,b5,d0,b0,2d,9e,5b,82,65,6a,11,a6,21,17,ba,\ + 5a,ad,1b,ca,ec,1b,02,22,3e,9e,bd,cf,2b,20,ee,54,64,84,b0,75,aa,e6,6e,17,6e,\ + 69,ed,28,57,4f,a0,b4,67,06,f2,37,73,d0,88,2a,c9,e7,c7,c3,c3,82,bc,02,42,8e,\ + 06,45,8a,3b,e6,8a,f8,ed,6e,8e,6d,7e,5b,3a,ee,5a,79,65,76,ae,f6,0f,4c,af,6b,\ + f3,2b,3b,3a,ce,27,24,84,f1,78,bc,df,03,a8,be,87,8f,3c,ac,52,92,8f,d5,13,d5,\ + 26,db,cc,82,6d,ea,fd,b7,97,bd,23,ee,be,f1,f9,ad,c2,62,62,43,a9,54,f6,a9,48,\ + 55,55,5a,5a,5a,26,87,c3,89,0b,09,a1,ff,14,32,18,c7,0e,89,ee,0b,af,77,77,77,\ + 19,09,82,d8,9a,98,fe,80,d5,f5,af,f8,bc,b2,86,99,8f,cb,68,52,bf,40,6d,6d,0d,\ + cc,66,33,74,3a,1d,46,46,86,61,b7,4f,2e,31,99,27,69,94,f6,76,ad,54,a5,22,bf,\ + 58,ad,16,f7,cc,3b,07,9e,d5,c9,91,9d,95,85,d2,32,29,9e,c8,9e,42,5c,54,82,92,\ + d2,72,b4,28,db,d0,a2,50,62,74,6c,0c,93,93,13,d0,68,34,6e,36,9b,1d,47,91,cb,\ + 9b,36,4d,a6,51,0c,f4,0f,43,d1,4c,22,2f,ef,36,2a,08,19,14,2d,cd,d0,a8,d5,3b,\ + 8b,d0,eb,f5,70,38,1c,70,3a,9d,50,28,14,90,48,24,db,19,19,19,a6,d4,d4,d4,13,\ + 94,c6,46,c5,42,4f,af,11,9d,5a,3d,08,a2,02,24,d9,09,97,6b,09,46,a3,05,d5,f2,\ + 2a,48,8a,0b,31,eb,9a,85,ae,53,07,b1,58,8c,dc,dc,dc,55,8f,7f,31,8b,c5,f2,fb,\ + e1,3f,22,82,c9,a8,af,6b,5a,24,db,48,37,9f,9f,b3,69,30,0c,c2,32,e6,80,71,d0,\ + 0a,49,5b,0e,12,0b,c2,51,5e,56,06,81,40,b0,9d,9e,9e,6e,e2,72,b9,31,54,2a,75,\ + cf,2f,df,67,9d,61,e7,d3,68,34,82,4e,a7,47,f1,33,b3,b2,1f,88,0a,1b,1a,1b,5a,\ + e7,65,b5,c4,da,a5,9c,0b,10,89,44,cb,9e,84,0a,3d,57,0f,7a,8b,c1,5e,4f,fb,ec,\ + 0c,a1,a1,a1,bb,92,92,92,0e,70,b9,bc,e8,2b,97,af,de,49,49,49,89,65,30,18,bb,\ + bd,86,e8,5f,eb,3b,83,2c,62,74,1c,e9,7f,b9,00,00,00,00,49,45,4e,44,ae,42,60,\ + 82 +"PluginIconIndex"=dword:00000000 +"SubmenuIconIndex"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\10\Menu] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\10\Menu\1] +"State"=dword:00010002 +"ID"=dword:00000001 +"Name"="Show &DiskMap" +"HotKey"=dword:00000344 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\11] +"Name"="Encrypt & Decrypt" +"DLL"="encrypt\\encrypt.spl" +"Version"="1.11" +"Copyright"="Copyright © 2003-2019 ALTAP" +"Extensions"="ena" +"Description"="Strong file encryption and decryption, secure files shredding." +"Configuration Key"="Encrypt & Decrypt" +"FS Name"="" +"Functions"=dword:0000003f +"Load On Start"=dword:00000001 +"HomePage"="www.altap.cz" +"PluginIconList"=hex:89,50,4e,47,0d,0a,1a,0a,00,00,00,0d,49,48,44,52,00,00,00,\ + 10,00,00,00,10,08,06,00,00,00,1f,f3,ff,61,00,00,00,7b,49,44,41,54,78,9c,dd,\ + 92,db,09,c0,30,08,45,fd,c8,ac,1d,29,e0,36,0e,e0,4e,b6,5a,84,3c,54,4a,bf,4a,\ + 13,2e,42,d0,e3,45,03,02,f1,6d,ad,c9,a8,2c,2f,2d,d6,c3,cc,d2,7b,37,65,90,b0,\ + 98,88,ac,d8,bb,57,90,10,b0,26,47,6f,1f,05,ac,93,cf,14,02,7c,f2,d7,ec,07,e1,\ + 2c,06,61,84,09,b2,59,d7,0d,b8,dd,71,0b,78,80,01,34,a6,80,bb,ab,94,0e,4a,c0,\ + 6f,1c,b0,25,66,2a,01,ba,a2,27,0a,01,6f,3f,d2,09,c9,ee,12,5c,52,7c,70,e1,00,\ + 00,00,00,49,45,4e,44,ae,42,60,82 +"PluginIconIndex"=dword:00000000 +"SubmenuIconIndex"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\11\Menu] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\11\Menu\1] +"State"=dword:01b00002 +"ID"=dword:00000001 +"Name"="&Encrypt..." +"HotKey"=dword:00000345 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\11\Menu\10] +"State"=dword:00010002 +"ID"=dword:00000004 +"Name"="Clean Disk &Free Space..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\11\Menu\2] +"State"=dword:20000001 +"ID"=dword:00000002 +"Name"="&Decrypt Archive..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\11\Menu\3] +"State"=dword:00010002 +"ID"=dword:00000007 +"Name"="Create a &Key..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\11\Menu\4] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\11\Menu\5] +"State"=dword:20040001 +"ID"=dword:00000005 +"Name"="Change Archive &Password or Key..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\11\Menu\6] +"State"=dword:00010012 +"ID"=dword:00000008 +"Name"="Change Key Pass&word..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\11\Menu\7] +"State"=dword:00010012 +"ID"=dword:00000006 +"Name"="Change Archive or Key &Comment..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\11\Menu\8] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\11\Menu\9] +"State"=dword:01b00002 +"ID"=dword:00000003 +"Name"="&Shred Files..." +"HotKey"=dword:00000353 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\12] +"Name"="File Comparator" +"DLL"="filecomp\\filecomp.spl" +"Version"="1.19" +"Copyright"="Copyright © 2000-2019 ALTAP" +"Extensions"="" +"Description"="Visual comparison of two text or binary files." +"Configuration Key"="File Comparator" +"FS Name"="" +"Functions"=dword:00000030 +"HomePage"="www.altap.cz" +"PluginIconList"=hex:89,50,4e,47,0d,0a,1a,0a,00,00,00,0d,49,48,44,52,00,00,00,\ + 10,00,00,00,10,08,06,00,00,00,1f,f3,ff,61,00,00,00,84,49,44,41,54,78,9c,a5,\ + 93,d1,0d,80,20,0c,44,f9,60,23,77,72,94,ee,c0,4e,ec,84,50,6d,02,e5,0a,25,42,\ + 2e,31,35,3c,ef,45,0d,25,fc,db,70,48,44,05,e5,08,a0,57,9b,c5,18,27,88,13,90,\ + 8a,cc,34,64,0d,a8,b7,39,df,c1,3e,03,c0,74,ae,4f,96,06,6d,e5,9c,39,10,60,3b,\ + 87,21,4e,80,72,ee,9a,2c,01,d7,fd,06,3b,bb,1a,d8,ce,72,bd,00,24,ad,cb,91,03,\ + db,b7,80,1a,20,67,f8,21,79,1a,6c,01,bd,a3,ce,16,80,1c,2d,67,d7,bf,70,b2,1f,\ + 94,75,57,fb,32,b4,09,6f,00,00,00,00,49,45,4e,44,ae,42,60,82 +"PluginIconIndex"=dword:00000000 +"SubmenuIconIndex"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\12\Menu] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\12\Menu\1] +"State"=dword:00020000 +"ID"=dword:00000001 +"Name"="Compare Files..." +"HotKey"=dword:00000343 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\13] +"Name"="FTP Client" +"DLL"="ftp\\ftp.spl" +"Version"="1.35" +"Copyright"="Copyright © 2002-2019 ALTAP" +"Extensions"="" +"Description"="Transfer files and directories over FTP." +"Configuration Key"="FTP" +"FS Name"="ftp:ftps" +"Functions"=dword:000000b0 +"FS Cmd Name"="/ FTP Client" +"FS Cmd Icon"=dword:00000000 +"Uses Password Manager"=dword:00000001 +"HomePage"="www.altap.cz" +"PluginIconList"=hex:89,50,4e,47,0d,0a,1a,0a,00,00,00,0d,49,48,44,52,00,00,00,\ + 10,00,00,00,10,08,06,00,00,00,1f,f3,ff,61,00,00,00,b5,49,44,41,54,78,9c,ad,\ + 92,d1,0d,c5,20,08,45,f9,f0,d3,6d,dc,c9,39,de,1a,dd,89,9d,68,11,11,b0,b5,a9,\ + c9,93,dc,0f,09,f7,40,50,20,78,8e,72,00,79,ad,ea,96,46,3e,05,8b,88,73,95,9a,\ + 5e,01,6a,c4,1e,66,36,c0,0c,79,34,8f,ce,55,cc,70,50,00,00,fc,28,00,56,66,36,\ + 36,33,46,00,2b,e7,4c,06,68,c9,3e,ea,e8,dc,8d,48,61,02,60,f0,a5,94,92,00,38,\ + 89,bc,30,d2,42,31,6b,e7,d9,ac,7b,51,88,01,fa,f6,c7,c8,ae,3b,17,fb,a5,fa,29,\ + 6e,cf,06,35,42,56,e6,00,d0,67,e3,c4,ae,ec,f3,50,95,c5,b8,f3,e5,1e,7e,9f,16,\ + cc,5d,7c,ce,83,06,40,21,be,c3,1b,e0,36,81,c6,ce,04,61,07,7f,05,ec,ea,04,5b,\ + 0f,17,29,cb,4e,cb,63,00,00,00,00,49,45,4e,44,ae,42,60,82 +"PluginIconIndex"=dword:00000000 +"SubmenuIconIndex"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\13\Menu] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\13\Menu\1] +"State"=dword:00010001 +"ID"=dword:00000001 +"Name"="&Connect to FTP Server..." +"HotKey"=dword:00000346 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\13\Menu\10] +"State"=dword:ffffffff +"ID"=dword:0000000c +"Name"="&Binary" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\13\Menu\11] +"Type"=dword:00000002 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\13\Menu\12] +"State"=dword:00080001 +"ID"=dword:0000000d +"Name"="&Refresh" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\13\Menu\13] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\13\Menu\14] +"State"=dword:00080001 +"ID"=dword:00000003 +"Name"="&Add Bookmark..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\13\Menu\15] +"State"=dword:00080001 +"ID"=dword:00000006 +"Name"="&Send FTP Command..." +"Skill"=dword:00000006 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\13\Menu\16] +"State"=dword:00080001 +"ID"=dword:00000009 +"Name"="S&how Raw Listing..." +"Skill"=dword:00000004 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\13\Menu\17] +"State"=dword:ffffffff +"ID"=dword:00000014 +"Name"="L&ist Hidden Files and Directories (Unix)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\13\Menu\2] +"State"=dword:00010001 +"ID"=dword:00000007 +"Name"="&Organize Bookmarks..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\13\Menu\3] +"State"=dword:00010001 +"ID"=dword:00000005 +"Name"="Show &Logs..." +"Skill"=dword:00000006 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\13\Menu\4] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\13\Menu\5] +"State"=dword:00010001 +"ID"=dword:00000012 +"Name"="&Disconnect... F12" +"HotKey"=dword:00020000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\13\Menu\6] +"State"=dword:ffffffff +"ID"=dword:00000018 +"Name"="Sho&w Certificate..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\13\Menu\7] +"State"=dword:00080001 +"ID"=dword:00000015 +"Name"="&Transfer Mode" +"Type"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\13\Menu\8] +"State"=dword:ffffffff +"ID"=dword:0000000a +"Name"="&Automatic" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\13\Menu\9] +"State"=dword:ffffffff +"ID"=dword:0000000b +"Name"="A&SCII" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\14] +"Name"="Multimedia Viewer" +"DLL"="mmviewer\\mmviewer.spl" +"Version"="1.16" +"Copyright"="Copyright © 2003-2019 ALTAP & Tomas Jelinek (tomas@tjelinek.com)" +"Extensions"="" +"Description"="Display information about multimedia files such as MP3, OGG, WAV, etc." +"Configuration Key"="MMVIEWER" +"FS Name"="" +"Functions"=dword:00000060 +"HomePage"="www.altap.cz" +"PluginIconList"=hex:89,50,4e,47,0d,0a,1a,0a,00,00,00,0d,49,48,44,52,00,00,00,\ + 10,00,00,00,10,08,06,00,00,00,1f,f3,ff,61,00,00,00,69,49,44,41,54,78,9c,bd,\ + d2,51,0a,c0,20,0c,03,d0,1e,3d,47,eb,cd,1c,9d,08,a5,1a,96,fa,b1,4a,60,a0,3e,\ + 82,cc,86,cd,05,60,28,59,e7,d7,b2,0c,7c,8d,bb,6f,48,1b,88,c9,08,05,60,78,93,\ + c7,e2,78,8a,04,9c,a0,68,22,01,ac,49,0b,a8,df,ff,00,b5,76,0b,38,3d,dc,15,c0,\ + da,c8,6f,c0,da,5c,01,75,64,80,0d,05,62,43,cd,06,d4,ff,5c,49,dc,7b,00,e8,a1,\ + cb,89,a2,3f,7c,27,00,00,00,00,49,45,4e,44,ae,42,60,82 +"PluginIconIndex"=dword:00000000 +"SubmenuIconIndex"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\14\Menu] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\14\Menu\1] +"State"=dword:ffffffff +"ID"=dword:00000001 +"Name"="Export Info into &HTML..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\15] +"Name"="Network" +"DLL"="nethood\\nethood.spl" +"Version"="1.08" +"Copyright"="Copyright © 2008-2019 ALTAP" +"Extensions"="" +"Description"="Provides access to computers on the network." +"Configuration Key"="nethood" +"FS Name"="net" +"Functions"=dword:000000b0 +"FS Cmd Name"=", Network" +"FS Cmd Icon"=dword:00000000 +"Is Nethood"=dword:00000001 +"HomePage"="www.altap.cz" +"PluginIconList"=hex:89,50,4e,47,0d,0a,1a,0a,00,00,00,0d,49,48,44,52,00,00,00,\ + 10,00,00,00,10,08,06,00,00,00,1f,f3,ff,61,00,00,02,de,49,44,41,54,78,9c,ad,\ + 93,49,4c,93,51,14,85,bb,31,e2,80,14,04,64,b0,65,92,c1,28,76,e1,42,37,86,a8,\ + 89,91,80,11,08,2a,46,8d,10,22,06,63,20,46,a3,21,04,28,16,cb,50,a0,0c,65,28,\ + 14,a1,02,45,28,50,64,1e,84,0a,54,a0,14,fa,53,40,26,a5,05,04,8d,90,c8,b0,50,\ + e3,e2,1d,7f,9a,28,ac,60,e3,4d,ee,ee,7e,e7,9e,f3,6e,1e,83,41,57,ab,fe,1b,a7,\ + 79,76,a9,58,32,ac,5f,f5,97,28,11,51,a5,32,14,a8,c6,e3,38,91,42,26,63,b7,6a,\ + fa,b8,e0,d7,f7,65,05,5d,8b,eb,68,9d,5f,43,88,5c,4b,2e,8b,da,49,da,5b,0a,01,\ + c9,af,28,ce,dd,b8,9d,45,64,e3,9f,0d,5d,4b,1b,e0,a9,97,11,54,37,8b,80,0a,1d,\ + f1,29,e8,46,60,5e,33,a9,d6,7d,42,a5,6e,9a,bb,a3,00,ff,fd,1c,1e,77,7f,c5,ed,\ + 96,25,dc,ac,37,20,b0,72,0c,be,92,5e,5c,14,28,40,ad,ac,43,a4,d2,c2,39,a5,00,\ + 4e,89,62,38,24,e4,83,fd,3c,1f,ac,d8,5c,d8,47,e7,c0,2e,4a,a4,64,84,d6,4f,21,\ + bc,6d,0e,21,2d,f3,b8,51,3b,03,ff,72,0a,3e,62,25,ce,27,c9,91,a3,a4,c0,ab,ed,\ + c0,a9,ae,19,9c,ec,98,c6,f1,a6,49,e2,51,3f,01,b7,9a,71,1c,a3,17,d9,3c,c9,02,\ + c3,4f,3a,68,78,b7,b8,86,91,ef,bf,c0,ed,36,c0,b7,48,85,4b,59,cd,38,17,2f,c5,\ + e9,88,14,78,84,c5,e2,44,cb,14,3c,1a,68,50,31,4e,5c,e5,63,70,96,8d,12,a7,d2,\ + 11,58,45,64,10,86,77,5e,27,b7,68,48,8f,e9,8d,9f,d0,ff,f8,0d,89,46,0f,ef,d4,\ + 6a,9c,7d,2a,82,67,68,0c,dc,78,25,f0,78,33,01,d7,ea,31,e2,f2,7a,14,4e,65,3a,\ + 38,14,53,84,2d,d1,c2,f2,81,10,0c,2f,a1,82,79,41,50,43,35,4e,2f,60,68,79,15,\ + a5,ea,49,9c,a1,61,ce,fd,78,b8,d1,ed,5a,31,4c,db,1d,25,f4,56,38,49,47,c0,2e,\ + d2,92,a3,e2,61,d8,e7,0c,c1,fc,5e,1a,8c,0f,e9,15,57,cc,8c,6e,ee,41,a4,ac,cd,\ + 68,db,33,22,19,ee,09,a5,70,29,d3,c0,a5,62,14,8e,34,e8,f0,52,0b,56,a1,16,f6,\ + b9,43,b0,cd,d2,e0,48,9a,1a,87,82,05,f8,77,0d,16,37,8f,d0,39,89,bb,e2,03,e8,\ + 9c,84,06,e9,9c,46,bb,7f,41,62,97,ad,81,8d,70,10,d6,82,01,62,99,d8,0f,d3,5b,\ + 29,5b,02,f4,59,c8,b6,9c,c4,b1,84,c2,66,4e,16,6d,d7,4e,b4,09,aa,89,75,ea,00,\ + 36,41,0b,5e,1f,98,dc,5e,b2,ff,7a,d2,96,80,ed,b3,6c,38,97,eb,8c,76,d9,45,14,\ + 61,89,b5,b0,cb,d1,10,db,cc,41,a3,5d,ab,e4,7e,72,f8,45,1f,cc,b9,2a,98,c5,f4,\ + c2,34,aa,07,26,fe,fc,2d,01,eb,47,99,4a,eb,c8,4c,58,3e,14,e2,70,78,3a,b1,08,\ + 4b,07,33,34,95,98,05,a7,c2,f4,4e,0a,0e,d2,76,0f,04,25,63,df,b5,44,62,12,c0,\ + c7,de,ab,7c,ec,b9,92,a0,dc,f5,af,48,ab,1a,b0,d9,bb,0e,fe,57,81,c6,ae,01,43,\ + 5d,7b,2f,e4,8d,9d,90,29,5a,20,ad,ac,47,61,59,35,72,8b,65,c8,10,97,e8,b7,cf,\ + fe,01,21,11,e3,36,87,84,b0,90,00,00,00,00,49,45,4e,44,ae,42,60,82 +"PluginIconIndex"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\16] +"Name"="Portable Executable Viewer" +"DLL"="peviewer\\peviewer.spl" +"Version"="3.0" +"Copyright"="Copyright © 2001-2019 ALTAP" +"Extensions"="" +"Description"="Display information about Portable Executable files such as EXE, DLL, etc." +"Configuration Key"="PEVIEWER" +"FS Name"="" +"Functions"=dword:00000070 +"HomePage"="www.altap.cz" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\17] +"Name"="PictView" +"DLL"="pictview\\pictview.spl" +"Version"="2.13" +"Copyright"="Copyright © 2000-2019 ALTAP & Jan Patera" +"Extensions"="" +"Description"="Fast image viewer and converter." +"Configuration Key"="PictView" +"FS Name"="" +"Functions"=dword:00000070 +"HomePage"="www.pictview.com/salamander" +"ThumbnailMasks"="*.mng;*.dtx;*.dds;*.nef;*.crw;*.eps;*.ept;*.ai;*.raf;*.mov;*.hpi;*.pntg;*.thumb;*.tiff;*.wbmp;*.mbm;*.ani;*.psp*;*.clk;*.thm;*.zno;*.st;*.cals;*.itiff;*.jfif;*.jpeg;*.macp;*.mpnt;*.paint;*.pict;*.2bp;*.stw;*.sun;*.tga;*.tif;*.udi;*.web;*.wpg;*.xar;*.zbr;*.zmf;*.bw;*.psd;*.pyx;*.qfx;*.ras;*.rgb;*.rle;*.sam;*.scx;*.sep;*.sgi;*.ska;*.pat;*.pbm;*.pc2;*.pcd;*.pct;*.pcx;*.pgm;*.pic;*.png;*.pnm;*.ppm;*.jff;*.jif;*.jmx;*.jpe;*.jpg;*.lbm;*.mac;*.mil;*.msp;*.ofx;*.pan;*.flc;*.fli;*.gem;*.gif;*.ham;*.hmr;*.hrz;*.icn;*.ico;*.iff;*.img;*.cdt;*.cel;*.clp;*.cit;*.cmx;*.cot;*.cpt;*.cur;*.cut;*.dcx;*.dib;*.82i;*.83i;*.85i;*.86i;*.89i;*.92i;*.awd;*.bmi;*.bmp;*.cal;*.cdr;*.arw;*.blp;*.cr2;*.dng;*.orf;*.pef" +"PluginIconList"=hex:89,50,4e,47,0d,0a,1a,0a,00,00,00,0d,49,48,44,52,00,00,00,\ + 10,00,00,00,10,08,06,00,00,00,1f,f3,ff,61,00,00,01,13,49,44,41,54,78,9c,a5,\ + 53,cb,0d,c3,30,08,65,9d,9c,99,23,c7,ac,c0,1c,de,a1,27,16,ea,89,73,d7,e8,08,\ + 94,07,49,e4,b8,49,5b,a9,8a,9e,c2,f7,19,30,26,11,f6,d6,c8,97,65,71,a7,fa,60,\ + 03,ae,74,c4,22,07,36,82,00,8f,19,b9,6a,c1,ad,70,a5,23,16,39,c8,a5,79,9e,d3,\ + c9,c1,c6,aa,09,02,5a,73,65,49,b0,94,be,f9,11,8b,1c,e4,66,49,60,cd,a4,e4,75,\ + 67,b7,38,09,8a,fa,83,6e,ce,e6,bb,2f,11,ce,ac,2c,d2,76,02,5e,09,e2,4c,77,38,\ + 15,25,36,17,9c,68,72,20,e0,9e,20,87,03,29,82,47,02,8a,32,45,a3,1e,ae,ff,4e,\ + 12,b1,90,72,88,23,41,91,c4,d4,6d,25,10,fa,4c,30,b6,50,c0,20,39,09,28,7d,5c,\ + b6,b3,16,4e,09,30,34,1a,f0,eb,0c,76,48,97,2c,c3,2d,7c,9b,c1,69,05,86,d9,d8,\ + 8f,33,d0,77,02,11,f3,e7,e3,1e,24,17,7b,90,15,58,57,41,d7,02,47,91,6a,16,37,\ + 63,e5,c3,96,6e,04,b9,ca,21,4d,d3,54,eb,9c,7d,65,6f,91,18,4b,14,ab,2c,90,57,\ + 7b,c6,70,b7,ca,a7,8f,69,bb,cc,0b,fd,f0,98,fe,7d,ce,2f,84,62,5c,36,ab,ee,03,\ + f6,00,00,00,00,49,45,4e,44,ae,42,60,82 +"PluginIconIndex"=dword:00000000 +"SubmenuIconIndex"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\17\Menu] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\17\Menu\1] +"State"=dword:ffffffff +"ID"=dword:00000069 +"Name"="View Bitmap from &Clipboard" +"HotKey"=dword:00000342 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\17\Menu\2] +"State"=dword:00010001 +"ID"=dword:00000094 +"Name"="&Screen Capture..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\17\Menu\3] +"State"=dword:00900001 +"ID"=dword:000000bc +"Name"="&Update Thumbnail" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\17\Menu\4] +"State"=dword:00010001 +"ID"=dword:000000b4 +"Name"="Sc&an Image..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\18] +"Name"="Registry Editor" +"DLL"="regedt\\regedt.spl" +"Version"="1.14" +"Copyright"="Copyright © 2003-2019 ALTAP" +"Extensions"="" +"Description"="Browse, view, and modify Windows Registry." +"Configuration Key"="RegEdit" +"FS Name"="reg" +"Functions"=dword:000000b0 +"FS Cmd Name"=" Windows Registry" +"FS Cmd Icon"=dword:00000000 +"HomePage"="www.altap.cz" +"PluginIconList"=hex:89,50,4e,47,0d,0a,1a,0a,00,00,00,0d,49,48,44,52,00,00,00,\ + 10,00,00,00,10,08,06,00,00,00,1f,f3,ff,61,00,00,00,8d,49,44,41,54,78,9c,95,\ + 93,51,0e,c0,20,08,43,39,3a,37,57,59,d4,14,0a,ea,5c,1a,3f,06,8f,d6,04,69,72,\ + ff,54,b5,55,ff,de,9a,c7,91,51,fa,1b,60,cd,62,32,80,dd,13,82,8e,9e,1c,ec,e6,\ + 71,a2,23,2a,ce,84,cd,d1,11,4f,9a,13,1a,16,01,c8,39,5a,0e,74,52,97,35,49,00,\ + ee,86,07,f5,cd,58,08,93,b6,60,b2,03,7c,cd,08,00,65,4e,08,e0,a6,2d,e0,7e,24,\ + 06,33,00,23,54,71,5e,23,9c,e2,dc,23,04,11,ac,04,54,11,62,9c,64,1f,8e,11,a2,\ + 83,74,99,28,67,a1,6a,57,3a,ae,83,15,dd,05,1e,82,79,00,00,00,00,49,45,4e,44,\ + ae,42,60,82 +"PluginIconIndex"=dword:00000000 +"SubmenuIconIndex"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\18\Menu] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\18\Menu\1] +"State"=dword:00010001 +"ID"=dword:00000001 +"Name"="&Search in Windows Registry..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\18\Menu\2] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\18\Menu\3] +"State"=dword:10081008 +"ID"=dword:00000002 +"Name"="New &Key..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\18\Menu\4] +"State"=dword:10081008 +"ID"=dword:00000003 +"Name"="New &Value..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\18\Menu\5] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\18\Menu\6] +"State"=dword:00010001 +"ID"=dword:00000004 +"Name"="&Export..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\19] +"Name"="Renamer" +"DLL"="renamer\\renamer.spl" +"Version"="1.13" +"Copyright"="Copyright © 2003-2019 ALTAP" +"Extensions"="" +"Description"="Powerful batch renamer with real-time preview." +"Configuration Key"="Renamer" +"FS Name"="" +"Functions"=dword:00000030 +"HomePage"="www.altap.cz" +"PluginIconList"=hex:89,50,4e,47,0d,0a,1a,0a,00,00,00,0d,49,48,44,52,00,00,00,\ + 10,00,00,00,10,08,06,00,00,00,1f,f3,ff,61,00,00,00,91,49,44,41,54,78,9c,bd,\ + 93,dd,0d,80,20,0c,84,79,60,23,76,62,14,76,e8,4e,dd,09,29,a4,fc,d8,52,34,26,\ + 9e,39,1f,80,7e,57,04,5d,76,f2,49,29,65,cb,f3,5a,a5,bc,01,76,a2,39,ef,7d,56,\ + 01,4b,8a,01,20,31,44,4d,b6,00,54,38,db,c5,18,f2,c9,43,50,df,88,58,dd,01,1a,\ + 9d,35,e6,41,40,3a,20,60,d9,0e,e0,d8,5b,11,8f,35,00,08,c8,02,a0,85,77,00,8f,\ + fd,d3,c1,e7,6f,70,3e,05,a3,83,fd,3d,40,35,59,74,b0,03,f0,59,5b,de,00,50,dc,\ + 36,cb,02,f0,34,59,fd,99,de,24,73,cd,05,7d,1b,a0,61,47,90,be,66,00,00,00,00,\ + 49,45,4e,44,ae,42,60,82 +"PluginIconIndex"=dword:00000000 +"SubmenuIconIndex"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\19\Menu] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\19\Menu\1] +"State"=dword:01b00002 +"ID"=dword:00000001 +"Name"="&Batch Rename..." +"HotKey"=dword:00000352 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\2] +"Name"="TAR" +"DLL"="tar\\tar.spl" +"Version"="3.34" +"Copyright"="Copyright © 1999-2019 ALTAP" +"Extensions"="tar;tgz;taz;tbz;gz;bz;bz2;z;rpm;cpio;deb" +"Description"="Browse and extract Unix archives." +"Configuration Key"="TAR" +"FS Name"="" +"Functions"=dword:00000069 +"HomePage"="www.altap.cz" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\20] +"Name"="Split & Combine" +"DLL"="splitcbn\\splitcbn.spl" +"Version"="1.11" +"Copyright"="Copyright © 2001-2019 ALTAP" +"Extensions"="" +"Description"="Split and combine files." +"Configuration Key"="SplitCombine" +"FS Name"="" +"Functions"=dword:00000030 +"HomePage"="www.altap.cz" +"PluginIconList"=hex:89,50,4e,47,0d,0a,1a,0a,00,00,00,0d,49,48,44,52,00,00,00,\ + 10,00,00,00,10,08,06,00,00,00,1f,f3,ff,61,00,00,00,91,49,44,41,54,78,9c,a5,\ + 92,d1,0d,c0,20,08,44,fd,70,76,77,60,27,77,a2,11,73,09,20,2a,6d,db,5c,1b,08,\ + 3c,0d,47,e1,c2,a5,b5,c6,59,8d,7a,fd,16,00,ee,0f,09,a0,d6,ca,1f,00,24,5f,d4,\ + 69,48,02,40,e6,06,10,20,17,00,2d,ff,de,bb,28,04,48,52,35,cf,38,86,2c,00,24,\ + d0,e4,63,1c,30,14,df,40,4d,d6,4f,1a,8d,51,6c,3c,f5,a0,c8,77,7f,88,2d,86,55,\ + 41,ac,17,ee,b0,07,d6,6f,1d,cf,1c,2d,50,05,58,a7,7d,b2,72,b3,07,39,c8,06,f0,\ + f3,06,d8,b0,ac,0c,00,be,be,d5,e8,7d,00,f3,22,b7,a4,5a,4a,17,78,00,00,00,00,\ + 49,45,4e,44,ae,42,60,82 +"PluginIconIndex"=dword:00000000 +"SubmenuIconIndex"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\20\Menu] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\20\Menu\1] +"State"=dword:00010012 +"ID"=dword:00000001 +"Name"="&Split File..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\20\Menu\2] +"State"=dword:00900002 +"ID"=dword:00000002 +"Name"="&Combine Files..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\21] +"Name"="UnARJ" +"DLL"="unarj\\unarj.spl" +"Version"="1.21" +"Copyright"="Copyright © 2000-2019 ALTAP" +"Extensions"="arj" +"Description"="Browse and extract ARJ archives." +"Configuration Key"="UnARJ" +"FS Name"="" +"Functions"=dword:00000039 +"HomePage"="www.altap.cz" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\22] +"Name"="UnCAB" +"DLL"="uncab\\uncab.spl" +"Version"="1.27" +"Copyright"="Copyright © 2001-2019 ALTAP" +"Extensions"="cab" +"Description"="Browse and extract CAB archives." +"Configuration Key"="UnCAB" +"FS Name"="" +"Functions"=dword:00000039 +"HomePage"="www.altap.cz" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\23] +"Name"="UnCHM" +"DLL"="unchm\\unchm.spl" +"Version"="1.03" +"Copyright"="Copyright © 2009-2019 ALTAP" +"Extensions"="chm" +"Description"="Browse and extract CHM files." +"Configuration Key"="" +"FS Name"="" +"Functions"=dword:00000009 +"HomePage"="www.altap.cz" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\24] +"Name"="Undelete" +"DLL"="undelete\\undelete.spl" +"Version"="1.11" +"Copyright"="Copyright © 2004-2019 ALTAP" +"Extensions"="" +"Description"="Recovers files deleted from FAT or NTFS partitions." +"Configuration Key"="UNDELETE" +"FS Name"="del" +"Functions"=dword:000000b0 +"FS Cmd Name"=" Undelete" +"FS Cmd Icon"=dword:00000000 +"HomePage"="www.altap.cz" +"PluginIconList"=hex:89,50,4e,47,0d,0a,1a,0a,00,00,00,0d,49,48,44,52,00,00,00,\ + 10,00,00,00,10,08,06,00,00,00,1f,f3,ff,61,00,00,02,34,49,44,41,54,78,9c,ad,\ + cf,cb,6e,12,61,14,07,70,1e,c1,85,71,ab,5b,5d,b9,33,ae,74,e1,03,f8,02,4d,9a,\ + 68,aa,31,31,31,3e,01,0b,13,a3,6d,3a,60,45,70,28,4c,01,b9,59,4a,b9,14,ab,48,\ + 19,5a,60,ca,7d,b8,86,81,d2,61,06,e6,1b,86,3b,e5,ba,1c,67,16,2e,74,5a,16,c6,\ + 93,fc,f3,6d,ce,f9,9d,f3,c9,64,ff,ab,a2,b9,da,8d,78,a1,b2,9d,28,54,3d,cb,22,\ + f6,88,bd,12,20,91,c9,37,a6,f3,45,77,32,5b,b4,27,b3,79,6b,3c,9d,b1,17,93,19,\ + 18,8e,a7,cc,60,34,69,0c,2f,a6,d4,60,34,ae,f7,47,63,32,70,82,e5,21,04,b9,f6,\ + 07,e0,70,1f,d6,1b,6c,9b,ee,f4,47,d5,56,6f,50,66,bb,fd,22,d3,ee,e6,e8,56,27,\ + 43,b1,5c,92,64,b8,d8,19,0d,b0,0a,c5,44,d4,db,46,5e,72,81,cd,e1,c5,ab,24,5d,\ + 17,06,4b,4c,bb,9f,a7,d9,0e,4e,81,4e,4a,18,8c,9f,35,c0,a9,30,1c,21,c8,e6,49,\ + 8e,38,8f,7c,d2,1a,86,12,c0,64,75,ee,c4,33,f9,66,93,eb,64,29,b6,93,7e,82,e0,\ + 40,f6,12,e5,65,4a,96,5f,f1,00,3a,5c,6e,46,8b,35,3a,18,3a,4d,67,b6,34,7a,54,\ + 02,e8,0d,36,c5,31,96,68,92,80,4b,9e,37,5b,b1,f7,07,a5,f2,8a,36,49,3f,b2,03,\ + 4e,44,dc,38,1d,cd,57,a9,9f,fe,63,0c,87,54,5a,97,04,f8,ac,33,be,f2,fe,08,72,\ + e2,b9,f7,2d,a0,7f,cf,0c,7a,c5,1a,15,72,e1,34,a6,0c,d3,29,fd,51,29,96,ad,90,\ + 7e,d7,e1,11,b1,a9,d4,28,24,80,0a,46,56,ed,fb,de,1e,46,30,98,b8,f1,ce,0e,18,\ + 08,1b,03,ae,14,15,59,33,e2,84,ec,b9,9f,0f,66,aa,a8,c3,f3,bd,b6,0e,a9,e4,12,\ + 00,52,c1,77,75,26,fb,44,d8,8a,de,86,eb,43,f1,ff,72,77,21,7b,5d,0d,e6,22,f8,\ + c0,ca,00,f1,02,c4,bc,db,7e,b7,b1,f5,58,0a,40,ea,5b,6a,9d,71,91,ab,90,81,fd,\ + 78,2d,fc,da,92,29,3a,a3,44,f8,a9,8f,26,d6,84,38,d3,64,58,04,60,83,65,f0,76,\ + 1d,7a,28,01,c4,52,a8,60,5e,6c,5a,96,0f,1a,fd,fc,cd,c6,c7,9b,97,02,7a,93,0d,\ + 4d,e4,cb,e8,32,00,46,be,e0,97,0e,8b,15,8a,a6,5e,98,f7,0e,e6,88,c5,c9,23,56,\ + 69,cc,0e,ef,1c,c5,d2,cf,ae,04,76,dd,3e,b9,c3,f3,8d,df,13,f2,fb,fd,3b,5f,3d,\ + be,d5,2b,81,7f,a9,5f,f9,f6,e9,d1,ff,ad,56,be,00,00,00,00,49,45,4e,44,ae,42,\ + 60,82 +"PluginIconIndex"=dword:00000000 +"SubmenuIconIndex"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\24\Menu] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\24\Menu\1] +"State"=dword:00010001 +"ID"=dword:00000001 +"Name"="&Recover Deleted Files and Directories..." +"HotKey"=dword:00000355 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\24\Menu\2] +"State"=dword:01b00202 +"ID"=dword:00000002 +"Name"="Restore &Encrypted Files from Backup..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\25] +"Name"="UnFAT" +"DLL"="unfat\\unfat.spl" +"Version"="1.1" +"Copyright"="Copyright © 2003-2019 ALTAP" +"Extensions"="ima" +"Description"="Browse and extract FAT 12, 16, and 32 disk images." +"Configuration Key"="" +"FS Name"="" +"Functions"=dword:00000009 +"HomePage"="www.altap.cz" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\26] +"Name"="UnISO" +"DLL"="uniso\\uniso.spl" +"Version"="1.37" +"Copyright"="Copyright © 2003-2019 ALTAP" +"Extensions"="iso;isz;nrg;bin;img;pdi;cdi;cif;ncd;c2d;dmg" +"Description"="Browse and extract CD/DVD ISO image files." +"Configuration Key"="UnISO" +"FS Name"="" +"Functions"=dword:00000079 +"HomePage"="www.altap.cz" +"PluginIconList"=hex:89,50,4e,47,0d,0a,1a,0a,00,00,00,0d,49,48,44,52,00,00,00,\ + 10,00,00,00,10,08,06,00,00,00,1f,f3,ff,61,00,00,00,c9,49,44,41,54,78,9c,9d,\ + 93,cb,0d,c4,20,0c,05,d3,53,0a,e2,46,29,94,80,44,1b,54,90,02,b8,73,a2,16,6f,\ + 9c,e8,81,6d,60,b5,da,58,16,22,62,c6,16,9f,83,8e,39,5a,6b,64,73,b5,8e,63,09,\ + 5e,d7,d5,b3,d6,4a,54,12,c5,18,29,84,30,89,14,2c,41,2b,28,a9,3c,69,25,db,ca,\ + 48,09,73,52,d1,12,55,7d,25,81,80,41,a4,12,58,08,73,ef,3d,9d,e7,f9,8c,00,6f,\ + 55,4f,e7,1c,2d,05,16,c6,08,10,6b,b6,02,ae,d4,2b,df,1f,b7,cb,73,5b,44,09,d0,\ + a2,ed,00,30,cf,bf,0a,f0,13,6d,f2,a6,c9,f6,2d,9c,73,1e,02,9c,02,c0,b1,e3,69,\ + da,58,5b,bd,0b,f8,96,69,78,08,ec,11,cb,ea,ea,26,b2,44,c2,52,b0,83,a7,b7,c0,\ + 92,57,94,54,db,00,2d,3c,09,10,58,2c,f3,a7,d7,f8,4f,7c,00,80,0d,bc,54,c3,13,\ + d5,02,00,00,00,00,49,45,4e,44,ae,42,60,82 +"PluginIconIndex"=dword:00000000 +"SubmenuIconIndex"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\27] +"Name"="UnLHA" +"DLL"="unlha\\unlha.spl" +"Version"="1.13" +"Copyright"="Copyright © 2001-2019 ALTAP" +"Extensions"="lzh;lha;lzs" +"Description"="Browse and extract LHA archives." +"Configuration Key"="" +"FS Name"="" +"Functions"=dword:00000009 +"HomePage"="www.altap.cz" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\28] +"Name"="UnMIME" +"DLL"="unmime\\unmime.spl" +"Version"="1.14" +"Copyright"="Copyright © 2001-2019 ALTAP" +"Extensions"="eml;b64;uue;xxe;hqx;ntx;cnm" +"Description"="Browse and extract MIME/Base64, UU/XXEncode, yEncode and BinHex files." +"Configuration Key"="UnMIME" +"FS Name"="" +"Functions"=dword:00000039 +"HomePage"="www.altap.cz" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\29] +"Name"="UnRAR" +"DLL"="unrar\\unrar.spl" +"Version"="3.01" +"Copyright"="Copyright © 2000-2019 ALTAP" +"Extensions"="rar" +"Description"="Browse and extract RAR archives." +"Configuration Key"="UnRAR" +"FS Name"="" +"Functions"=dword:00000039 +"HomePage"="www.altap.cz" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\3] +"Name"="PAK" +"DLL"="pak\\pak.spl" +"Version"="1.71" +"Copyright"="Copyright © 1999-2019 ALTAP" +"Extensions"="pak" +"Description"="Browse and extract Quake PAK archives." +"Configuration Key"="" +"FS Name"="" +"Functions"=dword:0000000f +"HomePage"="www.altap.cz" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\30] +"Name"="Windows Mobile" +"DLL"="wmobile\\wmobile.spl" +"Version"="1.08" +"Copyright"="Copyright © 2003-2019 Juraj Rojko & ALTAP" +"Extensions"="" +"Description"="Access files on your Windows Mobile device." +"Configuration Key"="WMOBILE" +"FS Name"="CE" +"Functions"=dword:000000a0 +"FS Cmd Name"=" Mobile Device" +"FS Cmd Icon"=dword:00000000 +"FS Cmd Visible"=dword:00000000 +"HomePage"="www.altap.cz" +"PluginIconList"=hex:89,50,4e,47,0d,0a,1a,0a,00,00,00,0d,49,48,44,52,00,00,00,\ + 10,00,00,00,10,08,06,00,00,00,1f,f3,ff,61,00,00,02,21,49,44,41,54,78,9c,8d,\ + cc,4f,48,93,61,1c,07,70,6f,d1,a1,43,74,a9,43,97,a0,43,87,a2,ac,fd,53,34,31,\ + 45,0a,42,87,ee,54,d1,48,9b,4b,db,1c,2b,51,b3,cd,51,52,6f,31,5a,5b,6c,ee,75,\ + ad,f6,be,6b,6b,6d,cb,65,64,a6,16,b2,37,37,b7,c7,25,24,c3,8a,4c,28,68,14,66,\ + 5e,84,3a,14,df,1e,47,87,12,dc,eb,ef,c7,97,e7,f0,fc,be,9f,a2,a2,55,d3,d1,a1,\ + 52,87,ef,69,f9,17,11,cd,0c,f1,d4,83,d8,6a,d0,d7,2c,87,35,56,0b,b3,6a,5f,96,\ + 9e,6c,59,dd,f9,6f,32,a1,e3,f8,e9,a9,c2,44,93,04,23,4d,25,98,d4,2b,10,6b,de,\ + 03,f7,79,19,02,67,8a,41,4f,4c,05,91,29,9f,0a,c9,ce,32,a8,35,5d,60,9c,4e,78,\ + 22,1c,1c,03,76,18,7d,6d,60,35,fb,57,00,3f,cd,d6,b5,81,7e,25,26,bb,64,58,fc,\ + bd,88,ef,74,3f,d2,7d,fc,61,10,a6,68,37,58,ad,64,05,b8,5f,10,20,ce,a3,48,75,\ + cb,30,b7,fc,3e,5f,ce,d2,e5,5e,fb,c0,0c,5f,01,db,2a,17,07,d2,b6,c3,48,5d,94,\ + 81,7c,23,f9,72,e2,47,02,d6,b1,eb,b0,c7,6f,82,d5,97,8a,03,a9,6b,d5,48,9b,a4,\ + 18,cb,8d,82,fc,22,e0,67,f8,7c,d9,fb,ea,36,58,43,99,38,c0,1b,ca,41,cc,52,0c,\ + e5,86,30,be,24,a0,2f,e9,82,43,b0,c3,9d,72,81,35,1e,5c,07,d0,5a,02,d2,23,c5,\ + c0,fc,20,82,d9,30,f4,de,b3,d0,79,5a,d0,fb,e4,12,d8,f6,4a,71,c0,50,27,a1,80,\ + 0c,a1,d9,28,dc,09,2f,2c,31,33,9c,89,5b,88,ce,47,c0,76,56,8b,03,5c,e3,01,10,\ + 8b,1c,fc,74,08,dc,74,10,c3,5f,9e,42,58,8e,c3,4f,fc,08,5e,3e,22,0e,4c,e8,f6,\ + 22,6d,51,a0,37,c0,20,14,eb,41,f8,ae,09,82,b5,1e,6f,03,e7,30,6a,6b,58,07,a0,\ + dd,8d,05,47,25,16,fa,eb,f0,29,a0,06,c3,30,78,fe,50,87,39,a1,0d,99,58,a3,38,\ + f0,f2,d4,2e,cc,ba,94,60,af,1e,c3,bb,47,27,f0,35,de,0e,4c,9d,46,ee,d9,49,54,\ + 29,76,bc,a1,27,ee,82,40,4b,f9,4e,f5,03,a3,f4,73,45,a9,04,99,3b,4a,64,38,15,\ + 5c,17,0e,2d,6d,df,b6,39,49,bf,bd,34,0d,34,1b,d7,04,e8,6c,a0,a9,a5,b1,d3,8c,\ + d0,8c,ff,7d,6f,d0,54,d0,6c,fa,f7,f8,0f,38,9c,50,10,86,fc,d9,39,00,00,00,00,\ + 49,45,4e,44,ae,42,60,82 +"PluginIconIndex"=dword:00000000 +"SubmenuIconIndex"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\4] +"Name"="Internet Explorer Viewer" +"DLL"="ieviewer\\ieviewer.spl" +"Version"="1.12" +"Copyright"="Copyright © 1999-2019 ALTAP" +"Extensions"="" +"Description"="Lightweight HTML and XML viewer based on Internet Explorer." +"Configuration Key"="IEVIEWER" +"FS Name"="" +"Functions"=dword:00000060 +"HomePage"="www.altap.cz" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\5] +"Name"="7-Zip" +"DLL"="7zip\\7zip.spl" +"Version"="1.31" +"Copyright"="Copyright © 2004-2019 ALTAP" +"Extensions"="7z" +"Description"="Create, browse, and extract 7-Zip archives." +"Configuration Key"="7zip" +"FS Name"="" +"Functions"=dword:0000003f +"HomePage"="www.altap.cz" +"PluginIconList"=hex:89,50,4e,47,0d,0a,1a,0a,00,00,00,0d,49,48,44,52,00,00,00,\ + 10,00,00,00,10,08,06,00,00,00,1f,f3,ff,61,00,00,00,6d,49,44,41,54,78,9c,bd,\ + 92,41,0e,c0,20,08,04,39,f0,76,de,c5,cf,6c,39,d0,6c,29,62,94,a4,90,3d,28,38,\ + 22,48,83,7a,de,3c,7e,03,98,79,ac,f4,0f,40,44,3e,aa,62,ae,07,90,59,15,33,7b,\ + 01,50,aa,da,03,98,19,04,d7,59,4e,0a,88,b7,63,32,f6,25,05,d8,86,07,22,00,ab,\ + c2,3c,5a,dd,1e,9f,e4,87,b7,01,b3,4a,8f,00,65,13,67,53,d9,1a,63,54,f9,13,bb,\ + 7e,01,91,b6,0e,57,df,9e,05,8e,00,00,00,00,49,45,4e,44,ae,42,60,82 +"PluginIconIndex"=dword:00000000 +"SubmenuIconIndex"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\5\Menu] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\5\Menu\1] +"State"=dword:20000001 +"ID"=dword:00000001 +"Name"="Test Archive" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\6] +"Name"="Automation" +"DLL"="automation\\automation.spl" +"Version"="1.7" +"Copyright"="Copyright © 2009-2019 ALTAP" +"Extensions"="" +"Description"="Automates common tasks using scripts." +"Configuration Key"="Automation" +"FS Name"="" +"Functions"=dword:00000130 +"HomePage"="www.altap.cz" +"PluginIconList"=hex:89,50,4e,47,0d,0a,1a,0a,00,00,00,0d,49,48,44,52,00,00,00,\ + 40,00,00,00,10,08,06,00,00,00,a6,e7,79,29,00,00,06,45,49,44,41,54,78,9c,e5,\ + 96,79,4c,53,77,00,c7,7f,45,30,71,cb,66,b6,6c,ce,8c,c5,b0,e0,34,1a,af,78,e2,\ + 31,85,b9,18,75,d3,2c,a2,13,af,c9,60,5e,a0,a2,72,ca,a1,a8,30,45,41,11,11,e5,\ + 50,0e,91,1b,61,82,47,55,10,10,dc,80,81,88,e5,1c,ca,38,0b,14,e8,4d,69,5f,db,\ + ef,de,ab,69,55,5a,3b,f4,0f,f7,c7,7e,c9,37,ed,6b,9b,d7,f7,f9,bc,df,f7,f7,7b,\ + c4,fe,a2,1d,3c,ee,3b,2f,03,40,fe,8f,21,8c,80,f9,1e,d3,df,5a,c2,d0,71,bd,a8,\ + 1e,86,72,2d,9f,83,54,f6,23,24,e6,94,32,39,a5,fd,fd,7f,2e,60,63,f8,1a,44,96,\ + 06,eb,24,08,7f,23,23,44,b9,64,a1,f8,16,eb,bc,f8,b6,59,ab,98,6d,aa,a4,8f,29,\ + 51,36,69,12,66,b0,8e,0b,92,4c,66,f2,e3,4c,48,7f,e4,08,d2,1b,66,6a,50,80,b1,\ + 11,93,5e,80,b9,2b,7f,d1,49,30,74,51,ef,72,46,12,db,d0,ef,b0,8f,bd,4d,27,21,\ + ff,d6,94,14,f1,4d,02,59,f1,67,90,57,2e,c0,40,d9,2c,48,0b,3e,86,e8,06,81,28,\ + 9d,40,90,44,14,fc,78,13,57,5a,00,cb,90,80,ac,fb,35,46,05,9c,4f,64,e3,4e,09,\ + 47,2b,21,d8,d0,45,bd,cb,5a,92,ef,4f,2e,c5,f6,6b,1b,e1,9c,b3,15,eb,63,57,69,\ + 24,54,e7,59,42,5a,b6,08,68,71,87,f2,e9,3e,0c,94,cf,01,23,45,94,49,27,89,40,\ + 18,47,40,0b,d8,43,0b,18,c1,40,db,7e,6b,61,51,90,e9,83,3b,c9,1e,c8,8d,dd,8f,\ + cc,0b,bb,90,78,da,01,1e,0e,33,e0,e9,38,f3,15,01,e7,12,6e,69,e0,b5,79,9d,80,\ + b7,a9,65,48,8e,0a,27,b3,15,f8,35,73,00,47,52,c4,f0,bb,c2,87,d7,e5,1e,b8,45,\ + 73,b1,ef,42,1b,dc,a3,da,f4,fe,8f,d8,1c,b3,82,7d,f2,5a,0d,fc,d7,c7,a6,63,8a,\ + ab,05,c6,6e,7f,1f,95,d5,59,78,5a,e8,01,55,9b,27,06,4a,27,43,fa,60,3c,28,6e,\ + 06,84,a5,2e,e8,8d,31,03,3f,92,25,ee,3d,67,3a,8e,11,10,b0,7b,96,92,12,66,42,\ + 2d,c9,86,5a,9c,05,aa,3f,09,3e,3f,4f,44,49,a2,2d,9e,5c,df,8a,2d,2b,be,d0,09,\ + a0,94,2a,8d,04,ad,08,43,20,43,6b,39,5c,01,0c,7c,4d,8b,12,9c,56,0a,0f,eb,15,\ + 60,57,c8,91,53,26,47,c6,43,39,2e,dd,95,62,ea,ba,34,7d,01,f3,7c,a7,61,6d,cc,\ + 4a,1d,fc,68,7b,53,34,b7,e5,43,a1,06,38,6c,3f,c8,ca,67,40,72,6f,24,06,1b,dd,\ + 34,00,4d,b5,15,a8,0b,33,87,28,82,a0,fb,ac,e9,11,46,40,5a,b4,93,5a,45,83,ab,\ + 04,a9,50,f0,e2,31,d8,1e,81,70,8f,d9,1a,01,01,2e,56,38,ec,6c,f5,ca,2c,90,ca,\ + 14,1a,01,73,56,38,1a,14,30,b4,96,c3,95,c0,dc,f9,c6,0e,0a,65,8d,94,06,3c,a5,\ + 68,10,17,6f,0e,e0,6c,8e,18,c7,af,34,e1,ab,d5,09,fa,02,a6,b9,5b,be,02,cf,89,\ + 7b,0f,f2,3a,6f,fa,3b,35,24,3d,1c,f0,b3,4c,21,c9,1d,03,b5,e2,19,84,52,a0,f8,\ + ca,0e,b4,9c,36,83,24,d2,04,1d,21,a6,55,8c,80,84,d0,cd,c8,8c,73,87,8c,06,97,\ + 36,05,41,c8,f1,43,57,89,33,22,bc,17,42,26,15,e8,c0,d5,6a,b5,06,be,bb,4f,6a,\ + 54,80,a1,5a,0e,47,02,33,ed,9f,b4,50,b8,53,29,c7,d5,fb,83,08,a7,c1,03,53,44,\ + f0,8e,e5,61,77,48,15,c6,2d,8b,d2,17,30,de,e5,73,1d,fc,e3,8b,f4,d4,4e,a0,fb,\ + 1d,cb,82,a2,e1,04,7d,c5,4a,08,ca,ec,41,d5,bb,43,ae,a2,d0,90,e3,8a,f6,93,04,\ + e2,0b,04,7d,a7,09,9a,4f,b0,ba,18,01,81,7b,66,cf,3c,ed,69,0d,71,43,20,f8,15,\ + fb,c1,2b,de,86,ee,fc,8d,1a,01,b9,f1,6e,3a,01,72,85,12,fd,42,19,5a,b8,42,a3,\ + 02,5e,57,4b,fa,75,82,31,01,4c,e7,ff,a8,a3,90,f9,3b,7d,e7,6f,c9,70,22,9d,81,\ + ef,c3,9e,f0,4e,ac,f3,cc,c7,98,c5,61,fa,02,cc,77,7e,f4,1c,3e,74,94,52,98,32,\ + 11,82,54,0b,f4,9e,1b,01,51,c6,a7,50,cb,5a,75,17,2f,e2,fe,89,67,a1,1f,42,1c,\ + 62,06,41,ac,25,ba,22,2c,51,e7,cf,e2,6a,57,ff,18,7f,eb,cc,5e,ce,71,f4,14,fe,\ + a4,09,97,6d,8b,b6,dc,55,48,08,58,82,4b,a7,ec,a1,54,a9,21,92,ca,d1,c9,93,a0,\ + b1,a5,df,a8,00,43,b5,fc,37,78,26,cc,82,77,b7,4a,8e,f8,bc,41,84,66,4b,70,30,\ + 96,8f,9d,61,9d,d8,10,d0,84,e5,ce,b9,18,3d,f7,94,be,80,4f,1c,47,69,4e,ce,4f,\ + 5b,f0,b7,66,9a,2a,45,18,ac,3d,03,aa,ed,3a,7d,40,e9,04,a8,28,19,64,8d,57,41,\ + d5,46,d0,47,4a,cd,67,15,41,96,e5,69,e1,f6,88,0a,58,8d,73,be,cb,10,17,b4,5e,\ + 97,a8,63,b6,88,09,d8,84,86,f4,65,b8,e4,bf,08,b2,41,0a,3c,fe,00,9a,3b,04,78,\ + f2,17,cf,a8,80,a1,b5,1c,0e,3c,13,66,b5,cf,2a,95,23,fc,86,14,87,ae,f4,61,f7,\ + 79,1a,3e,b0,11,ab,0f,56,62,e9,b6,0c,8c,9a,11,a8,2f,40,7b,72,6e,fc,fc,93,14,\ + bf,1e,72,49,0f,14,b2,17,bd,7d,79,30,d8,62,51,3f,04,02,1e,ba,5a,eb,51,78,74,\ + d2,81,60,b7,05,68,ae,4d,85,b8,eb,36,44,1d,59,ba,f0,9a,ae,e2,ac,b7,0d,1e,27,\ + 7e,83,b3,5e,56,10,88,07,d1,d6,2d,42,7d,73,1f,ca,6b,b8,46,05,bc,5c,cb,e1,c2,\ + 33,61,b6,ba,b8,7b,62,1c,8b,af,c3,9e,90,4a,6c,f0,2d,a4,ef,7c,16,ac,1d,92,31,\ + cf,2e,1a,66,53,8e,e8,0b,d0,be,69,3c,6c,32,bd,f9,fc,54,71,6b,f4,62,70,23,ad,\ + 20,ca,da,0a,65,4f,e5,f3,bb,4f,a7,ab,a1,08,8d,31,9b,50,17,32,17,a5,c1,d6,60,\ + fb,4c,e1,dd,73,22,63,83,5c,17,2f,39,e3,65,43,ef,f9,73,e0,b4,6e,92,2e,3b,d6,\ + 4c,80,db,e6,39,d8,fd,e3,64,dd,c2,d7,d4,c6,c7,e3,86,1e,14,3f,6a,37,2a,40,5b,\ + cb,37,81,67,c2,ec,f3,f3,1d,6e,62,d6,e6,6c,4c,b6,4d,86,c5,f2,4b,9a,de,7f,30,\ + 3b,08,23,a7,1e,35,2e,a0,c1,97,98,55,ed,27,ae,35,9e,04,4f,7d,08,9a,5c,e8,6d,\ + 2e,c9,46,53,03,a9,88,87,87,c7,67,a2,66,27,c1,a3,03,04,45,bb,08,ee,39,12,bb,\ + 3c,27,c2,1a,fa,24,c8,80,69,07,b3,e8,bd,bc,f0,d5,3c,ed,45,e9,93,4e,e4,95,b5,\ + 18,15,a0,ad,e5,9b,c0,bf,6d,5e,08,f0,23,a4,fa,20,31,ab,38,c4,da,5b,ee,c7,1a,\ + 28,71,24,a8,0d,fa,92,16,20,87,a0,b7,1d,97,1d,cc,c1,de,42,50,ec,c9,ea,2d,70,\ + 65,d9,e5,ed,22,84,16,a0,37,b4,02,b4,0f,3b,c6,f2,3a,01,ef,0a,de,90,00,52,e1,\ + c7,22,f7,f7,12,cb,ea,a8,1f,fc,25,ed,55,74,07,d4,5c,95,4a,c5,6d,e0,94,95,46,\ + 7b,2d,3f,70,d5,9e,98,3f,70,a3,e1,8d,08,60,c0,86,9b,77,05,fa,ba,fc,03,da,3d,\ + f7,20,f5,8b,8b,64,00,00,00,00,49,45,4e,44,ae,42,60,82 +"PluginIconIndex"=dword:00000000 +"SubmenuIconIndex"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\6\Menu] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\6\Menu\1] +"State"=dword:ffffffff +"ID"=dword:00000001 +"Name"="Run Focused Script" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\6\Menu\10] +"State"=dword:ffffffff +"ID"=dword:23bb6d00 +"Name"="Unpack Multiple Archives" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\6\Menu\2] +"State"=dword:ffffffff +"ID"=dword:00000002 +"Name"="Open Script Menu" +"HotKey"=dword:00000341 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\6\Menu\3] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\6\Menu\4] +"State"=dword:ffffffff +"ID"=dword:0ccb5b00 +"Name"="Convert Images" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\6\Menu\5] +"State"=dword:ffffffff +"ID"=dword:1797e000 +"Name"="Count Lines" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\6\Menu\6] +"State"=dword:ffffffff +"ID"=dword:79d13200 +"Name"="Launch Elevated Command Prompt" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\6\Menu\7] +"State"=dword:ffffffff +"ID"=dword:4e1cc200 +"Name"="Make Link" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\6\Menu\8] +"State"=dword:ffffffff +"ID"=dword:276fa200 +"Name"="Make List (JScript)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\6\Menu\9] +"State"=dword:ffffffff +"ID"=dword:0fe6ea00 +"Name"="Make List (VBScript)" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\7] +"Name"="Checksum" +"DLL"="checksum\\checksum.spl" +"Version"="2.2" +"Copyright"="Copyright © 2003-2019 ALTAP" +"Extensions"="" +"Description"="SFV, MD5, SHA-1, SHA-256, and SHA-512 checksum verifier and calculator." +"Configuration Key"="Checksum" +"FS Name"="" +"Functions"=dword:00000030 +"HomePage"="www.altap.cz" +"PluginIconList"=hex:89,50,4e,47,0d,0a,1a,0a,00,00,00,0d,49,48,44,52,00,00,00,\ + 10,00,00,00,10,08,06,00,00,00,1f,f3,ff,61,00,00,00,7d,49,44,41,54,78,9c,95,\ + 92,cb,0d,00,21,08,44,39,58,f8,9e,ec,81,6e,e8,0c,83,1b,36,2b,f8,19,35,a3,07,\ + 99,e7,44,24,25,a5,5a,ab,22,b2,da,38,c9,01,a7,21,22,53,08,08,e0,0e,b0,11,21,\ + 00,80,fb,5a,4a,19,04,02,38,ed,96,04,04,8c,66,7a,e8,7b,8b,0d,20,df,e8,e6,17,\ + b0,4d,b0,37,43,09,bc,68,65,3e,26,f8,17,cf,cc,50,82,a8,8b,2e,ac,63,c3,09,62,\ + cb,2e,ff,c1,bc,0b,70,02,3b,40,95,00,f1,9f,23,72,40,03,1a,6b,bf,de,d9,2e,02,\ + 93,00,00,00,00,49,45,4e,44,ae,42,60,82 +"PluginIconIndex"=dword:00000000 +"SubmenuIconIndex"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\7\Menu] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\7\Menu\1] +"State"=dword:00010012 +"ID"=dword:00000002 +"Name"="&Verify Checksums..." +"HotKey"=dword:00000356 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\7\Menu\2] +"State"=dword:01b00002 +"ID"=dword:00000001 +"Name"="&Calculate Checksums..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\8] +"Name"="Check Version" +"DLL"="checkver\\checkver.spl" +"Version"="1.26" +"Copyright"="Copyright © 2000-2019 ALTAP" +"Extensions"="" +"Description"="Check for updates of Altap Salamander and plugins." +"Configuration Key"="CHECKVER" +"FS Name"="" +"Functions"=dword:00000030 +"Load On Start"=dword:00000001 +"HomePage"="www.altap.cz" +"PluginIconList"=hex:89,50,4e,47,0d,0a,1a,0a,00,00,00,0d,49,48,44,52,00,00,00,\ + 10,00,00,00,10,08,06,00,00,00,1f,f3,ff,61,00,00,01,66,49,44,41,54,78,9c,7d,\ + 93,b1,91,02,31,0c,45,15,10,10,90,90,50,00,19,b1,3a,20,a7,0d,b5,40,4a,44,09,\ + 3b,e3,8c,80,b9,02,b6,02,e2,1b,e7,44,74,70,c1,75,a0,d3,ff,8b,cc,c2,c2,8d,e7,\ + 83,2d,a4,27,59,16,e2,f2,bc,76,bb,9d,43,af,f6,4f,eb,e9,70,3c,1e,c3,22,14,f6,\ + b0,5d,2e,17,87,3e,02,fa,be,f7,eb,f5,ea,af,80,ae,eb,68,53,d5,7f,2b,92,ed,76,\ + eb,9b,cd,a6,39,2c,16,0b,5f,2e,97,3c,03,b2,5e,af,bd,d4,4a,d5,1f,9f,80,f8,b1,\ + df,ef,7d,b5,5a,31,f3,6c,36,a3,00,c2,59,4d,dd,aa,ba,16,75,29,d5,ad,3c,43,da,\ + 06,57,01,28,03,51,55,a9,c5,23,6f,7c,9b,6b,08,00,b1,1a,b0,e2,13,40,ae,ac,04,\ + d7,48,80,45,00,2a,21,e0,70,08,88,d2,36,01,e0,8e,a2,d6,1a,a9,2a,e1,a8,84,45,\ + 37,07,01,74,c0,d5,6c,0a,f8,fa,fe,65,89,f3,f9,bc,41,d0,0f,d8,24,12,b2,3a,93,\ + 01,12,80,d3,e9,fc,08,c6,5b,c3,01,d9,d0,87,84,b0,27,a8,96,d2,3b,40,08,d0,e8,\ + 68,03,a0,81,2c,df,ea,43,28,59,e4,5e,7a,da,8d,15,20,d8,c6,00,0c,4b,73,54,38,\ + 3a,f7,d9,d4,01,ee,fc,0d,f7,57,2d,9c,d6,06,b8,dd,6e,1c,59,bc,33,01,a9,c8,c6,\ + 3e,44,74,da,14,4f,a9,6f,9a,d8,de,d6,46,00,bd,03,22,e3,10,ec,cc,9e,a3,fe,16,\ + 10,53,3b,34,48,94,d2,0c,64,e6,47,f0,47,40,2e,cc,bf,95,4a,18,94,ff,d0,f1,fa,\ + 03,87,ce,fe,95,3a,db,83,4d,00,00,00,00,49,45,4e,44,ae,42,60,82 +"PluginIconIndex"=dword:00000000 +"SubmenuIconIndex"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\8\Menu] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\8\Menu\1] +"State"=dword:00010001 +"ID"=dword:0000005a +"Name"="&Check For New Versions..." + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins\9] +"Name"="Database Viewer" +"DLL"="dbviewer\\dbviewer.spl" +"Version"="1.23" +"Copyright"="Copyright © 2003-2019 ALTAP" +"Extensions"="" +"Description"="Display dBase, FoxPro and CSV database files." +"Configuration Key"="DBVIEWER" +"FS Name"="" +"Functions"=dword:00000070 +"HomePage"="www.altap.cz" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\7zip] +"Version"=dword:00000003 +"Show Extended Options"=dword:00000001 +"Extended List Info"=dword:00000000 +"List Info Packed Size"=dword:00000000 +"List Info Method"=dword:00000000 +"Column PackedSize FixedWidth"=dword:00000000 +"Column PackedSize Width"=dword:00000000 +"Column Method FixedWidth"=dword:00000000 +"Column Method Width"=dword:00000000 +"Compression Level"=dword:00000005 +"Compression Method"=dword:00000000 +"Dictionary Size"=dword:00004000 +"Word Size"=dword:00000020 +"Solid Archive"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\Automation] +"Version"=dword:00000001 +"EnableDebugger"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\Automation\Directories] +"1"="$[AppData]\\Altap\\Altap Salamander\\Automation\\scripts" +"2"="$[AllUsersProfile]\\Altap\\Altap Salamander\\Automation\\scripts" +"3"="$(SalDir)\\plugins\\automation\\scripts" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\Automation\Scripts] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\Automation\Scripts\0CCB5B] +"00"="$(SalDir)\\plugins\\automation\\scripts\\Convert Images.js" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\Automation\Scripts\0FE6EA] +"00"="$(SalDir)\\plugins\\automation\\scripts\\Make List (VBScript).vbs" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\Automation\Scripts\1797E0] +"00"="$(SalDir)\\plugins\\automation\\scripts\\Count Lines.js" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\Automation\Scripts\23BB6D] +"00"="$(SalDir)\\plugins\\automation\\scripts\\Unpack Multiple Archives.js" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\Automation\Scripts\276FA2] +"00"="$(SalDir)\\plugins\\automation\\scripts\\Make List (JScript).js" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\Automation\Scripts\4E1CC2] +"00"="$(SalDir)\\plugins\\automation\\scripts\\Make Link.js" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\Automation\Scripts\79D132] +"00"="$(SalDir)\\plugins\\automation\\scripts\\Launch Elevated Command Prompt.vbs" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\Checksum] +"Version"=dword:00000001 +"Hash Type"=dword:00000001 +"Dialog Size 1"=hex:96,02,00,00,2d,01,00,00,e6,00,00,00,50,00,00,00,50,00,00,\ + 00,e5,00,00,00,17,01,00,00,ae,01,00,00,5c,03,00,00 +"Dialog Size 2"=hex:b1,01,00,00,2d,01,00,00,e6,00,00,00,50,00,00,00,50,00,00,\ + 00 +"CRC"=dword:00000001 +"MD5"=dword:00000001 +"SHA1"=dword:00000001 +"SHA256"=dword:00000001 +"SHA512"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\CHECKVER] +"Version"=dword:00000004 +"AutoCheckMode"=dword:00000002 +"AutoConnect"=dword:00000001 +"AutoClose"=dword:00000001 +"CheckBetaVersions"=dword:00000001 +"CheckPBVersions"=dword:00000000 +"CfgOfPB"=dword:00000000 +"CheckReleaseVersions"=dword:00000001 +"IneternetConnection"=dword:00000001 +"InternetProtocol"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\CHECKVER\Filters] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\DBVIEWER] +"Version"=dword:00000000 +"Use Custom Font"=dword:00000000 +"LogFont"=hex:f4,ff,ff,ff,00,00,00,00,00,00,00,00,00,00,00,00,90,01,00,00,00,\ + 00,00,01,00,00,05,00,53,65,67,6f,65,20,55,49,00,00,00,00,00,00,00,00,00,00,\ + 00,00,00,00,00,00,00,00,00,00,00,00,00,00 +"SavePosition"=dword:00000000 +"WindowPlacement"=hex:00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\ + 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 +"Auto Select"=dword:00000001 +"Default Coding"="" +"CSV Text Qualifier"=dword:00000000 +"CSV Value Separator"=dword:00000000 +"CSV Value Separator Char"=dword:00000000 +"CSV First Row As Name"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\DBVIEWER\Find History] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\DISKMAP] +"Confirm ESC Close"=dword:00000001 +"Highlight Folders"=dword:00000001 +"Display Tooltip"=dword:00000001 +"Tooltip Path Format"=dword:00000002 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\Encrypt & Decrypt] +"Version"=dword:00000003 +"SF Method"=dword:00000001 +"CFS Method"=dword:00000002 +"TFS Method"=dword:00000001 +"SF Random Passes"=dword:00000001 +"CFS Random Passes"=dword:00000001 +"TFS Random Passes"=dword:00000001 +"Hash"=hex:02 +"Cipher"=hex:03 +"Compression"=hex:09 +"Mode"=hex:01 +"Hide Typing"=dword:00000001 +"Clear Cluster Tips"=dword:00000001 +"Clear FAT Directories"=dword:00000001 +"Shred Temporary Files"=dword:00000001 +"Temp Dir"="C:\\Users\\zx\\AppData\\Local\\Temp\\SalEncTemp" +"Last Key"="" +"Use Key Password"=dword:00000001 +"Use Key File"=dword:00000000 +"Dont Show Small Files Warning"=dword:00000000 +"Dont Ask Open On SSD"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\File Comparator] +"Version"=dword:00000008 +"Configuration"=hex:01,00,00,00,02,00,00,00,08,00,00,00,f3,ff,ff,ff,00,00,00,\ + 00,00,00,00,00,00,00,00,00,90,01,00,00,00,00,00,00,00,00,00,01,43,6f,6e,73,\ + 6f,6c,61,73,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\ + 00,00,00,01,00,00,00,b7,00,00,00,00,00,00,00,00,00,00,00,01,00,00,00 +"Colors"=hex:00,00,00,01,00,00,00,01,00,00,00,01,00,00,00,01,00,00,00,01,e3,e3,\ + e3,01,e3,e3,e3,01,e3,e3,e3,01,f0,f0,f0,01,f0,f0,f0,01,a0,a0,a0,01,a0,a0,a0,\ + 01,00,00,00,01,00,00,00,01,00,00,00,01,00,00,00,01,00,00,00,01,ff,ff,ff,00,\ + ff,ff,ff,00,ff,ff,ff,01,eb,eb,eb,01,eb,eb,eb,01,bf,df,ff,01,ff,cc,cc,01,0a,\ + 80,f0,00,ff,78,78,00,a0,a0,a0,01,a0,a0,a0,01,ff,ff,ff,01,00,00,00,01 +"Custom Colors"=hex:00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\ + 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\ + 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 +"Force Text"=dword:00000000 +"Force Binary"=dword:00000000 +"Ignore Space Change"=dword:00000000 +"Ignore All Space"=dword:00000000 +"Ignore Line Breaks Changes"=dword:00000000 +"Ignore Case"=dword:00000000 +"EOL Conversion 0"=dword:00000007 +"EOL Conversion 1"=dword:00000007 +"Encoding 0"=dword:00000000 +"Encoding 1"=dword:00000000 +"Endians 0"=dword:00000000 +"Endians 1"=dword:00000000 +"InputEnc 0"=dword:00000000 +"InputEnc 1"=dword:00000000 +"InputEnc Table 0"="" +"InputEnc Table 1"="" +"Normalization Form"=dword:00000001 +"Rebar Bands Layout"=hex:ff,ff,ff,ff,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\ + 00,00,00,00,00,00 +"Last Configuration Page"=dword:00000000 +"Load On Start"=dword:00000000 +"Horizontal View"=dword:00000000 +"Auto-Copy Selection"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\FTP] +"Version"=dword:00000025 +"Last Config Page"=dword:00000000 +"Show Welcome Message"=dword:00000001 +"Priority to Panel Connections"=dword:00000001 +"Enable Total Speed Limit"=dword:00000000 +"Total Speed Limit"="2" +"Anonymous Password"="name@someserver.com" +"Passive Mode"=dword:00000000 +"Keep Alive"=dword:00000001 +"Compress Data"=dword:00000000 +"Max. Connections"=dword:ffffffff +"Speed Limit"="-1" +"Use Listings Cache"=dword:00000001 +"Transfer Mode"=dword:00000002 +"ASCII File Masks"="*.txt;*.*htm;*.*html;*.pl;*.php;*.php3;*.asp;*.cgi;*.css;*.bat;*.tcl;*.diz;*.nfo;*.ini;*.mak;*.cpp;*.c;*.h;*.bas;*.pas;*.tex;*.log" +"Server Replies Timeout"=dword:0000001e +"No Data Transfer Timeout"=dword:0000012c +"Delay Connect Retries"=dword:00000014 +"Connect Attempts"=dword:0000003c +"Resume Overlap"=dword:00000400 +"Resume Min File Size"=dword:00008000 +"Keep Alive - Every"=dword:0000005a +"Keep Alive - Stop After"=dword:0000001e +"Keep Alive - Command"=dword:00000000 +"Mem Cache Max Size"=dword:00400000 +"Download Add To Queue"=dword:00000000 +"Delete Add To Queue"=dword:00000000 +"ChngAttr Add To Queue"=dword:00000000 +"If Cannot Create File"=dword:00000000 +"If Cannot Create Dir"=dword:00000000 +"If File Already Exists"=dword:00000000 +"If Dir Already Exists"=dword:00000002 +"If Retry On Created"=dword:00000003 +"If Retry On Resumed"=dword:00000002 +"If Ascii Mode For Binary File"=dword:00000000 +"If Unknown Attrs"=dword:00000000 +"If Directory Is Not Empty"=dword:00000001 +"If File Is Hidden"=dword:00000000 +"If Dir Is Hidden"=dword:00000001 +"Upload - If Cannot Create File"=dword:00000000 +"Upload - If Cannot Create Dir"=dword:00000000 +"Upload - If File Already Exists"=dword:00000000 +"Upload - If Dir Already Exists"=dword:00000002 +"Upload - If Retry On Created"=dword:00000003 +"Upload - If Retry On Resumed"=dword:00000002 +"Upload - If Ascii Mode For Binary File"=dword:00000000 +"Last Bookmark"=dword:00000002 +"Default Proxy UID"=dword:ffffffff +"Always Detach"=dword:00000000 +"Always Disconnect"=dword:00000000 +"Enable Logging"=dword:00000001 +"Log Max. Size"=dword:00000032 +"Max. Closed Connections Logs"=dword:0000000a +"Always Show Panel Log"=dword:00000001 +"Disable Log for Operations"=dword:00000000 +"Logs Position"="" +"OperDlg Position"="" +"OperDlg Split Pos."=dword:0000c350 +"Send Secret Command"=dword:00000000 +"Always Reconnect"=dword:00000000 +"Connection Lost Message"=dword:00000001 +"List Hidden Files Hint"=dword:00000001 +"Always Overwrite"=dword:00000000 +"Convert Hex-esc-sequences"=dword:00000001 +"Close OperDlg If Successfully Finished"=dword:00000001 +"Open SolveErrDlg If Idle"=dword:00000001 +"Simple Listing Fixed Column Width"=dword:00000000 +"Simple Listing Column Width"=dword:00000000 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\FTP\Bookmarks] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\FTP\Bookmarks\1] +"Name"="ALTAP" +"Address"="ftp.altap.cz" +"Initial Path"="/pub/altap/salamand" +"Anonymous"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\FTP\Bookmarks\2] +"Name"="polymech" +"Address"="polymech.io" +"Anonymous"=dword:00000000 +"User"="polymech.io_6z8t5kbi9np" +"PasswordS"=hex:01,28,4a,c0,82,99,2f,b5,b1,d5,01,95,c0,f7,b9,97,e4,8f,71,97,31,\ + 03,06,a1,9f,20,93,51,fd,6e,61,e8,02,3d,f4 +"Save Password"=dword:00000001 + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\FTP\Command History] +"1"="HELP" +"2"="CDUP" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\FTP\Host Address History] +"1"="polymech.io" +"2"="polymech" + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\FTP\Init Path History] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\FTP\Proxy Servers] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\FTP\Server Types] + +[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\Plugins Configuration\FTP\Server Types\1] +"Name"="UNIX1" +"Autodetect Condition"="not syst_contains(\"z/VM \") and not syst_contains(\"OS/2 \") and not syst_contains(\" MACOS \") and not syst_contains(\"Windows_NT\")" +"Rules For Parsing"="# parse lines with files and directories|* if(next_char\\!=\"l\"), assign(, next_char==\"d\"), word(),| white_spaces(), word(), white_spaces(), word(), white_spaces(),| word(), white_spaces(), positive_number(), white_spaces(),| month_3(), white_spaces(), day(), white_spaces(),| year(), white_spaces(2),| assign(, next_char==\".\"), rest_of_line();||# parse lines with files and directories|* if(next_char\\!=\"l\"), assign(, next_char==\"d\"), word(),| white_spaces(), word(), white_spaces(), word(), white_spaces(),| word(), white_spaces(), positive_number(), white_spaces(),| month_3(), white_spaces(), day(), white_spaces(),| year_or_time(,