Page 9 of 24

Posted: Sun Jan 16, 2011 7:03 pm
by KDJ
Sorts lines according to two keys: by line length and by string, alphabetically or numerically.
Removes duplicate lines.
Reverses the order of lines.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=10988#p10988
// Version: 2019-07-01
// Author: KDJ
//
// *** Sort lines ***
//
// Sort lines according to two keys: by line length and by string, alphabetically or numerically; removes duplicate lines, reverses the order of lines
//
// Usage:
//   Call("Scripts::Main", 1, "SortLines.js")
//
// Shortcut keys in dialog box:
//   Enter - Sort
//   Esc   - Close
//   Shift+Alt+Right (Left, Down, Up, End, Home, PgDn, PgUp) - move dialog box.

if (AkelPad.GetLangId(0 /*LANGID_FULL*/) == 0x0415) //Polish
{
  var sTxtCaption   = "Sortowanie wierszy";
  var sTxtRange     = "Zakres";
  var sTxtFrom      = "Od";
  var sTxtTo        = "Do";
  var sTxtLines     = "Wiersze:";
  var sTxtColumns   = "&Kolumny:";
  var sTxtKeys      = "Klucze sortowania";
  var sTxtKey1      = "Klucz &1 - Długość wiersza";
  var sTxtKey2      = "Klucz &2 - Zawartość wiersza";
  var sTxtRTL       = "Czytaj od prawej do lewej";
  var sTxtEntLine   = "Cały &wiersz";
  var sTxtDesc      = "&Malejąco";
  var sTxtIgCase    = "&Ignoruj wlk. liter";
  var sTxtString    = "&String";
  var sTxtLocale    = "&Alfabetycznie";
  var sTxtNum       = "&Numerycznie";
  var sTxtSortAnd   = "Sortuj, a następnie";
  var sTxtRemoDuKey = "&Usuń wiersze z duplikatami kluczy";
  var sTxtExtrDuKey = "&Zachowaj tylko wiersze z duplikatami kluczy";
  var sTxtExtrUnKey = "Zac&howaj tylko wiersze z unikalnymi kluczami";
  var sTxtNoSort    = "Nie sortuj, ale";
  var sTxtReverse   = "&Odwróć kolejność wierszy";
  var sTxtCopyToCB  = "Wynik kopiuj do schowka, nie zmieniaj &tekstu";
  var sTxtUsePlug   = "Użyj wtyczki &Format";
  var sTxtSort      = "Sortuj";
  var sTxtUndo      = "&Cofnij"; 
  var sTxtRedo      = "&Powtórz";
  var sTxtNoRangeL  = "Brak zakresu wierszy.";
  var sTxtNoKey2    = "Brak zakresu kolumn w drugim kluczu sortowania.";
}
else if (AkelPad.GetLangId(0 /*LANGID_FULL*/) == 0x0419) //Russian translation by AZJIO
{
  var sTxtCaption   = "Сортировка строк";
  var sTxtRange     = "Диапазон строк";
  var sTxtFrom      = "От";
  var sTxtTo        = "До";
  var sTxtLines     = "Строки:";
  var sTxtColumns   = "&Колонки:";
  var sTxtKeys      = "Сортировать по ключам";
  var sTxtKey1      = "Ключ &1 - По длине строки";
  var sTxtKey2      = "Ключ &2 - По содержимому";
  var sTxtRTL       = "Читать справа налево";
  var sTxtEntLine   = "Вычислять всю &строку";
  var sTxtDesc      = "&По убыванию";
  var sTxtIgCase    = "&Игнор регистр";
  var sTxtString    = "&Строка";
  var sTxtLocale    = "&По алфавиту";
  var sTxtNum       = "&По номерам";
  var sTxtSortAnd   = "Сортировать, и далее:";
  var sTxtRemoDuKey = "&Удалить строки с дубль-ключами";
  var sTxtExtrDuKey = "&Оставить строки только с дубль-ключами";
  var sTxtExtrUnKey = "Оставить строки с уникальными ключами";
  var sTxtNoSort    = "Не сортировать, но:";
  var sTxtReverse   = "&Обратный порядок строк";
  var sTxtCopyToCB  = "Результат в буфер обмена, не изменяя документ";
  var sTxtUsePlug   = "Использовать плагин &Format";
  var sTxtSort      = "Сортировать";
  var sTxtUndo      = "&Отменить";
  var sTxtRedo      = "&Вернуть";
  var sTxtNoRangeL  = "Нет диапазона строк.";
  var sTxtNoKey2    = "Нет диапазона колонок во 2-м ключе сортировки.";
}
else
{
  var sTxtCaption   = "Sort lines";
  var sTxtRange     = "Range";
  var sTxtFrom      = "From";
  var sTxtTo        = "To";
  var sTxtLines     = "Lines:";
  var sTxtColumns   = "&Columns:";
  var sTxtKeys      = "Keys";
  var sTxtKey1      = "Key &1 - Line length";
  var sTxtKey2      = "Key &2 - Line content";
  var sTxtRTL       = "Read from right to left";
  var sTxtEntLine   = "&Entire line";
  var sTxtDesc      = "&Descending";
  var sTxtIgCase    = "&Ignore case";
  var sTxtString    = "&String";
  var sTxtLocale    = "&Alphabetically";
  var sTxtNum       = "&Numerically";
  var sTxtSortAnd   = "Sort, and also";
  var sTxtRemoDuKey = "Re&move lines with duplicate keys";
  var sTxtExtrDuKey = "E&xtract lines with duplicate keys";
  var sTxtExtrUnKey = "Extra&ct lines with unique keys";
  var sTxtNoSort    = "Not sort, but";
  var sTxtReverse   = "Reverse &order of lines";
  var sTxtCopyToCB  = "Resul&t copy to clipboard, do not replace text";
  var sTxtUsePlug   = "Use &Format plugin";
  var sTxtSort      = "Sort";
  var sTxtUndo      = "&Undo";
  var sTxtRedo      = "&Redo";
  var sTxtNoRangeL  = "There is no range of lines.";
  var sTxtNoKey2    = "There is no range of columns in second key.";
}

var DT_DWORD    = 3;
var BM_SETCHECK = 241;

var oSys       = AkelPad.SystemFunction();
var hMainWnd   = AkelPad.GetMainWnd();
var hEditWnd   = AkelPad.GetEditWnd();
var hGuiFont   = oSys.Call("Gdi32::GetStockObject", 17 /*DEFAULT_GUI_FONT*/);
var hInstDLL   = AkelPad.GetInstanceDll();
var sClassName = "AkelPad::Scripts::" + WScript.ScriptName + "::" + hInstDLL;
var bKey1      = 0;
var bDescLen   = 0;
var bKey2      = 1;
var bRTL       = 0;
var bEntLine   = 0;
var bDesc      = 0;
var bIgCase    = 1;
var nMethod    = 1;
var nSortAnd   = 0;
var nNoSort    = 0;
var bCopyToCB  = 0;
var bUsePlug   = 0;
var nUndoLimit = 0;
var nRedoLimit = 0;
var nWordWrap;
var nLastCol;
var hWndDlg;
var lpBuffer;
var bGetSel;
var bIsReturn;
var hFocus;
var nWndPosX;
var nWndPosY;

ReadWriteIni(0);

var aWnd        = [];
var IDRANGE     = 1000;
var IDFROM      = 1001;
var IDTO        = 1002;
var IDLINES     = 1003;
var IDBEGLINE   = 1004;
var IDENDLINE   = 1005;
var IDSORT1     = 1006;
var IDKEY1      = 1007;
var IDDESCLEN   = 1008;
var IDSORT2     = 1009;
var IDKEY2      = 1010;
var IDRTL       = 1011;
var IDENTLINE   = 1012;
var IDFROM2     = 1013;
var IDTO2       = 1014;
var IDCOLUMNS   = 1015;
var IDBEGCOL    = 1016;
var IDENDCOL    = 1017;
var IDDESC      = 1018;
var IDIGCASE    = 1019;
var IDSORT3     = 1020;
var IDSTRING    = 1021;
var IDLOCALE    = 1022;
var IDNUM       = 1023;
var IDSORT4     = 1024;
var IDREMODUKEY = 1025;
var IDEXTRDUKEY = 1026;
var IDEXTRUNKEY = 1027;
var IDNOSORT    = 1028;
var IDREVERSE   = 1029;
var IDREMODULIN = 1030;
var IDEXTRDULIN = 1031;
var IDEXTRUNLIN = 1032;
var IDCOPYTOCB  = 1033;
var IDUSEPLUG   = 1034;
var IDSORT      = 1035;
var IDUNDO      = 1036;
var IDREDO      = 1037;

var CLASS   = 0;
var WND     = 1;
var EXSTYLE = 2;
var STYLE   = 3;
var X       = 4;
var Y       = 5;
var W       = 6;
var H       = 7;
var TXT     = 8;

//0x50000000 - WS_VISIBLE|WS_CHILD
//0x50000007 - WS_VISIBLE|WS_CHILD|BS_GROUPBOX
//0x50000009 - WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON
//0x50010000 - WS_VISIBLE|WS_CHILD|WS_TABSTOP
//0x50010003 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
//0x50012080 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL|ES_NUMBER
//Windows               CLASS, WND, EXSTYLE,      STYLE,   X,   Y,   W,   H, TXT
aWnd[IDRANGE    ] = ["BUTTON",   0,       0, 0x50000007,  10,  10, 185,  70, sTxtRange];
aWnd[IDFROM     ] = ["STATIC",   0,       0, 0x50000000,  70,  30,  55,  13, sTxtFrom];
aWnd[IDTO       ] = ["STATIC",   0,       0, 0x50000000, 130,  30,  55,  13, sTxtTo];
aWnd[IDLINES    ] = ["STATIC",   0,       0, 0x50000000,  20,  45,  50,  13, sTxtLines];
aWnd[IDBEGLINE  ] = ["STATIC",   0,   0x200, 0x50000000,  70,  45,  55,  20, ""];
aWnd[IDENDLINE  ] = ["STATIC",   0,   0x200, 0x50000000, 130,  45,  55,  20, ""];
aWnd[IDSORT1    ] = ["BUTTON",   0,       0, 0x50000007,  10,  90, 290,  52, sTxtKeys];
aWnd[IDKEY1     ] = ["BUTTON",   0,       0, 0x50010003,  20, 115, 150,  16, sTxtKey1];
aWnd[IDDESCLEN  ] = ["BUTTON",   0,       0, 0x50010003, 205, 115,  90,  16, sTxtDesc];
aWnd[IDSORT2    ] = ["BUTTON",   0,       0, 0x50000007,  10, 135, 290, 130, ""];
aWnd[IDKEY2     ] = ["BUTTON",   0,       0, 0x50010003,  20, 150, 150,  16, sTxtKey2];
aWnd[IDRTL      ] = ["BUTTON",   0,       0, 0x50010003,  40, 170, 140,  16, sTxtRTL];
aWnd[IDENTLINE  ] = ["BUTTON",   0,       0, 0x50010003,  40, 190, 140,  16, sTxtEntLine];
aWnd[IDFROM2    ] = ["STATIC",   0,       0, 0x50000000,  70, 215,  55,  13, sTxtFrom];
aWnd[IDTO2      ] = ["STATIC",   0,       0, 0x50000000, 130, 215,  55,  13, sTxtTo];
aWnd[IDCOLUMNS  ] = ["STATIC",   0,       0, 0x50000000,  20, 230,  50,  13, sTxtColumns];
aWnd[IDBEGCOL   ] = ["EDIT",     0,   0x200, 0x50012080,  70, 230,  55,  20, ""];
aWnd[IDENDCOL   ] = ["EDIT",     0,   0x200, 0x50012080, 130, 230,  55,  20, ""];
aWnd[IDDESC     ] = ["BUTTON",   0,       0, 0x50010003, 205, 150,  90,  16, sTxtDesc];
aWnd[IDIGCASE   ] = ["BUTTON",   0,       0, 0x50010003, 205, 170,  90,  16, sTxtIgCase];
aWnd[IDSORT3    ] = ["BUTTON",   0,       0, 0x50000007, 195, 185, 105,  80, ""];
aWnd[IDSTRING   ] = ["BUTTON",   0,       0, 0x50000009, 205, 200,  90,  16, sTxtString];
aWnd[IDLOCALE   ] = ["BUTTON",   0,       0, 0x50000009, 205, 220,  90,  16, sTxtLocale];
aWnd[IDNUM      ] = ["BUTTON",   0,       0, 0x50000009, 205, 240,  90,  16, sTxtNum];
aWnd[IDSORT4    ] = ["BUTTON",   0,       0, 0x50000007,  10, 275, 290,  85, sTxtSortAnd];
aWnd[IDREMODUKEY] = ["BUTTON",   0,       0, 0x50010003,  60, 295, 230,  16, sTxtRemoDuKey];
aWnd[IDEXTRDUKEY] = ["BUTTON",   0,       0, 0x50010003,  60, 315, 230,  16, sTxtExtrDuKey];
aWnd[IDEXTRUNKEY] = ["BUTTON",   0,       0, 0x50010003,  60, 335, 230,  16, sTxtExtrUnKey];
aWnd[IDNOSORT   ] = ["BUTTON",   0,       0, 0x50000007,  10, 370, 290, 105, sTxtNoSort];
aWnd[IDREVERSE  ] = ["BUTTON",   0,       0, 0x50010003,  60, 390, 230,  16, sTxtReverse];
aWnd[IDREMODULIN] = ["BUTTON",   0,       0, 0x50010003,  60, 410, 230,  16, sTxtRemoDuKey];
aWnd[IDEXTRDULIN] = ["BUTTON",   0,       0, 0x50010003,  60, 430, 230,  16, sTxtExtrDuKey];
aWnd[IDEXTRUNLIN] = ["BUTTON",   0,       0, 0x50010003,  60, 450, 230,  16, sTxtExtrUnKey];
aWnd[IDCOPYTOCB ] = ["BUTTON",   0,       0, 0x50010003,  20, 485, 270,  16, sTxtCopyToCB];
aWnd[IDUSEPLUG  ] = ["BUTTON",   0,       0, 0x50010003,  20, 505, 270,  16, sTxtUsePlug];
aWnd[IDSORT     ] = ["BUTTON",   0,       0, 0x50010000, 220,  10,  80,  23, sTxtSort];
aWnd[IDUNDO     ] = ["BUTTON",   0,       0, 0x50010000, 220,  35,  80,  23, sTxtUndo];
aWnd[IDREDO     ] = ["BUTTON",   0,       0, 0x50010000, 220,  60,  80,  23, sTxtRedo];

if (hEditWnd)
{
  nWordWrap = AkelPad.SendMessage(hEditWnd, 3241 /*AEM_GETWORDWRAP*/, 0, 0);
  if (nWordWrap > 0) AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);

  if (AkelPad.WindowRegisterClass(sClassName))
  {
    if (lpBuffer = AkelPad.MemAlloc(256 * _TSIZE))
    {
      hWndDlg = oSys.Call("User32::CreateWindowEx" + _TCHAR,
                  0,               //dwExStyle
                  sClassName,      //lpClassName
                  sTxtCaption,     //lpWindowName
                  0x90CA0000,      //WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX
                  0,               //x
                  0,               //y
                  315,             //nWidth
                  560,             //nHeight
                  hMainWnd,        //hWndParent
                  0,               //ID
                  hInstDLL,        //hInstance
                  DialogCallback); //Script function callback. To use it class must be registered by WindowRegisterClass.
      if (hWndDlg)
      {
        //Disable main window, to make dialog modal
        oSys.Call("User32::EnableWindow", hMainWnd, false);

        //Message loop
        AkelPad.WindowGetMessage();
      }
      AkelPad.MemFree(lpBuffer);
    }
    AkelPad.WindowUnregisterClass(sClassName);
  }

  if (nWordWrap > 0) AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);
}

function DialogCallback(hWnd, uMsg, wParam, lParam)
{
  var i, nLowParam;

  if (uMsg == 1) //WM_CREATE
  {
    for (i = 1000; i < aWnd.length; ++i)
    {
      aWnd[i][WND] = oSys.Call("User32::CreateWindowEx" + _TCHAR,
                       aWnd[i][EXSTYLE], //dwExStyle
                       aWnd[i][CLASS],   //lpClassName
                       0,                //lpWindowName
                       aWnd[i][STYLE],   //dwStyle
                       aWnd[i][X],       //x
                       aWnd[i][Y],       //y
                       aWnd[i][W],       //nWidth
                       aWnd[i][H],       //nHeight
                       hWnd,             //hWndParent
                       i,                //ID
                       hInstDLL,         //hInstance
                       0);               //lpParam
      SetWindowFontAndText(aWnd[i][WND], hGuiFont, aWnd[i][TXT]);
    }

    GetSelection();
    SetSelection();
    CheckButtons();
    CheckUndoRedo();

    //Set window position
    if ((nWndPosX == undefined) || (nWndPosY == undefined))
      MoveWindow(hMainWnd, hWnd, "RT");
    else
      MoveWindow(hMainWnd, hWnd, [nWndPosX, nWndPosY]);

    hFocus = aWnd[bUsePlug ? IDKEY2 : IDKEY1][WND];
  }

  else if ((uMsg == 6 /*WM_ACTIVATE*/) && (! wParam))
    hFocus = oSys.Call("User32::GetFocus");

  else if (uMsg == 7) //WM_SETFOCUS
    oSys.Call("User32::SetFocus", hFocus);

  else if (uMsg == 256) //WM_KEYDOWN
  {
    if (wParam == 27) //VK_ESCAPE
      oSys.Call("User32::PostMessage" + _TCHAR, hWndDlg, 16 /*WM_CLOSE*/, 0, 0);
    else if (wParam == 13) //VK_RETURN
    {
      if (! bIsReturn)
      {
        hFocus = oSys.Call("User32::GetFocus");
        if ((hFocus != aWnd[IDSORT][WND]) && (hFocus != aWnd[IDUNDO][WND]) && (hFocus != aWnd[IDREDO][WND]))
          oSys.Call("User32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDSORT, 0);
      }
    }
  }

  else if (uMsg == 257) //WM_KEYUP
    bIsReturn = 0;

  else if ((uMsg == 260) /*WM_SYSKEYDOWN*/ &&
           (oSys.Call("User32::GetAsyncKeyState", 0xA0 /*VK_LSHIFT*/)))
  {
    if (wParam == 0x27) //VK_RIGHT
      MoveWindow(hMainWnd, hWnd, "R");
    else if (wParam == 0x25) //VK_LEFT
      MoveWindow(hMainWnd, hWnd, "L");
    else if (wParam == 0x28) //VK_DOWN
      MoveWindow(hMainWnd, hWnd, "D");
    else if (wParam == 0x26) //VK_UP
      MoveWindow(hMainWnd, hWnd, "U");
    else if (wParam == 0x23) //VK_END
      MoveWindow(hMainWnd, hWnd, "E");
    else if (wParam == 0x24) //VK_HOME
      MoveWindow(hMainWnd, hWnd, "H");
    else if (wParam == 0x22) //VK_NEXT
      MoveWindow(hMainWnd, hWnd, "B");
    else if (wParam == 0x21) //VK_PRIOR
      MoveWindow(hMainWnd, hWnd, "T");
  }

  else if (uMsg == 273) //WM_COMMAND
  {
    nLowParam = LoWord(wParam);

    if ((nLowParam == IDBEGCOL) || (nLowParam == IDENDCOL))
    {
      CheckEditValue(nLowParam);
      if (bGetSel)
        SetSelection();
    }

    else if (((nLowParam >= IDKEY1) && (nLowParam <= IDENTLINE)) || ((nLowParam >= IDDESC) && (nLowParam <= IDUSEPLUG)))
      CheckButtons(nLowParam);

    else if (nLowParam == IDSORT)
    {
      if (SortLines())
      {
        CheckUndoRedo(nLowParam);
        GetSelection();
      }
    }

    else if (nLowParam == IDUNDO)
    {
      bIsReturn = 1;
      CheckUndoRedo(nLowParam);
      GetSelection();
    }

    else if (nLowParam == IDREDO)
    {
      bIsReturn = 1;
      CheckUndoRedo(nLowParam);
      GetSelection();
    }
  }

  else if (uMsg == 16) //WM_CLOSE
  {
    ReadWriteIni(1);

    //Enable main window
    oSys.Call("User32::EnableWindow", hMainWnd, true);
    //Destroy dialog
    oSys.Call("User32::DestroyWindow", hWnd);
  }

  else if (uMsg == 2) //WM_DESTROY
    oSys.Call("User32::PostQuitMessage", 0);

  else
    SetDefID(hWnd);

  return 0;
}

function SetWindowFontAndText(hWnd, hFont, sText)
{
  AkelPad.SendMessage(hWnd, 48 /*WM_SETFONT*/, hFont, true);
  oSys.Call("User32::SetWindowText" + _TCHAR, hWnd, sText);
}

function MoveWindow(hWndParent, hWnd, vAction)
{
  var aRectParent;
  var aRect;
  var nX;
  var nY;

  if (! hWndParent)
    hWndParent=oSys.Call("User32::GetDesktopWindow");

  aRectParent = GetWindowPos(hWndParent);
  aRect       = GetWindowPos(hWnd);

  nX = aRect.left;
  nY = aRect.top;

  if (vAction == "R") //Move right
    nX = aRect.left + ((aRect.left < aRectParent.right - 50) ? 20 : 0);
  else if (vAction == "L") //Move left
    nX = aRect.left - ((aRect.right > aRectParent.left + 50) ? 20 : 0);
  else if (vAction == "D") //Move down
    nY = aRect.top + ((aRect.top < aRectParent.bottom - 50) ? 20 : 0);
  else if (vAction == "U") //Move up
    nY = aRect.top - ((aRect.bottom > aRectParent.top + 50) ? 20 : 0);
  else if (vAction == "E") //Move end (right)
    nX = aRect.left + (aRectParent.right - aRect.right);
  else if (vAction == "H") //Move home (left)
    nX = aRect.left + (aRectParent.left - aRect.left);
  else if (vAction == "B") //Move bottom
    nY = aRect.top + (aRectParent.bottom - aRect.bottom);
  else if (vAction == "T") //Move top
    nY = aRect.top + (aRectParent.top - aRect.top);
  else if (vAction == "C") //Center window
  {
    nX = aRectParent.left + ((aRectParent.right  - aRectParent.left) / 2 - (aRect.right  - aRect.left) / 2);
    nY = aRectParent.top  + ((aRectParent.bottom - aRectParent.top)  / 2 - (aRect.bottom - aRect.top)  / 2);
  }
  else if (vAction == "LT") //Move left top
  {
    nX = aRectParent.left;
    nY = aRectParent.top;
  }
  else if (vAction == "RT") //Move right top
  {
    nX = aRect.left + (aRectParent.right - aRect.right);
    nY = aRectParent.top;
  }
  else if (vAction == "LB") //Move left bottom
  {
    nX = aRectParent.left;
    nY = aRect.top + (aRectParent.bottom - aRect.bottom);
  }
  else if (vAction == "RB") //Move right bottom
  {
    nX = aRect.left + (aRectParent.right - aRect.right);
    nY = aRect.top + (aRectParent.bottom - aRect.bottom);
  }
  else
  {
    nX = vAction[0];
    nY = vAction[1];
  }

  oSys.Call("User32::SetWindowPos", hWnd, 0, nX, nY, 0, 0, 0x15 /*SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE*/);
}

function GetWindowPos(hWnd)
{
  var lpRect = AkelPad.MemAlloc(16) //sizeof(RECT);
  var aRect  = [];

  oSys.Call("User32::GetWindowRect", hWnd, lpRect);

  aRect.left   = AkelPad.MemRead(_PtrAdd(lpRect,  0), DT_DWORD);
  aRect.top    = AkelPad.MemRead(_PtrAdd(lpRect,  4), DT_DWORD);
  aRect.right  = AkelPad.MemRead(_PtrAdd(lpRect,  8), DT_DWORD);
  aRect.bottom = AkelPad.MemRead(_PtrAdd(lpRect, 12), DT_DWORD);
  AkelPad.MemFree(lpRect);

  return aRect;
}

function LoWord(nParam)
{
  return (nParam & 0xFFFF);
}

function SetDefID(hWnd)
{
  var nID    = 1000;
  var hFocus = oSys.Call("User32::GetFocus");

  while ((nID < aWnd.length) && (hFocus != aWnd[nID][WND]))
    ++nID;

  if ((nID != IDUNDO) && (nID != IDREDO))
    nID = IDSORT;

  oSys.Call("User32::DefDlgProc" + _TCHAR, hWnd, 1025 /*DM_SETDEFID*/, nID, 0);
}

function ReadWriteIni(bWrite)
{
  var oFSO     = new ActiveXObject("Scripting.FileSystemObject");
  var sIniName = WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf(".")) + ".ini";
  var aRect;
  var oFile;
  var sIniTxt;

  if (bWrite)
  {
    aRect = GetWindowPos(hWndDlg);
    sIniTxt =
      'nWndPosX='  + aRect.left + ';\r\n' +
      'nWndPosY='  + aRect.top  + ';\r\n' +
      'bKey1='     + bKey1 + ';\r\n' +
      'bDescLen='  + bDescLen + ';\r\n' +
      'bKey2='     + bKey2 + ';\r\n' +
      'bRTL='      + bRTL + ';\r\n' +
      'bEntLine='  + bEntLine + ';\r\n' +
      'bDesc='     + bDesc + ';\r\n' +
      'bIgCase='   + bIgCase + ';\r\n' +
      'nMethod='   + nMethod + ';\r\n' +
      'nSortAnd='  + nSortAnd + ';\r\n' +
      'nNoSort='   + nNoSort + ';\r\n' +
      'bCopyToCB=' + bCopyToCB + ';\r\n' +
      'bUsePlug='  + bUsePlug + ';'

    oFile = oFSO.OpenTextFile(sIniName, 2, true, 0);
    oFile.Write(sIniTxt);
    oFile.Close();
  }

  else if (oFSO.FileExists(sIniName))
  {
    try
    {
      eval(AkelPad.ReadFile(sIniName));
    }
    catch (oError)
    {}
  }
}

function CheckButtons(nButton)
{
  if ((nButton == IDKEY1) && ((! bKey1) || bKey2))
    bKey1 = ! bKey1;
  else if (nButton == IDDESCLEN)
    bDescLen = ! bDescLen;
  else if ((nButton == IDKEY2) && ((! bKey2) || bKey1))
    bKey2 = ! bKey2;
  else if (nButton == IDRTL)
    bRTL = ! bRTL;
  else if (nButton == IDENTLINE)
    bEntLine = ! bEntLine;
  else if (nButton == IDDESC)
    bDesc = ! bDesc;
  else if (nButton == IDIGCASE)
    bIgCase = ! bIgCase;
  else if ((nButton == IDSTRING) || (nButton == IDLOCALE) || (nButton == IDNUM))
    nMethod = nButton - IDSTRING + 1;
  else if ((nButton == IDREMODUKEY) || (nButton == IDEXTRDUKEY) || (nButton == IDEXTRUNKEY))
  {
    if (nSortAnd == nButton - IDREMODUKEY + 1)
      nSortAnd = 0;
    else
      nSortAnd = nButton - IDREMODUKEY + 1;
  }
  else if ((nButton == IDREVERSE) || (nButton == IDREMODULIN) || (nButton == IDEXTRDULIN) || (nButton == IDEXTRUNLIN))
  {
    if (nNoSort == nButton - IDREVERSE + 1)
      nNoSort = 0;
    else
      nNoSort = nButton - IDREVERSE + 1;
  }
  else if (nButton == IDCOPYTOCB)
    bCopyToCB = ! bCopyToCB;
  else if (nButton == IDUSEPLUG)
    bUsePlug = ! bUsePlug;

  if ((bUsePlug) && ((nNoSort > 1) || (nMethod == 2)))
    nMethod = 1;

  AkelPad.SendMessage(aWnd[IDKEY1][WND],      BM_SETCHECK, bKey1,           0);
  AkelPad.SendMessage(aWnd[IDDESCLEN][WND],   BM_SETCHECK, bDescLen,        0);
  AkelPad.SendMessage(aWnd[IDKEY2][WND],      BM_SETCHECK, bKey2,           0);
  AkelPad.SendMessage(aWnd[IDRTL][WND],       BM_SETCHECK, bRTL,            0);
  AkelPad.SendMessage(aWnd[IDENTLINE][WND],   BM_SETCHECK, bEntLine,        0);
  AkelPad.SendMessage(aWnd[IDDESC][WND],      BM_SETCHECK, bDesc,           0);
  AkelPad.SendMessage(aWnd[IDIGCASE][WND],    BM_SETCHECK, bIgCase,         0);
  AkelPad.SendMessage(aWnd[IDSTRING][WND],    BM_SETCHECK, (nMethod == 1),  0);
  AkelPad.SendMessage(aWnd[IDLOCALE][WND],    BM_SETCHECK, (nMethod == 2),  0);
  AkelPad.SendMessage(aWnd[IDNUM][WND],       BM_SETCHECK, (nMethod == 3),  0);
  AkelPad.SendMessage(aWnd[IDREMODUKEY][WND], BM_SETCHECK, (nSortAnd == 1), 0);
  AkelPad.SendMessage(aWnd[IDEXTRDUKEY][WND], BM_SETCHECK, (nSortAnd == 2), 0);
  AkelPad.SendMessage(aWnd[IDEXTRUNKEY][WND], BM_SETCHECK, (nSortAnd == 3), 0);
  AkelPad.SendMessage(aWnd[IDREVERSE][WND],   BM_SETCHECK, (nNoSort == 1),  0);
  AkelPad.SendMessage(aWnd[IDREMODULIN][WND], BM_SETCHECK, (nNoSort == 2),  0);
  AkelPad.SendMessage(aWnd[IDEXTRDULIN][WND], BM_SETCHECK, (nNoSort == 3),  0);
  AkelPad.SendMessage(aWnd[IDEXTRUNLIN][WND], BM_SETCHECK, (nNoSort == 4),  0);
  AkelPad.SendMessage(aWnd[IDCOPYTOCB][WND],  BM_SETCHECK, bCopyToCB,       0);
  AkelPad.SendMessage(aWnd[IDUSEPLUG][WND],   BM_SETCHECK, bUsePlug,        0);

  oSys.Call("User32::EnableWindow", aWnd[IDKEY1][WND],      (nNoSort != 1) && (! bUsePlug));
  oSys.Call("User32::EnableWindow", aWnd[IDDESCLEN][WND],   (nNoSort == 0) && bKey1 && (! bUsePlug));
  oSys.Call("User32::EnableWindow", aWnd[IDKEY2][WND],      (nNoSort != 1));
  oSys.Call("User32::EnableWindow", aWnd[IDRTL][WND],       (nNoSort != 1) && bKey2 && (! bUsePlug));
  oSys.Call("User32::EnableWindow", aWnd[IDENTLINE][WND],   (nNoSort != 1) && bKey2);
  oSys.Call("User32::EnableWindow", aWnd[IDFROM2][WND],     (nNoSort != 1) && bKey2 && (! bEntLine));
  oSys.Call("User32::EnableWindow", aWnd[IDTO2][WND],       (nNoSort != 1) && bKey2 && (! bEntLine));
  oSys.Call("User32::EnableWindow", aWnd[IDCOLUMNS][WND],   (nNoSort != 1) && bKey2 && (! bEntLine));
  oSys.Call("User32::EnableWindow", aWnd[IDBEGCOL][WND],    (nNoSort != 1) && bKey2 && (! bEntLine));
  oSys.Call("User32::EnableWindow", aWnd[IDENDCOL][WND],    (nNoSort != 1) && bKey2 && (! bEntLine));
  oSys.Call("User32::EnableWindow", aWnd[IDDESC][WND],      (nNoSort == 0) && bKey2);
  oSys.Call("User32::EnableWindow", aWnd[IDIGCASE][WND],    (nNoSort != 1) && bKey2 && ((nMethod != 3) || bUsePlug));
  oSys.Call("User32::EnableWindow", aWnd[IDSTRING][WND],    (nNoSort != 1) && bKey2);
  oSys.Call("User32::EnableWindow", aWnd[IDLOCALE][WND],    (nNoSort != 1) && bKey2 && (! bUsePlug));
  oSys.Call("User32::EnableWindow", aWnd[IDNUM][WND],       (nNoSort != 1) && bKey2 && (! (bUsePlug && (nNoSort > 1))));
  oSys.Call("User32::EnableWindow", aWnd[IDREMODUKEY][WND], (nNoSort == 0) && (! bUsePlug));
  oSys.Call("User32::EnableWindow", aWnd[IDEXTRDUKEY][WND], (nNoSort == 0) && (! bUsePlug));
  oSys.Call("User32::EnableWindow", aWnd[IDEXTRUNKEY][WND], (nNoSort == 0) && (! bUsePlug));
  oSys.Call("User32::EnableWindow", aWnd[IDCOPYTOCB][WND],  (! bUsePlug));
}

function CheckUndoRedo(nButton)
{
  var nBegSel  = AkelPad.GetSelStart();
  var sTxtUndo = aWnd[IDUNDO][TXT];
  var sTxtRedo = aWnd[IDREDO][TXT];

  if (nButton == IDSORT)
  {
    if (nUndoLimit < AkelPad.SendMessage(hEditWnd, 3084 /*AEM_GETUNDOLIMIT*/, 0, 0))
      ++nUndoLimit;
    nRedoLimit = 0;
  }
  else if ((nButton == IDUNDO) && (nUndoLimit))
  {
    --nUndoLimit;
    ++nRedoLimit;
    AkelPad.SendMessage(hEditWnd, 3077 /*AEM_UNDO*/, 0, 0);
  }
  else if ((nButton == IDREDO) && (nRedoLimit))
  {
    ++nUndoLimit;
    --nRedoLimit;
    AkelPad.SendMessage(hEditWnd, 3078 /*AEM_REDO*/, 0, 0);
    AkelPad.SetSel(nBegSel, AkelPad.GetSelEnd());
  }

  if (nUndoLimit)
    sTxtUndo += " (" + nUndoLimit + ")";
  if (nRedoLimit)
    sTxtRedo += " (" + nRedoLimit + ")";

  if (((oSys.Call("User32::GetFocus") == aWnd[IDUNDO][WND]) && (nUndoLimit == 0)) ||
      ((oSys.Call("User32::GetFocus") == aWnd[IDREDO][WND]) && (nRedoLimit == 0)))
    oSys.Call("User32::SetFocus", aWnd[IDKEY1][WND]);

  SetWindowFontAndText(aWnd[IDUNDO][WND], hGuiFont, sTxtUndo);
  SetWindowFontAndText(aWnd[IDREDO][WND], hGuiFont, sTxtRedo);

  oSys.Call("User32::EnableWindow", aWnd[IDUNDO][WND], nUndoLimit);
  oSys.Call("User32::EnableWindow", aWnd[IDREDO][WND], nRedoLimit);
}

function CheckEditValue(nID)
{
  var sEditValue;

  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[nID][WND], lpBuffer, 256);
  sEditValue = AkelPad.MemRead(lpBuffer, _TSTR);

  if (sEditValue == 0)
  {
    SetWindowFontAndText(aWnd[nID][WND], hGuiFont, "1");
    AkelPad.SendMessage(aWnd[nID][WND], 177 /*EM_SETSEL*/, 0, -1);
  }
  else if (sEditValue > nLastCol)
  {
    SetWindowFontAndText(aWnd[nID][WND], hGuiFont, String(nLastCol));
    AkelPad.SendMessage(aWnd[nID][WND], 177 /*EM_SETSEL*/, 0, -1);
  }
}

function GetSelection()
{
  var lpBegSel = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/);
  var lpEndSel = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/);
  var nLine1, nLine2, nCol1, nCol2;

  AkelPad.SendMessage(hEditWnd, 3123 /*AEM_EXGETSEL*/, lpBegSel, lpEndSel);

  nLine1 = AkelPad.MemRead(lpBegSel, DT_DWORD) + 1;
  nLine2 = AkelPad.MemRead(lpEndSel, DT_DWORD) + 1;

  if ((nLine1 == nLine2) && (! bGetSel))
  {
    nLine1 = 1;
    nLine2 = AkelPad.SendMessage(hEditWnd, 3129 /*AEM_GETLINENUMBER*/, 0 /*AEGL_LINECOUNT*/, 0);
  }

  nLastCol = LineMaxLength(nLine1, nLine2) + 1;
  SetWindowFontAndText(aWnd[IDBEGLINE][WND], hGuiFont, String(nLine1));
  SetWindowFontAndText(aWnd[IDENDLINE][WND], hGuiFont, String(nLine2));

  if (! bGetSel)
  {
    if (AkelPad.MemRead(_PtrAdd(lpBegSel, _X64 ? 16 : 8), DT_DWORD) < AkelPad.MemRead(_PtrAdd(lpEndSel, _X64 ? 16 : 8), DT_DWORD))
    {
      nCol1 = AkelPad.MemRead(_PtrAdd(lpBegSel, _X64 ? 16 : 8), DT_DWORD) + 1;
      nCol2 = AkelPad.MemRead(_PtrAdd(lpEndSel, _X64 ? 16 : 8), DT_DWORD) + 1;
    }
    else
    {
      nCol1 = AkelPad.MemRead(_PtrAdd(lpEndSel, _X64 ? 16 : 8), DT_DWORD) + 1;
      nCol2 = AkelPad.MemRead(_PtrAdd(lpBegSel, _X64 ? 16 : 8), DT_DWORD) + 1;
    }
  
    if (nCol1 > nLastCol)
      nCol1 = nLastCol;
    if (nCol2 > nLastCol)
      nCol2 = nLastCol;

    SetWindowFontAndText(aWnd[IDBEGCOL][WND],  hGuiFont, String(nCol1));
    SetWindowFontAndText(aWnd[IDENDCOL][WND],  hGuiFont, String(nCol2));

    //removed (2018-02-01)
    //bEntLine = ! AkelPad.SendMessage(hEditWnd, 3127 /*AEM_GETCOLUMNSEL*/, 0, 0);
  }

  AkelPad.MemFree(lpBegSel);
  AkelPad.MemFree(lpEndSel);
  bGetSel = 1;
}

function LineMaxLength(nLine1, nLine2)
{
  var nMaxLenL = 0;
  var nBegLine;
  var nLenLine;
  var i;

  for (i = nLine1 - 1; i < nLine2; ++i)
  {
    nBegLine = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, i, 0);
    nLenLine = AkelPad.SendMessage(hEditWnd, 193 /*EM_LINELENGTH*/, nBegLine, 0);
    if (nLenLine > nMaxLenL)
      nMaxLenL = nLenLine;
  }

  return nMaxLenL;
}

function SetSelection()
{
  var hFocus    = oSys.Call("User32::GetFocus");
  var lpSelect  = AkelPad.MemAlloc(_X64 ? 56 : 32 /*sizeof(AESELECTION)*/);
  var lpBegSel  = lpSelect;
  var lpEndSel  = _PtrAdd(lpSelect, _X64 ? 24 : 12);
  var lpSelFlag = _PtrAdd(lpSelect, _X64 ? 48 : 24);
  var nColSel   = 1;
  var nLine1, nLine2, nCol1, nCol2;

  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDBEGLINE][WND], lpBuffer, 256);
  nLine1 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDENDLINE][WND], lpBuffer, 256);
  nLine2 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;

  if ((hFocus == aWnd[IDBEGCOL][WND]) || (hFocus == aWnd[IDENDCOL][WND]))
  {
    oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDBEGCOL][WND], lpBuffer, 256);
    nCol1 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;
    oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDENDCOL][WND], lpBuffer, 256);
    nCol2 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;
  }
  else
  {
    nCol1   = 0;
    nCol2   = AkelPad.SendMessage(hEditWnd, 193 /*EM_LINELENGTH*/, AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine2, 0), 0);
    nColSel = 0;
  }

  AkelPad.MemCopy(lpBegSel, nLine1,  DT_DWORD);
  AkelPad.MemCopy(_PtrAdd(lpBegSel, _X64 ? 16 : 8), nCol1, DT_DWORD);
  AkelPad.MemCopy(lpEndSel, nLine2,  DT_DWORD);
  AkelPad.MemCopy(_PtrAdd(lpEndSel, _X64 ? 16 : 8), nCol2, DT_DWORD);
  AkelPad.MemCopy(lpSelFlag, nColSel, DT_DWORD);

  AkelPad.SendMessage(hEditWnd, 3132 /*AEM_INDEXUPDATE*/, 0, lpBegSel);
  AkelPad.SendMessage(hEditWnd, 3132 /*AEM_INDEXUPDATE*/, 0, lpEndSel);

  AkelPad.SendMessage(hEditWnd, 3126 /*AEM_SETSEL*/, 0, lpSelect);

  AkelPad.MemFree(lpSelect);
}

function SortLines()
{
  var aTxt  = [];
  var sText = "";
  var nLine1;
  var nLine2;
  var nCol1;
  var nCol2;
  var i;

  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDBEGLINE][WND], lpBuffer, 256);
  nLine1 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDENDLINE][WND], lpBuffer, 256);
  nLine2 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDBEGCOL][WND], lpBuffer, 256);
  nCol1 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDENDCOL][WND], lpBuffer, 256);
  nCol2 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;

  if (nLine1 == nLine2)
  {
    AkelPad.MessageBox(hWndDlg, sTxtNoRangeL, sTxtCaption, 48 /*MB_ICONEXCLAMATION*/);
    return 0;
  }

  if ((nCol1 == nCol2) && bKey2 && (! bEntLine) && (nNoSort != 1))
  {
    AkelPad.MessageBox(hWndDlg, sTxtNoKey2, sTxtCaption, 48 /*MB_ICONEXCLAMATION*/);
    oSys.Call("User32::SetFocus", aWnd[IDENDCOL][WND]);
    AkelPad.SendMessage(aWnd[IDENDCOL][WND], 177 /*EM_SETSEL*/, 0, -1);
    return 0;
  }

  hFocus = oSys.Call("User32::GetFocus");

  if (bUsePlug)
  {
    if (! bEntLine)
    {
      oSys.Call("User32::SetFocus", aWnd[IDENDCOL][WND]);
      SetSelection();
    }
    SortByPlugin();
    oSys.Call("User32::SetFocus", hFocus);
    return 1;
  }
  else
  {
    oSys.Call("User32::SetFocus", aWnd[IDSORT][WND]);
    SetSelection();

    if (nNoSort == 1)
    {
      aTxt  = AkelPad.GetSelText(1 /*\r*/).split("\r");
      sText = aTxt.reverse().join("\r");
    }
    else
    {
      aTxt[0] = AkelPad.GetSelText(1 /*\r*/).split("\r");

      if (bKey2)
      {
        if (bEntLine)
          aTxt[1] = AkelPad.GetSelText(1 /*\r*/).split("\r");
        else
          aTxt[1] = GetTextRangeColumn([nLine1, nCol1], [nLine2, nCol2]);

        if (bRTL)
        {
          for (i = 0; i < aTxt[1].length; ++i)
            aTxt[1][i] = aTxt[1][i].split("").reverse().join("");
        }
      }

      aTxt = ArrayTransp(aTxt);

      ArraySort(aTxt);

      for (i = 0; i < aTxt.length; ++i)
        sText += aTxt[i][0] + "\r";

      sText = sText.slice(0, -1);
    }

    if (bCopyToCB)
    {
      AkelPad.SetClipboardText(sText);
      oSys.Call("User32::SetFocus", hFocus);
      return 0;
    }
    else
    {
      AkelPad.ReplaceSel(sText, -1);
      oSys.Call("User32::SetFocus", hFocus);
      return 1;
    }
  }
}

function GetTextRangeColumn(aBeg, aEnd, bReturnText, nNewLine, bFillSpaces)
{
  var nBegLine1;
  var nBegLine2;
  var nLenLine2;
  var nLine1;
  var nLine2;
  var nCol1;
  var nCol2;
  var aLines;
  var nWidth;
  var i;

  if (aBeg[0] < aEnd[0])
  {
    nLine1 = aBeg[0];
    nLine2 = aEnd[0];
  }
  else
  {
    nLine1 = aEnd[0];
    nLine2 = aBeg[0];
  }

  if (aBeg[1] < aEnd[1])
  {
    nCol1 = aBeg[1];
    nCol2 = aEnd[1];
  }
  else
  {
    nCol1 = aEnd[1];
    nCol2 = aBeg[1];
  }

	nBegLine1 = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine1, 0);
	nBegLine2 = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine2, 0);
	nLenLine2 = AkelPad.SendMessage(hEditWnd, 193 /*EM_LINELENGTH*/, nBegLine2, 0);
  aLines    = AkelPad.GetTextRange(nBegLine1, nBegLine2 + nLenLine2, 1 /*"\r"*/).split("\r");
  nWidth    = nCol2 - nCol1;

  for (i = 0; i < aLines.length; ++i)
  {
    aLines[i] = aLines[i].substring(nCol1, nCol2);
    if (bFillSpaces)
      while (aLines[i].length < nWidth)
        aLines[i] += " ";
  }

  if (bReturnText)
  {
    if ((! nNewLine) || (nNewLine == 1))
      pNewLine = "\r";
    else if (nNewLine == 2)
      pNewLine = "\n";
    else
      pNewLine = "\r\n";

    return aLines.join(pNewLine);
  }
  else
    return aLines;
}

function ArrayTransp(aA)
{
  var nLen1 = aA.length;
  var nLen2 = aA[0].length;
  var aB    = new Array(nLen2);
  var i, n;

  for (n = 0; n < nLen2; ++n)
  {
    aB[n] = [];

    for (i = 0; i < nLen1; ++i)
      aB[n].push(aA[i][n]);
  }

  return aB;
}

function ArraySort(aTxt)
{
  if (nNoSort == 0)
  {
    aTxt.sort(CompareValue);
    RemoveFromArray(aTxt);
  }
  else
    NoSort(aTxt);
}

function CompareValue(aA, aB)
{
  var nResult = 0;

  if (bKey1)
  {
    if (aA[0].length > aB[0].length)
      nResult = bDescLen ? -1 : 1;
    else if (aA[0].length < aB[0].length)
      nResult = bDescLen ? 1 : -1;
  }

  if (bKey2 && (nResult == 0))
  {
    if (nMethod == 1)
    {
      if (bIgCase)
      {
        aA[1] = aA[1].toUpperCase();
        aB[1] = aB[1].toUpperCase();
      }
      if (aA[1] > aB[1])
        nResult = bDesc ? -1 : 1;
      else if (aA[1] < aB[1])
        nResult = bDesc ? 1 : -1;
    }
    else if (nMethod == 2)
    {
      nResult = oSys.Call("Kernel32::lstrcmp" + (bIgCase ? "i" : "") + _TCHAR, aA[1], aB[1]);
      if (bDesc)
        nResult = -nResult;
    }
    else
    {
      var oRegExp = /(-?\d+\.?\d*)|(-?\.\d+)/;
  
      aA[1] = oRegExp.exec(aA[1]);
      aB[1] = oRegExp.exec(aB[1]);
      aA[1] = aA[1] ? parseFloat(aA[1][0]) : 0;
      aB[1] = aB[1] ? parseFloat(aB[1][0]) : 0;
      nResult = bDesc ? (aB[1] - aA[1]) : (aA[1] - aB[1]);
    }
  }

  return nResult;
}

function RemoveFromArray(aTxt)
{
  var i;

  if (nSortAnd == 1)
  {
    for (i = aTxt.length - 1; i > 0; --i)
    {
      if (CompareValue(aTxt[i], aTxt[i - 1]) == 0)
        aTxt.splice(i, 1);
    }
  }
  else if (nSortAnd == 2)
  {
    for (i = aTxt.length - 2; i > 0; --i)
    {
      if ((CompareValue(aTxt[i], aTxt[i + 1]) != 0) && (CompareValue(aTxt[i], aTxt[i - 1]) != 0))
        aTxt.splice(i, 1);
    }
    if ((aTxt.length > 1) && (CompareValue(aTxt[aTxt.length - 1], aTxt[aTxt.length - 2]) != 0))
      aTxt.splice(aTxt.length - 1, 1);
    if ((aTxt.length > 1) && (CompareValue(aTxt[0], aTxt[1]) != 0))
      aTxt.splice(0, 1);
    if (aTxt.length == 1)
      aTxt.splice(0, 1);
  }
  else if (nSortAnd == 3)
  {
    i = aTxt.length - 1;
    while (i > 0)
    {
      if (CompareValue(aTxt[i], aTxt[i - 1]) == 0)
      {
        aTxt.splice(i - 1, 2);
        i -= 2;
      }
      else
        --i;
    }
  }
}

function NoSort(aTxt)
{
  var i, n, bIsDup;

  if (nNoSort == 2)
  {
    for (n = 0; n < aTxt.length; ++n)
    {
      i = n + 1;
      while (i < aTxt.length)
      {
        if (CompareValue(aTxt[i], aTxt[n]) == 0)
          aTxt.splice(i, 1);
        else
          ++i;
      }
    }
  }

  else if (nNoSort == 3)
  {
    n = 0;
    while (n < aTxt.length)
    {
      bIsDup = false;
      for (i = 0; i < aTxt.length; ++i)
      {
        if ((CompareValue(aTxt[i], aTxt[n]) == 0) && (i != n))
        {
          bIsDup = true;
          break;
        }
      }
      if (bIsDup)
        ++n;
      else
        aTxt.splice(n, 1);
    }
  }

  else if (nNoSort == 4)
  {
    n = 0;
    while (n < aTxt.length)
    {
      bIsDup = false;
      i = n + 1;
      while (i < aTxt.length)
      {
        if (CompareValue(aTxt[i], aTxt[n]) == 0)
        {
          bIsDup = true;
          aTxt.splice(i, 1);
        }
        else
          ++i;
      }
      if (bIsDup)
        aTxt.splice(n, 1);
      else
        ++n;
    }
  }
}

function SortByPlugin()
{
  var sAscDesc = bDesc ? "Desc" : "Asc";

  if (nNoSort == 1)
    AkelPad.Call("Format::LineReverse");
  else if (nNoSort == 2)
    AkelPad.Call("Format::LineRemoveDuplicates", ! bIgCase);
  else if (nNoSort == 3)
    AkelPad.Call("Format::LineGetDuplicates", ! bIgCase);
  else if (nNoSort == 4)
    AkelPad.Call("Format::LineGetUnique", ! bIgCase);
  else if (nMethod == 1)
    AkelPad.Call("Format::LineSortStr" + sAscDesc, ! bIgCase);
  else if (nMethod == 3)
    AkelPad.Call("Format::LineSortInt" + sAscDesc, ! bIgCase);
}


Posted: Mon Jan 17, 2011 10:39 pm
by Andrey_A_A

Code: Select all

' SwitchSplittedWindow.vbs
'========================   Описание   =====================================
' Переключение между позициями окна в заданной очерёдностью
'========================  Параметры =====================================
'В параметрах вызова скрипта должен быть прописан один параметр:
' 1 - Переключение горизонтальное --> вертикальное --> четыре части
' 2 - Переключение вертикальное --> горизонтальное --> четыре части
' 3 - Переключение горизонтальное --> четыре части -> вертикальное
' 4 - Переключение вертикальное --> четыре части --> горизонтальное
' 5 - Переключение четыре части --> вертикальное --> горизонтальное
' 6 - Переключение четыре части -- > горизонтальное --> вертикальное
'
' Call("Scripts::Main", 1, "SwitchSplittedWindow.vbs", `"2"`)
'
' Автор:           Аверин Андрей & VladSh
' Версия:          1.4 (2011.01.06 - 18.11.2011)
' Mail:            Averin-And@yandex.ru
' Site:            http://tc-image.3dn.ru/forum/9-412-1196-16-1333816090
' Site:            http://akelpad.sourceforge.net/forum/viewtopic.php?p=11012#p11012
'========================================================================
Set WSH = CreateObject("WScript.Shell")

If WScript.Arguments.Count < 1 Then
   Param = 1 'если порядок не задан в аргументах, то по умолчанию работает 1-й вариант: гор -> верт -> 4 части
Else
   Param = CInt(WScript.Arguments(0))
End If

Select Case Param
   Case 1 Call Switch(4214, 4213, 4212)
   Case 2 Call Switch(4213, 4214, 4212)
   Case 3 Call Switch(4214, 4212, 4213)
   Case 4 Call Switch(4213, 4212, 4214)
   Case 5 Call Switch(4212, 4213, 4214)
   Case 6 Call Switch(4212, 4214, 4213)
End Select

Sub Switch(n, m, k)
   Tree = "HKCU\Software\Akelsoft\AkelPad\Plugs\Scripts\SwitchSplittedWindow\"
   Name = GetHandleCurrent()
   If Name = 0 Then
      Call SplitWindow(n) : Call RegWrite(Tree, n)
   Else
      On Error Resume Next
      l = CInt(WSH.RegRead(Tree & Name))
      Select Case l
        Case 0 l = n
        Case n l = m
        Case m l = k
        Case k Call SplitWindow(k) : Call WSH.RegDelete(Tree & Name) : Call WsEnd
      End Select
      Call SplitWindow(l) : Call RegWrite(Tree, l) : Call WsEnd
   End If
End Sub

Function GetHandleCurrent() : GetHandleCurrent = AkelPad.SendMessage(AkelPad.GetEditWnd(), 3447, 0, 0) : End Function
Sub SplitWindow(n) : Call AkelPad.SendMessage(AkelPad.GetMainWnd(), 273, n, 0) : End Sub
Sub RegWrite(Tree, n) : Call WSH.RegWrite(Tree & GetHandleCurrent(), Cstr(n)) : End Sub
Sub WsEnd : Set WSH = Nothing : WScript.Quit : End Sub


А это иконка для скрипта:

Code: Select all

MIME-Version: 1.0
Content-Type: application/octet-stream; name="SwitchWindow.zip"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="SwitchWindow.zip"

UEsDBBQAAgAIAI2ZJj5r+EqoaQIAADYVAAAWAAAAQWtlbFBhZFRvb2xCYXJfNjMyLmljb+1YQU8T
QRR+VbCIhlQFtbWtDcEGEz0Y/wBXEyWevFStJzUxRgViJBpZCm1tJZj4D4BENCZeQI3BHrxw8KBW
arQV2Y3B7smLF4+fb3dbusXdSrfFEt3XfJk37823XyY7+zozRA7aRIEAcRughy6iIBG5XFr/YhPR
G/a7OcZDqIe0uGKCi2yzbUPZ5AlCI6DXt2qTvda4RvpE1UGvT1X8zPSrsdX6a+bZ+rb+f6xf6fu3
qm8J/9D8FRNIWDMa+f5tfVu/HvpW9x9m+otiGp8zKWQzL5GriFTJ/5BS9Y3GKc/JLsyVIacgM4cl
8e1v+tMnCVPFvZmuRpX1e3X9P+3vjhMmjmko+lPcPmI8Mah/L8KEp6ESZk8XWgVnClBiBcyGSijj
nCXM8NgZ9udvdOFVnwfPOPb61kE8P0cYDIcROx+CONy+oj9/yYFcxI/8+CHIST/ku53Ijx2AnPBB
HgsyujgW4FhQzcnJ/cgneDzn8wkv8nEPw43lWAfk+B4sRxkjHfj5+JT6vuVkQP3X+3bviLpu70Qm
8ON+54r+xwHCp+F9kMYPQ4r7IUXZj3ogRnZDGnVD5GeJwk7296pxacQNKeZjeLnv02KjPF7YxZx2
iEM7sHS7DYuDzfhyc1vB34KvQhvkSAu+R1uQue6EffLZGGZc32jzekKvpdxTuAp3FcV7ip6m+s8z
fbUZtcLMHlw+WrHu6vlG57gi3+y8Zqa/mm+2320U32j+ZvxK+Bv6ZvvIWua/3vxq11+teNe/He/7
tiJ9jWv4QCsW+lvZd3LOqeWvODjvRHbIq64cZX7TF7pRnzplkejQuL8AUEsBAhQAFAACAAgAjZkm
Pmv4SqhpAgAANhUAABYAAAAAAAAAAAAgAAAAAAAAAEFrZWxQYWRUb29sQmFyXzYzMi5pY29QSwUG
AAAAAAEAAQBEAAAAnQIAAAAA

Posted: Fri Jan 21, 2011 11:46 am
by VladSh

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11092#p11092
// Description(1033): Opens the selected branch in the registry editor
// Description(1049): Открывает выделенную ветвь в редакторе реестра
// если выделения искомой ветви не произошло, значит её не существует
// Version: 1.10 (2015.08.31)
// 	from 1.4 (2011.01.21)
// Author: VladSh
// Initial version: 1.3 by mozers™ (SciTE)
//
// Понимает записи вида:
//		HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
//		[HKLM\SYSTEM\CurrentControlSet\Control]	/символы [] обрезаются/
//		HKLM\\SYSTEM\\CurrentControlSet\\Control
// 
//	Предлагаемая комбинация клавиш:	Ctrl+Alt+J

var key = AkelPad.GetSelText();
if (!key) {		//Если текст не выделен, то будем пытаться получить "ссылку" из текущей строки
	var hWndEdit = AkelPad.GetEditWnd();
	var nPosCurrent = AkelPad.GetSelStart();		//позиция курсора в файле
	
	var oLine = getLine(nPosCurrent);
	var nIndexCurrent = nPosCurrent - oLine.start + 1;		//позиция курсора в строке
	
	key = getKey(oLine.text, nIndexCurrent)		//предварительный поиск ключа, отталкиваясь от позиции курсора
	if (!key)
		key = getKey(oLine.text, -1);		//предварительный поиск ключа - во всей строке
}
else {
	key = getKey(key, -1);		//предварительный поиск ключа - по выделенному тексту
	if (!key) WScript.Quit();
}
//Проверяем, есть ли что-то похожее на ветку реестра
var posStart = key.indexOf("HK");
if (posStart == -1) WScript.Quit();
key = key.substr(posStart);

var pSlash = "\\";
var procRegEdit = "regedit.exe";
var WshShell = new ActiveXObject("WScript.Shell");

var LastKeyPath = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit\\";
var LastKeyName = LastKeyPath + "Lastkey";		//параметр отдельно от пути, т.к. с помощью Run выделение осуществляется только для каталога
key = key.replace(/^HKLM\\/, "HKEY_LOCAL_MACHINE\\");
key = key.replace(/^HKCR\\/, "HKEY_CLASSES_ROOT\\");
key = key.replace(/^HKCU\\/, "HKEY_CURRENT_USER\\");
key = key.replace(/\\\\/g, pSlash);
key = key.replace(/\[/g, "");		//обрезаем [] (для строки из *.reg-файла)
key = key.replace(/\]/g, "");
key = WshShell.RegRead(LastKeyName).match(/^[^\\]+/) + pSlash + key;

if (key.lastIndexOf(pSlash) == key.length - pSlash.length)
	key = key.substr(0, key.length - pSlash.length);		//обрезаем финальный слэш, если он есть, т.к. с ним не происходит выделения ветки

TaskKill(procRegEdit);		//для "обновления", т.к. иначе перехода на нужную ветку не производится

WshShell.RegWrite(LastKeyName, key, "REG_SZ");
WshShell.Run(WshShell.ExpandEnvironmentStrings("%WinDir%") + "\\" + procRegEdit, 1, false);


function getLine(nPos) {
	var line = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, nPos);
	var index = AkelPad.SendMessage(hWndEdit, 187 /*EM_LINEINDEX*/, line, 0);
	var len = AkelPad.SendMessage(hWndEdit, 193 /*EM_LINELENGTH*/, index, 0);
	var text = AkelPad.GetTextRange(index, index + len);
	
	return {
		text: text,
		start: index,
		len: len
	};
}

///Поиск ключа по границам, иначе берём всю переданную строку, т.к. возможно текст выделен правильно, без ограничителей
function getKey(pText, nIndex) {
	var key = getBlock(pText, nIndex, '[', ']');		//ищём внутри []
	if (!key) {
		key = getBlock(pText, nIndex, '"', '"');		//иначе ищём внутри ""
		if (!key) {
			key = getBlock(pText, nIndex, "'", "'");		//иначе ищём внутри ''
			if (!key) {
				key = pText;		//берём всю переданную строку
			}
		}
	}
	return key;
}

function getBlock(pText, nPos, pTextStart, pTextEnd) {		//если в nPos передано -1, то искать во всей строке
	var pBlock = "";
	var nLbound;
	var nUbound;
	if (nPos != -1) {
		nLbound = nPos;
		nUbound = nPos;
	}
	else {
		nLbound = pTextStart.length + 1;
		nUbound = pText.length - pTextEnd.length - 1;
	}
	
	var posTextStart = pText.lastIndexOf(pTextStart, nUbound);					//Ищем вверх
	if (posTextStart != -1) {
		var posTextEnd = pText.indexOf(pTextEnd, nLbound);							//Ищем вниз
		if (posTextEnd != -1) {
			posTextStart += 1;
			if (posTextStart < posTextEnd)
				pBlock = pText.substring(posTextStart, posTextEnd);
			else
				pBlock = pText.substring(posTextEnd + pTextStart.length, posTextStart - pTextEnd.length);
		}
	}
	return pBlock;
}

function TaskKill(process_name) {
	var objWMIService = GetObject("winmgmts:\\\\.\\root\\CIMV2");
	var colProcessList = objWMIService.ExecQuery ('SELECT * FROM Win32_Process WHERE NAME = "' + process_name + '"');
	var enumItems = new Enumerator(colProcessList);
	for (; !enumItems.atEnd(); enumItems.moveNext())
		enumItems.item().Terminate();
}
Алгоритм:
1. Если есть выделение, то берётся чисто выделение; пробелы в конце не обрезаются, т.к. кроме пробелов там может быть любые символы...;
2. Если нет выделения, тогда:
- отталкиваемся от позиции курсора (считаем, что он установлен внутри [] или "");
- если ничего не найдено, то берём всю строку и берём текст внутри крайних [] или "";
3. Если в строке нет символов, в которые может быть заключён путь. то предполагаем, что это просто текстовый файл, поэтому берём строку с символов "HK" и пытаемся открыть; если этих символов - выходим, т.к. это не ветка реестра.

Из этого следует несколько вариантов работы скрипта (для пользователя):
- по выделению (путь должен быть чётко выделен);
- по позиции курсора внутри пути (самый частый и простой способ);
- из всей строки, в которой установлен курсор (в этом случае пользователь соглашается с тем, что текст между крайними [] или "" считается путём, т.е. корректно скрипт будет работать, если в текущей строке пара вышеуказанных символов встречается 1 раз); этот способ подходит для больших строк (трудно такое придумать чтобы курсором тяжело было попасть, но... пусть будет).

Благодарности: mozers™, KDJ, Skif_off.

Posted: Fri Jan 21, 2011 5:04 pm
by Infocatcher
converter.js <download | mirror | development version>
  • Encode/decode HTML entities
  • Convert JavaScript escape sequences like "\u00a9" or "\xa9" («©» symbol)
  • Escape/unescape special RegExp symbols
  • Escape/unescape special strings symbols
  • Encode/decode Uniform Resource Identifiers (URIs)
  • Hexadecimal escape/unescape
  • Base64 encode/decode
  • Convert charset

Image Image


Post size limit, here is packed file:

Code: Select all

begin 644 converter.7z
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
A`'(`+@!J`',````4"@$``!#KHUUISP$5!@$`(```````
`
end
sum -r/size 26769/18078

Save as text file with .uue extension, unpack with Total Commander or WinRAR. And unpack .7z with WinRAR or 7-Zip. :)

Posted: Fri Jan 21, 2011 5:24 pm
by Infocatcher
getHash.js <download | mirror | development version>
Calculates hash sum of text.
It can be very slow, be careful.


Image Image


Post size limit, here is packed file:

Code: Select all

begin 644 getHash.7z
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
,SP$5!@$`(```````
`
end
sum -r/size 45042/18462

Save as text file with .uue extension, unpack with Total Commander or WinRAR. And unpack .7z with WinRAR or 7-Zip. :)

Posted: Mon Jan 24, 2011 7:45 pm
by KDJ
Sorts lists in lines by using Format plugin.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11121#p11121
// Version: 2015-09-19
// Author: KDJ
//
// *** Sort list by using Format plugin ***
//
// Usage:
//   Call("Scripts::Main", 1, "SortList.js")
//
// Shortcut keys in dialog box:
//   Enter - Sort
//   Esc   - Close
//   Shift+Alt+Right (Left, Down, Up, End, Home, PgDn, PgUp) - move dialog box.
//
// Remarks:
//   In each line, sorts separately.
//   If you do not specify a separator, it will be sorted single characters.

if (AkelPad.GetLangId(0 /*LANGID_FULL*/) == 0x0415) //Polish
{
  var sTxtCaption  = "Sortowanie list w wierszach";
  var sTxtSep      = "Separator:";
  var sTxtTab      = "\\t = Tabulacja";
  var sTxtSortMet  = "Metoda sortowania";
  var sTxtDesc     = "&Malejąco";
  var sTxtIgCase   = "&Ignoruj wlk. liter";
  var sTxtString   = "&String";
  var sTxtNum      = "&Numerycznie";
  var sTxtNoSort   = "Nie sortuj, ale";
  var sTxtReverse  = "&Odwróć kolejność elementów";
  var sTxtRemoDup  = "&Usuń duplikaty elementów";
  var sTxtExtrDup  = "&Zachowaj tylko powielone elementy";
  var sTxtExtrUni  = "Zac&howaj tylko unikalne elementy";
  var sTxtCopyToCB = "Wynik kopiuj do schowka, nie zmieniaj &tekstu";
  var sTxtSort     = "Sortuj";
  var sTxtUndo     = "&Cofnij";
  var sTxtRedo     = "&Powtórz";
  var sTxtNoSep    = "Zaznaczony tekst nie zawiera separatora.";
}
else
{
  var sTxtCaption  = "Sort lists in lines";
  var sTxtSep      = "Separator:";
  var sTxtTab      = "\\t = Tabulation";
  var sTxtSortMet  = "Sort method";
  var sTxtDesc     = "&Descending";
  var sTxtIgCase   = "&Ignore case";
  var sTxtString   = "&String";
  var sTxtNum      = "&Numerically";
  var sTxtNoSort   = "No sort, but";
  var sTxtReverse  = "Reverse &order of elements";
  var sTxtRemoDup  = "Re&move duplicate elements";
  var sTxtExtrDup  = "E&xtract duplicate elements";
  var sTxtExtrUni  = "Extra&ct unique elements";
  var sTxtCopyToCB = "Resul&t copy to clipboard, do not replace text";
  var sTxtSort     = "Sort";
  var sTxtUndo     = "&Undo";
  var sTxtRedo     = "&Redo";
  var sTxtNoSep    = "Selected text not contain separator.";
}

var DT_DWORD    = 3;
var BM_SETCHECK = 241;

var oSys       = AkelPad.SystemFunction();
var hMainWnd   = AkelPad.GetMainWnd();
var hEditWnd   = AkelPad.GetEditWnd();
var hGuiFont   = oSys.Call("Gdi32::GetStockObject", 17 /*DEFAULT_GUI_FONT*/);
var hInstDLL   = AkelPad.GetInstanceDll();
var sClassName = "AkelPad::Scripts::" + WScript.ScriptName + "::" + hInstDLL;
var sSep       = ";";
var bTab       = 1;
var bDesc      = 0;
var bIgCase    = 1;
var nMethod    = 1;
var nNoSort    = 0;
var bCopyToCB  = 0;
var nUndoLimit = 0;
var nRedoLimit = 0;
var hWndDlg;
var lpBuffer;
var bIsReturn;
var hFocus;
var nWndPosX;
var nWndPosY;

ReadWriteIni(0);

var aWnd       = [];
var IDGROUP1   = 1000;
var IDSTATSEP  = 1001;
var IDSEP      = 1002;
var IDTAB      = 1003;
var IDGROUP2   = 1004;
var IDDESC     = 1005;
var IDIGCASE   = 1006;
var IDGROUP3   = 1007;
var IDSTRING   = 1008;
var IDNUM      = 1009;
var IDGROUP4   = 1010;
var IDREVERSE  = 1011;
var IDREMODUP  = 1012;
var IDEXTRDUP  = 1013;
var IDEXTRUNI  = 1014;
var IDCOPYTOCB = 1015;
var IDSORT     = 1016;
var IDUNDO     = 1017;
var IDREDO     = 1018;

var CLASS   = 0;
var WND     = 1;
var EXSTYLE = 2;
var STYLE   = 3;
var X       = 4;
var Y       = 5;
var W       = 6;
var H       = 7;
var TXT     = 8;

//0x50000000 - WS_VISIBLE|WS_CHILD
//0x50000007 - WS_VISIBLE|WS_CHILD|BS_GROUPBOX
//0x50000009 - WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON
//0x50010000 - WS_VISIBLE|WS_CHILD|WS_TABSTOP
//0x50010003 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
//0x50010080 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL
//Windows              CLASS, WND, EXSTYLE,      STYLE,   X,   Y,   W,   H, TXT
aWnd[IDGROUP1  ] = ["BUTTON",   0,       0, 0x50000007,  10,  10, 170,  75, ""];
aWnd[IDSTATSEP ] = ["STATIC",   0,       0, 0x50000000,  20,  30,  60,  13, sTxtSep];
aWnd[IDSEP     ] = ["EDIT",     0,   0x200, 0x50010080,  80,  30,  90,  20, sSep];
aWnd[IDTAB     ] = ["BUTTON",   0,       0, 0x50010003,  80,  60,  90,  16, sTxtTab];
aWnd[IDGROUP2  ] = ["BUTTON",   0,       0, 0x50000007,  10,  95, 260,  65, sTxtSortMet];
aWnd[IDDESC    ] = ["BUTTON",   0,       0, 0x50010003,  40, 115,  90,  16, sTxtDesc];
aWnd[IDIGCASE  ] = ["BUTTON",   0,       0, 0x50010003,  40, 135,  90,  16, sTxtIgCase];
aWnd[IDGROUP3  ] = ["BUTTON",   0,       0, 0x50000007, 150,  95, 120,  65, ""];
aWnd[IDSTRING  ] = ["BUTTON",   0,       0, 0x50000009, 175, 115,  90,  16, sTxtString];
aWnd[IDNUM     ] = ["BUTTON",   0,       0, 0x50000009, 175, 135,  90,  16, sTxtNum];
aWnd[IDGROUP4  ] = ["BUTTON",   0,       0, 0x50000007,  10, 170, 260, 105, sTxtNoSort];
aWnd[IDREVERSE ] = ["BUTTON",   0,       0, 0x50010003,  60, 190, 200,  16, sTxtReverse];
aWnd[IDREMODUP ] = ["BUTTON",   0,       0, 0x50010003,  60, 210, 200,  16, sTxtRemoDup];
aWnd[IDEXTRDUP ] = ["BUTTON",   0,       0, 0x50010003,  60, 230, 200,  16, sTxtExtrDup];
aWnd[IDEXTRUNI ] = ["BUTTON",   0,       0, 0x50010003,  60, 250, 200,  16, sTxtExtrUni];
aWnd[IDCOPYTOCB] = ["BUTTON",   0,       0, 0x50010003,  20, 285, 240,  16, sTxtCopyToCB];
aWnd[IDSORT    ] = ["BUTTON",   0,       0, 0x50010000, 190,  14,  80,  23, sTxtSort];
aWnd[IDUNDO    ] = ["BUTTON",   0,       0, 0x50010000, 190,  39,  80,  23, sTxtUndo];
aWnd[IDREDO    ] = ["BUTTON",   0,       0, 0x50010000, 190,  64,  80,  23, sTxtRedo];

if (hEditWnd)
{
  AkelPad.SendMessage(hEditWnd, 3128 /*AEM_UPDATESEL*/, 0 /*AESELT_COLUMNOFF*/, 0);
  if (AkelPad.GetSelStart() == AkelPad.GetSelEnd())
    AkelPad.SetSel(0, -1);

  if (AkelPad.WindowRegisterClass(sClassName))
  {
    if (lpBuffer = AkelPad.MemAlloc(256 * _TSIZE))
    {
      hWndDlg = oSys.Call("User32::CreateWindowEx" + _TCHAR,
                  0,               //dwExStyle
                  sClassName,      //lpClassName
                  sTxtCaption,     //lpWindowName
                  0x90CA0000,      //WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX
                  0,               //x
                  0,               //y
                  285,             //nWidth
                  340,             //nHeight
                  hMainWnd,        //hWndParent
                  0,               //ID
                  hInstDLL,        //hInstance
                  DialogCallback); //Script function callback. To use it class must be registered by WindowRegisterClass.
      if (hWndDlg)
      {
        //Disable main window, to make dialog modal
        oSys.Call("User32::EnableWindow", hMainWnd, false);

        //Message loop
        AkelPad.WindowGetMessage();
      }
      AkelPad.MemFree(lpBuffer);
    }
    AkelPad.WindowUnregisterClass(sClassName);
  }
}

function DialogCallback(hWnd, uMsg, wParam, lParam)
{
  var i, nLowParam;

  if (uMsg == 1) //WM_CREATE
  {
    for (i = 1000; i < aWnd.length; ++i)
    {
      aWnd[i][WND] = oSys.Call("User32::CreateWindowEx" + _TCHAR,
                       aWnd[i][EXSTYLE], //dwExStyle
                       aWnd[i][CLASS],   //lpClassName
                       0,                //lpWindowName
                       aWnd[i][STYLE],   //dwStyle
                       aWnd[i][X],       //x
                       aWnd[i][Y],       //y
                       aWnd[i][W],       //nWidth
                       aWnd[i][H],       //nHeight
                       hWnd,             //hWndParent
                       i,                //ID
                       hInstDLL,         //hInstance
                       0);               //lpParam
      SetWindowFontAndText(aWnd[i][WND], hGuiFont, aWnd[i][TXT]);
    }

    //Set limit edit text
    AkelPad.SendMessage(aWnd[IDSEP][WND], 197 /*EM_LIMITTEXT*/, 20, 0);

    CheckButtons();
    CheckUndoRedo();

    //Set window position
    if ((nWndPosX == undefined) || (nWndPosY == undefined))
      MoveWindow(hMainWnd, hWnd, "RT");
    else
      MoveWindow(hMainWnd, hWnd, [nWndPosX, nWndPosY]);
  }

  else if (uMsg == 7) //WM_SETFOCUS
  {
    oSys.Call("User32::SetFocus", aWnd[IDSEP][WND]);
    AkelPad.SendMessage(aWnd[IDSEP][WND], 177 /*EM_SETSEL*/, 0, -1);
  }

  else if (uMsg == 256) //WM_KEYDOWN
  {
    if (wParam == 27) //VK_ESCAPE
      oSys.Call("User32::PostMessage" + _TCHAR, hWndDlg, 16 /*WM_CLOSE*/, 0, 0);
    else if (wParam == 13) //VK_RETURN
    {
      if (! bIsReturn)
      {
        hFocus = oSys.Call("User32::GetFocus");
        if ((hFocus != aWnd[IDSORT][WND]) && (hFocus != aWnd[IDUNDO][WND]) && (hFocus != aWnd[IDREDO][WND]))
          oSys.Call("User32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDSORT, 0);
      }
    }
  }

  else if (uMsg == 257) //WM_KEYUP
    bIsReturn = 0;

  else if ((uMsg == 260) /*WM_SYSKEYDOWN*/ &&
           (oSys.Call("User32::GetAsyncKeyState", 0xA0 /*VK_LSHIFT*/)))
  {
    if (wParam == 0x27) //VK_RIGHT
      MoveWindow(hMainWnd, hWnd, "R");
    else if (wParam == 0x25) //VK_LEFT
      MoveWindow(hMainWnd, hWnd, "L");
    else if (wParam == 0x28) //VK_DOWN
      MoveWindow(hMainWnd, hWnd, "D");
    else if (wParam == 0x26) //VK_UP
      MoveWindow(hMainWnd, hWnd, "U");
    else if (wParam == 0x23) //VK_END
      MoveWindow(hMainWnd, hWnd, "E");
    else if (wParam == 0x24) //VK_HOME
      MoveWindow(hMainWnd, hWnd, "H");
    else if (wParam == 0x22) //VK_NEXT
      MoveWindow(hMainWnd, hWnd, "B");
    else if (wParam == 0x21) //VK_PRIOR
      MoveWindow(hMainWnd, hWnd, "T");
  }

  else if (uMsg == 273) //WM_COMMAND
  {
    nLowParam = LoWord(wParam);

    if ((nLowParam >= IDTAB) && (nLowParam <= IDCOPYTOCB))
    {
      CheckButtons(nLowParam);
    }

    else if (nLowParam == IDSORT)
    {
      if (SortList())
        CheckUndoRedo(nLowParam);
    }

    else if (nLowParam == IDUNDO)
    {
      bIsReturn = 1;
      CheckUndoRedo(nLowParam);
    }

    else if (nLowParam == IDREDO)
    {
      bIsReturn = 1;
      CheckUndoRedo(nLowParam);
    }
  }

  else if (uMsg == 16) //WM_CLOSE
  {
    ReadWriteIni(1);

    //Enable main window
    oSys.Call("User32::EnableWindow", hMainWnd, true);
    //Destroy dialog
    oSys.Call("User32::DestroyWindow", hWnd);
  }

  else if (uMsg == 2) //WM_DESTROY
  {
    //Exit message loop
    oSys.Call("User32::PostQuitMessage", 0);
  }

  else
    SetDefID(hWnd);

  return 0;
}

function SetWindowFontAndText(hWnd, hFont, sText)
{
  AkelPad.SendMessage(hWnd, 48 /*WM_SETFONT*/, hFont, true);
  oSys.Call("User32::SetWindowText" + _TCHAR, hWnd, sText);
}

function MoveWindow(hWndParent, hWnd, vAction)
{
  var aRectParent;
  var aRect;
  var nX;
  var nY;

  if (! hWndParent)
    hWndParent=oSys.Call("User32::GetDesktopWindow");

  aRectParent = GetWindowPos(hWndParent);
  aRect       = GetWindowPos(hWnd);

  nX = aRect.left;
  nY = aRect.top;

  if (vAction == "R") //Move right
    nX = aRect.left + ((aRect.left < aRectParent.right - 50) ? 20 : 0);
  else if (vAction == "L") //Move left
    nX = aRect.left - ((aRect.right > aRectParent.left + 50) ? 20 : 0);
  else if (vAction == "D") //Move down
    nY = aRect.top + ((aRect.top < aRectParent.bottom - 50) ? 20 : 0);
  else if (vAction == "U") //Move up
    nY = aRect.top - ((aRect.bottom > aRectParent.top + 50) ? 20 : 0);
  else if (vAction == "E") //Move end (right)
    nX = aRect.left + (aRectParent.right - aRect.right);
  else if (vAction == "H") //Move home (left)
    nX = aRect.left + (aRectParent.left - aRect.left);
  else if (vAction == "B") //Move bottom
    nY = aRect.top + (aRectParent.bottom - aRect.bottom);
  else if (vAction == "T") //Move top
    nY = aRect.top + (aRectParent.top - aRect.top);
  else if (vAction == "C") //Center window
  {
    nX = aRectParent.left + ((aRectParent.right  - aRectParent.left) / 2 - (aRect.right  - aRect.left) / 2);
    nY = aRectParent.top  + ((aRectParent.bottom - aRectParent.top)  / 2 - (aRect.bottom - aRect.top)  / 2);
  }
  else if (vAction == "LT") //Move left top
  {
    nX = aRectParent.left;
    nY = aRectParent.top;
  }
  else if (vAction == "RT") //Move right top
  {
    nX = aRect.left + (aRectParent.right - aRect.right);
    nY = aRectParent.top;
  }
  else if (vAction == "LB") //Move left bottom
  {
    nX = aRectParent.left;
    nY = aRect.top + (aRectParent.bottom - aRect.bottom);
  }
  else if (vAction == "RB") //Move right bottom
  {
    nX = aRect.left + (aRectParent.right - aRect.right);
    nY = aRect.top + (aRectParent.bottom - aRect.bottom);
  }
  else
  {
    nX = vAction[0];
    nY = vAction[1];
  }

  oSys.Call("User32::SetWindowPos", hWnd, 0, nX, nY, 0, 0, 0x15 /*SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE*/);
}

function GetWindowPos(hWnd)
{
  var lpRect = AkelPad.MemAlloc(16) //sizeof(RECT);
  var aRect  = [];

  oSys.Call("User32::GetWindowRect", hWnd, lpRect);

  aRect.left   = AkelPad.MemRead(_PtrAdd(lpRect,  0), DT_DWORD);
  aRect.top    = AkelPad.MemRead(_PtrAdd(lpRect,  4), DT_DWORD);
  aRect.right  = AkelPad.MemRead(_PtrAdd(lpRect,  8), DT_DWORD);
  aRect.bottom = AkelPad.MemRead(_PtrAdd(lpRect, 12), DT_DWORD);
  AkelPad.MemFree(lpRect);

  return aRect;
}

function LoWord(nParam)
{
  return (nParam & 0xFFFF);
}

function SetDefID(hWnd)
{
  var nID    = 1000;
  var hFocus = oSys.Call("User32::GetFocus");

  while ((nID < aWnd.length) && (hFocus != aWnd[nID][WND]))
    ++nID;

  if ((nID != IDUNDO) && (nID != IDREDO))
    nID = IDSORT;

  oSys.Call("User32::DefDlgProc" + _TCHAR, hWnd, 1025 /*DM_SETDEFID*/, nID, 0);
}

function ReadWriteIni(bWrite)
{
  var oFSO     = new ActiveXObject("Scripting.FileSystemObject");
  var sIniName = WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf(".")) + ".ini";
  var aRect;
  var oFile;
  var sIniTxt;

  if (bWrite)
  {
    aRect = GetWindowPos(hWndDlg);

    oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDSEP][WND], lpBuffer, 256);
    sSep = AkelPad.MemRead(lpBuffer, _TSTR);

    sIniTxt = 'nWndPosX='  + aRect.left + ';\r\n' +
              'nWndPosY='  + aRect.top  + ';\r\n' +
              'sSep="'     + sSep.replace(/[\\"]/g, "\\$&") + '";\r\n' +
              'bTab='      + bTab + ';\r\n' +
              'bDesc='     + bDesc + ';\r\n' +
              'bIgCase='   + bIgCase + ';\r\n' +
              'nMethod='   + nMethod + ';\r\n' +
              'nNoSort='   + nNoSort + ';\r\n' +
              'bCopyToCB=' + bCopyToCB + ';'

    oFile = oFSO.OpenTextFile(sIniName, 2, true, 0);
    oFile.Write(sIniTxt);
    oFile.Close();
  }

  else if (oFSO.FileExists(sIniName))
  {
    try
    {
      eval(AkelPad.ReadFile(sIniName));
    }
    catch (oError)
    {
    }
  }
}

function CheckButtons(nButton)
{
  if (nButton == IDTAB)
    bTab = ! bTab;
  else if (nButton == IDDESC)
    bDesc = ! bDesc;
  else if (nButton == IDIGCASE)
    bIgCase = ! bIgCase;
  else if ((nButton == IDSTRING) || (nButton == IDNUM))
    nMethod = nButton - IDSTRING + 1;
  else if ((nButton == IDREVERSE) || (nButton == IDREMODUP) ||
           (nButton == IDEXTRDUP) || (nButton == IDEXTRUNI))
  {
    if (nNoSort == nButton - IDREVERSE + 1)
      nNoSort = 0;
    else
      nNoSort = nButton - IDREVERSE + 1;
  }
  else if (nButton == IDCOPYTOCB)
    bCopyToCB = ! bCopyToCB;

  if (nNoSort > 1)
    nMethod = 1;

  AkelPad.SendMessage(aWnd[IDTAB][WND],      BM_SETCHECK, bTab,           0);
  AkelPad.SendMessage(aWnd[IDDESC][WND],     BM_SETCHECK, bDesc,          0);
  AkelPad.SendMessage(aWnd[IDIGCASE][WND],   BM_SETCHECK, bIgCase,        0);
  AkelPad.SendMessage(aWnd[IDSTRING][WND],   BM_SETCHECK, (nMethod == 1), 0);
  AkelPad.SendMessage(aWnd[IDNUM][WND],      BM_SETCHECK, (nMethod == 2), 0);
  AkelPad.SendMessage(aWnd[IDREVERSE][WND],  BM_SETCHECK, (nNoSort == 1), 0);
  AkelPad.SendMessage(aWnd[IDREMODUP][WND],  BM_SETCHECK, (nNoSort == 2), 0);
  AkelPad.SendMessage(aWnd[IDEXTRDUP][WND],  BM_SETCHECK, (nNoSort == 3), 0);
  AkelPad.SendMessage(aWnd[IDEXTRUNI][WND],  BM_SETCHECK, (nNoSort == 4), 0);
  AkelPad.SendMessage(aWnd[IDCOPYTOCB][WND], BM_SETCHECK, bCopyToCB,      0);

  oSys.Call("User32::EnableWindow", aWnd[IDDESC][WND],   (nNoSort == 0));
  oSys.Call("User32::EnableWindow", aWnd[IDIGCASE][WND], (nNoSort != 1));
  oSys.Call("User32::EnableWindow", aWnd[IDSTRING][WND], (nNoSort != 1));
  oSys.Call("User32::EnableWindow", aWnd[IDNUM][WND],    (nNoSort == 0));
}

function CheckUndoRedo(nButton)
{
  var nBegSel  = AkelPad.GetSelStart();
  var sTxtUndo = aWnd[IDUNDO][TXT];
  var sTxtRedo = aWnd[IDREDO][TXT];

  if (nButton == IDSORT)
  {
    if (nUndoLimit < AkelPad.SendMessage(hEditWnd, 3084 /*AEM_GETUNDOLIMIT*/, 0, 0))
      ++nUndoLimit;
    nRedoLimit = 0;
  }
  else if ((nButton == IDUNDO) && (nUndoLimit))
  {
    --nUndoLimit;
    ++nRedoLimit;
    AkelPad.SendMessage(hEditWnd, 3077 /*AEM_UNDO*/, 0, 0);
  }
  else if ((nButton == IDREDO) && (nRedoLimit))
  {
    ++nUndoLimit;
    --nRedoLimit;
    AkelPad.SendMessage(hEditWnd, 3078 /*AEM_REDO*/, 0, 0);
    AkelPad.SetSel(nBegSel, AkelPad.GetSelEnd());
  }

  if (nUndoLimit)
    sTxtUndo += " (" + nUndoLimit + ")";
  if (nRedoLimit)
    sTxtRedo += " (" + nRedoLimit + ")";

  if (((oSys.Call("User32::GetFocus") == aWnd[IDUNDO][WND]) && (nUndoLimit == 0)) ||
      ((oSys.Call("User32::GetFocus") == aWnd[IDREDO][WND]) && (nRedoLimit == 0)))
    oSys.Call("User32::SetFocus", aWnd[IDSEP][WND]);

  SetWindowFontAndText(aWnd[IDUNDO][WND], hGuiFont, sTxtUndo);
  SetWindowFontAndText(aWnd[IDREDO][WND], hGuiFont, sTxtRedo);

  oSys.Call("User32::EnableWindow", aWnd[IDUNDO][WND], nUndoLimit);
  oSys.Call("User32::EnableWindow", aWnd[IDREDO][WND], nRedoLimit);
}

function SortList()
{
  var nBegSel  = AkelPad.GetSelStart();
  var nEndSel  = AkelPad.GetSelEnd();
  var sText    = AkelPad.GetSelText();
  var nLine1   = AkelPad.SendMessage(hEditWnd, 1078 /*EM_EXLINEFROMCHAR*/, 0, nBegSel);
  var nLine2   = AkelPad.SendMessage(hEditWnd, 1078 /*EM_EXLINEFROMCHAR*/, 0, nEndSel);
  var nBegLen  = TextLen();
  var nBegLine;
  var nEndLine;
  var bSepEnd;
  var rSep;
  var rSep_g;
  var rSepEnd;
  var i;

  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDSEP][WND], lpBuffer, 256);
  sSep = AkelPad.MemRead(lpBuffer, _TSTR);

  if (bTab) sSep = sSep.replace(/\\t/g, "\t");

  rSep    = new RegExp(escapeRegExp(sSep));
  rSep_g  = new RegExp(escapeRegExp(sSep), "g");
  rSepEnd = new RegExp(escapeRegExp(sSep) + "$");

  if (! rSep.test(sText))
  {
    AkelPad.MessageBox(hWndDlg, sTxtNoSep, sTxtCaption, 48 /*MB_ICONEXCLAMATION*/);
    return 0;
  }

  SetRedraw(hEditWnd, false);
  AkelPad.SendMessage(hEditWnd, 3080 /*AEM_STOPGROUPTYPING*/, 0, 0);
  AkelPad.SendMessage(hEditWnd, 3081 /*AEM_BEGINUNDOACTION*/, 0, 0);
  AkelPad.ReplaceSel(sText, -1);

  for (i = nLine1; i <= nLine2; ++i)
  {
    if (nLine1 < nLine2)
    {
       nBegLine = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, i, 0);
       nEndLine = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, i, 0) +
                    AkelPad.SendMessage(hEditWnd, 193 /*EM_LINELENGTH*/, nBegLine, 0);
      if (i == nLine1)
        AkelPad.SetSel(nBegSel, nEndLine);
      else if (i == nLine2)
        AkelPad.SetSel(nBegLine, nEndSel - nBegLen + TextLen());
      else
        AkelPad.SetSel(nBegLine, nEndLine);

      sText = AkelPad.GetSelText();
    }

    if (rSep.test(sText))
    {
      bSepEnd = rSepEnd.test(sText);
      sText   = sText.replace(rSep_g, "\r");
      AkelPad.ReplaceSel("\r" + sText + "\r", -1);
      AkelPad.SetSel(AkelPad.GetSelStart() + 1, AkelPad.GetSelEnd() - 1);
      SortByPlugin();
      sText = AkelPad.GetTextRange(AkelPad.GetSelStart(), AkelPad.GetSelEnd() - 1 + bSepEnd).replace(/\r/g, sSep);
      AkelPad.SetSel(AkelPad.GetSelStart() - 1, AkelPad.GetSelEnd() + bSepEnd);
      AkelPad.ReplaceSel(sText, -1);
    }
  }

  AkelPad.SetSel(nBegSel, AkelPad.GetSelEnd());
  AkelPad.SendMessage(hEditWnd, 3082 /*AEM_ENDUNDOACTION*/, 0, 0);
  AkelPad.SendMessage(hEditWnd, 3080 /*AEM_STOPGROUPTYPING*/, 0, 0);

  if (bCopyToCB)
  {
    AkelPad.SetClipboardText(AkelPad.GetSelText());
    AkelPad.SendMessage(hEditWnd, 3077 /*AEM_UNDO*/, 0, 0);
  }

  SetRedraw(hEditWnd, true);
  return ! bCopyToCB;
}

function SortByPlugin()
{
  var sAscDesc = bDesc ? "Desc" : "Asc";

  if (nNoSort == 1)
    AkelPad.Call("Format::LineReverse");
  else if (nNoSort == 2)
    AkelPad.Call("Format::LineRemoveDuplicates", ! bIgCase);
  else if (nNoSort == 3)
    AkelPad.Call("Format::LineGetDuplicates", ! bIgCase);
  else if (nNoSort == 4)
    AkelPad.Call("Format::LineGetUnique", ! bIgCase);
  else if (nMethod == 1)
    AkelPad.Call("Format::LineSortStr" + sAscDesc, ! bIgCase);
  else if (nMethod == 2)
    AkelPad.Call("Format::LineSortInt" + sAscDesc, ! bIgCase);
}

function escapeRegExp(sStr)
{
  return sStr.replace(/[\\\/.^$+*?|()\[\]{}]/g, "\\$&");
}

function SetRedraw(hWnd, bRedraw)
{
  var oSys = AkelPad.SystemFunction();
  AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
  bRedraw && oSys.Call("User32::InvalidateRect", hWnd, 0, true);
}

function TextLen()
{
  var nOffset = -1;
  var lpIndex;

  if (lpIndex = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/))
  {
    AkelPad.SendMessage(hEditWnd, 3130 /*AEM_GETINDEX*/, 2 /*AEGI_LASTCHAR*/, lpIndex);
    nOffset = AkelPad.SendMessage(hEditWnd, 3136 /*AEM_INDEXTORICHOFFSET*/, 0, lpIndex);
    AkelPad.MemFree(lpIndex);
  }
  return nOffset;
}


Posted: Sun Jan 30, 2011 9:37 pm
by Infocatcher

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11212#p11212
// http://infocatcher.ucoz.net/js/akelpad_scripts/AESCrypt.js
// https://github.com/Infocatcher/AkelPad_scripts/blob/master/AESCrypt.js

// (c) Infocatcher 2010-2011, 2014
// version 0.2.7.1 - 2014-05-06

//===================
// AES-256 encrypt/decrypt
// Based on script from http://www.movable-type.co.uk/scripts/aes.html

// Arguments:
//   -mode=0             - (default) ask user about direction (encrypt or decrypt)
//        =1             - encrypt
//        =2             - decrypt
//   -maxLineWidth=75    - allow split output to lines with fixed width
//   -showPassword=true  - force show or hide password
//   -saveOptions=true   - allow store last used password state

// Usage:
//   Call("Scripts::Main", 1, "AESCrypt.js", "-mode=1")     - encrypt
//   Call("Scripts::Main", 1, "AESCrypt.js", "-mode=2")     - decrypt
//   Call("Scripts::Main", 1, "AESCrypt.js", "-mode=0 -maxLineWidth=0 -showPassword=true -saveOptions=false")
//===================

function _localize(s) {
	var strings = {
		"Nothing to encrypt!": {
			ru: "Нечего зашифровывать!"
		},
		"Nothing to decrypt!": {
			ru: "Нечего расшифровывать!"
		},
		"Direction": {
			ru: "Направление"
		},
		"Encrypt": {
			ru: "Зашифровать"
		},
		"Decrypt": {
			ru: "Расшифровать"
		},
		"Password": {
			ru: "Пароль"
		},
		"&Encrypt": {
			ru: "&Зашифровать"
		},
		"&Decrypt": {
			ru: "&Расшифровать"
		},
		"Impossible to decrypt: invalid format!": {
			ru: "Невозможно расшифровать: некорректный формат!"
		},
		"Enter &password:": {
			ru: "Введите &пароль:"
		},
		"Reenter p&assword:": {
			ru: "Повторите п&ароль:"
		},
		"&Show password": {
			ru: "По&казывать пароль"
		},
		"OK": {
			ru: "ОК"
		},
		"Cancel": {
			ru: "Отмена"
		},
		"Passwords do not match!": {
			ru: "Пароли не совпадают!"
		}
	};
	var lng;
	switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
		case 0x19: lng = "ru"; break;
		default:   lng = "en";
	}
	_localize = function(s) {
		return strings[s] && strings[s][lng] || s;
	};
	return _localize(s);
}

var MODE_USER_SELECT = 0;
var MODE_ENCRYPT     = 1;
var MODE_DECRYPT     = 2;

// Read arguments:
// getArg(argName, defaultValue)
var mode         = getArg("mode", 0);
var maxLineWidth = getArg("maxLineWidth", 75);
var showPassword = getArg("showPassword");
var saveOptions  = getArg("saveOptions", true);

var decrypt = mode == MODE_DECRYPT;


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
/*  AES implementation in JavaScript (c) Chris Veness 2005-2010                                   */
/*   - see http://csrc.nist.gov/publications/PubsFIPS.html#197                                    */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */

var Aes = {};  // Aes namespace

/**
 * AES Cipher function: encrypt 'input' state with Rijndael algorithm
 *   applies Nr rounds (10/12/14) using key schedule w for 'add round key' stage
 *
 * @param {Number[]} input 16-byte (128-bit) input state array
 * @param {Number[][]} w   Key schedule as 2D byte-array (Nr+1 x Nb bytes)
 * @returns {Number[]}     Encrypted output state array
 */
Aes.cipher = function(input, w) {    // main Cipher function [§5.1]
  var Nb = 4;               // block size (in words): no of columns in state (fixed at 4 for AES)
  var Nr = w.length/Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys

  var state = [[],[],[],[]];  // initialise 4xNb byte-array 'state' with input [§3.4]
  for (var i=0; i<4*Nb; i++) state[i%4][Math.floor(i/4)] = input[i];

  state = Aes.addRoundKey(state, w, 0, Nb);

  for (var round=1; round<Nr; round++) {
    state = Aes.subBytes(state, Nb);
    state = Aes.shiftRows(state, Nb);
    state = Aes.mixColumns(state, Nb);
    state = Aes.addRoundKey(state, w, round, Nb);
  }

  state = Aes.subBytes(state, Nb);
  state = Aes.shiftRows(state, Nb);
  state = Aes.addRoundKey(state, w, Nr, Nb);

  var output = new Array(4*Nb);  // convert state to 1-d array before returning [§3.4]
  for (var i=0; i<4*Nb; i++) output[i] = state[i%4][Math.floor(i/4)];
  return output;
}

/**
 * Perform Key Expansion to generate a Key Schedule
 *
 * @param {Number[]} key Key as 16/24/32-byte array
 * @returns {Number[][]} Expanded key schedule as 2D byte-array (Nr+1 x Nb bytes)
 */
Aes.keyExpansion = function(key) {  // generate Key Schedule (byte-array Nr+1 x Nb) from Key [§5.2]
  var Nb = 4;            // block size (in words): no of columns in state (fixed at 4 for AES)
  var Nk = key.length/4  // key length (in words): 4/6/8 for 128/192/256-bit keys
  var Nr = Nk + 6;       // no of rounds: 10/12/14 for 128/192/256-bit keys

  var w = new Array(Nb*(Nr+1));
  var temp = new Array(4);

  for (var i=0; i<Nk; i++) {
    var r = [key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]];
    w[i] = r;
  }

  for (var i=Nk; i<(Nb*(Nr+1)); i++) {
    w[i] = new Array(4);
    for (var t=0; t<4; t++) temp[t] = w[i-1][t];
    if (i % Nk == 0) {
      temp = Aes.subWord(Aes.rotWord(temp));
      for (var t=0; t<4; t++) temp[t] ^= Aes.rCon[i/Nk][t];
    } else if (Nk > 6 && i%Nk == 4) {
      temp = Aes.subWord(temp);
    }
    for (var t=0; t<4; t++) w[i][t] = w[i-Nk][t] ^ temp[t];
  }

  return w;
}

/*
 * ---- remaining routines are private, not called externally ----
 */

Aes.subBytes = function(s, Nb) {    // apply SBox to state S [§5.1.1]
  for (var r=0; r<4; r++) {
    for (var c=0; c<Nb; c++) s[r][c] = Aes.sBox[s[r][c]];
  }
  return s;
}

Aes.shiftRows = function(s, Nb) {    // shift row r of state S left by r bytes [§5.1.2]
  var t = new Array(4);
  for (var r=1; r<4; r++) {
    for (var c=0; c<4; c++) t[c] = s[r][(c+r)%Nb];  // shift into temp copy
    for (var c=0; c<4; c++) s[r][c] = t[c];         // and copy back
  }          // note that this will work for Nb=4,5,6, but not 7,8 (always 4 for AES):
  return s;  // see asmaes.sourceforge.net/rijndael/rijndaelImplementation.pdf
}

Aes.mixColumns = function(s, Nb) {   // combine bytes of each col of state S [§5.1.3]
  for (var c=0; c<4; c++) {
    var a = new Array(4);  // 'a' is a copy of the current column from 's'
    var b = new Array(4);  // 'b' is a•{02} in GF(2^8)
    for (var i=0; i<4; i++) {
      a[i] = s[i][c];
      b[i] = s[i][c]&0x80 ? s[i][c]<<1 ^ 0x011b : s[i][c]<<1;

    }
    // a[n] ^ b[n] is a•{03} in GF(2^8)
    s[0][c] = b[0] ^ a[1] ^ b[1] ^ a[2] ^ a[3]; // 2*a0 + 3*a1 + a2 + a3
    s[1][c] = a[0] ^ b[1] ^ a[2] ^ b[2] ^ a[3]; // a0 * 2*a1 + 3*a2 + a3
    s[2][c] = a[0] ^ a[1] ^ b[2] ^ a[3] ^ b[3]; // a0 + a1 + 2*a2 + 3*a3
    s[3][c] = a[0] ^ b[0] ^ a[1] ^ a[2] ^ b[3]; // 3*a0 + a1 + a2 + 2*a3
  }
  return s;
}

Aes.addRoundKey = function(state, w, rnd, Nb) {  // xor Round Key into state S [§5.1.4]
  for (var r=0; r<4; r++) {
    for (var c=0; c<Nb; c++) state[r][c] ^= w[rnd*4+c][r];
  }
  return state;
}

Aes.subWord = function(w) {    // apply SBox to 4-byte word w
  for (var i=0; i<4; i++) w[i] = Aes.sBox[w[i]];
  return w;
}

Aes.rotWord = function(w) {    // rotate 4-byte word w left by one byte
  var tmp = w[0];
  for (var i=0; i<3; i++) w[i] = w[i+1];
  w[3] = tmp;
  return w;
}

// sBox is pre-computed multiplicative inverse in GF(2^8) used in subBytes and keyExpansion [§5.1.1]
Aes.sBox =  [0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
             0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
             0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
             0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
             0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
             0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
             0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
             0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
             0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
             0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
             0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
             0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
             0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
             0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
             0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
             0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16];

// rCon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [§5.2]
Aes.rCon = [ [0x00, 0x00, 0x00, 0x00],
             [0x01, 0x00, 0x00, 0x00],
             [0x02, 0x00, 0x00, 0x00],
             [0x04, 0x00, 0x00, 0x00],
             [0x08, 0x00, 0x00, 0x00],
             [0x10, 0x00, 0x00, 0x00],
             [0x20, 0x00, 0x00, 0x00],
             [0x40, 0x00, 0x00, 0x00],
             [0x80, 0x00, 0x00, 0x00],
             [0x1b, 0x00, 0x00, 0x00],
             [0x36, 0x00, 0x00, 0x00] ];


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
/*  AES Counter-mode implementation in JavaScript (c) Chris Veness 2005-2009                      */
/*   - see http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf                       */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */

Aes.Ctr = {};  // Aes.Ctr namespace: a subclass or extension of Aes

/**
 * Encrypt a text using AES encryption in Counter mode of operation
 *
 * Unicode multi-byte character safe
 *
 * @param {String} plaintext Source text to be encrypted
 * @param {String} password  The password to use to generate a key
 * @param {Number} nBits     Number of bits to be used in the key (128, 192, or 256)
 * @returns {string}         Encrypted text
 */
Aes.Ctr.encrypt = function(plaintext, password, nBits) {
  var blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
  if (!(nBits==128 || nBits==192 || nBits==256)) return '';  // standard allows 128/192/256 bit keys
  plaintext = Utf8.encode(plaintext);
  password = Utf8.encode(password);
  //var t = new Date();  // timer

  // use AES itself to encrypt password to get cipher key (using plain password as source for key
  // expansion) - gives us well encrypted key
  var nBytes = nBits/8;  // no bytes in key
  var pwBytes = new Array(nBytes);
  for (var i=0; i<nBytes; i++) {
    pwBytes[i] = isNaN(password.charCodeAt(i)) ? 0 : password.charCodeAt(i);
  }
  var key = Aes.cipher(pwBytes, Aes.keyExpansion(pwBytes));  // gives us 16-byte key
  key = key.concat(key.slice(0, nBytes-16));  // expand key to 16/24/32 bytes long

  // initialise counter block (NIST SP800-38A §B.2): millisecond time-stamp for nonce in 1st 8 bytes,
  // block counter in 2nd 8 bytes
  var counterBlock = new Array(blockSize);
  var nonce = (new Date()).getTime();  // timestamp: milliseconds since 1-Jan-1970
  var nonceSec = Math.floor(nonce/1000);
  var nonceMs = nonce%1000;
  // encode nonce with seconds in 1st 4 bytes, and (repeated) ms part filling 2nd 4 bytes
  for (var i=0; i<4; i++) counterBlock[i] = (nonceSec >>> i*8) & 0xff;
  for (var i=0; i<4; i++) counterBlock[i+4] = nonceMs & 0xff;
  // and convert it to a string to go on the front of the ciphertext
  var ctrTxt = '';
  for (var i=0; i<8; i++) ctrTxt += String.fromCharCode(counterBlock[i]);

  // generate key schedule - an expansion of the key into distinct Key Rounds for each round
  var keySchedule = Aes.keyExpansion(key);

  var blockCount = Math.ceil(plaintext.length/blockSize);
  var ciphertxt = new Array(blockCount);  // ciphertext as array of strings

  for (var b=0; b<blockCount; b++) {
    // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
    // done in two stages for 32-bit ops: using two words allows us to go past 2^32 blocks (68GB)
    for (var c=0; c<4; c++) counterBlock[15-c] = (b >>> c*8) & 0xff;
    for (var c=0; c<4; c++) counterBlock[15-c-4] = (b/0x100000000 >>> c*8)

    var cipherCntr = Aes.cipher(counterBlock, keySchedule);  // -- encrypt counter block --

    // block size is reduced on final block
    var blockLength = b<blockCount-1 ? blockSize : (plaintext.length-1)%blockSize+1;
    var cipherChar = new Array(blockLength);

    for (var i=0; i<blockLength; i++) {  // -- xor plaintext with ciphered counter char-by-char --
      cipherChar[i] = cipherCntr[i] ^ plaintext.charCodeAt(b*blockSize+i);
      cipherChar[i] = String.fromCharCode(cipherChar[i]);
    }
    ciphertxt[b] = cipherChar.join('');
  }

  // Array.join is more efficient than repeated string concatenation in IE
  var ciphertext = ctrTxt + ciphertxt.join('');
  ciphertext = Base64.encode(ciphertext);  // encode in base64

  //alert((new Date()) - t);
  return ciphertext;
}

/**
 * Decrypt a text encrypted by AES in counter mode of operation
 *
 * @param {String} ciphertext Source text to be encrypted
 * @param {String} password   The password to use to generate a key
 * @param {Number} nBits      Number of bits to be used in the key (128, 192, or 256)
 * @returns {String}          Decrypted text
 */
Aes.Ctr.decrypt = function(ciphertext, password, nBits) {
  var blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
  if (!(nBits==128 || nBits==192 || nBits==256)) return '';  // standard allows 128/192/256 bit keys
  ciphertext = Base64.decode(ciphertext);
  password = Utf8.encode(password);
  //var t = new Date();  // timer

  // use AES to encrypt password (mirroring encrypt routine)
  var nBytes = nBits/8;  // no bytes in key
  var pwBytes = new Array(nBytes);
  for (var i=0; i<nBytes; i++) {
    pwBytes[i] = isNaN(password.charCodeAt(i)) ? 0 : password.charCodeAt(i);
  }
  var key = Aes.cipher(pwBytes, Aes.keyExpansion(pwBytes));
  key = key.concat(key.slice(0, nBytes-16));  // expand key to 16/24/32 bytes long

  // recover nonce from 1st 8 bytes of ciphertext
  var counterBlock = new Array(8);
  ctrTxt = ciphertext.slice(0, 8);
  for (var i=0; i<8; i++) counterBlock[i] = ctrTxt.charCodeAt(i);

  // generate key schedule
  var keySchedule = Aes.keyExpansion(key);

  // separate ciphertext into blocks (skipping past initial 8 bytes)
  var nBlocks = Math.ceil((ciphertext.length-8) / blockSize);
  var ct = new Array(nBlocks);
  for (var b=0; b<nBlocks; b++) ct[b] = ciphertext.slice(8+b*blockSize, 8+b*blockSize+blockSize);
  ciphertext = ct;  // ciphertext is now array of block-length strings

  // plaintext will get generated block-by-block into array of block-length strings
  var plaintxt = new Array(ciphertext.length);

  for (var b=0; b<nBlocks; b++) {
    // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
    for (var c=0; c<4; c++) counterBlock[15-c] = ((b) >>> c*8) & 0xff;
    for (var c=0; c<4; c++) counterBlock[15-c-4] = (((b+1)/0x100000000-1) >>> c*8) & 0xff;

    var cipherCntr = Aes.cipher(counterBlock, keySchedule);  // encrypt counter block

    var plaintxtByte = new Array(ciphertext[b].length);
    for (var i=0; i<ciphertext[b].length; i++) {
      // -- xor plaintxt with ciphered counter byte-by-byte --
      plaintxtByte[i] = cipherCntr[i] ^ ciphertext[b].charCodeAt(i);
      plaintxtByte[i] = String.fromCharCode(plaintxtByte[i]);
    }
    plaintxt[b] = plaintxtByte.join('');
  }

  // join array of blocks into single plaintext string
  var plaintext = plaintxt.join('');
  plaintext = Utf8.decode(plaintext);  // decode from UTF8 back to Unicode multi-byte chars

  //alert((new Date()) - t);
  return plaintext;
}


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
/*  Base64 class: Base 64 encoding / decoding (c) Chris Veness 2002-2010                          */
/*    note: depends on Utf8 class                                                                 */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */

var Base64 = {};  // Base64 namespace

Base64.code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

/**
 * Encode string into Base64, as defined by RFC 4648 [http://tools.ietf.org/html/rfc4648]
 * (instance method extending String object). As per RFC 4648, no newlines are added.
 *
 * @param {String} str The string to be encoded as base-64
 * @param {Boolean} [utf8encode=false] Flag to indicate whether str is Unicode string to be encoded
 *   to UTF8 before conversion to base64; otherwise string is assumed to be 8-bit characters
 * @returns {String} Base64-encoded string
 */
Base64.encode = function(str, utf8encode) {  // http://tools.ietf.org/html/rfc4648
  utf8encode =  (typeof utf8encode == 'undefined') ? false : utf8encode;
  var o1, o2, o3, bits, h1, h2, h3, h4, e=[], pad = '', c, plain, coded;
  var b64 = Base64.code;

  plain = utf8encode ? str.encodeUTF8() : str;

  c = plain.length % 3;  // pad string to length of multiple of 3
  if (c > 0) { while (c++ < 3) { pad += '='; plain += '\0'; } }
  // note: doing padding here saves us doing special-case packing for trailing 1 or 2 chars

  for (c=0; c<plain.length; c+=3) {  // pack three octets into four hexets
    o1 = plain.charCodeAt(c);
    o2 = plain.charCodeAt(c+1);
    o3 = plain.charCodeAt(c+2);

    bits = o1<<16 | o2<<8 | o3;

    h1 = bits>>18 & 0x3f;
    h2 = bits>>12 & 0x3f;
    h3 = bits>>6 & 0x3f;
    h4 = bits & 0x3f;

    // use hextets to index into code string
    e[c/3] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
  }
  coded = e.join('');  // join() is far faster than repeated string concatenation in IE

  // replace 'A's from padded nulls with '='s
  coded = coded.slice(0, coded.length-pad.length) + pad;

  return coded;
}

/**
 * Decode string from Base64, as defined by RFC 4648 [http://tools.ietf.org/html/rfc4648]
 * (instance method extending String object). As per RFC 4648, newlines are not catered for.
 *
 * @param {String} str The string to be decoded from base-64
 * @param {Boolean} [utf8decode=false] Flag to indicate whether str is Unicode string to be decoded
 *   from UTF8 after conversion from base64
 * @returns {String} decoded string
 */
Base64.decode = function(str, utf8decode) {
  utf8decode =  (typeof utf8decode == 'undefined') ? false : utf8decode;
  var o1, o2, o3, h1, h2, h3, h4, bits, d=[], plain, coded;
  var b64 = Base64.code;

  coded = utf8decode ? str.decodeUTF8() : str;


  for (var c=0; c<coded.length; c+=4) {  // unpack four hexets into three octets
    h1 = b64.indexOf(coded.charAt(c));
    h2 = b64.indexOf(coded.charAt(c+1));
    h3 = b64.indexOf(coded.charAt(c+2));
    h4 = b64.indexOf(coded.charAt(c+3));

    bits = h1<<18 | h2<<12 | h3<<6 | h4;

    o1 = bits>>>16 & 0xff;
    o2 = bits>>>8 & 0xff;
    o3 = bits & 0xff;

    d[c/4] = String.fromCharCode(o1, o2, o3);
    // check for padding
    if (h4 == 0x40) d[c/4] = String.fromCharCode(o1, o2);
    if (h3 == 0x40) d[c/4] = String.fromCharCode(o1);
  }
  plain = d.join('');  // join() is far faster than repeated string concatenation in IE

  return utf8decode ? plain.decodeUTF8() : plain;
}


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
/*  Utf8 class: encode / decode between multi-byte Unicode characters and UTF-8 multiple          */
/*              single-byte character encoding (c) Chris Veness 2002-2010                         */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */

var Utf8 = {};  // Utf8 namespace

/**
 * Encode multi-byte Unicode string into utf-8 multiple single-byte characters
 * (BMP / basic multilingual plane only)
 *
 * Chars in range U+0080 - U+07FF are encoded in 2 chars, U+0800 - U+FFFF in 3 chars
 *
 * @param {String} strUni Unicode string to be encoded as UTF-8
 * @returns {String} encoded string
 */
Utf8.encode = function(strUni) {
  // use regular expressions & String.replace callback function for better efficiency
  // than procedural approaches
  var strUtf = strUni.replace(
      /[\u0080-\u07ff]/g,  // U+0080 - U+07FF => 2 bytes 110yyyyy, 10zzzzzz
      function(c) {
        var cc = c.charCodeAt(0);
        return String.fromCharCode(0xc0 | cc>>6, 0x80 | cc&0x3f); }
    );
  strUtf = strUtf.replace(
      /[\u0800-\uffff]/g,  // U+0800 - U+FFFF => 3 bytes 1110xxxx, 10yyyyyy, 10zzzzzz
      function(c) {
        var cc = c.charCodeAt(0);
        return String.fromCharCode(0xe0 | cc>>12, 0x80 | cc>>6&0x3F, 0x80 | cc&0x3f); }
    );
  return strUtf;
}

/**
 * Decode utf-8 encoded string back into multi-byte Unicode characters
 *
 * @param {String} strUtf UTF-8 string to be decoded back to Unicode
 * @returns {String} decoded string
 */
Utf8.decode = function(strUtf) {
  // note: decode 3-byte chars first as decoded 2-byte strings could appear to be 3-byte char!
  var strUni = strUtf.replace(
      /[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g,  // 3-byte chars
      function(c) {  // (note parentheses for precence)
        var cc = ((c.charCodeAt(0)&0x0f)<<12) | ((c.charCodeAt(1)&0x3f)<<6) | ( c.charCodeAt(2)&0x3f);
        return String.fromCharCode(cc); }
    );
  strUni = strUni.replace(
      /[\u00c0-\u00df][\u0080-\u00bf]/g,                 // 2-byte chars
      function(c) {  // (note parentheses for precence)
        var cc = (c.charCodeAt(0)&0x1f)<<6 | c.charCodeAt(1)&0x3f;
        return String.fromCharCode(cc); }
    );
  return strUni;
}

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */


var hMainWnd = AkelPad.GetMainWnd();
var oSys = AkelPad.SystemFunction();
var hWndEdit = AkelPad.GetEditWnd();

if(hMainWnd && !AkelPad.GetEditReadOnly(hWndEdit))
	encryptOrDecrypt();

function encryptOrDecrypt(pass) {
	var text = AkelPad.GetSelText();
	var selectAll = false;
	if(!text) {
		text = getAllText();
		if(!text) {
			var msg = _localize("Nothing to " + (decrypt ? "decrypt" : "encrypt") + "!");
			AkelPad.MessageBox(hMainWnd, msg, WScript.ScriptName, 48 /*MB_ICONEXCLAMATION*/);
			return;
		}
		selectAll = true;
	}

	if(mode == MODE_USER_SELECT) {
		var dirObj = { value: isBase64(text) };
		var pass = passwordPrompt(WScript.ScriptName, _localize("Password"), true, dirObj);
		if(!pass) // Cancel
			return;
		decrypt = dirObj.value;
	}

	if(decrypt) {
		//if(maxLineWidth > 0)
		text = text.replace(/[\n\r]+/g, "");
		if(!isBase64(text)) {
			AkelPad.MessageBox(
				hMainWnd,
				_localize("Impossible to decrypt: invalid format!"),
				WScript.ScriptName,
				16 /*MB_ICONERROR*/
			);
			return;
		}
	}

	if(!pass)
		pass = passwordPrompt(WScript.ScriptName, _localize(decrypt ? "Decrypt" : "Encrypt"), true);
	if(!pass) // Cancel
		return;

	var res = Aes.Ctr[decrypt ? "decrypt" : "encrypt"](text, pass, 256);
	if(!decrypt && maxLineWidth > 0)
		res = res.replace(new RegExp(".{" + maxLineWidth + "}", "g"), "$&\n");

	insertNoScroll(res, selectAll);
}
function isBase64(str) {
	str = str.replace(/[\n\r]+/g, "");
	return str.length % 4 == 0 && !/[^a-zA-Z0-9+\/]/.test(str.replace(/=+$/, ""));
}

function passwordPrompt(caption, label, modal, direction) {
	var hInstanceDLL = AkelPad.GetInstanceDll();
	var dialogClass = "AkelPad::Scripts::" + WScript.ScriptName + "::" + oSys.Call("kernel32::GetCurrentProcessId");

	// Note: "modal" argument is always true now and following should not happens
	var hWndDialog = oSys.Call("user32::FindWindowEx" + _TCHAR, 0, 0, dialogClass, 0);
	if(hWndDialog) {
		if(oSys.Call("user32::IsIconic", hWndDialog))
			oSys.Call("user32::ShowWindow", hWndDialog, 9 /*SW_RESTORE*/);
		AkelPad.SendMessage(hWndDialog, 7 /*WM_SETFOCUS*/, 0, 0);
		return null;
	}

	if(
		!AkelPad.WindowRegisterClass(dialogClass)
		&& ( // Previous script instance crashed
			!AkelPad.WindowUnregisterClass(dialogClass)
			|| !AkelPad.WindowRegisterClass(dialogClass)
		)
	)
		return null;

	var pass;
	var lpBuffer = AkelPad.MemAlloc(256 * _TSIZE);
	if(!lpBuffer)
		return null;

	var IDC_STATIC      = -1;
	var IDC_ENCRYPT     = 1001;
	var IDC_DECRYPT     = 1002;
	var IDC_PASS        = 1003;
	var IDC_PASS2       = 1004;
	var IDC_PASS2_LABEL = 1005;
	var IDC_SHOWPASS    = 1006;
	var IDC_OK          = 1007;
	var IDC_CANCEL      = 1008;

	var hWndGroupMode, hWndEncrypt, hWndDecrypt;
	var hWndGroup, hWndPassLabel, hWndPass, hWndPass2Label, hWndPass2, hWndShowPass;
	var hWndOK, hWndCancel;

	var addY = direction ? 54 : 0;
	var p2h = direction || !decrypt ? 0 : 52;

	var scale = new Scale(0, hMainWnd);
	var sizeNonClientX = oSys.Call("user32::GetSystemMetrics", 7 /*SM_CXFIXEDFRAME*/)*2;
	var sizeNonClientY = oSys.Call("user32::GetSystemMetrics", 8 /*SM_CYFIXEDFRAME*/)*2
		+ oSys.Call("user32::GetSystemMetrics", 4 /*SM_CYCAPTION*/);

	// Create dialog
	hWndDialog = oSys.Call(
		"user32::CreateWindowEx" + _TCHAR,
		0,                                          //dwExStyle
		dialogClass,                                //lpClassName
		0,                                          //lpWindowName
		0x90CA0000,                                 //WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX
		scale.x(0),                                 //x
		scale.y(0),                                 //y
		scale.x(252) + sizeNonClientX,              //nWidth
		scale.y(214 + addY - p2h) + sizeNonClientY, //nHeight
		hMainWnd,                                   //hWndParent
		0,                                          //ID
		hInstanceDLL,                               //hInstance
		dialogCallback                              //Script function callback. To use it class must be registered by WindowRegisterClass.
	);
	if(!hWndDialog)
		return null;

	function dialogCallback(hWnd, uMsg, wParam, lParam) {
		switch(uMsg) {
			case 1: //WM_CREATE
				function setWindowFontAndText(hWnd, hFont, pText) {
					AkelPad.SendMessage(hWnd, 48 /*WM_SETFONT*/, hFont, true);
					oSys.Call("user32::SetWindowText" + _TCHAR, hWnd, pText.substr(0, 255));
				}

				var hGuiFont = oSys.Call("gdi32::GetStockObject", 17 /*DEFAULT_GUI_FONT*/);

				// Dialog caption
				oSys.Call("user32::SetWindowText" + _TCHAR, hWnd, caption);

				if(direction) {
					// GroupBox mode
					hWndGroupMode = createWindowEx(
						0,            //dwExStyle
						"BUTTON",     //lpClassName
						0,            //lpWindowName
						0x50000007,   //WS_VISIBLE|WS_CHILD|BS_GROUPBOX
						14,           //x
						13,           //y
						224,          //nWidth
						44,           //nHeight
						hWnd,         //hWndParent
						IDC_STATIC,   //ID
						hInstanceDLL, //hInstance
						0             //lpParam
					);
					setWindowFontAndText(hWndGroupMode, hGuiFont, _localize("Direction"));

					// Radiobutton encrypt
					hWndEncrypt = createWindowEx(
						0,            //dwExStyle
						"BUTTON",     //lpClassName
						0,            //lpWindowName
						0x50000009,   //WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON
						26,           //x
						33,           //y
						96,           //nWidth
						16,           //nHeight
						hWnd,         //hWndParent
						IDC_ENCRYPT,  //ID
						hInstanceDLL, //hInstance
						0             //lpParam
					);
					setWindowFontAndText(hWndEncrypt, hGuiFont, _localize("&Encrypt"));
					checked(hWndEncrypt, !direction.value);

					// Radiobutton decrypt
					hWndDecrypt = createWindowEx(
						0,            //dwExStyle
						"BUTTON",     //lpClassName
						0,            //lpWindowName
						0x50000009,   //WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON
						128,          //x
						33,           //y
						96,           //nWidth
						16,           //nHeight
						hWnd,         //hWndParent
						IDC_DECRYPT,  //ID
						hInstanceDLL, //hInstance
						0             //lpParam
					);
					setWindowFontAndText(hWndDecrypt, hGuiFont, _localize("&Decrypt"));
					//checked(hWndDecrypt, mode == MODE_DECRYPT);
					checked(hWndDecrypt, direction.value);
				}

				// GroupBox
				hWndGroup = createWindowEx(
					0,            //dwExStyle
					"BUTTON",     //lpClassName
					0,            //lpWindowName
					0x50000007,   //WS_VISIBLE|WS_CHILD|BS_GROUPBOX
					14,           //x
					13 + addY,    //y
					224,          //nWidth
					152 - p2h,    //nHeight
					hWnd,         //hWndParent
					IDC_STATIC,   //ID
					hInstanceDLL, //hInstance
					0             //lpParam
				);
				setWindowFontAndText(hWndGroup, hGuiFont, label);

				// Static window: password label
				hWndPassLabel = createWindowEx(
					0,            //dwExStyle
					"STATIC",     //lpClassName
					0,            //lpWindowName
					0x50000000,   //WS_VISIBLE|WS_CHILD
					32,           //x
					35 + addY,    //y
					177,          //nWidth
					13,           //nHeight
					hWnd,         //hWndParent
					IDC_STATIC,   //ID
					hInstanceDLL, //hInstance
					0             //lpParam
				);
				setWindowFontAndText(hWndPassLabel, hGuiFont, _localize("Enter &password:"));

				// Edit window: password
				hWndPass = createWindowEx(
					0x200,        //WS_EX_CLIENTEDGE
					"EDIT",       //lpClassName
					0,            //lpWindowName
					0x500100A0,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL|ES_PASSWORD
					29,           //x
					53 + addY,    //y
					195,          //nWidth
					23,           //nHeight
					hWnd,         //hWndParent
					IDC_PASS,     //ID
					hInstanceDLL, //hInstance
					0             //lpParam
				);
				setWindowFontAndText(hWndPass, hGuiFont, "");

				if(direction || !decrypt) {
					// Static window: password 2 label
					hWndPass2Label = createWindowEx(
						0,               //dwExStyle
						"STATIC",        //lpClassName
						0,               //lpWindowName
						0x50000000,      //WS_VISIBLE|WS_CHILD
						32,              //x
						86 + addY,       //y
						177,             //nWidth
						13,              //nHeight
						hWnd,            //hWndParent
						IDC_PASS2_LABEL, //ID
						hInstanceDLL,    //hInstance
						0                //lpParam
					);
					setWindowFontAndText(hWndPass2Label, hGuiFont, _localize("Reenter p&assword:"));

					// Edit window: password 2
					hWndPass2 = createWindowEx(
						0x200,        //WS_EX_CLIENTEDGE
						"EDIT",       //lpClassName
						0,            //lpWindowName
						0x500100A0,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL|ES_PASSWORD
						29,           //x
						104 + addY,   //y
						195,          //nWidth
						23,           //nHeight
						hWnd,         //hWndParent
						IDC_PASS2,    //ID
						hInstanceDLL, //hInstance
						0             //lpParam
					);
					setWindowFontAndText(hWndPass2, hGuiFont, "");
				}

				// Checkbox: show password
				hWndShowPass = createWindowEx(
					0,                //dwExStyle
					"BUTTON",         //lpClassName
					0,                //lpWindowName
					0x50010003,       //WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
					32,               //x
					138 + addY - p2h, //y
					177,              //nWidth
					16,               //nHeight
					hWnd,             //hWndParent
					IDC_SHOWPASS,     //ID
					hInstanceDLL,     //hInstance
					0                 //lpParam
				);
				setWindowFontAndText(hWndShowPass, hGuiFont, _localize("&Show password"));
				var sp = showPassword === undefined
					? saveOptions
						? pref("showPassword", 1 /*PO_DWORD*/) == 1
						: false
					: showPassword;
				checked(hWndShowPass, sp);
				setShowPass(sp, direction ? !direction.value : !decrypt);

				// OK button window
				hWndOK = createWindowEx(
					0,                //dwExStyle
					"BUTTON",         //lpClassName
					0,                //lpWindowName
					0x50010001,       //WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_DEFPUSHBUTTON
					13,               //x
					178 + addY - p2h, //y
					107,              //nWidth
					23,               //nHeight
					hWnd,             //hWndParent
					IDC_OK,           //ID
					hInstanceDLL,     //hInstance
					0                 //lpParam
				);
				setWindowFontAndText(hWndOK, hGuiFont, _localize("OK"));

				// Cancel button window
				hWndCancel = createWindowEx(
					0,                //dwExStyle
					"BUTTON",         //lpClassName
					0,                //lpWindowName
					0x50010000,       //WS_VISIBLE|WS_CHILD|WS_TABSTOP
					132,              //x
					178 + addY - p2h, //y
					107,              //nWidth
					23,               //nHeight
					hWnd,             //hWndParent
					IDC_CANCEL,       //ID
					hInstanceDLL,     //hInstance
					0                 //lpParam
				);
				setWindowFontAndText(hWndCancel, hGuiFont, _localize("Cancel"));

				oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_PASS, 0);

				//centerWindow(hMainWnd, hWnd);
				centerWindow(null, hWnd);
			break;
			case 7: //WM_SETFOCUS
				var hWndFocus = hWndPass;
				if(direction) {
					if(checked(hWndEncrypt))      hWndFocus = hWndEncrypt;
					else if(checked(hWndDecrypt)) hWndFocus = hWndDecrypt;
				}
				oSys.Call("user32::SetFocus", hWndFocus);
			break;
			case 256: //WM_KEYDOWN
				if(wParam == 27) //VK_ESCAPE
					oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_CANCEL, 0);
				else if(wParam == 13) //VK_RETURN
					oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_OK, 0);
			break;
			case 273: //WM_COMMAND
				switch(wParam & 0xffff) {
					case IDC_OK:
						oSys.Call("user32::GetWindowText" + _TCHAR, hWndPass, lpBuffer, 256);
						var pass1 = AkelPad.MemRead(lpBuffer, _TSTR);
						if(!pass1)
							break;
						var showPass = checked(hWndShowPass);
						var enc = direction ? checked(hWndEncrypt) : !decrypt;
						if(!showPass && enc) {
							oSys.Call("user32::GetWindowText" + _TCHAR, hWndPass2, lpBuffer, 256);
							var pass2 = AkelPad.MemRead(lpBuffer, _TSTR);
							if(pass1 != pass2) {
								AkelPad.MessageBox(
									hWnd,
									_localize("Passwords do not match!"),
									WScript.ScriptName,
									16 /*MB_ICONERROR*/
								);
								break;
							}
						}
						if(direction && !readRadiosState())
							break;
						saveOptions && pref("showPassword", 1 /*PO_DWORD*/, Number(showPass));
						pass = pass1;
						closeDialog();
					break;
					case IDC_CANCEL:
						closeDialog();
					break;
					case IDC_SHOWPASS:
					case IDC_ENCRYPT:
					case IDC_DECRYPT:
						setShowPass(checked(hWndShowPass), direction ? checked(hWndEncrypt) : !decrypt);
					break;
					case IDC_PASS:
					case IDC_PASS2:
						var hasPass = oSys.Call("user32::GetWindowTextLength" + _TCHAR, hWndPass) > 0;
						enabled(hWndOK,    hasPass);
						enabled(hWndPass2, hasPass);
				}
			break;
			case 16: //WM_CLOSE
				modal && enabled(hMainWnd, true); // Enable main window
				oSys.Call("user32::DestroyWindow", hWnd); // Destroy dialog
			break;
			case 2: //WM_DESTROY
				oSys.Call("user32::PostQuitMessage", 0); // Exit message loop
		}
		return 0;
	}
	function centerWindow(hWndParent, hWnd) {
		var lpRect = AkelPad.MemAlloc(16); //sizeof(RECT)
		if(!lpRect)
			return;
		if(!hWndParent)
			hWndParent = oSys.Call("user32::GetDesktopWindow");
		oSys.Call("user32::GetWindowRect", hWndParent, lpRect);
		var rcWndParent = parseRect(lpRect);
		oSys.Call("user32::GetWindowRect", hWnd, lpRect);
		var rcWnd = parseRect(lpRect);
		var x = rcWndParent.left + ((rcWndParent.right  - rcWndParent.left) / 2 - (rcWnd.right  - rcWnd.left) / 2);
		var y = rcWndParent.top  + ((rcWndParent.bottom - rcWndParent.top)  / 2 - (rcWnd.bottom - rcWnd.top)  / 2);
		oSys.Call("user32::SetWindowPos", hWnd, 0, x, y, 0, 0, 0x15 /*SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE*/);
		AkelPad.MemFree(lpRect);
	}
	function parseRect(lpRect) {
		return {
			left:   AkelPad.MemRead(lpRect,      3 /*DT_DWORD*/),
			top:    AkelPad.MemRead(lpRect +  4, 3 /*DT_DWORD*/),
			right:  AkelPad.MemRead(lpRect +  8, 3 /*DT_DWORD*/),
			bottom: AkelPad.MemRead(lpRect + 12, 3 /*DT_DWORD*/)
		};
	}
	function readRadiosState() {
		if(checked(hWndEncrypt))
			direction.value = false;
		else if(checked(hWndDecrypt))
			direction.value = true;
		else
			return false;
		return true;
	}
	function checked(hWnd, val) {
		return arguments.length == 1
			? AkelPad.SendMessage(hWnd, 240 /*BM_GETCHECK*/, 0, 0)
			: AkelPad.SendMessage(hWnd, 241 /*BM_SETCHECK*/, val ? 1 /*BST_CHECKED*/ : 0, 0);
	}
	function enabled(hWnd, val) {
		oSys.Call("user32::EnableWindow", hWnd, val);
	}
	function showWindow(hWnd, val) {
		oSys.Call("user32::ShowWindow", hWnd, val);
	}
	function closeDialog() {
		oSys.Call("user32::PostMessage" + _TCHAR, hWndDialog, 16 /*WM_CLOSE*/, 0, 0);
	}
	function setShowPass(showPass, showSecondField) {
		showSecondField = !showPass && showSecondField;
		hWndPass2Label && showWindow(hWndPass2Label, showSecondField);
		hWndPass2      && showWindow(hWndPass2,      showSecondField);
		if(!setShowPass.passChar)
			setShowPass.passChar = AkelPad.SendMessage(hWndPass, 0x00D2/*EM_GETPASSWORDCHAR*/, 0, 0) || 0x002A;
		var passChar = showPass ? 0 : setShowPass.passChar;
		AkelPad.SendMessage(hWndPass, 0x00CC/*EM_SETPASSWORDCHAR*/, passChar, 0);
		oSys.Call("user32::InvalidateRect", hWndPass, 0, 1/*TRUE*/);
	}

	function Scale(hDC, hWnd) {
		var hNewDC = hDC || oSys.Call("user32::GetDC", hWnd);
		if(hNewDC) {
			this._x = oSys.Call("gdi32::GetDeviceCaps", hNewDC, 88 /*LOGPIXELSX*/);
			this._y = oSys.Call("gdi32::GetDeviceCaps", hNewDC, 90 /*LOGPIXELSY*/);

			//Align to 16 pixel
			this._x += (16 - this._x % 16) % 16;
			this._y += (16 - this._y % 16) % 16;

			!hDC && oSys.Call("user32::ReleaseDC", hWnd, hNewDC);

			this.x = function(x) {
				return oSys.Call("kernel32::MulDiv", x, this._x, 96);
			};
			this.y = function(y) {
				return oSys.Call("kernel32::MulDiv", y, this._y, 96);
			};
		}
		else {
			this.x = this.y = function(n) {
				return n;
			};
		}
	}
	function createWindowEx(
		dwExStyle, lpClassName, lpWindowName, dwStyle,
		x, y, w, h,
		hWndParent, id, hInstance, callback
	) {
		return oSys.Call(
			"user32::CreateWindowEx" + _TCHAR,
			dwExStyle,
			lpClassName,
			lpWindowName,
			dwStyle,
			scale.x(x),
			scale.y(y),
			scale.x(w),
			scale.y(h),
			hWndParent,
			id,
			hInstance,
			callback || 0
		);
	}

	modal && enabled(hMainWnd, false); // Disable main window, to make dialog modal

	AkelPad.ScriptNoMutex(); // Allow other scripts running
	AkelPad.WindowGetMessage(); // Message loop

	AkelPad.MemFree(lpBuffer);
	AkelPad.WindowUnregisterClass(dialogClass);
	return pass;
}

function getAllText() {
	if(typeof AkelPad.GetTextRange != "undefined")
		return AkelPad.GetTextRange(0, -1);
	var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
	if(!lpPoint)
		return "";
	setRedraw(hWndEdit, false);
	AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

	var columnSel = AkelPad.SendMessage(hWndEdit, 3127 /*AEM_GETCOLUMNSEL*/, 0, 0);
	var ss = AkelPad.GetSelStart();
	var se = AkelPad.GetSelEnd();

	AkelPad.SetSel(0, -1);
	var str = AkelPad.GetSelText();

	AkelPad.SetSel(ss, se);
	columnSel && AkelPad.SendMessage(hWndEdit, 3128 /*AEM_UPDATESEL*/, 0x1 /*AESELT_COLUMNON*/, 0);

	AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
	AkelPad.MemFree(lpPoint);
	setRedraw(hWndEdit, true);
	return str;
}
function insertNoScroll(str, selectAll) {
	var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
	if(!lpPoint)
		return;
	setRedraw(hWndEdit, false);
	AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

	selectAll && AkelPad.SetSel(0, -1);
	//var ss = AkelPad.GetSelStart();
	AkelPad.ReplaceSel(str, true);
	//if(ss != AkelPad.GetSelStart())
	//	AkelPad.SetSel(ss, ss + str.length);

	AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
	setRedraw(hWndEdit, true);
	AkelPad.MemFree(lpPoint);
}
function setRedraw(hWnd, bRedraw) {
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
	bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
function pref(name, type, val) {
	var oSet = AkelPad.ScriptSettings();
	if(arguments.length == 3) {
		if(!oSet.Begin(WScript.ScriptBaseName, 0x2 /*POB_SAVE*/))
			return false;
		var ok = oSet.Write(name, type, val);
		oSet.End();
		return ok;
	}
	if(!oSet.Begin(WScript.ScriptBaseName, 0x1 /*POB_READ*/))
		return undefined;
	var ret = oSet.Read(name, type || 1 /*PO_DWORD*/);
	oSet.End();
	return ret;
}
function getArg(argName, defaultVal) {
	var args = {};
	for(var i = 0, argsCount = WScript.Arguments.length; i < argsCount; i++)
		if(/^[-\/](\w+)(=(.+))?$/i.test(WScript.Arguments(i)))
			args[RegExp.$1.toLowerCase()] = RegExp.$3 ? eval(RegExp.$3) : true;
	getArg = function(argName, defaultVal) {
		argName = argName.toLowerCase();
		return typeof args[argName] == "undefined" // argName in args
			? defaultVal
			: args[argName];
	};
	return getArg(argName, defaultVal);
}
<download | mirror | development version> (see crypt.js)
Encrypt/decrypt text using AES-256.
It can be very slow, be careful.

Posted: Sun Jan 30, 2011 11:05 pm
by Infocatcher

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11213#p11213
// http://infocatcher.ucoz.net/js/akelpad_scripts/insertTag.js
// https://github.com/Infocatcher/AkelPad_scripts/blob/master/insertTag.js

// (c) Infocatcher 2009-2012, 2014
// version 0.2.6 - 2014-07-28

//===================
// Simplify tags insertion.
// By default ask user for tag and insert
// <tag>{selected_text}</tag>

// Arguments:
//   -bbcode=0                            - Use <tag>
//          =1                            - Use [tag]
//          =-1                           - Autodetection
//   -xmlExts="[sx]html?|mht(ml)?|xml"    - Detect <html>, mask for Coder plugin alias or file extension (for -bbcode=-1)
//   -tagExts='{"": "i", "fb2": "em"}'    - Detect tag by Coder plugin alias or file extension, for %T variable
//                                          "": "i"            - default tag
//                                          "fb2|xhtml?": "em" - regular expression for special files
//                                          "ext": ""          - tag not supported in *.ext files
//   -clip=true                           - Use text from clipboard instead of selected text
//   -selectMode=0                        - Select all inserted text: [<tag>text</tag>]
//              =1                        - Select text inside tags:  <tag>[text]</tag>
//   -tag="div"                           - Don't ask tag, you also can use %T with -tagExts
//   -template='<a href="%%|">%%S</a>'    - Use template (and ignore all other arguments)
//   -saveLastTag=0                       - don't save last used tag
//               =1                       - save only typed (default)
//               =2                       - always save

// Special variables in templates:
//   %|  - selection start or end
//   %S  - selected text
//   %C  - clipboard text
//   %SC - selected text or clipboard text
//   %CS - clipboard text or selected text
//   %T  - tag (detected using -tagExts)

// Usage:
//   Call("Scripts::Main", 1, "insertTag.js")
//   Call("Scripts::Main", 1, "insertTag.js", `-bbcode=1 -tag="quote"`)
//   Call("Scripts::Main", 1, "insertTag.js", `-template='<a href="%%C">%%|%%S%%|</a>'`)
//   Call("Scripts::Main", 1, "insertTag.js", `-bbcode=-1 -tag="%%T" -tagExts='{"": "i", "fb2|xhtml?": "em"}'`)
//===================

function _localize(s) {
	var strings = {
		"Tag or template:": {
			ru: "Тэг или шаблон:"
		},
		"Tag %T not supported!": {
			ru: "Тэг %T не поддерживается!"
		},
		"Tags %T not supported!": {
			ru: "Тэги %T не поддерживаются!"
		}
	};
	var lng = "en";
	switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
		case 0x19: lng = "ru";
	}
	_localize = function(s) {
		return strings[s] && strings[s][lng] || s;
	};
	return _localize(s);
}

// Read arguments:
// getArg(argName, defaultValue)
var useBBCode    = getArg("bbcode", -1);
var xmlExts      = getArg("xmlExts", "[xs]?html?|mht(ml)?|hta|asp|jsm?|css|xml|axl|dxl|fb2|kml|manifest|msc|ndl|rdf|rss|svg|user|wsdl|xaml|xmp|xsd|xslt?|xul|xbl|resx|v[cbd]proj|csproj|wx[ils]|wixobj|wixout|wixlib|wixpdb|wixmsp|wixmst");
var tagExts      = getArg("tagExts", "");
var useClipboard = getArg("clip", false);
var selectMode   = getArg("selectMode", 0);
var tag          = getArg("tag"); // Override tag prompt
var template     = getArg("template"); // Use template and ignore all arguments except -bbcode=-1 (and -xmlExts)
var saveLastTag  = getArg("saveLastTag", 1);


var hMainWnd = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();

if(hMainWnd && !AkelPad.GetEditReadOnly(hWndEdit))
	insertTag();

function insertTag() {
	var txt, ss, se;
	if(template) {
		// Example: <a href="%C">%|%S%|</a>
		if(useBBCode == -1) {
			template = detectBBCode()
				? template.replace(/</g, "[").replace(/>/g, "]")
				: template.replace(/\[/g, "<").replace(/\]/g, ">");
		}

		var rnd = function() {
			return Math.random().toString(36).substr(2) + Math.random().toString(36).substr(2);
		};
		var posMarker = rnd();
		var percent   = rnd();

		var sel  = /%C?S/.test(template) && AkelPad.GetSelText();
		var clip = /%S?C/.test(template) && AkelPad.GetClipboardText();
		if(/%T/.test(template)) {
			var autoTag = detectTag();
			if(tagNotSupported(autoTag))
				return;
		}

		txt = template
			.replace(/%%/g, percent)
			.replace(/%\|/g, posMarker)
			.replace(/%SC/g, sel || clip)
			.replace(/%CS/g, clip || sel)
			.replace(/%S/g, sel)
			.replace(/%C/g, clip)
			.replace(/%T/g, autoTag)
			.replace(new RegExp(percent, "g"), "%");

		var posMarkerRe = new RegExp(posMarker);
		if(posMarkerRe.test(txt)) {
			ss = se = AkelPad.GetSelStart() + RegExp.leftContext.length;
			txt = RegExp.leftContext + RegExp.rightContext;
		}
		if(posMarkerRe.test(txt)) {
			se = AkelPad.GetSelStart() + RegExp.leftContext.length;
			txt = RegExp.leftContext + RegExp.rightContext;
		}
	}
	else {
		txt = useClipboard
			? AkelPad.GetClipboardText()
			: AkelPad.GetSelText();
		var hasTxt = !!txt;

		if(!tag) {
			var tagTyped = true;
			tag = AkelPad.InputBox(
				hMainWnd,
				WScript.ScriptName,
				_localize("Tag or template:"),
				saveLastTag && pref("lastTag", 3 /*PO_STRING*/) || ""
			);
		}
		if(!tag)
			return;
		if(saveLastTag && (tagTyped || saveLastTag == 2))
			pref("lastTag", 3 /*PO_STRING*/, tag);

		if(tagTyped && /%[%|SC]/.test(tag)) {
			template = tag;
			useBBCode = tag.charAt(0) == "[";
			insertTag();
			return;
		}

		if(tagTyped) {
			var first = tag.charAt(0);
			if(first == "<" || first == "[") { // [tag -> tag
				useBBCode = first == "[";
				tag = tag.substr(1);
				if(tag.charAt(tag.length - 1) == (useBBCode ? "]" : ">")) // tag] -> tag
					tag = tag.slice(0, -1);
			}
		}

		if(useBBCode == -1)
			useBBCode = detectBBCode();

		var attrs = /^([^\s=]+)([\s=].*)$/.test(tag) ? RegExp.$2 : "";
		if(attrs)
			tag = RegExp.$1;

		if(/%T/.test(tag)) {
			var autoTag = detectTag();
			if(tagNotSupported(autoTag))
				return;
			tag = tag.replace(/%T/g, autoTag);
		}

		var sTag = (useBBCode ? "["  : "<")  + tag + attrs + (useBBCode ? "]" : ">");
		var eTag = (useBBCode ? "[/" : "</") + tag         + (useBBCode ? "]" : ">");
		txt = sTag + txt + eTag;

		if(!hasTxt || selectMode == 1) {
			var _ss = AkelPad.GetSelStart();
			ss = _ss + sTag.length;
			se = _ss + txt.length - eTag.length;
		}
	}
	insertNoScroll(txt, ss, se);
}
function detectBBCode() {
	return !extPattern(xmlExts).test(getFileType());
}
function detectTag() {
	var patterns = getTagData();
	if(!patterns)
		return undefined;
	var fileType = getFileType();
	for(var exts in patterns)
		if(extPattern(exts).test(fileType))
			return patterns[exts];
	return patterns[""] || undefined;
}
function getTagData() {
	var patterns = tagExts && eval("(" + tagExts + ")");
	getTagData = function() {
		return patterns;
	};
	return patterns;
}
function tagNotSupported(tag) {
	if(!tag) {
		var tags = [];
		var patterns = getTagData();
		if(patterns) for(var exts in patterns)
			if(patterns[exts])
				tags.push(patterns[exts]);
		AkelPad.MessageBox(
			hMainWnd,
			_localize(tags.length > 1 ? "Tags %T not supported!" : "Tag %T not supported!")
				.replace("%T", tags.join(", ")),
			WScript.ScriptName,
			48 /*MB_ICONEXCLAMATION*/
		);
	}
	return !tag;
}
function extPattern(exts) {
	return new RegExp("\\.(" + exts + ")$", "i");
}
function getFileType() {
	var fileType = getCoderAlias() || AkelPad.GetEditFile(0);
	getFileType = function() {
		return fileType;
	};
	return fileType;
}
function getCoderAlias() {
	if(
		!AkelPad.IsPluginRunning("Coder::HighLight")
		&& !AkelPad.IsPluginRunning("Coder::CodeFold")
		&& !AkelPad.IsPluginRunning("Coder::AutoComplete")
	)
		return "";
	// http://akelpad.sourceforge.net/forum/viewtopic.php?p=19363#p19363
	var hWndEdit = AkelPad.GetEditWnd();
	var hDocEdit = AkelPad.GetEditDoc();
	var pAlias = "";
	if(hWndEdit && hDocEdit) {
		var lpAlias = AkelPad.MemAlloc(256 * 2 /*sizeof(wchar_t)*/);
		if(lpAlias) {
			AkelPad.CallW("Coder::Settings", 18 /*DLLA_CODER_GETALIAS*/, hWndEdit, hDocEdit, lpAlias, 0);
			pAlias = AkelPad.MemRead(lpAlias, 1 /*DT_UNICODE*/);
			AkelPad.MemFree(lpAlias);
		}
	}
	return pAlias;
}

function insertNoScroll(str, ss, se) {
	var nFirstLine = saveLineScroll(hWndEdit);

	//var ss = AkelPad.GetSelStart();
	AkelPad.ReplaceSel(str, true);
	//if(ss != AkelPad.GetSelStart())
	//	AkelPad.SetSel(ss, ss + str.length);

	if(ss != undefined || se != undefined) {
		if(ss == undefined) ss = AkelPad.GetSelStart();
		if(se == undefined) se = AkelPad.GetSelEnd();
		AkelPad.SetSel(ss, se);
	}

	restoreLineScroll(hWndEdit, nFirstLine);
}
// From Instructor's SearchReplace.js
function saveLineScroll(hWnd)
{
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, false, 0);
	return AkelPad.SendMessage(hWnd, 3129 /*AEM_GETLINENUMBER*/, 4 /*AEGL_FIRSTVISIBLELINE*/, 0);
}
function restoreLineScroll(hWnd, nBeforeLine)
{
	if (AkelPad.SendMessage(hWnd, 3129 /*AEM_GETLINENUMBER*/, 4 /*AEGL_FIRSTVISIBLELINE*/, 0) != nBeforeLine)
	{
		var lpScrollPos;
		var nPosY=AkelPad.SendMessage(hWnd, 3198 /*AEM_VPOSFROMLINE*/, 0 /*AECT_GLOBAL*/, nBeforeLine);

		if (lpScrollPos=AkelPad.MemAlloc(_X64?16:8 /*sizeof(POINT64)*/))
		{
			AkelPad.MemCopy(lpScrollPos + 0 /*offsetof(POINT64, x)*/, -1, 2 /*DT_QWORD*/);
			AkelPad.MemCopy(lpScrollPos + (_X64?8:4) /*offsetof(POINT64, y)*/, nPosY, 2 /*DT_QWORD*/);
			AkelPad.SendMessage(hWnd, 3180 /*AEM_SETSCROLLPOS*/, 0, lpScrollPos);
			AkelPad.MemFree(lpScrollPos);
		}
	}
	AkelPad.SendMessage(hWnd, 3377 /*AEM_UPDATECARET*/, 0, 0);
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, true, 0);
	oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}

function getArg(argName, defaultVal) {
	var args = {};
	for(var i = 0, argsCount = WScript.Arguments.length; i < argsCount; i++)
		if(/^[-\/](\w+)(=(.+))?$/i.test(WScript.Arguments(i)))
			args[RegExp.$1.toLowerCase()] = RegExp.$3 ? eval(RegExp.$3) : true;
	getArg = function(argName, defaultVal) {
		argName = argName.toLowerCase();
		return typeof args[argName] == "undefined" // argName in args
			? defaultVal
			: args[argName];
	};
	return getArg(argName, defaultVal);
}
function pref(name, type, val) {
	var oSet = AkelPad.ScriptSettings();
	if(arguments.length == 3) {
		if(!oSet.Begin(WScript.ScriptBaseName, 0x2 /*POB_SAVE*/))
			return false;
		var ok = oSet.Write(name, type, val);
		oSet.End();
		return ok;
	}
	if(!oSet.Begin(WScript.ScriptBaseName, 0x1 /*POB_READ*/))
		return undefined;
	var ret = oSet.Read(name, type || 1 /*PO_DWORD*/);
	oSet.End();
	return ret;
}
<download | mirror | development version>
Simplify tags insertion.
By default ask user for tag and insert
<tag>{selected_text}</tag>

Posted: Tue Feb 01, 2011 6:43 pm
by Infocatcher

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11240#p11240

// (c) Infocatcher 2008, 2011-2012
// version 0.1.2 - 2012-12-11

var map = {
	"à": "a",
	"À": "A",
	"á": "a",
	"Á": "A",
	"â": "a",
	"Â": "A",
	"ã": "a",
	"Ã": "A",
	"ä": "a",
	"Ä": "A",
	"å": "a",
	"Å": "A",
	"æ": "ae",
	"Æ": "AE",
	"ç": "c",
	"Ç": "C",
	"È": "E",
	"è": "e",
	"é": "e",
	"É": "E",
	"ê": "e",
	"Ê": "E",
	"ë": "e",
	"Ë": "E",
	"Ì": "I",
	"ì": "i",
	"í": "i",
	"Í": "I",
	"î": "i",
	"Î": "I",
	"Ï": "I",
	"ï": "i",
	"Ð": "D",
	"ð": "d",
	"ñ": "n",
	"Ñ": "N",
	"Ò": "O",
	"ò": "o",
	"Ó": "O",
	"Ó": "O",
	"ó": "o",
	"ó": "o",
	"ô": "o",
	"Ô": "O",
	"Õ": "O",
	"õ": "o",
	"ö": "o",
	"Ö": "O",
	"ù": "u",
	"Ù": "U",
	"Ú": "U",
	"ú": "u",
	"û": "u",
	"Û": "U",
	"ü": "u",
	"Ü": "U",
	"ý": "y",
	"Ý": "Y",
	"ÿ": "y",
	"Ÿ": "Y",
	"ā": "a",
	"Ā": "A",
	"ă": "a",
	"Ă": "A",
	"Ą": "A",
	"Ą": "A",
	"ą": "a",
	"ą": "a",
	"Ć": "C",
	"ć": "c",
	"Ć": "C",
	"ć": "c",
	"ĉ": "c",
	"Ĉ": "C",
	"Ċ": "C",
	"ċ": "c",
	"č": "c",
	"Č": "C",
	"ď": "d",
	"Ď": "D",
	"Đ": "D",
	"đ": "d",
	"Ē": "E",
	"ē": "e",
	"ĕ": "e",
	"Ĕ": "E",
	"ė": "e",
	"Ė": "E",
	"ę": "e",
	"Ę": "E",
	"Ę": "E",
	"ę": "e",
	"Ě": "E",
	"ě": "e",
	"ĝ": "g",
	"Ĝ": "G",
	"ğ": "g",
	"Ğ": "G",
	"ġ": "g",
	"Ġ": "G",
	"ģ": "g",
	"Ģ": "G",
	"Ĥ": "H",
	"ĥ": "h",
	"ħ": "h",
	"Ħ": "H",
	"ĩ": "i",
	"Ĩ": "I",
	"ī": "i",
	"Ī": "I",
	"Ĭ": "I",
	"ĭ": "i",
	"Į": "I",
	"į": "i",
	"İ": "I",
	"ı": "i",
	"ij": "ij",
	"IJ": "IJ",
	"ĵ": "j",
	"Ĵ": "J",
	"ķ": "k",
	"Ķ": "K",
	"ĸ": "k",
	"ĺ": "l",
	"Ĺ": "L",
	"Ļ": "L",
	"ļ": "l",
	"Ľ": "L",
	"ľ": "l",
	"Ŀ": "L",
	"ŀ": "l",
	"Ł": "L",
	"ł": "l",
	"Ł": "L",
	"ł": "l",
	"ń": "n",
	"Ń": "N",
	"ń": "n",
	"Ń": "N",
	"ņ": "n",
	"Ņ": "N",
	"ň": "n",
	"Ň": "N",
	"ʼn": "n",
	"Ō": "O",
	"ō": "o",
	"Ŏ": "O",
	"ŏ": "o",
	"ő": "o",
	"Ő": "O",
	"œ": "oe",
	"Œ": "OE",
	"Ŕ": "R",
	"ŕ": "r",
	"ŗ": "r",
	"Ŗ": "R",
	"ř": "r",
	"Ř": "R",
	"Ś": "S",
	"ś": "s",
	"ś": "s",
	"Ś": "S",
	"ŝ": "s",
	"Ŝ": "S",
	"ş": "s",
	"Ş": "S",
	"š": "s",
	"Š": "S",
	"Ţ": "T",
	"ţ": "t",
	"ť": "t",
	"Ť": "T",
	"ŧ": "t",
	"Ŧ": "T",
	"ũ": "u",
	"Ũ": "U",
	"Ū": "U",
	"ū": "u",
	"ŭ": "u",
	"Ŭ": "U",
	"ů": "u",
	"Ů": "U",
	"Ű": "U",
	"ű": "u",
	"Ų": "U",
	"ų": "u",
	"ŵ": "w",
	"Ŵ": "W",
	"ŷ": "Y",
	"Ŷ": "Y",
	"Ź": "Z",
	"Ź": "Z",
	"ź": "z",
	"ź": "z",
	"ż": "z",
	"Ż": "Z",
	"Ż": "Z",
	"ż": "z",
	"ž": "z",
	"Ž": "Z",
	"ƀ": "b",
	"ƈ": "c",
	"Ƈ": "C",
	"ƒ": "f",
	"Ƒ": "F",
	"Ƙ": "K",
	"ƙ": "k",
	"ơ": "o",
	"Ơ": "O",
	"ƥ": "p",
	"Ƥ": "P",
	"ƫ": "t",
	"ƭ": "t",
	"Ƭ": "T",
	"Ư": "U",
	"ư": "u",
	"Ƶ": "Z",
	"ƶ": "z",
	"DŽ": "DZ",
	"Dž": "Dz",
	"dž": "dz",
	"Lj": "Lj",
	"LJ": "LJ",
	"lj": "lj",
	"Nj": "Nj",
	"nj": "nj",
	"NJ": "NJ",
	"ǎ": "a",
	"Ǎ": "A",
	"ǐ": "i",
	"Ǐ": "I",
	"Ǒ": "O",
	"ǒ": "o",
	"Ǔ": "U",
	"ǔ": "u",
	"ǖ": "u",
	"Ǖ": "U",
	"ǘ": "u",
	"Ǘ": "U",
	"Ǚ": "U",
	"ǚ": "u",
	"Ǜ": "U",
	"ǜ": "u",
	"ǝ": "e",
	"ǟ": "a",
	"Ǟ": "A",
	"ǡ": "a",
	"Ǡ": "A",
	"ǣ": "ae",
	"Ǣ": "AE",
	"ǥ": "g",
	"Ǥ": "G",
	"ǧ": "g",
	"Ǧ": "G",
	"ǩ": "k",
	"Ǩ": "K",
	"ǫ": "o",
	"Ǫ": "O",
	"ǭ": "o",
	"Ǭ": "O",
	"Ǯ": "Z",
	"ǰ": "J",
	"ǯ": "z",
	"DZ": "DZ",
	"Dz": "Dz",
	"dz": "dz",
	"Ǵ": "G",
	"ǵ": "g",
	"Ǻ": "A",
	"ǻ": "a",
	"Ǽ": "AE",
	"ǽ": "ae",
	"Ǿ": "O",
	"ǿ": "o",
	"Ȁ": "A",
	"ȁ": "a",
	"Ȃ": "A",
	"ȃ": "a",
	"Ȅ": "E",
	"ȅ": "e",
	"Ȇ": "E",
	"ȇ": "e",
	"ȉ": "i",
	"Ȉ": "I",
	"Ȋ": "I",
	"ȋ": "i",
	"Ȍ": "O",
	"ȍ": "o",
	"ȏ": "o",
	"Ȏ": "O",
	"Ȑ": "R",
	"ȑ": "r",
	"Ȓ": "R",
	"ȓ": "r",
	"ȕ": "u",
	"Ȕ": "U",
	"ȗ": "u",
	"Ȗ": "U",
	"ɐ": "a",
	"ɑ": "a",
	"ɒ": "a",
	"Ɓ": "B",
	"Ɖ": "D",
	"ɖ": "d",
	"Ɗ": "D",
	"ɗ": "d",
	"ɛ": "e",
	"Ɠ": "G",
	"Ʀ": "R",
	"Ʈ": "T",
	"ʤ": "dz",
	"ʣ": "dz",
	"ʥ": "dz",
	"ʦ": "ts",
	"ʧ": "tf",
	"ΐ": "i",
	"Ά": "A",
	"Έ": "E",
	"Ή": "H",
	"Ί": "I",
	"ϊ": "i",
	"ϋ": "u",
	"Ό": "O",
	"ό": "o",
	"ύ": "u",
	"Ύ": "Y",
	"і": "i",
	"ї": "i",
	"ј": "j",
	"ќ": "k",
	"ў": "y",
	"ӑ": "a",
	"Ӑ": "A",
	"Ӓ": "A",
	"ӓ": "a",
	"ӕ": "ae",
	"Ӕ": "AE",
	"Ӗ": "E",
	"ӗ": "e"
};

function replaceLetters(str) {
	for(var s in map)
		str = str.replace(new RegExp(s, "g"), map[s]);
	return str;
}

var hMainWnd = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();

if(hMainWnd && !AkelPad.GetEditReadOnly(hWndEdit)) {
	var text = AkelPad.GetSelText();
	if(!text) {
		var selectAll = true;
		text = AkelPad.GetTextRange(0, -1);
	}
	var res = replaceLetters(text);
	if(res != text)
		insertNoScroll(res, selectAll);
}

function insertNoScroll(str, selectAll) {
	var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
	if(!lpPoint)
		return;
	setRedraw(hWndEdit, false);
	AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

	selectAll && AkelPad.SetSel(0, -1);
	//var ss = AkelPad.GetSelStart();
	AkelPad.ReplaceSel(str, true);
	//if(ss != AkelPad.GetSelStart())
	//	AkelPad.SetSel(ss, ss + str.length);

	AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
	setRedraw(hWndEdit, true);
	AkelPad.MemFree(lpPoint);
}
function setRedraw(hWnd, bRedraw) {
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
	bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
<download>
Updated version of old script.

Posted: Wed Feb 02, 2011 12:11 am
by Infocatcher
jsBeautifier.js <download | development version>
JavaScript unpacker and beautifier, based on code from https://beautifier.io/.
Additionally can unpack HTML with scripts and styles inside.

File is too big and can't be placed here.
Alternative download: Infocatcher.zip (all in one).

Posted: Wed Feb 02, 2011 2:16 pm
by Andrey_A_A

Code: Select all

' OpenFileNameFromBuffer.vbs
'========================   Описание   =====================================
' Открыть файл, имя/путь которого, находится в выделении или в буфере обмена
' - можно скопировать/выделить кнопку/пункт меню AkelPad, Total Commander ...
' - можно скопировать/выделить пути с абсолютными именами
' - можно скопировать/выделить строку со всяким "лишним мусором" в котором есть имя/путь для открытия
' (если ни в выделении, ни в буфере ничего нет ничего подходящего - поиск имени производится во всей строке...)
'====================  Как работает скрипт  ================================
' из выделенной/отправленной в буфер строки извлекается имя/путь скрипта/файла
' и далее имя проверяется в указанных папках и открывается в AkelPad
' (если такого нет в папках - выдаётся сообщение
'=======================  Дополнение =======================================
' Вы можете удалить/внести свои условия/адреса поиска в скрипте
' используется Functions.vbs, который следует положить ...AkelFiles\Plugs\Scripts\Include\
'=========================    Пример    ====================================
' -"Открыть выделенное имя/путь файла или из буфера" Call("Scripts::Main", 1, "OpenFileNameFromBuffer.vbs")

' используется Functions.vbs, который следует положить в ...AkelFiles\Plugs\Scripts\Include\

' Автор:           Аверин Андрей
' Версия:          1.8 (10.10.2010 - 19.08.2012)
' Mail:            Averin-And@yandex.ru
' Site:            http://tc-image.3dn.ru/forum/9-391-1166-16-1333732766
' Site:            http://akelpad.sourceforge.net/forum/viewtopic.php?p=11255#p11255
'===========================================================================
Count = 1 : Call TestingPath

Sub TestingPath
  With AkelPad Text = .GetSelText()
    If Count = 0 Then : Text = ClearNameOrPath(GetLine) : Count = 2 : End If
    If Len(Text) = 0 And Count = 1 Then : Text = .GetClipboardText() : Count = 0 : End If
    If Len(Text) = 0 Then MsBoxErr
    nSelStart = .GetSelStart()
    If InStr(Text, vbNewLine) > 0 Then : sText = Split(Text, vbNewLine) : pText = sText(0) : Else : pText = Text : End If
    Call .Include("Functions.vbs")
  End With
  If CreateObject("Scripting.FileSystemObject").FileExists(pText) Then OpenFF(pText)
  If pText = "TOTALCMD#BAR#DATA" Then pText = sText(1) ' если выделена в буфер кнопка Total Commander
  pText = ClearNameOrPath(pText)
  If Len(pText) = 0 Then Call MsBoxErr
  If InStr(UCase(pText), "AU3") = 0 Then pText = ClearEndLine(pText, "0123456789")
  pText = ReplaceSymPath(pText)

  If Instr(pText, "\") > 0 And Instr(pText, ".") > 0 Then
    If Left(pText, 1) = "%" Then pText = GetPath(pText) ' если путь содержит переменные окружения
    If CreateObject("Scripting.FileSystemObject").FileExists(pText) Then
      OpenFF(pText)
    Else
      If Instr(pText, ".") = InstrRev(pText, ".") Then OpenFF(RunPath(pText)) : Call MsBoxErr
    End If
  Else
    If Instr(pText, ".") = InstrRev(pText, ".") Then OpenFF(RunPath(pText)) : Call MsBoxErr
  End If
End Sub

Sub OpenFF(Name) : Call AkelPad.OpenFile(Name) : Wscript.Quit : End Sub

' функция проверки нахождения имени файла в указанных папках
' удалите ненужные и вставьте свои папки
Function RunPath(FName)
  With AkelPad
    P0 = .GetAkelDir(0) & "\" : P1 = .GetAkelDir(1) & "\" : P2 = .GetAkelDir(2) & "\"
    P4 = .GetAkelDir(4) & "\" : P5 = .GetAkelDir(5) & "\" : P6 = .GetAkelDir(6) & "\" 
  End With
  TC =  GetPath("%COMMANDER_PATH%") & "\" : TCF = TC & "Files\" : TU =  TC & "Utilities\"
  TCFL = TCF & "Lists\" : TCC = TC & "Scripts\" : TCB = TC & "Bar\"
  PT = P4 & "Templates\" : TM = TC & "0\" : TS = TM & "Script_Site\"
  WD = GetPath("%WINDIR%") & "\"
  APath = Array(P0, P0 & "Help", P1 & "List", P2, P4, P4 & "AkelMenu", P4 & "AutoComplete",_
          P4 & "AkelMenu", P4 & "Coder", P4 & "Sessions", P4 & "SpellCheck", P4 & "Templates",_
          PT & "AkelPad", PT & "Asp", PT & "Asp.net", PT & "Assemblers", PT & "Batch",_
          PT & "C-Language", PT & "Css", PT & "Html", PT & "Pascal", PT & "Xml", P5,_
          P5 & "Include", P5 & "Include\win32", P5 & "Params", P5 & "Params\ShowMenuEx",_
          P5 & "Params\ShowMenuAlt", P5 & "ShowMenu", P5 & "win32lib", P6, TC, TC & "Language",_
          TC & "Keys", TCB, TCB & "Bars", TCB & "Bars_Plus", TCB & "Filter", TCF & "ExtProgram", _
          TCB & "Font", TCB & "Rename", TCB & "Search", TCB & "Select", TCB & "Start_Menu", _
          TCF, TCF & "Bat", TCF & "Comands", TCF & "Ncl", TCF & "Tab", TCF & "HTML",_
          TCF & "Help\TCInfo",  TCFL & "Collection", TCFL & "CreateMenu", TCFL & "Lst", _
          TCFL & "MarkerList", TCFL & "MusicList", TCFL & "PathList", TCFL & "Play", _
          TCFL & "ProgramList", TCFL & "ReportList", TCFL & "StatisticFile", _
          TCC & "AddIcons", TCC & "Attributes", TCC & "Buffer", TCC & "Copy", TCC & "CreateBar", _
          TCC & "CreateLists", TCC & "CreateRegistration", TCC & "FileEditing", TCC & "Filters", _
          TCC & "Folders", TCC & "ImageWSH", TCC & "Include", TCC & "Keyboard", TCC & "Link", _
          TCC & "Marker", TCC & "Miscellanea", TCC & "Move", TCC & "Panel", TCC & "Plus", _
          TCC & "ReNames", TCC & "Run", TCC & "Searches", TCC & "SysScript", TCC & "NetWork", _
          TCC & "TextWork", TCC & "Un-Packing", WD, WD & "system32", "c:\MyFiles",_
          TS & "N_V", TS & "S", TS & "V", TU & "Inet\WGet", P1 & "Regs")
  p = 0
  For ii = 0 To Ubound(APath)
    PF = Trim(APath(ii) & "\" & FName)
    If CreateObject("Scripting.FileSystemObject").FileExists(PF) Then : RunPath = PF : p = 1 : Exit For : End If
  Next
  If p = 0 Then MsBoxErr
End Function

Sub MsBoxErr
  If Count = 1 Then
    Call AkelPad.SetSel(nSelStart, nSelStart) : Call TestingPath
  Else
    If Count = 0 Then
      Call TestingPath
    Else
      MsgBox "Ни в выделении ни в буфере обмена" & vbNewLine &_
      "Нет корректного ИМЕНИ / ПУТИ файла для открытия" & vbNewLine &_
      "или такого файла нет в папках, указанных в скрипте" & vbNewLine &_
      "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" & vbNewLine &_
      "Выделите или скопируйте чего-нибудь подходящее" & vbNewLine &_
      "И повторите попытку " , vbApplicationModal & vbExclamation,_
      "Открытие файла, путь/имя которого скопирован или выделен" : Wscript.Quit
    End If
  End If
End Sub



используется: Functions.vbs

Posted: Wed Feb 02, 2011 3:47 pm
by Andrey_A_A

Code: Select all

' DublicateFile.vbs
'========================   Описание   =====================================
' Создание дубликата файла в той же папке и его открытие с добавлением счетчика _N
'
' Call("Scripts::Main", 1, "DublicateFile.vbs")
' предлагаемая горячая клавиша Alt + F5

' Автор:           Аверин Андрей
' Версия:          1.3 (22.11.2010 - 01.05.2012)
' Mail:            Averin-And@yandex.ru
' Site:            http://tc-image.3dn.ru/forum/9-354-1087-16-1333507842
' Site:            http://akelpad.sourceforge.net/forum/viewtopic.php?p=11259#p11259
'===========================================================================
File = AkelPad.GetEditFile(0)
If AkelPad.GetEditWnd() = 0 Or Len(File) = 0 Then WScript.Quit
With CreateObject("Scripting.FileSystemObject")
  Path  = .GetParentFolderName(File) & "\"
  Name = .GetBaseName(File)
  Ext = "." & .GetExtensionName(File)
  FPath = Path  & Name & Ext
  Do While .FileExists(FPath)
      i = i + 1 : FPath = Path & Name & "_" & (i Mod 10) & Ext
  Loop
  If .FileExists(File) Then .CopyFile File, FPath
  AkelPad.OpenFile(FPath)
End With


Иконка к скрипту:

Code: Select all

MIME-Version: 1.0
Content-Type: application/octet-stream; name="DublicateFile.zip"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="DublicateFile.zip"

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
BgAAAAABAAEAPwAAABgJAAAAAA==

Posted: Thu Feb 03, 2011 7:37 am
by VladSh

Code: Select all

// Description(1033): Deleting block of whitespaces; for other characters - a usual deleting (1 symbol)
// Description(1049): Удаляет пробелы блоками (количество пробелов в блоке берётся из настроек программы)
// 	для других символов - обычное удаление (посимвольно)
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11267#p11267
// Version: 2.2 (2011.01.26)
// 	from 2.0 (2011.01.21)
// Author: VladSh
// Initial version: 1.0 by lexa
// 
// Предлагаемая комбинация клавиш:	Shift+Alt+Backspace

var nPosCurrent = AkelPad.GetSelStart();
if (!nPosCurrent) WScript.Quit();

if (nPosCurrent == AkelPad.GetSelEnd()) {
	var hWndEdit = AkelPad.GetEditWnd();
	var oLine = getBlockLeft(nPosCurrent);
	
	var nTabStop = AkelPad.SendMessage(AkelPad.GetEditWnd(), 3239 /*AEM_GETTABSTOP*/, 0, 0);		//количество пробелов (из настроек)
	var pSpaces = repeat(" ", nTabStop);
	
	var posCursorNew = oLine.len - nTabStop;
	var pPartDel = oLine.text.substr(posCursorNew);		//предполагаемая удаляемая часть
	if (pPartDel != pSpaces)
		posCursorNew = oLine.len - 1;
	var pPartRemain = oLine.text.substr(0, posCursorNew);
	
	var bNoSelEOL = false;
	if (!oLine.start) {
		var fNoSelEOL = "SmartSel::NoSelEOL";
		var bNoSelEOL = AkelPad.IsPluginRunning(fNoSelEOL);
		if (bNoSelEOL) AkelPad.Call(fNoSelEOL);		//Turn OFF
	}
	
	setRedraw(hWndEdit, false);
	AkelPad.SetSel(nPosCurrent - oLine.text.length, nPosCurrent);
	AkelPad.ReplaceSel(pPartRemain);
	setRedraw(hWndEdit, true);
	
	if (bNoSelEOL) AkelPad.Call(fNoSelEOL);		//Turn ON
}
else
	AkelPad.ReplaceSel("");


function repeat(pText, nCount) {
	return (new Array(nCount + 1)).join(pText);
}

function getBlockLeft(nPos) {
	var line = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, nPos);
	var index = AkelPad.SendMessage(hWndEdit, 187 /*EM_LINEINDEX*/, line, 0);
	if (index == nPos && index != 0) {
		var line = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, nPos - 1);
		var index = AkelPad.SendMessage(hWndEdit, 187 /*EM_LINEINDEX*/, line, 0);
	}
	var text = AkelPad.GetTextRange(index, nPos);
	
	return {
		text: text,
		start: index,
		len: text.length
	};
}

function setRedraw(hWnd, bRedraw) {
   var oSys = AkelPad.SystemFunction();
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
   bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}


Code: Select all

// Description(1033): Removal of the current paragraph by Ctrl+Alt+Y
// Description(1049): Удаление текущего параграфа по Ctrl+Alt+Y
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11267#p11267
// Version: 1.2 (2011.12.12)
// Author: VladSh

if (! AkelPad.Include("selCompleteLine.js")) WScript.Quit();
selCompleteLine(AkelPad.GetSelStart(), AkelPad.GetSelEnd());

AkelPad.Command(4197);
N.B. Скрипт использует selCompleteLine.js.

Posted: Fri Feb 04, 2011 4:48 pm
by VladSh

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11340#p11340
// Description(1033): Receiving appointed attributes of each line of XML-file
// Description(1049): Вытягивание определённых атрибутов из каждой строки файла с XML-структурой
// Version: 1.8 (2015.04.17)
// Author: VladSh
// 
// Arguments:
// 	см. скрипт ShowMenuEx.js

if (! AkelPad.Include("ShowMenuEx.js")) WScript.Quit();
if (! AkelPad.Include("selCompleteLine.js")) WScript.Quit();

var arrAttr = getSelectedMenuItem(POS_CURSOR, false).split(", ");

//создаём структуру искомых тэгов, перечень которых берём из файла параметров
var structAttr = {};
for (var i = 0, l = arrAttr.length; i < l; i++)
	structAttr[arrAttr[i]] = 1;

var pContent = AkelPad.GetTextRange(0, -1);

//вызываем основную функцию обработчика всего файла
var pContent = processRowText(pContent, /\r\n|\n|\r/);

AkelPad.Call("Log::Output", 4, pContent, -1, 2);


//функция обработки отдельной строки
function processString(rowXML) {
	var pResult = "";
	var aRES = getAttributesValues(rowXML);
	if (aRES != null)
      pResult = aRES.join(", ");
	return pResult
}

function getAttributesValues(sXML) {
	var aXML = sXML.split('"');
	
	var sATTR = "";
	var aRES = [];
	var r = 0;
	
	for (var n = 0; n <= aXML.length; n++) {
		sATTR = aXML[n].replace(/ /g, "");
		sATTR = sATTR.replace(/=/g, "");
		sATTR = sATTR.replace(/</g, "");
		
		if (structAttr[sATTR] == 1) {
			aRES[r] = aXML[n + 1];
			r += 1;
		}
		n += 1;
	}
	
	if (r > 0) return aRES
}

function addToResult(arrOutput, vResult) {
	if (vResult) arrOutput[arrOutput.length] = vResult;
}
NB: Скрипт использует:
- ShowMenuEx.js (для вывода меню наименований атрибутов);
- selCompleteLine.js (для обработки всех строк файла в цикле).

Атрибуты для отбора в файле параметров указываются через ", ", например строка:

Code: Select all

model, posX, posY
Пример XML можно взять здесь.

Благодарности: Infocatcher

Posted: Fri Feb 04, 2011 7:29 pm
by Infocatcher

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11346#p11346
// http://infocatcher.ucoz.net/js/akelpad_scripts/openRelativeFile.js
// https://github.com/Infocatcher/AkelPad_scripts/blob/master/openRelativeFile.js

// (c) Infocatcher 2011, 2014
// version 0.1.7 - 2014-08-01

//===================
// Tries to open file with relative path
// (will be used system association to open binary files)
// Supports Mozilla's chrome.manifest files (https://developer.mozilla.org/en/chrome_registration)
// Priorities: selected path (if any) or autodetected path (you can just place caret anywhere inside path)

// Usage:
//   Call("Scripts::Main", 1, "openRelativeFile.js")
// Also you can use -showPath argument for debug purposes:
//   Call("Scripts::Main", 1, "openRelativeFile.js", "-showPath=true")
//===================

//== Settings begin
// You can use openRelativeFile-options.js file to override settings

//var paths = ["%ProgramFiles%\\Something"];
var paths = [];

var delimitersStart = {
	'"': true,
	"'": true,
	"<": true,
	"[": true,
	"(": true,
	">": true,
	"=": true,
	"\n": true,
	"\r": true,
	"": true
};
var delimitersEnd = {
	'"': true,
	"'": true,
	">": true,
	"]": true,
	")": true,
	"<": true,
	"\n": true,
	"\r": true,
	"": true
};
var delimitersSpaces = {
	" ": true,
	"\t": true,
	"\n": true,
	"\r": true,
	"\0": true,
	"\u00a0": true, //  
	"\u2002": true, //  
	"\u2003": true, //  
	"\u2009": true //  
};
var delimitersStop = {
	"\n": true,
	"\r": true,
	"\0": true,
	"" : true
};

var maxLength = 2000;
//== Settings end

var optionsPath = WScript.ScriptFullName.replace(/(\.[^.]+)?$/, "-options$&");
if(new ActiveXObject("Scripting.FileSystemObject").FileExists(optionsPath))
	eval(AkelPad.ReadFile(optionsPath));

var showPath = AkelPad.GetArgValue("showPath", false);

var hMainWnd = AkelPad.GetMainWnd();
var fso = new ActiveXObject("Scripting.FileSystemObject");
var wsh = new ActiveXObject("WScript.Shell");

if(hMainWnd)
	openRelative();

function openRelative() {
	var pathStarts = [];
	var pathEnds = [];

	var ss = AkelPad.GetSelStart();
	var se = AkelPad.GetSelEnd();

	if(ss != se) {
		checkPrefix(ss);
		var relPath = decodePathURI(AkelPad.GetSelText());
		if(openRelativePath(relPath))
			return true;
		++ss, --se;
	}

	var cnt = 0;
	for(;;) {
		var chr = --ss < 0 ? "" : AkelPad.GetTextRange(ss, ss + 1);
		if(chr in delimitersSpaces && !pathStarts.length)
			pathStarts.push(ss + 1);
		else if(chr in delimitersStart) {
			pathStarts.push(ss + 1);
			break;
		}
		if(chr in delimitersStop)
			break;
		if(++cnt > maxLength)
			break;
	}
	if(!pathStarts.length)
		return false;

	for(var i = 0, l = pathStarts.length; i < l; ++i)
		if(checkPrefix(pathStarts[i]))
			break;

	cnt = 0;
	for(;;) {
		var chr = AkelPad.GetTextRange(se, ++se);
		if(chr in delimitersSpaces && !pathEnds.length)
			pathEnds.push(se - 1);
		else if(chr in delimitersEnd) {
			pathEnds.push(se - 1);
			break;
		}
		if(chr in delimitersStop)
			break;
		if(++cnt > maxLength)
			break;
	}
	if(!pathEnds.length)
		return false;

	for(var i = Math.max(pathStarts.length, pathEnds.length) - 1; i >= 0; --i) {
		// Use corresponding points: 1 - delimitersStart/End, 0 - delimitersSpaces
		var pathStart = pathStarts[i] || pathStarts[pathStarts.length - 1];
		var pathEnd = pathEnds[i] || pathEnds[pathEnds.length - 1];
		var relPathRaw = AkelPad.GetTextRange(pathStart, pathEnd);
		var relPath = decodePathURI(relPathRaw);
		if(openRelativePath(relPath, pathStart, pathEnd))
			return true;
	}
	return false;
}
function checkPrefix(pathStart) {
	if(pathStart > 0) { // Detect AkelPad.Include()
		var before = AkelPad.GetTextRange(Math.max(0, pathStart - 40), pathStart);
		if(/\bAkelPad\s*\.\s*Include\s*\(\s*["']$/.test(before)) {
			var includeDir = AkelPad.GetAkelDir(6 /*ADTYPE_INCLUDE*/);
			if(arrayIndexOf(paths, includeDir) == -1)
				paths.push(includeDir);
			return true;
		}
	}
	return false;
}
function arrayIndexOf(arr, item) {
	for(var i = 0, l = arr.length; i < l; ++i)
		if(arr[i] === item)
			return i;
	return -1;
}
function openRelativePath(relPath, pathStart, pathEnd) {
	var path;

	var curPath = AkelPad.GetEditFile(0);
	var curDir = fso.GetParentFolderName(curPath);
	var tmp = curDir + "\\" + relPath;
	if(fso.FileExists(tmp))
		path = tmp;
	else {
		tmp = wsh.ExpandEnvironmentStrings(relPath);
		if(fso.FileExists(tmp))
			path = tmp;
		if(!path && /^(chrome|resource):\/\//.test(relPath)) {
			tmp = parseChromePath(curDir, relPath);
			if(tmp)
				path = tmp;
		}
		if(!path && /^\w+:\//.test(relPath)) {
			var tokens = relPath.replace(/^\w+:/, "").split(/[\\\/]+/);
			for(;;) {
				tmp = getFile(curDir, tokens.concat());
				if(tmp) {
					path = tmp;
					break;
				}
				var newDir = getParentDir(curDir);
				if(!newDir || newDir == curDir)
					break;
				curDir = newDir;
			}
		}
		if(!path) {
			for(var i = 0, l = paths.length; i < l; ++i) {
				tmp = wsh.ExpandEnvironmentStrings(paths[i]) + "\\" + relPath;
				if(fso.FileExists(tmp)) {
					path = tmp;
					break;
				}
			}
		}
	}
	if(!path)
		return false;

	if(showPath) {
		var msg = "Relative path:\n" + relPath
			+ "\nDetected path:";
		path = AkelPad.InputBox(hMainWnd, WScript.ScriptName, msg, path);
		if(!path)
			return false;
	}

	if(pathStart && pathEnd)
		AkelPad.SetSel(pathStart, pathEnd);
	if(isFileBinary(path)) // Use system association for binary files
		wsh.Exec('rundll32.exe shell32.dll,ShellExec_RunDLL "' + path + '"');
	else
		AkelPad.OpenFile(path);

	return true;
}
function decodePathURI(path) {
	path = path
		.replace(/^file:\/+/i, "")
		.replace(/[?#].*$/, "");
	try {
		path = decodeURIComponent(path);
	}
	catch(e) {
	}
	return path;
}
function parseChromePath(curDir, chromePath) {
	if(/^(resource):\/+([^\/]+)(\/.*)?/.test(chromePath)) {
		var protocol = RegExp.$1;
		var domain   = RegExp.$2;
		var path     = RegExp.$3;
	}
	else if(/^(\w+):\/+([^\/]+)\/([^\/]+)(\/.*)?/.test(chromePath)) {
		var protocol = RegExp.$1;
		var domain   = RegExp.$2;
		var type     = RegExp.$3;
		var path     = RegExp.$4;
	}
	else
		return false;

	for(;;) { // See https://developer.mozilla.org/en/chrome_registration
		var tmp = curDir + "\\chrome.manifest";
		if(fso.FileExists(tmp)) {
			var manifest = AkelPad.ReadFile(tmp);
			break;
		}
		var newDir = getParentDir(curDir);
		if(!newDir || newDir == curDir)
			return false;
		curDir = newDir;
	}
	if(!manifest)
		return false;

	var pattern;
	switch(protocol) {
		case "chrome":
			switch(type) {
				case "content":
					// content extensionname chrome/content/
					pattern = new RegExp("(^|[\\n\\r])content[ \\t]+" + escapeRegExp(domain) + "[ \\t]+(\\S+)");
				break;
				case "skin":
					// skin extensionname classic/1.0 chrome/skin/
					pattern = new RegExp("(^|[\\n\\r])skin[ \\t]+" + escapeRegExp(domain) + "[ \\t]+\\S+[ \\t]+(\\S+)");
				break;
				case "locale":
					// locale extensionname en-US chrome/locale/en-US/
					pattern = new RegExp("(^|[\\n\\r])locale[ \\t]+" + escapeRegExp(domain) + "[ \\t]+\\S+[ \\t]+(\\S+)");
			}
		break;
		case "resource":
			// resource extensionname resource/
			pattern = new RegExp("(^|[\\n\\r])resource[ \\t]+" + escapeRegExp(domain) + "[ \\t]+(\\S+)");
	}

	if(!pattern)
		return false;

	tmp = getManifestInfo(pattern, manifest, curDir, path);
	if(tmp)
		return tmp;

	// https://developer.mozilla.org/en/chrome_registration#manifest
	var lines = manifest.split(/[\n\r]+/);
	for(var i = 0, l = lines.length; i < l; ++i) {
		var line = lines[i];
		if(!/^manifest[ \t]+(\S+)/.test(line))
			continue;
		var manifestPath = curDir + "\\" + RegExp.$1;
		if(!fso.FileExists(manifestPath))
			continue;
		manifest = AkelPad.ReadFile(manifestPath);
		tmp = getManifestInfo(pattern, manifest, fso.GetParentFolderName(manifestPath), path);
		if(tmp)
			return tmp;
	}

	return false;
}
function getManifestInfo(pattern, manifest, curDir, path) {
	if(!pattern.test(manifest))
		return false;
	var fullPath = curDir + "\\" + unwrapChromePath(RegExp.$2) + path;
	if(fso.FileExists(fullPath))
		return fullPath;
	return false;
}
function unwrapChromePath(path) {
	if(/^jar:/.test(path))
		path = path.substr(4).replace(/[^\/]+!\//, "");
	return path;
}
function escapeRegExp(str) {
	return str.replace(/[\\\/.^$+*?|()\[\]{}]/g, "\\$&");
}
function getFile(curDir, tokens) {
	var parts = [];
	for(;;) {
		parts.unshift(tokens.pop());
		var tmp = curDir + "\\" + parts.join("\\");
		if(fso.FileExists(tmp))
			return tmp;
		if(!tokens.length)
			break;
	}
	return null;
}
function getParentDir(dir) {
	return dir.replace(/[\\\/]+[^\\\/]+$/, "");
}
function isFileBinary(pFile) {
	// Thanks to Instructor
	// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11344#p11344
	var lpDetectCodepage;
	var bResult=false;

	if (lpDetectCodepage=AkelPad.MemAlloc(_X64?24:20 /*sizeof(DETECTCODEPAGEW)*/))
	{
		AkelPad.MemCopy(lpDetectCodepage /*offsetof(DETECTCODEPAGEW, pFile)*/, AkelPad.MemStrPtr(pFile), 2 /*DT_QWORD*/);
		AkelPad.MemCopy(lpDetectCodepage + (_X64?8:4) /*offsetof(DETECTCODEPAGEW, dwBytesToCheck)*/, 1024, 3 /*DT_DWORD*/);
		AkelPad.MemCopy(lpDetectCodepage + (_X64?12:8) /*offsetof(DETECTCODEPAGEW, dwFlags)*/, 0x11 /*ADT_BINARY_ERROR|ADT_NOMESSAGES*/, 3 /*DT_DWORD*/);
		if (AkelPad.SendMessage(hMainWnd, 1177 /*AKD_DETECTCODEPAGEW*/, 0, lpDetectCodepage) == -4 /*EDT_BINARY*/)
			bResult=true;

		AkelPad.MemFree(lpDetectCodepage);
	}
	return bResult;
}
<download | mirror | development version>
Tries to open file with relative path (will be used system association to open binary files).
Supports Mozilla's chrome.manifest files.
Priorities: selected path (if any) or autodetected path (you can just place caret anywhere inside path)

Thanks to Instructor for IsFileBinary() example.