{
     Apophysis "7X" Copyright (C) 2009-2013 Georg Kiehne
     Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
}

unit Translation;

interface

uses Global, Classes, Forms, LibXmlParser, LibXmlComps, SysUtils, RegexHelper;

procedure ListLanguages;
procedure LanguageInfo(path: string; var name, localName: string);
function LanguageAuthor(path: string): string;
procedure Add(key, value: string);
procedure LoadLanguage(path: string);
procedure LoadEnglish();
function TextByKey(key: string):string;

type
  TParser = class
    public
      constructor Create;
      destructor Destroy; override; // AV: added to clean up the memory

      procedure ListXmlScannerStartTag(Sender: TObject; TagName: string; Attributes: TAttrList);
      procedure ListXmlScannerEndTag(Sender: TObject; TagName: string);
      procedure ListXmlScannerEmptyTag(Sender: TObject; TagName: string; Attributes: TAttrList);
      procedure ListXmlScannerContent(Sender: TObject; Content: string);
    private
      currentTagname: string;
      parentTagnames: TStringList;
  end;
  
  TKeyValuePair = class
    public
      key: string;
      value: string;
  end;

  TDictionary = array of TKeyValuePair;
var
  language: TDictionary;
  defaultlanguage: TDictionary;
  tokenCount: integer;
  ListXmlScanner: TEasyXmlScanner;
  parser: TParser;

implementation

procedure ListLanguages;
var
  searchResult: TSearchRec;
  langpath: string;
begin
  if FindFirst(ExtractFilePath(Application.ExeName) + 'Languages\*.xml', faAnyFile, searchResult) = 0 then
  begin
    repeat
      AvailableLanguages.Add(ExtractFilePath(Application.ExeName) + 'Languages\' + searchResult.Name);
    until (FindNext(searchResult) <> 0);
    SysUtils.FindClose(searchResult);
  end;
end;

procedure LanguageInfo(path: string; var name, localName: string);
const
  exp1 = '\stitle="([^"]*)"';
  exp2 = '\slocalized-title="([^"]*)"';
var
  langxml : string;
  sl: TStringList;
begin
  sl := TStringList.Create;
  sl.LoadFromFile(path);
  langxml := sl.Text;
  sl.Destroy;

  name := GetStringPart(langxml, exp1, 1, '');
  localname := GetStringPart(langxml, exp2, 1, '');
end;

function LanguageAuthor(path: string): string;
const
  exp = '\sauthor="([^"]*)"';
var
  langxml : string;
  sl: TStringList;
begin
  sl := TStringList.Create;
  sl.LoadFromFile(path);
  langxml := sl.Text;
  sl.Destroy;

  Result := GetStringPart(langxml, exp, 1, '');
end;

procedure LoadEnglish();
begin
  //TODO:
    //render-status-renderhibernated

  Add('common-ok', 'OK');
	Add('common-cancel', 'Cancel');
	Add('common-apply', 'Apply');
  Add('common-yes', 'Yes');
	Add('common-no', 'No');
	Add('common-lowquality', 'Low Quality');
	Add('common-mediumquality', 'Medium Quality');
	Add('common-highquality', 'High Quality');
	Add('common-copy', 'Copy');
	Add('common-paste', 'Paste');
  Add('common-cut', 'Cut');
	Add('common-delete', 'Delete');
	Add('common-rename', 'Rename');
	Add('common-undo', 'Undo');
	Add('common-redo', 'Redo');
	Add('common-width', 'Width');
	Add('common-height', 'Height');
	Add('common-size', 'Size');
	Add('common-pixels', 'Pixels');
	Add('common-keepaspect', 'Maintain aspect ratio');
	Add('common-destination', 'Destination');
	Add('common-filename', 'File name');
  Add('common-comment', 'Comment');
	Add('common-browse', 'Browse...');
	Add('common-quality', 'Quality');
	Add('common-filterradius', 'Filter Radius');
	Add('common-density', 'Density');
	Add('common-oversample', 'Oversample');
	Add('common-gamma', 'Gamma');
	Add('common-brightness', 'Brightness');
	Add('common-contrast', 'Contrast');
	Add('common-vibrancy', 'Vibrancy');
	Add('common-background', 'Background');
	Add('common-gammathreshold', 'Gamma Threshold');
	Add('common-start', 'Start');
	Add('common-pause', 'Pause');
  Add('common-resume', 'Resume');
	Add('common-close', 'Close');
	Add('common-clear', 'Clear');
	Add('common-enabled', 'Enabled');
	Add('common-disabled', 'Disabled');
	Add('common-minimum', 'Minimum');
	Add('common-maximum', 'Maximum');
  Add('common-resetlocation', 'Reset location');
  Add('common-openwav', 'Open the audiofile...');
  Add('common-genericopenfailure', 'Unable to open "%s".');
	Add('common-genericsavefailure', 'Unable to save "%s".');
	Add('common-genericcopyfailure', 'Cannot copy file.');	
  Add('common-openpngerror1', 'Error loading flame parameters from the "%s" image.');
	Add('common-openpngerror2', 'Could not find flame parameters in the "%s" image.');
  Add('common-openpngerror3', 'Error reading flame parameters from the "%s" image.');
	Add('common-loaderror', 'Cannot load plugin from %s: variation "%s" already exists!');
  Add('common-loaderror1', 'There were problems with some of the plugins:');
  Add('common-noparamfile', 'The file does not exists.');
  Add('common-invalidformat', 'Invalid format.');
	Add('common-confirmexit', 'Do you really want to exit? All unsaved data will be lost!');
  Add('common-confirmdelete', 'Are you sure you want to permanently delete "%s"? ');
  Add('common-confirmselect', 'After new selection, all changes made to the current flame will be lost. Do you want to save its editing history?');
  Add('common-deletecurrent', 'All changes made to the current flame will be lost!');
	Add('common-dragpanelhint', 'Click and drag to change value');
  Add('common-trace-title', 'Trace log');
  Add('common-trace-main', 'Main');
  Add('common-trace-fullscreen', 'Fullscreen');
  Add('common-trace-notrace', 'No trace');
  Add('common-trace-minimal', 'Minimal trace');
  Add('common-trace-fulltrace', 'Full trace');
  Add('common-trace-pausing', 'Pausing render');
	Add('common-trace-resuming', 'Resuming render');
	Add('common-trace-terminating', 'Terminating render');
	Add('common-trace-stopping', 'Stopping render');
	Add('common-trace-saving', 'Saving image...');
	Add('common-trace-creating-simple', 'Creating image...');
	Add('common-trace-creating-detailed', 'Creating image with quality: %f...');
	Add('common-trace-rendering-oneslice', 'Rendering...');
	Add('common-trace-rendering-multipleslices', 'Rendering slice %d of %d...');
	Add('common-trace-allocating', 'Allocating %n Mb of memory...');
	Add('common-trace-notenoughmemory', 'ERROR: Not enough memory for this render!');
	Add('common-statistics-title-oneslice', 'Render Statistics:');
	Add('common-statistics-title-multipleslices', 'Render Statistics for the last slice:');
	Add('common-statistics-maxpossiblebits', 'Max possible bits: %2.3f');
	Add('common-statistics-maxred', 'Max Red:   %2.3f bits');
	Add('common-statistics-maxgreen', 'Max Green: %2.3f bits');
	Add('common-statistics-maxblue', 'Max Blue:  %2.3f bits');
	Add('common-statistics-maxcounter', 'Max Count: %2.3f bits');
	Add('common-statistics-pointhitratio', 'Point hit ratio: %2.2f%%');
	Add('common-statistics-averagespeed', 'Average speed: %n iterations per second');
	Add('common-statistics-purerenderingtime', 'Pure rendering time:');
  Add('common-seconds', 'second(s)');
  Add('common-minutes', 'minute(s)');
  Add('common-hours', 'hour(s)');
  Add('common-days', 'day(s)');
  Add('common-suspendtodisk', 'Suspend to disk');
  Add('common-resumefromdisk', 'Resume from disk');
  Add('common-filter-flamefiles', 'Apophysis Flame Library (*.flame;*.xml)');
	Add('common-filter-gradientfiles', 'Gradient files (*.gradient;*.ugr)');
  Add('common-filter-fractintfiles', 'Fractint maps (*.map)');
	Add('common-filter-uprfiles', 'UltraFractal parameters (*.upr)');
  Add('common-filter-templatefiles', 'Apophysis Template Library (*.template;*.flame)');
  Add('common-filter-undofiles', 'Apophysis Undo Parameters (*.undo;*.apo)');
	Add('common-filter-scriptfiles', 'Apophysis Script (*.aposcript;*.asc)');
  Add('common-filter-allimages', 'All images (*.bmp;*.dib;*.jpg;*.jpeg;*.png)');
	Add('common-filter-bitmap', 'Windows Bitmap (*.bmp;*.dib)');
	Add('common-filter-jpeg', 'JPEG (*.jpg;*.jpeg)');
	Add('common-filter-png', 'Portable Network Graphics (*.png)');
	Add('common-filter-allfiles', 'All files (*.*)');
	Add('common-open-apoimage', 'Import Apophysis parameters from the image...');
	Add('common-selectimage', 'Select an image file...');
  Add('common-favscriptadded', 'The script "%s" was added to your favourites list.');
  Add('common-favscriptexists', 'The script "%s" already exists in your favourites list.');
  Add('common-screenshot-saved', 'The screenshot "%s" was successfully saved in "%s" directory.');
  Add('common-screenshot-error', 'Cannot save the screenshot.');
  Add('common-translation', 'translation contributed by:');
  Add('common-pluginlink', 'Apophysis Plugins (download)');
  Add('common-thirdparty', 'This application was created using:');
  Add('common-donate', 'Donate');
  Add('common-donatehint', 'If you really like Apophysis, please, donate a dime for its future development');
  Add('splash-loadingui', 'Loading user interface...');
	Add('splash-loadingsettings', 'Loading settings...');
	Add('splash-loadingplugins', 'Loading plugins...');
	Add('splash-initrenderer', 'Initializing renderer...');
	Add('splash-initcolormap', 'Initializing gradients...');
	Add('splash-initbatch', 'Creating fractal batch...');
	Add('splash-execstartupscript', 'Executing "autoexec.asc"...');
  Add('transitions-title', 'Transform Transitions');
  Add('transitions-matrix', 'Probability matrix');
  Add('transitions-transform', 'Transform:');
  Add('transitions-inpercents', ' Show probabilities in percents');
	Add('adjustment-title', 'Adjustment');
	Add('adjustment-common-depthblur', 'Depth Blur');
	Add('adjustment-common-pitch', 'Pitch');
	Add('adjustment-common-yaw', 'Yaw');
  Add('adjustment-common-roll', 'Roll');
	Add('adjustment-common-height', 'Height');
	Add('adjustment-common-perspective', 'Perspective');
	Add('adjustment-common-scale', 'Scale');
	Add('adjustment-hint-depthblur', 'Strength of blurring from edges');
	Add('adjustment-hint-pitch', 'Angle (in degrees) of rotation around X-axis');
	Add('adjustment-hint-yaw', 'Angle (in degrees) of rotation around Z-axis');
  Add('adjustment-hint-roll', 'Angle (in degrees) of rotation around Y-axis');
	Add('adjustment-hint-height', 'Height of the 3D-camera');
	Add('adjustment-hint-perspective', 'Strength of a perspective distortion');
	Add('adjustment-hint-scale', 'Scale factor for the flame');
  Add('adjustment-hint-resetzoom', 'Reset camera zooming without changing flame size and position'); // AV
	Add('adjustment-tab-camera-title', 'Camera');
	Add('adjustment-tab-camera-zoom', 'Zoom');
	Add('adjustment-tab-camera-xpos', 'X-Position');
	Add('adjustment-tab-camera-ypos', 'Y-Position');
	Add('adjustment-tab-camera-rotation', 'Rotation');
  Add('adjustment-tab-camera-resetzoom', 'Reset zoom'); // AV
  Add('adjustment-tab-camera-draw3daxes', 'Display coordinate axes in 3D-space'); // AV
	Add('adjustment-tab-rendering-title', 'Rendering');
	Add('adjustment-tab-rendering-istransparent', 'Transparent');
	Add('adjustment-tab-gradient-title', 'Gradient');
	Add('adjustment-tab-gradient-palettehint', 'Right-click for context menu, Double click to randomize, Drag to rotate gradient, Alt + Drag to choose the fragment, Ctrl + Drag to stretch the palette');
	Add('adjustment-tab-gradient-moderotate', 'Rotate');
	Add('adjustment-tab-gradient-modehue', 'Hue');
	Add('adjustment-tab-gradient-modesaturation', 'Saturation');
  Add('adjustment-tab-gradient-modeluminance', 'Luminance');  // AV
	Add('adjustment-tab-gradient-modebrightness', 'Brightness');
	Add('adjustment-tab-gradient-modecontrast', 'Contrast');
	Add('adjustment-tab-gradient-modeblur', 'Blur');
	Add('adjustment-tab-gradient-modefrequency', 'Frequency');
	Add('adjustment-tab-gradient-preset', 'Preset');
  Add('adjustment-tab-gradient-reset', 'Reset');
  Add('adjustment-tab-gradient-current', 'Current');
  Add('adjustment-tab-gradient-start', 'Start');
  Add('adjustment-tab-gradient-last', 'Last');
	Add('adjustment-tab-gradient-modehint', 'Click for menu');
 	Add('adjustment-tab-gradient-copyhint', 'Copy gradient to clipboard');
  Add('adjustment-tab-gradient-selectedhint', 'Change the selected color area');
	Add('adjustment-tab-gradient-pastehint', 'Paste gradient from clipboard');
	Add('adjustment-tab-gradient-presethint', 'Click to choose random preset');
	Add('adjustment-tab-size-title', 'Image size');
	Add('adjustment-tab-size-preset', 'Change the image size according to the preset');
  Add('adjustment-tab-size-savepreset', 'Save current size as a preset');
  Add('adjustment-tab-size-presets', 'Size presets');
	Add('adjustment-tab-size-resizemain', 'Resize main window');
  Add('adjustment-tab-size-custom', 'Custom');
  Add('adjustment-tab-size-ratio', 'Aspect ratio'); //AV
  Add('adjustment-tab-size-output', 'Settings');
  Add('adjustment-tab-curves-title', 'Curves');
  Add('adjustment-tab-curves-reset', 'Reset');
  Add('adjustment-tab-curves-selected', 'Selected curve:');
  Add('adjustment-tab-curves-overall', 'Overall');
  Add('adjustment-tab-curves-red', 'Red');
  Add('adjustment-tab-curves-green', 'Green');
  Add('adjustment-tab-curves-blue', 'Blue');
	Add('adjustment-popup-quality-instantpreview', 'Instant preview');
	Add('adjustment-popup-gradient-randomize', 'Randomize');
  Add('adjustment-popup-gradient-adjustbyslider', 'Adjust colors using slider');
	Add('adjustment-popup-gradient-invert', 'Invert');
	Add('adjustment-popup-gradient-reverse', 'Reverse');
	Add('adjustment-popup-gradient-invertsel', 'Invert selected colors');
	Add('adjustment-popup-gradient-reversesel', 'Reverse fragment');
  Add('adjustment-popup-gradient-interprgb', 'Interpolate RGB values  between end points');
  Add('adjustment-popup-gradient-interphsv', 'Interpolate HSV values  between end points');
  Add('adjustment-popup-gradient-randomizesel', 'Randomize the selected color area');
  Add('adjustment-popup-gradient-setcolor', 'Set the color for the selected area...');
  Add('adjustment-popup-gradient-swaprgb', 'Swap RGB values...');
  Add('adjustment-popup-gradient-copysel', 'Copy color fragment');
  Add('adjustment-popup-gradient-pastesel', 'Paste color fragment');
  Add('adjustment-popup-gradient-mixcolors', 'Mix colors of copied and selected fragments ');
  Add('adjustment-popup-gradient-grayscale', 'Greyscale');
  Add('adjustment-popup-gradient-sepia', 'Sepia');
  Add('adjustment-popup-gradient-removedark', 'Brighten dark areas');
  Add('adjustment-popup-gradient-symmetry', 'Add symmetry...');
  Add('adjustment-popup-gradient-flipleft', 'Flip the left half to the right');
  Add('adjustment-popup-gradient-flipright', 'Flip the right half to the left');
	Add('adjustment-popup-gradient-smoothize', 'Smoothize');
  Add('adjustment-popup-gradient-smoothizesel', 'Smoothize the selected color area');
	Add('adjustment-popup-gradient-smooth', 'Smooth Palette...');
	Add('adjustment-popup-gradient-browser', 'Gradient Browser...');
	Add('adjustment-popup-gradient-saveasugr', 'Save Gradient...');
	Add('adjustment-popup-gradient-saveasmap', 'Save as Map file...');
	Add('adjustment-popup-gradient-saveasdefault', 'Save as default');
  Add('adjustment-popup-gradient-saveasscript', 'Save as script file...');
  Add('adjustment-popup-gradient-adjustfragment', 'Adjust color fragment...');
  Add('editor-title', 'Transform Editor');
	Add('editor-common-transform', 'Transform:');
	Add('editor-common-name', 'Name:');
	Add('editor-common-weight', 'Weight:');
  Add('editor-common-finalxformlistitem', 'Final');
	Add('editor-common-fromprefix', 'from %d');
	Add('editor-common-toprefix', 'to %d');
  Add('editor-common-editcomment', 'Edit flame comment...');
	Add('editor-tab-variations-title', 'Variations');
	Add('editor-tab-variations-name', 'Name');
	Add('editor-tab-variations-value', 'Value');
  Add('editor-tab-variations-search', 'Search:');  // AV
  Add('editor-tab-variations-searchhint', 'Type a variation name...');  // AV
  Add('editor-tab-variations-order', 'Edit the Order...');  // AV
  Add('editor-tab-variations-orderhint', 'Adjust the order of variations for the chosen transform');  // AV
	Add('editor-tab-variations-togglehideunused', '  Hide unused variations');
  Add('editor-tab-variations-toggleshowall', '  Show all variations'); // AV
  Add('editor-tab-variations-togglefavourites', '  Favourite variations'); // AV
  Add('editor-tab-variations-toggle3d', '  3D-aware variations'); // AV
  Add('editor-tab-variations-toggledc', '  Direct coloring variations'); // AV
	Add('editor-tab-variables-title', 'Variables');
	Add('editor-tab-variables-name', 'Name');
	Add('editor-tab-variables-value', 'Value');
	Add('editor-tab-variables-toggleshowall', 'Show all variables');
	Add('editor-tab-variables-reset', 'Reset');
	Add('editor-tab-chaos-title', 'Xaos');
	Add('editor-tab-chaos-path', 'Path');
	Add('editor-tab-chaos-modifier', 'Weight modifier');
	Add('editor-tab-chaos-viewasto', 'View links as "to"');
	Add('editor-tab-chaos-viewasfrom', 'View links as "from"');
	Add('editor-tab-triangle-title', 'Triangle');
	Add('editor-tab-triangle-pivot', 'Pivot Point');
	Add('editor-tab-triangle-modelocal', 'Local');
	Add('editor-tab-triangle-modeworld', 'World');
	Add('editor-tab-triangle-tolocal', 'Toggle local (affine) pivot cooordinates');
	Add('editor-tab-triangle-toworld', 'Toggle world (cartesian) pivot cooordinates');
	Add('editor-tab-triangle-resetpivot', 'Reset pivot point');
	Add('editor-tab-triangle-pickpivot', 'Pick pivot point using mouse');
	Add('editor-tab-triangle-rotateleft', 'Rotate triangle counter-clockwise');
	Add('editor-tab-triangle-rotateright', 'Rotate triangle clockwise');
	Add('editor-tab-triangle-moveup', 'Move triangle up');
	Add('editor-tab-triangle-movedown', 'Move triangle down');
	Add('editor-tab-triangle-moveleft', 'Move triangle left');
	Add('editor-tab-triangle-moveright', 'Move triangle right');
	Add('editor-tab-triangle-scaledown', 'Scale triangle down');
	Add('editor-tab-triangle-scaleup', 'Scale triangle up');
	Add('editor-tab-triangle-autoweight', 'Auto-balance weights');
  Add('editor-tab-triangle-reflection', 'Reflection Axis');
  Add('editor-tab-triangle-fliptriangle', 'Flip triangle');
  Add('editor-tab-triangle-flipx', 'Set the X-axis as a reflection line');
  Add('editor-tab-triangle-flipy', 'Set the Y-axis as a reflection line');
  Add('editor-tab-triangle-flipxy', 'Set the main XY-diagonal as a reflection line');
  Add('editor-tab-triangle-hideline', 'Hide line');
  Add('editor-tab-triangle-showline', 'Show line');
  Add('editor-tab-triangle-showlinehint', 'Draw or hide the reflection axis for the selected triangle');
  Add('editor-tab-triangle-fliptrianglehint', 'Flip triangle through a line');
  Add('editor-tab-triangle-resetflip', 'Reset point coordinates to (0,0)');
  Add('editor-tab-triangle-transforms', 'Geometric Operations');
  Add('editor-tab-triangle-transformshint', ' Hotkey A - apply to all vectors, hotkey X - apply to OX-vector only, hotkey Y - apply to OY-vector only, hotkey O - apply to O-vector only');
  Add('editor-tab-triangle-coordinates', 'Coordinates');
  Add('editor-tab-triangle-menuhint', 'Adjust the transformation tools...');
  Add('editor-tab-triangle-syncall', 'Apply operations to all triangles');
  Add('editor-tab-triangle-pivot1x', 'Pivot point abscissa in the chosen coordinate system');
  Add('editor-tab-triangle-pivot1y', 'Pivot point ordinate in the chosen coordinate system');
  Add('editor-tab-triangle-pivot2x', 'Second point abscissa in the chosen coordinate system');
  Add('editor-tab-triangle-pivot2y', 'Second point ordinate in the chosen coordinate system');
  Add('editor-tab-triangle-enablesync', 'Synchronize operations for selected triangles');
  Add('editor-tab-triangle-disablesync', 'Synchronization for triangles disabled');
	Add('editor-tab-transform-title', 'Transform');
	Add('editor-tab-transform-reset', 'Reset transform');
	Add('editor-tab-transform-resethint', 'Reset all vectors to default position');
  Add('editor-tab-transform-affine', 'Affine coefficients');
  Add('editor-tab-transform-postaffine', 'Post-affine coefficients');
  Add('editor-tab-transform-swapaffine', 'Swap matrices');
  Add('editor-tab-transform-swapaffinehint', 'Swap pre- and post-affine coefficients');
  Add('editor-tab-transform-conjugate', 'Conjugate');
  Add('editor-tab-transform-conjugatehint', 'Calculate the invert matrix and write the result into the second matrix');
  Add('editor-tab-transform-coordsystem', 'Coordinate system');
	Add('editor-tab-transform-rectangular', 'Rectangular');
	Add('editor-tab-transform-rectangularhint', 'Show vectors in rectangular (cartesian) coordinates');
	Add('editor-tab-transform-polar', 'Polar (deg)');
	Add('editor-tab-transform-polarhint', 'Show vector in polar coordinates');
	Add('editor-tab-transform-resetpost', 'Reset post transform');
	Add('editor-tab-transform-resetposthint', 'Reset all post-transform vectors to default position');
	Add('editor-tab-transform-autozscale', 'Auto-calculate pre_zscale');
	Add('editor-tab-transform-resetxhint', 'Reset vector X');
	Add('editor-tab-transform-resetyhint', 'Reset vector Y');
	Add('editor-tab-transform-resetohint', 'Reset vector O');
	Add('editor-tab-color-title', 'Colors');
	Add('editor-tab-color-transformcolor', 'Transform color');
	Add('editor-tab-color-colorspeed', 'Color speed');
	Add('editor-tab-color-opacity', 'Opacity');
	Add('editor-tab-color-directcolor', 'Direct color');
	Add('editor-tab-color-togglesolo', 'Solo');
  Add('editor-tab-color-togglesoloformat', 'Solo transform #%d');
	Add('editor-tab-color-varpreview', 'Variation preview');
	Add('editor-tab-color-previewrange', 'Range');
	Add('editor-tab-color-previewdepth', 'Depth');
	Add('editor-tab-color-previewdensity', 'Density');
  Add('editor-tab-color-previewrangehint', 'Area to which variations are applied');
	Add('editor-tab-color-previewdepthhint', 'Number of recursive calculations');
	Add('editor-tab-color-previewdensityhint', 'Frequency of the grid nodes');
  Add('editor-tab-color-preview', 'Preview');
  Add('editor-grid-type', 'Grid Type');
  Add('editor-grid-typehint', 'Coordinate system for the grid');
  Add('editor-grid-polar', 'Polar');
  Add('editor-grid-bipolar', 'Bipolar');
  Add('editor-grid-elliptic', 'Elliptic');
  Add('editor-grid-rectangular', 'Rectangular');
	Add('editor-toolbar-newflame', 'New blank flame');
	Add('editor-toolbar-newtransform', 'Add a new transform');
	Add('editor-toolbar-addlinkedtransform', 'Add linked post-transform');
  Add('editor-toolbar-addlinkedpretransform', 'Add linked pre-transform');
	Add('editor-toolbar-duplicatetransform', 'Duplicate transform');
	Add('editor-toolbar-removetransform', 'Remove the selected transform');
	Add('editor-toolbar-modeselect', 'Selection mode');
	Add('editor-toolbar-modemove', 'Movement mode');
	Add('editor-toolbar-moderotate', 'Rotation mode');
	Add('editor-toolbar-modescale', 'Scale mode');
	Add('editor-toolbar-toggleworldpivot', 'Toggle world pivot');
	Add('editor-toolbar-rotate90ccw', 'Rotate 90° counter-clockwise');
	Add('editor-toolbar-rotate90cw', 'Rotate 90° clockwise');
	Add('editor-toolbar-fliph', 'Flip transform horizontal');
	Add('editor-toolbar-flipv', 'Flip transform vertical');
	Add('editor-toolbar-togglevarpreview', 'Show variation preview');
	Add('editor-toolbar-toggleposttransform', 'Enable/edit affine post-transform');
	Add('editor-toolbar-togglefinaltransform', 'Enable final transform');
  Add('editor-toolbar-pihint', 'Insert math constant into the selected text field');
	Add('editor-toolbar-pimenu', 'Insert fraction of');
  Add('editor-toolbar-squareroots', 'Insert square root...');
  Add('editor-toolbar-squareroot', 'Square root of the number');
  Add('editor-toolbar-goldenratio', 'Insert Golden ratio');
  Add('editor-toolbar-invert', 'Invert the number');
  Add('editor-toolbar-square', 'Square the number');
  Add('editor-toolbar-multiply', 'Multiply by 2');
  Add('editor-toolbar-divide', 'Divide by 2');
  Add('editor-toolbar-calccos', 'Calculate cosine of the value');
  Add('editor-toolbar-calcsin', 'Calculate sine of the value');
  Add('editor-toolbar-calctan', 'Calculate tangent of the value');
  Add('editor-toolbar-usedegrees', 'Use degrees');
  Add('editor-toolbar-calcexpression', 'Calculate math expression...');
  Add('editor-toolbar-showchaos', 'Show chaotic transitions structure...');
  Add('editor-toolbar-savestate', 'Save current flame into the opened file');
	Add('editor-popup-panel-autozoom', 'Zoom automatically');
	Add('editor-popup-panel-toggleextendededit', 'Toggle extended edit mode');
	Add('editor-popup-panel-locktransformaxes', 'Lock transform axes');
	Add('editor-popup-panel-allfliph', 'Flip all horizontally');
  Add('editor-popup-panel-allflipv', 'Flip all vertically');
  Add('editor-popup-panel-allflipline', 'Flip all through a line');
	Add('editor-popup-quality-autoreset', 'Auto-reset location');
	Add('editor-popup-transform-resetposition', 'Reset position');
	Add('editor-popup-transform-resetrotation', 'Reset rotation');
	Add('editor-popup-transform-resetscale', 'Reset scale');
	Add('editor-popup-transform-resetflip', 'Reset reflection');
	Add('editor-popup-transform-copycoords', 'Copy triangle coordinates');
	Add('editor-popup-transform-pastecoords', 'Paste triangle coordinates');
	Add('editor-popup-transform-copywhole', 'Copy selected transform(s)');
	Add('editor-popup-transform-pastewhole', 'Paste transform(s)');
  Add('editor-popup-transform-copyvars', 'Copy variations with parameters');
	Add('editor-popup-transform-pastevars', 'Paste variations and parameters');
	Add('editor-popup-transform-resetentiretriangle', 'Reset triangle');
	Add('editor-popup-chaos-rebuildlinks', 'Rebuild chaos links');
	Add('editor-popup-chaos-clearall', 'Clear all current modifiers (reset to zero)');
 	Add('editor-popup-chaos-setall', 'Set all current modifiers to 1');
  Add('editor-popup-chaos-showmenu', 'More...');
 	Add('editor-popup-chaos-random', 'Randomize all current modifiers');
	Add('editor-popup-chaos-normalize', 'Normalize transition matrix');
	Add('editor-popup-chaos-randomize', 'Randomize transition matrix');
  Add('editor-popup-chaos-reset', 'Reset transition matrix');
	Add('editor-popup-chaos-clearabove', 'Clear modifiers above selected');
 	Add('editor-popup-chaos-clearbelow', 'Clear modifiers below selected');
 	Add('editor-popup-chaos-container', 'Add container transform');
 	Add('editor-popup-chaos-keepweight', 'Inherit original weights');
  Add('editor-popup-chaos-invert', 'Invert current settings');
  Add('editor-popup-chaos-copy', 'Copy current weight modifiers');
  Add('editor-popup-chaos-paste', 'Apply saved modifiers to transform(s)');
 	Add('editor-popup-triangle-rotateall', 'Rotate all vectors');
 	Add('editor-popup-triangle-rotatex', 'Rotate only X-axis');
 	Add('editor-popup-triangle-rotatey', 'Rotate only Y-axis');
 	Add('editor-popup-triangle-rotateo', 'Rotate only O-vector');
 	Add('editor-popup-triangle-scaleall', 'Scale all vectors');
 	Add('editor-popup-triangle-scalex', 'Scale only X-axis');
 	Add('editor-popup-triangle-scaley', 'Scale only Y-axis');
 	Add('editor-popup-triangle-scaleo', 'Scale only O-vector');
 	Add('editor-popup-triangle-squaregrid', 'Move along a square lattice');
 	Add('editor-popup-triangle-hexgrid', 'Move along a triangular lattice');
 	Add('editor-popup-triangle-invertstep', 'Invert current Move step');
 	Add('editor-popup-triangle-arcsin', 'Calculate arcsin of the scale factor');
 	Add('editor-popup-triangle-display', 'Display internally  modified values');
	Add('editor-status-xformat', 'X: %f');
	Add('editor-status-yformat', 'Y: %f');
	Add('editor-status-rotateformat', 'Rotate: %3.2f°  Inner angle: %3.2f°');
	Add('editor-status-rotateformat2', 'Rotate: %3.2f°  Local axis: %3.2f°');
	Add('editor-status-rotateformat3', 'Rotate: %3.2f°');
	Add('editor-status-scaleformat', 'Distance: %3.3f  Scale: %3.2f%%');
	Add('editor-status-scaleformat2', 'Scale: %3.2f%%');
	Add('editor-status-moveformat', 'Move: %3.3f ; %3.3f');
	Add('editor-status-moveformat2', 'Move: %3.3f ; %3.3f');
	Add('editor-status-transformformat', 'Transform #%d');
	Add('editor-status-zoomformat', 'Zoom: %f');
  Add('editor-status-angle', 'Current angle');  // AV
	Add('editor-status-selecton', 'Select ON');
	Add('editor-status-selectoff', 'Select OFF');
	Add('editor-status-warnscale', 'Current scale factor is out of range! The value inserted into the "Scale" field must be less than 100 percents.');
  Add('editor-status-warninvert', 'The affine determinant is too small for this operation.');
	Add('editor-status-nonumfield', 'No active numeric field found. Please select a numeric field before opening the menu.');
  Add('editor-status-formula', 'Type the math formula: ');
	Add('export-title', 'Export to flam3');
	Add('export-paramoptions-title', 'Parameter options');
	Add('export-paramoptions-bufferdepth', 'Buffer depth');
	Add('export-paramoptions-strips', 'Strips');
	Add('export-paramoptions-estimatorradius', 'DE radius');
	Add('export-paramoptions-estimatorcurve', 'DE curve');
	Add('export-paramoptions-estimatormin', 'DE minimum');
	Add('export-paramoptions-dorender', 'Render');
	Add('export-paramoptions-warningtitle', 'WARNING');
	Add('export-paramoptions-warningtext', 'Fractals created with this version of Apophysis are not supported by flam3! To render 2D-only fractals, download the latest version of flam3 from');
	Add('favscripts-title', 'Favourite scripts');
	Add('favscripts-hint', 'User''s Favourite scripts list');
	Add('favscripts-add', 'Add');
	Add('favscripts-remove', 'Remove');
	Add('favscripts-moveup', 'Move up');
	Add('favscripts-movedown', 'Move down');
  Add('fullscreen-popup-rendermore', 'Render more');
	Add('fullscreen-popup-stoprender', 'Stop render');
  Add('gradientbrowser-title', 'Gradient Browser');
  Add('selectcolors-title', 'Palette Interval Selection');
  Add('selectcolors-start', 'Start palette index:');
  Add('selectcolors-last', 'Last palette index:');
	Add('postprocess-title', 'Post-process render');
  Add('postprocess-save', 'Save');
  Add('postprocess-fittowindow', 'Fit to window');
	Add('render-title', 'Render flame to disk');
	Add('render-common-gotofolder', 'Open target folder...');
	Add('render-tab-settings-title', 'Settings');
	Add('render-tab-output-title', 'Output');
  Add('render-presets-title', 'Presets');
  Add('render-presets-save', 'Save current preset');
  Add('render-presets-delete', 'Delete the selected preset');
  Add('render-prestatus-saveerror-preset', 'Cannot save preset settings.');
	Add('render-resourceusage-title', 'Resource usage');
	Add('render-resourceusage-infotext', 'The render process will use %u MB of %u MB available physical memory');
  Add('render-resourceusage-infotext2', 'Apophysis will try to use %u processor cores (%u available) - change this in the options');
	Add('render-resourceusage-limit', 'Memory limit');
	Add('render-resourceusage-nolimit', 'No limit');
	Add('render-resourceusage-bufferdepth', 'Buffer depth');
	Add('render-output-title', 'Output options');
	Add('render-output-saveparams1', 'Save parameters in the flame-file');
  Add('render-output-saveparams2', 'Save parameters in the PNG-image');
	Add('render-completion-title', 'Completion options');
	Add('render-completion-postprocess', 'Post-process after rendering');
	Add('render-completion-shutdown', 'Shut down the computer after rendering');
  Add('render-completion-playsound', 'Play sound after rendering');
	Add('render-completion-saveincomplete', 'Save incomplete renders');
  Add('render-status-rendererror-log', 'Rendering failed!');
	Add('render-status-rendererror-message', 'Error while rendering!');
	Add('render-status-saveerror-log', 'Error saving image!');
	Add('render-status-saveerror-message1', 'An error occured while saving the image:');
	Add('render-status-saveerror-message2', 'Check your free disk space and try again.');
	Add('render-status-totaltime', 'Total time:');
	Add('render-status-renderterminated', 'Rendering terminated!');
	Add('render-status-renderhibernated', 'Rendering paused and progress saved!');
	Add('render-status-elapsed', 'Elapsed');
	Add('render-status-remaining', 'Remaining');
	Add('render-status-slicestatus', 'Slice %d of %d');
	Add('render-status-notenoughmemory1', 'You do not have enough memory for this render. Do you want to continue anyway?');
	Add('render-status-notenoughmemory2', 'You do not have enough memory for this render. Please use a lower Maximum memory setting. Do you want to ignore this problem and continue?');
	Add('render-status-nofilename', 'Please enter a file name.');
	Add('render-status-fileexists-message1', '"%s" already exists');
	Add('render-status-fileexists-message2', 'Do you want to replace it?');
	Add('render-status-pathdoesnotexist', 'The directory does not exist.');
	Add('render-status-invaliddensity', 'Invalid Sample Density value');
	Add('render-status-invalidfilterradius', 'Invalid Filter Radius value');
	Add('render-status-invalidoversample', 'Invalid Oversample value');
	Add('render-status-invalidwidth', 'Invalid image width');
	Add('render-status-invalidheight', 'Invalid image height');
	Add('render-status-maxmemorytoosmall', 'Maximum memory value is too small. Do you want to continue anyway?');
	Add('render-status-shuttingdownrender', 'Shutting down previous render...');
	Add('render-status-log-title', 'Rendering "%s"');
	Add('render-status-log-size', 'Size: %dx%d');
	Add('render-status-log-quality', 'Quality: %g');
	Add('render-status-log-oversampling', 'Oversample: %d, Filter: %g');
	Add('render-status-log-bufferdepth', 'Buffer depth: %s');
	Add('render-status-log-memorylimit', 'Memory limit: %d MB');
	Add('render-status-log-largepng-message1', '*** WARNING *** You have selected PNG format and an image size which exceeds 20 megapixels');
	Add('render-status-log-largepng-message2', 'PNG format with extreme high-resolution images is not recommended!');
	Add('render-status-log-largepng-message3', 'To avoid slowdown (and possible memory problems) use BMP file format instead.');
	Add('render-status-confirmstop', 'Do you want to stop the current render?');
  Add('render-status-stop', 'Cancel current rendering');
  Add('render-status-dosnapshot', 'Do snapshot');
  Add('render-status-dosnapshothint', 'Save current state as a picture');
  Add('render-status-showimage', 'Show the image state...');
	Add('messages-title', 'Messages');
	Add('messages-openautomatically', 'Automatically open this window');
	Add('mutation-title', 'Mutation');
	Add('mutation-directions', 'Directions');
	Add('mutation-speed', 'Speed');
	Add('mutation-trend', 'Trend');
	Add('mutation-keepnumberoftransforms', 'Keep transform count');
  Add('mutation-randomtrend', 'Random');
	Add('mutation-maintainsymmetry', 'Maintain symmetry');
	Add('mutation-previous', 'Previous');
  Add('options-title', 'Settings ');
  Add('options-selectplugins', 'Please, specify the plugin folder');
	Add('options-restartnotice', 'You must restart Apophysis AV to make your changes have effect.');
	Add('options-tab-general-title', 'General ');
  Add('options-tab-general-language', 'Language file');
	Add('options-tab-general-multithreading', 'Multithreading ');
	Add('options-tab-general-multithreading-off', 'Off ');
	Add('options-tab-general-bufferdepth', 'Buffer depth ');
	Add('options-tab-general-jpegquality', 'JPEG quality ');
	Add('options-tab-general-pngtransparency', 'PNG transparency ');
  Add('options-tab-general-notifications', 'Notifications');
  Add('options-tab-general-defaults', 'Defaults');
	Add('options-tab-general-showextendedstatistics', 'Show extended render statistics ');
  Add('options-tab-general-showrenderimage', 'Show the rendered image ');
	Add('options-tab-general-confirmdelete', 'Confirm deleting flames ');
	Add('options-tab-general-confirmexit', 'Confirm exit ');
	Add('options-tab-general-confirmrenderstop', 'Confirm stop rendering ');
	Add('options-tab-general-confirmclearscript', 'Confirm clear script ');
  Add('options-tab-general-confirmresetundo', 'Confirm reset editing history ');
	Add('options-tab-general-oldgradientformat', 'Use old gradient format ');
  Add('options-tab-general-templaterandcolor', 'Randomize gradient for templates ');
	Add('options-tab-general-alwaysblankflame', 'Disable templates ');
  Add('options-tab-general-autosavepasted', 'Automatically save new and pasted flames ');
	Add('options-tab-general-enablemissingpluginswarning', 'Warn on missing plugins ');
	Add('options-tab-general-enablethumbnailembedding', 'Enable thumbnail embedding ');
  Add('options-tab-general-setenglayout', 'Set English keyboard layout');
	Add('options-tab-general-rotatemode', 'Rotation mode ');
	Add('options-tab-general-rotateimage', 'Rotate image ');
	Add('options-tab-general-rotateframe', 'Rotate frame ');
	Add('options-tab-general-zoommode', 'Zooming mode ');
	Add('options-tab-general-preservequality', 'Preserve quality ');
	Add('options-tab-general-preservespeed', 'Preserve speed ');
	Add('options-tab-general-enummode', 'Enumerating mode ');
	Add('options-tab-general-enum0', 'Script-compatible (zero-based) ');
	Add('options-tab-general-enum1', 'Standart (start from 1) ');	
	Add('options-tab-general-guides', 'Guidelines ');
	Add('options-tab-general-enableguides', 'Enable guides ');
	Add('options-tab-general-guidecentercolor', 'Center ');
	Add('options-tab-general-guidethirdscolor', 'Thirds ');
	Add('options-tab-general-guidegoldenratiocolor', 'Golden ratio ');
  //Add('options-tab-general-singleprecision', 'Use single-precision buffers ');
  Add('options-tab-general-onrendercomplete', 'On render complete ');
  Add('options-tab-general-playsound', 'Play sound ');
  Add('options-tab-general-soundfile', 'Sound file: ');
  Add('options-tab-general-playhint', 'Play');
  Add('options-tab-general-createanimdir', 'Create a new folder for frames');
  Add('options-tab-general-autoflatten', 'Apply flattening to old flames');
  Add('options-tab-general-pluginpath', 'Plugin folder ');
	Add('options-tab-editor-title', 'Editor ');
	Add('options-tab-editor-editorgraph', 'Graph ');
	Add('options-tab-editor-editordefaults', 'Defaults ');
	Add('options-tab-editor-usetransformcolor', 'Use transform color ');
	Add('options-tab-editor-helperlines', 'Show helper lines ');
	Add('options-tab-editor-alwaysshowbothtransformtypes', 'Always show both transform types ');
	Add('options-tab-editor-backgroundcolor', 'Background ');
	Add('options-tab-editor-gridcolors', 'Grid ');
	Add('options-tab-editor-referencecolor', 'Reference ');
	Add('options-tab-editor-helpercolors', 'Helpers ');
	Add('options-tab-editor-extendededit', 'Extended edit mode ');
	Add('options-tab-editor-locktransformaxes', 'Lock transform axes ');
	Add('options-tab-editor-rebuildxaoslinks', 'Rebuild links after deleting');
  Add('options-tab-editor-enablepreview', 'Enable background preview'); 
  Add('options-tab-editor-previewtransparency', 'Transparency');
  Add('options-tab-editor-resetcoefs', 'Reset affine values by double-click');
  Add('options-tab-editor-resetlinear', 'Reset linear when other variation is set');
  Add('options-tab-editor-synctriangles', 'Allow synchronize triangles');
	Add('options-tab-display-title', 'Display ');
	Add('options-tab-display-rendering', 'Rendering ');
	Add('options-tab-display-previewdensity', 'Preview density ');
	Add('options-tab-display-mainpreview', 'Main window preview ');
	Add('options-tab-display-extendpreviewbuffer', 'Extend preview buffer ');
	Add('options-tab-display-extenspreviewbufferlabel', 'Buffer extension ');
	Add('options-tab-display-showtransparency', 'Show transparency ');
	Add('options-tab-display-usesmallthumbs', 'Use small thumbnails (like Apophysis 2.09) ');
  Add('options-tab-display-fuse', 'Skipped iterations');
  Add('options-tab-display-tileradius', 'Tile radius');
	Add('options-tab-random-title', 'Random ');
	Add('options-tab-random-numberoftransforms', 'Number of transforms ');
	Add('options-tab-random-mutationtransforms', 'Mutation transforms ');
	Add('options-tab-random-randombatch', 'Random batch ');
	Add('options-tab-random-forcedsymmetry', 'Forced symmetry ');
	Add('options-tab-random-batchsize', 'Batch size ');
	Add('options-tab-random-titleprefix', 'Title prefix ');
	Add('options-tab-random-keepbackground', ' Keep the current background color');
	Add('options-tab-random-symtype', 'Type');
	Add('options-tab-random-symorder', 'Order');
	Add('options-tab-random-symlimit', 'Limit');
	Add('options-tab-random-type-none', 'None');
	Add('options-tab-random-type-bilateral', 'Bilateral');
	Add('options-tab-random-type-rotational', 'Rotational');
	Add('options-tab-random-type-dihedral', 'Dihedral');
	Add('options-tab-random-onrandom', 'On random flame use... ');
	Add('options-tab-random-userandom', 'Random preset gradient');
	Add('options-tab-random-usedefault', 'Default gradient ');
	Add('options-tab-random-usecurrent', 'Current gradient ');
	Add('options-tab-random-randomcalculated', 'Random gradient ');
	Add('options-tab-random-randomfromfile', 'Random from file ');
	Add('options-tab-random-filetouse', 'Gradient file to use ');
	Add('options-tab-variations-title', 'Variations ');
  Add('options-tab-variations-random', 'Random choise ');
  Add('options-tab-variations-faves', 'Favourites ');
	Add('options-tab-variations-setall', 'Set all ');
	Add('options-tab-variations-clearall', 'Clear all ');
  Add('options-tab-variations-invert', 'Invert selection');
	Add('options-tab-gradient-title', 'Gradient ');
	Add('options-tab-gradient-numberofnodes', 'Number of nodes ');
	Add('options-tab-gradient-smoothpalette', 'Smooth palette ');
	Add('options-tab-gradient-huebetween', 'Hue range ');
	Add('options-tab-gradient-satbetween', 'Saturation range ');
	Add('options-tab-gradient-lumbetween', 'Luminance range ');
	Add('options-tab-gradient-numtries', 'Number of tries ');
	Add('options-tab-gradient-trylength', 'Try length ');
  Add('options-tab-gradient-colorblend', 'Color blending type ');
  Add('options-tab-gradient-rgbblend', 'RGB blend ');
  Add('options-tab-gradient-hsvblend', 'HSV blend ');
  Add('options-tab-gradient-noblend', 'No blending ');
  Add('options-tab-gradient-equalstripes', 'Use equal width of gradient color stripes');
	Add('options-tab-upr-title', 'UltraFractal ');
	Add('options-tab-upr-paramdefaults', 'Parameter defaults ');
	Add('options-tab-upr-coloralgorithm', 'Coloring algorithm ');
	Add('options-tab-upr-uprsize', 'Image size ');
	Add('options-tab-upr-formula', 'Formula ');
	Add('options-tab-upr-identifier', 'Identifier ');
	Add('options-tab-upr-adjustdensity', 'Adjust sample density ');
	Add('options-tab-environment-title', 'Environment');
	Add('options-tab-environment-defaultparams', 'Default parameters ');
	Add('options-tab-environment-smoothpalette', 'Smooth palette ');
	Add('options-tab-environment-functionlib', 'Scripting function library ');
	Add('options-tab-environment-exportrenderer', 'Export renderer ');
	Add('options-tab-environment-helpfile', 'Help file ');
  Add('options-tab-environment-screenshots', 'Screenshot folder ');
  Add('options-tab-environment-defaultscript', 'Default script file ');
  Add('options-tab-environment-screenshotshint', 'Select a folder for Apophysis screenshots: ');
	Add('options-tab-environment-rememberlastopen', 'Remember last open parameters ');
	Add('options-tab-environment-autosave', 'Enable autosave ');
	Add('options-tab-environment-savefrequency', 'Save frequency ');
  Add('options-tab-environment-usex64chaotica', 'Use 64-bit version if possible');
	Add('preview-title', 'Preview');
	Add('preview-keepframe', 'Saving images with boarders');
  Add('preview-pause', 'Pause the animation');
  Add('preview-resume', 'Resume the animation');
	Add('save-title', 'Save');
	Add('save-name', 'Fractal name');
  Add('save-namepal', 'Palette name');
  Add('save-oldformat', 'Use old format');
  Add('save-newformat', 'Use new format');
  Add('save-type-parameters', 'Save Parameters');
	Add('save-type-allparameters', 'Save All Parameters');
  Add('save-type-template', 'Save Template');
	Add('save-type-gradient', 'Save Gradient');
	Add('save-type-exportupr', 'Export UPR');
	Add('save-status-notitle', 'No item name given.');
	Add('save-status-invalidfilename', 'Invalid file name.');
	Add('save-status-alreadyexists', '"%s" in "%s" already exists. Do you want to replace it?');
	Add('save-status-alreadyexists2', '"%s" already exists. Do you want to replace it?');
  Add('save-status-alreadyexists3', 'The flame "%s" already exists. Please, select another name.');
	Add('savepreset-title', 'Save preset');
	Add('savepreset-name', 'Name');
  Add('savepreset-notitle', 'No preset name given.');
	Add('script-title', 'Script Editor');
  Add('script-rendering', 'Rendering image "%s"...');
  Add('script-break', 'Break');
	Add('script-new', 'New script');
	Add('script-open', 'Open');
	Add('script-save', 'Save');
	Add('script-run', 'Run');
	Add('script-pause', 'Pause');
	Add('script-stop', 'Stop');
  Add('script-faves', 'Add to favourites');
  Add('script-line', 'Line');
  Add('script-position', 'Position');
	Add('script-confirmclear', 'Are you really want to delete the script? All unsaved changes will be lost!');
	Add('script-codeblocks', 'Show code blocks');
  Add('script-codeblock', 'Active code block renaming');
  Add('script-codeblockrename', 'Insert new caption: ');
	Add('script-codeblockhints', 'Show code blocks in hints');
	Add('script-commentout', 'Comment out the selection by...');
	Add('script-surround', 'Surround the selection by...');
  Add('script-clipboardview', 'Add code blocks from the clipboard');
  Add('script-codeblockhint', 'Select a block and drag it into the Script editor');
  Add('script-findreplace', 'Find and replace...');
  Add('script-textnotfound', 'The search is finished. The text is not found at the script.');
  Add('script-collapsecode', 'Collapse all blocks of code');
  Add('script-expandcode', 'Expand all blocks of code');
  Add('script-compileerror', 'Script: COMPILE ERROR');
  Add('script-runtimeerror', 'Script: RUNTIME ERROR');
  Add('script-status-default', 'Press Ctrl + "Space" for automathic code completion ');
  Add('script-status-compileerror', 'Fail to run the script');
  Add('script-status-runtimeerror', 'Script execution failed');
  Add('script-status-break', 'Execution stopped by user.');
  Add('script-status-executing', 'Executing current script...');
  Add('script-status-stopped', 'Infinite loop was stopped');
  Add('script-status-syntaxerror', 'Syntax error');
  Add('script-status-noclassmember', 'Unknown member identifier');
  Add('script-status-noidentifier', 'Unknown identifier or variable is not declared');
  Add('script-status-constassign', 'Cannot assign a value to constant');
  Add('script-status-varnotarray', 'Variable is not an array');
  Add('script-status-noformfile', 'Cannot find form file');
  Add('script-status-unknownmethod', 'Unknown method or routine');  
  Add('script-status-toomanyparams', 'Too many parameters for method');
  Add('script-status-notenoughparams', 'Not enough actual parameters for method');
  Add('script-status-expectparams', 'Expected # parameters');
  Add('script-status-expectvar', 'Method # expects variable reference');
  Add('script-status-notassign', 'Assign to method # is not allowed');
  Add('script-status-propnotfunc', 'Property # cannot be called as a method');
  Add('script-status-outofrange', 'Transform index is out of range!');
  Add('script-status-varoutofrange', 'The index or parameter value is out of range.');
  Add('script-status-notransforms', 'Not enough transforms to perform the operation.');
  Add('script-status-toomanytransforms', 'Too many transforms to perform the operation.');
  Add('script-status-paused', 'Script execution is paused');
  Add('script-status-cancelrender', 'Render was cancelled by user.');
	Add('splash-loadingtext', 'Loading');
	Add('template-title', 'Templates');
  Add('template-filename', 'Source template file: ');
  Add('main-common-title-lite', 'Lite Version');
	Add('main-common-title-t500', 'High-Memory Version');
	Add('main-common-randombatch', 'Random Batch');
  Add('main-menu-file-title', 'File');
	Add('main-menu-file-new', 'New');
	Add('main-menu-file-open', 'Open the flame...');
	Add('main-menu-file-loadpng', 'Load parameters from PNG...');
	Add('main-menu-file-loadpnghint', 'Open the PNG-image that containing flame parameters');
	Add('main-menu-file-restoreautosave', 'Restore last autosave');
  Add('main-menu-file-autosavehint', 'Open the last automatically saved fractal project');
	Add('main-menu-file-saveparams', 'Save parameters...');
	Add('main-menu-file-saveallparams', 'Save all parameters...');
  Add('main-menu-file-saveallhint', 'Save parameters of all fractals to a file');
	Add('main-menu-file-smoothpalette', 'Smooth palette...');
  Add('main-menu-file-smoothpalettehint', 'Create a smooth color gradient from an image');
	Add('main-menu-file-gradientbrowser', 'Gradient browser...');
 	Add('main-menu-file-gradientbrowserhint', 'Browse saved fractal palettes libraries...');
	Add('main-menu-file-exportupr', 'Export UPR...');
	Add('main-menu-file-exportflame', 'Export to flam3...');
	Add('main-menu-file-exportchaotica', 'Export to Chaotica...');
	Add('main-menu-file-importgimp', 'Import GIMP parameters...');
	Add('main-menu-file-exportuprhint', '*** OUTDATED *** Save the flame in UltraFractal''s parameters format. 3D-properties are not supported!');
	Add('main-menu-file-exportflamehint', '*** OUTDATED *** Export the current flame parameters in a FLAM3 format. 3D-properties are not supported!');
	Add('main-menu-file-exportchaoticahint', 'Export the current fractal to Chaotica software. 3D-properties are not supported!');
	Add('main-menu-file-importgimphint', '*** OUTDATED *** Import GIMP parameters, which were created using the Flame filter');
	Add('main-menu-file-randombatch', 'Random batch');
	Add('main-menu-file-exit', 'Exit');
  Add('main-menu-file-randombatchhint', 'Create and load a file consist of random fractal parameters');
	Add('main-menu-file-exithint', 'Quit and close Apophysis');
	Add('main-menu-edit-title', 'Edit');
	Add('main-menu-edit-saveundo', 'Save undo stack...');
	Add('main-menu-edit-copyasupr', 'Copy as UPR');
  Add('main-menu-edit-copy', 'Copy the flame XML-parameters to the clipboard');
  Add('main-menu-edit-paste', 'Paste the flame XML-parameters from cripboard');
  Add('main-menu-edit-copyuprhint', 'Copy the UltraFractal-parameters of the flame to the clipboard ');
	Add('main-menu-view-title', 'View');
	Add('main-menu-view-fullscreen', 'Full screen');
	Add('main-menu-view-editor', 'Editor');
	Add('main-menu-view-adjustment', 'Adjustment');
	Add('main-menu-view-gradient', 'Gradient');
	Add('main-menu-view-mutation', 'Mutation');
	Add('main-menu-view-imagesize', 'Image size');
	Add('main-menu-view-messages', 'Messages');
  Add('main-menu-view-curves', 'Curves');
  Add('main-menu-view-animator', 'Animator');
	Add('main-menu-flame-title', 'Flame');
	Add('main-menu-flame-reset', 'Reset location');
	Add('main-menu-flame-randomize', 'Randomize all parameters');
  Add('main-menu-flame-randomizehint', 'Randomize all parameters of the current fractal flame');
	Add('main-menu-flame-changeweights', 'Change weight distribution...');
	Add('main-menu-flame-changecolors', 'Change color distribution...');
	Add('main-menu-flame-randomweights', 'Randomize weights');
	Add('main-menu-flame-equalweights', 'Equalize weights');
	Add('main-menu-flame-randomweightshint', 'Randomize transform weights (probabilities)');
	Add('main-menu-flame-equalweightshint', 'Set all weights (transform probabilities) to the same value');
	//Add('main-menu-flame-computeweights', 'Compute weights');
  Add('main-menu-flame-calculateweights', 'Calculate weights');
	Add('main-menu-flame-normweights', 'Normalize weights');
	Add('main-menu-flame-calculateweightshint', 'Compute transform weights in accordance to their scale factors');
	Add('main-menu-flame-normweightshint', 'Set transform weights to their total sum equals to 1.0');
	Add('main-menu-flame-calculatecolors', 'Calculate color values');
	Add('main-menu-flame-randomizecolors', 'Randomize color values');
  Add('main-menu-flame-resetcolors', 'Reset color values');
  Add('main-menu-flame-calculatecolorspeed', 'Calculate color speed');
	Add('main-menu-flame-randomizecolorspeed', 'Randomize color speed');
 	Add('main-menu-flame-resetcolorspeed', 'Reset color speed');
	Add('main-menu-flame-calccolorshint', 'Distribute transform color parameters evenly');
	Add('main-menu-flame-randcolorshint', 'Randomize transform color parameters, but keep the existing color palette');
  Add('main-menu-flame-calccolorspeedhint', 'Calculate color speed values based on transform weights and contraction factors');
	Add('main-menu-flame-randcolorspeedhint', 'Randomize a speed of changing colors from the current palette');
 	Add('main-menu-flame-resetcolorspeedhint', 'Reset all color speed values to zero');
  Add('main-menu-flame-resetcolorshint', 'Reset all color values to zero (make the fractal monochrome)');
  Add('main-menu-flame-flatten', 'Apply flatten');
  Add('main-menu-flame-flattenhint', 'Apply "flatten" variation for all pseudo-3D transforms');
  Add('main-menu-flame-unflatten', 'Unflatten');
  Add('main-menu-flame-unflattenhint', 'Reset "flatten" variation for all transforms');
	Add('main-menu-flame-rendertodisk', 'Render flame...');
	Add('main-menu-flame-renderallflames', 'Render all flames...');
  Add('main-menu-flame-resumeunfinished', 'Resume unfinished render process...');
	Add('main-menu-flame-generatereport', 'Summarize flame...');
  Add('main-menu-flame-reporthint', 'Show some basic information about the current fractal');
  Add('main-menu-flame-addtile', 'Add equiaffine tile...');
  Add('main-menu-flame-addsymmetry', 'Add equiaffine symmetry...');
  Add('main-menu-flame-rhombustile', 'Rhombus');
  Add('main-menu-flame-squaretile', 'Square');
  Add('main-menu-flame-hextile', 'Hexagonal');
  Add('main-menu-flame-symorder', ', order...');
  Add('main-menu-flame-template', 'Save as template...');
  Add('main-menu-flame-templatehint', 'Save the fractal as a template for future flames');
	Add('main-menu-variation-title', 'Variation');
	Add('main-menu-variation-random', 'Random');
	Add('main-menu-variation-builtin', 'Built-in');
	Add('main-menu-variation-plugins', 'Plugins');
	Add('main-menu-variation-randomhint', 'Randomly selected variation');
	Add('main-menu-variation-builtinhint', 'The list of built-in variations');
	Add('main-menu-variation-pluginshint', 'The list of dinamically loaded variations');
	Add('main-menu-script-title', 'Script');
	Add('main-menu-script-run', 'Run script');
  Add('main-menu-script-run2', 'Run "%s"');
  Add('main-menu-script-run3', 'Load and run the "%s" script.');
	Add('main-menu-script-directory', 'Directory');
  Add('main-menu-script-directoryhint', 'Scripts from default directory');
	Add('main-menu-script-more', 'More');
	Add('main-menu-script-stop', 'Stop script');
	Add('main-menu-script-open', 'Open...');
  Add('main-menu-script-openhint', 'Open a saved script file');
	Add('main-menu-script-edit', 'Edit script');
	Add('main-menu-script-managefaves', 'Manage favourites...');
	Add('main-menu-script-flametoscript', 'Generate script from flame');
	Add('main-menu-script-managefaveshint', 'Show the Favourite Scripts Manager');
	Add('main-menu-script-flametoscripthint', 'Translate visual flame properties into a programming language');
	Add('main-menu-options-title', 'Tools');
	Add('main-menu-options-togglemaintoolbar', 'Show the toolbar');
	Add('main-menu-options-togglestatusbar', 'Show the status bar');
	Add('main-menu-options-togglefilelist', 'Show the parameter list');
	Add('main-menu-options-resetfilelistwidth', 'Reset the content list width');   // Reset layout
  Add('main-menu-options-resetwidthhint', 'Set default width for the left panel');
  Add('main-menu-options-sortflames', 'Sort flames alphabetically');
  Add('main-menu-options-enumflames', 'Display flame indices');
	Add('main-menu-options-tracelog', 'Trace log...');
  Add('main-menu-options-traceloghint', 'Show trace log (system processes connected with Apophysis)');
	Add('main-menu-options-showoptions', 'Settings...');
  Add('main-menu-options-apouistyle', 'Apophysis GUI style...');
  Add('main-menu-options-apouistylehint', 'Change the Apophysis visual appearance');
	Add('main-menu-help-title', 'Help');
	Add('main-menu-help-contents', 'Contents');
	Add('main-menu-help-aboutalgorithm', 'About fractal flames...');
	Add('main-menu-help-aboutapophysis', 'About Apophysis ...');
  Add('main-menu-help-contentshint', 'Open the Apophysis help file');
	Add('main-menu-help-aboutalgorithmhint', 'Open the corresponding documentation in your internet browser');
	Add('main-menu-help-aboutapophysishint', 'Show copyright and version information');
  Add('main-menu-help-ifstheory', 'Theory of IFS fractals...');
  Add('main-menu-help-ifstheoryhint', 'Open the link to M.Barnsley''s "Fractal Everywhere" book in your internet browser');
  Add('main-menu-help-pluginlink', 'Download Apophysis plugins....');
  Add('main-menu-renamehint', 'Rename the selected fractal');
  Add('main-menu-deletehint', 'Delete the selected fractal from the file');
  Add('main-menu-screenshot', 'Make a sreenshot of the active window');
  Add('main-menu-saveimage', 'Save the preview image with parameters');
  Add('main-menu-updatethumb', 'Update thumbnail');
  Add('main-menu-updateallthumbs', 'Update all thumbnails');
	Add('main-toolbar-listviewmode-classic', 'Classic view | Change the flame list view to a report (single text)');
	Add('main-toolbar-listviewmode-icons', 'Thumbnail view | Change a flame list view to icons');
	Add('main-toolbar-togglealpha', 'Show transparency | Show the flame on a transparent background');
	Add('main-toolbar-toggleguides', 'Show guidelines | Show flame thirds, center  and golden ratio');
	Add('main-toolbar-modemove', 'Translate the camera | Translate the fractal image using mouse');
	Add('main-toolbar-moderotate', 'Rotate the camera | Rotate the fractal image using mouse');
	Add('main-toolbar-modezoomin', 'Zoom in | Scale up the fractal image using mouse');
	Add('main-toolbar-modezoomout', 'Zoom out | Scale down the fractal image using mouse');
  // AV: added a bunch of missing hints
  Add('main-toolbar-new', 'New Flame | Create a new fractal project');
  Add('main-toolbar-open', 'Open (Ctrl+O) | Open a parameter file for browsing');
  Add('main-toolbar-saveparams', 'Save fractal parameters (Ctrl+S)| Save fractal parameters to a flame file');
  Add('main-toolbar-render', 'Render flame(Ctrl+R) | Save the current flame to disk as a picture');
  Add('main-toolbar-renderall', 'Render all flames| Save all fractals as pictures');
  Add('main-toolbar-undo', 'Undo (Ctrl+Z)| Undo the last action');
  Add('main-toolbar-redo', 'Redo (Ctrl+Y) | Redo the last cancelled action');
  Add('main-toolbar-reset', 'Reset Location (F12) | Recalculate  the flame size and position');
  Add('main-toolbar-fullscreen', 'Fullscreen (F3) | Show full-screen view of the flame');
  Add('main-toolbar-editor', 'Editor | Open transform editor');
  Add('main-toolbar-adjustment', 'Adjustment | Adjust the position, size and colors of the flame');
  Add('main-toolbar-gradient', 'Gradient | Change a color palette of the flame');
  Add('main-toolbar-curves', 'Curves | Edit color curves  of the fractal image');
  Add('main-toolbar-mutation', 'Mutation | Show randomly generated modifications of the current flame');
  Add('main-toolbar-quality', 'Rendering quality | Set flame quality (density) for the main preview window');
  Add('main-toolbar-imagesize', 'Image size | Change the image size');
  Add('main-toolbar-animator', 'Animator | Show animation editor');
  Add('main-toolbar-messages', 'Messages | Show error messages');
  Add('main-toolbar-options', 'Settings | Change Apophysis default settings');
  Add('main-toolbar-editscript', 'Edit script | Edit the script code');
  Add('main-toolbar-runscript', 'Run script | Execute the current script');
  Add('main-toolbar-stopscript', 'Stop script | To stop an animation script, you can press any key on your keyboard');
  Add('main-status-batchgenerate', 'Generating %d of %s...');
	Add('main-status-batcherror', 'Error creating batch.');
	Add('main-status-calculatingpalette', 'Calculating the palette, (%d%%)...'); // AV: doesn't work...
	Add('main-status-noflam3', 'Unable to find flam3 executable. Please verify your settings.');
	Add('main-status-nohelpfile', 'Please specify a help file path in the options dialog first.');
	Add('main-status-variationsorvariables', 'variations or variables');
	Add('main-status-plugins', 'plugins');
  Add('main-status-pluginpath-ioerror', 'Failed to write the setting for the plugin directory. Apophysis will use the default setting.');
	Add('main-status-noloadingerrors', 'Flame loaded without errors');
	Add('main-status-loadingerrorcount', '%d errors in flame');
	Add('main-status-morepluginsneeded', 'The flame "%s" requires the following additional %s:');
  Add('main-status-noautosave', 'No autosave present.');
  Add('main-status-chaoticacompatmissing', 'The variation compatibility data file can not be found at the configured location of Chaotica. The rendering result may look different from the preview. Do you want to proceed?');
  Add('main-status-nochaotica', 'The executable file of Chaotica could not be found. Please check your settings.');
  Add('main-status-oldchaotica', 'The rendering result may look different from the preview. Do you want to proceed?');
	Add('main-report-transformcount', 'Transform count: %d');
	Add('main-report-finaltransform', 'Has final transform: %s');
	Add('main-report-directcoloring', 'Has direct coloring: ');
	Add('main-report-flame3d', 'Has 3D view: ');
	Add('main-report-usedplugins', 'Used plugins:');
	Add('main-report-noplugins', '(none)');
  Add('varorder-title', 'Variation Execution Order');
  Add('varorder-totop', 'To Top');
  Add('varorder-tobottom', 'To Bottom');
  Add('varorder-byname', 'Sort by name');
  Add('varorder-bynamehint', 'Sort variations in alphabetical order');
  Add('varorder-byindex', 'Default order');
  Add('varorder-byindexhint', 'Restore the default variation order in Transform Editor');
  Add('varorder-noselected', 'Active variation not found. Please, select the variation to move.');
  Add('formula-wrongargscount', 'Invalid number of arguments to %s: expected %d, received %d.');
  Add('formula-wrongdatatype', 'The parameter must be a number.');
  Add('formula-outofrange', 'The value must be in range [-1, 1].');
  Add('formula-unsigned', 'The value must be positive.');
  Add('formula-cannotevaluate', 'Cannot evaluate the mathematical expression.');
  Add('animate-title', 'Animate flame');
  Add('animate-general', 'General');
  Add('animate-animation', 'Animation');  
  Add('animate-output', 'Output settings'); 
  Add('animate-duration', 'Duration');
  Add('animate-fps', 'Frames per second'); 
  Add('animate-parameters', 'Animation parameters');
  Add('animate-outflame', 'Output flame file'); 
  Add('animate-prefix', 'Name prefix');
  Add('animate-frame', 'Frame');
  Add('animate-preview', 'Animation preview');
  Add('animate-save', 'Save');
  Add('animate-stop', 'Stop');
  Add('animate-playhint', 'Play animation');
  Add('animate-stophint', 'Stop current animation');
  Add('animate-type', 'Animation type');
  Add('animate-showframes', 'Show generated frames');
  Add('animate-currentflame', ' (Current flame)');
  Add('animate-status-generating', 'Generating frame %d of %d...');
  Add('animate-status-finished', 'Frame generation finished.');
  Add('animate-status-changeflame', 'Initial and final frames must be different.');
  Add('animate-status-stopped', 'Frame generation is interrupted.');
  Add('animate-kind-rotateflame', 'Rotate flame');
  Add('animate-kind-rotatereference', 'Rotate reference triangle');
  Add('animate-kind-rotatehue', 'Change gradient hue');
  Add('animate-kind-rotatepalette', 'Rotate color gradient');
  Add('animate-kind-rotatecamera', 'Rotate 3D camera');
  Add('animate-kind-morph1', 'Morphing (interpolation: cosine, RGB)');
  Add('animate-kind-morph2', 'Morphing (interpolation: cosine, HSV)');
  Add('animate-kind-morph3', 'Morphing (interpolation: linear, RGB)');
  Add('animate-kind-morph4', 'Morphing (interpolation: linear, HSV)');
  Add('animate-render', 'Render all frames after generation');
  Add('animate-resetlocation', 'Calculate flame location for each frame');
  Add('animate-graphicext', 'Graphic extension');
  Add('animate-initflame', 'Initial flame');
  Add('animate-finalflame', 'Initial flame');
  Add('animate-savehint', 'Save all animated frames to hard disk');
  Add('animate-invertbg', 'Invert background color');
end;

procedure Add(key, value: string);
var entry : TKeyValuePair;
begin
  Inc(tokenCount);
  SetLength(language, tokenCount);
  SetLength(defaultlanguage, tokenCount);
  entry := TKeyValuePair.Create;
  entry.key := key;
  entry.value := value;
  language[tokenCount - 1] := entry;
  defaultlanguage[tokenCount - 1] := entry;
end;

procedure AddNoDefault(key, value: string);
var entry : TKeyValuePair;
begin
  Inc(tokenCount);
  SetLength(language, tokenCount);
  entry := TKeyValuePair.Create;
  entry.key := key;
  entry.value := value;
  language[tokenCount - 1] := entry;
end;

procedure LoadLanguage(path: string);
begin
  if (path = '') or (not FileExists(path)) then LoadEnglish()
  else begin
    tokenCount := 0;
    if true then begin
      parser := TParser.Create;
      ListXmlScanner := TEasyXmlScanner.Create(nil);

      ListXmlScanner.OnStartTag := parser.ListXmlScannerStartTag;
      ListXmlScanner.OnEndTag := parser.ListXmlScannerEndTag;
      ListXmlScanner.OnEmptyTag := parser.ListXmlScannerEmptyTag;
      ListXmlScanner.OnContent := parser.ListXmlScannerContent;

      ListXmlScanner.Filename := path;
      ListXmlScanner.Execute;

      ListXmlScanner.Destroy;
      parser.Destroy;
    end;
  end;
end;

function TextByKey(key:string):string;
var i: integer;
begin

  Result := '#ERR_NO_TEXT#';
  for i:=0 to tokenCount - 1 do begin
    if LowerCase(language[i].key) = LowerCase(key) then begin
      Result := language[i].value;
      exit;
    end;
  end;

  // maybe try default language?
  for i:=0 to tokenCount - 1 do begin
    if LowerCase(defaultlanguage[i].key) = LowerCase(key) then begin
      Result := defaultlanguage[i].value;
      exit;
    end;
  end;

end;

constructor TParser.Create;
begin
  self.parentTagnames := TStringList.Create;
end;

procedure TParser.ListXmlScannerStartTag(Sender: TObject; TagName: string; Attributes: TAttrList);
begin
  self.parentTagnames.Add(self.currentTagname);
  self.currentTagname := TagName;
end;

procedure TParser.ListXmlScannerEndTag(Sender: TObject; TagName: string);
var lastIndex : integer;
begin
  lastIndex := self.parentTagnames.Count - 1;
  self.currentTagname := self.parentTagnames.Strings[lastIndex];
  self.parentTagnames.Delete(lastIndex);
end;

procedure TParser.ListXmlScannerEmptyTag(Sender: TObject; TagName: string; Attributes: TAttrList);
var lastIndex : integer;
begin
  self.parentTagnames.Add(self.currentTagname);
  self.currentTagname := TagName;
  self.ListXmlScannerContent(Sender, '');
  lastIndex := self.parentTagnames.Count - 1;
  self.currentTagname := self.parentTagnames.Strings[lastIndex];
  self.parentTagnames.Delete(lastIndex);
end;

destructor TParser.Destroy;
begin
  self.parentTagnames.Free;  // AV: fixed memory leak
  inherited;
end;

procedure TParser.ListXmlScannerContent(Sender: TObject; Content: string);
const root: string = 'stringtable';
var key, tn: string; i: integer;
begin
  for i := 0 to self.parentTagnames.Count - 1 do begin
    tn := self.parentTagnames.Strings[i];
    if not (tn = '') and not (tn = root) then key := key + tn + '-';
  end;
  key := key + self.currentTagname;
  Add(key, Content);
end;

end.
