// // JS Standalone Template & ZLIB Function Library // Written by Zsolt Nagy-Perge // March 2021, Pensacola, Fla. FREEWARE. // Last Update: August 2022. // ////////////////////////////////////////////////// SEED = 111; B64SET = "i8r0Rl1o9mqGsMeZ_PuLzBp2cNb6S4UfwWOIatHEhxVAdF5XDyCJnKY7@vQkg3jT"; RANDOM = "47696F3164497142674F626534726153486E43636B3875456D57554E54684D767C746C70463641373220392F782E7752664479507330334C35595E0A804B3B277E860D882D60897A584A295D243A237B847D2C8B8540268E82515A216A005B5C1B223E2881833F875F2A093D252B568C8A3C04A98D8F08A71D129593A3A29A0B989F1A0E9E1C1F160F9611170119079997A69B101505A09C7F0C1E90181406139DA59194AA0302A1A492A8BDB2E3C7B7D4DFC8ADD0ACCBCDC9D7D9CAC5BCD6B4CCB9BEE0DAB8D5C0BBB5E2C1CED1ABDED3BFDBB3CFAFD8BADCAEB0C3C4C2D2C6DDE1B6B1F7F6FFFCE9E8EEEDEFF4F3E4F5E5EAFAECF2F8F0E7FBFEEBE6FDF1F95D8CA6A572959E8E766A3B7F99428388938A799F9D94878B9C8D826085789A86295B614E4C6C563F634A696D52442D2B350328360C382527152A4D3E716B626655260712311724001005493D371E1B0933592F0F1C1A6E1948395A5E5F4B3A68450E0A13040B30081D015C142218110223060D3421161F2E2C32474F205140983C64586550544167434670536F7457759BA2A97BA37A8990808F7E9297A0848196A77D7CA8A19177AA73A4CEB5B3D9D5DAE3ACD3BFC9E2AFC5C1D7C8BDABC2D1C7CBDDDBDCBCDFAEB2B8BBB6C0B7CCD4B4CDDED0B0C6BEB9D6BAC4D2D8E0CFB1C3E1CAADEFF1FCF8E9E8F2FBF4EBEAECF7FEF5EEEDF0E5E4F6FFF3F9E7FDFAE6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000263706110C0F3102072500000000000000130E3C1D011A031C050A2F172B142718152100293A302D0820320000000000001028193D0D16342E380B3912232C2A1F332236041B0924353B1E0000000000534537477449323858764A6A3465423561336C414E51664C5063467548447A705952726D7739304F62546F4D6E57684B56365A7167787331696B55794364"; TX = Hex2Str(RANDOM); COOKIEJAR = "^0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz$@!?*|#&%~+:-., []{}()_/\\><\"'`"; SELF = WScript.ScriptFullName; WshShell = new ActiveXObject("WScript.Shell"); ShellApp = new ActiveXObject("Shell.Application"); WordObj = WScript.CreateObject("Word.Application"); ABC = "\n.ABCDEFGHIJKLMNOPQRSTUVWXYZ"; ////////////////////////////////////////////////// CURDIR = CURRENT_DIRECTORY = cut(SELF, "\\", 0x10010); // Find WINDOWS folder. WINDOWS = GetReg("HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\PathName"); // DETECT WINDOWS VERSION WINVER = "?"; if (GetReg("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Version")) WINVER = "98"; if (GetReg("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\VersionNumber")) WINVER = "98"; if (GetReg("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\CurrentVersion")) WINVER = "XP"; // DETECT SCREEN SIZE & ORIENTATION, ETC... //ReadDeviceDetails(); Run("C:\\WINDOWS\\notepad.exe"); WAIT(1); WINFOCUS("notepad"); TYPE("sub {} YES?!;ZSOLT...\tFXT"); EXIT(); WEB_BROWSER = "C:\\BIN\\KM75\\k-meleon.exe"; WEB_BROWSER_NAME = "meleon"; CURRENT_DIRECTORY = cut(SELF, "\\", 0x10010); INPUT_FILE = CURRENT_DIRECTORY + "\\SYMBOL_LIST.TXT"; OUTPUT_FILE = CURRENT_DIRECTORY + "\\BIGLIST.CSV"; SYMBOLS = ReadFile(INPUT_FILE).toUpperCase(); SYMBOLS = tr(SYMBOLS, ABC).toLowerCase().split("\n"); HEADER = "Symb,SYMBOL,CUSIP,NAME\n"; if (FileExists(OUTPUT_FILE) == 0) CreateFile(OUTPUT_FILE, HEADER); TOTAL_COUNT = 1; CURRENT_SYMBOL = SYMBOLS[0]; URL = "https://stockzoa.com/ticker/$$$/"; URL = URL.split("$$$").join(CURRENT_SYMBOL); RUN(QUOTE(WEB_BROWSER) + " " + QUOTE(URL)); WAIT(1); WINFOCUS(WEB_BROWSER_NAME); WAIT(10); // LOAD PAGE FOR ABOUT 10 SECONDS... PRESS("^{a}"); // SELECT ALL PRESS("^{INSERT}"); // COPY SELECTED TEXT DATA = ReadClipboardText(); Process_and_Save(DATA); for (i = 1; i < SYMBOLS.length; i++) { CURRENT_SYMBOL = Trim(SYMBOLS[i]); if (CURRENT_SYMBOL == "") continue; SYMBOL_FILE = CURRENT_DIRECTORY + "\\" + CURRENT_SYMBOL.toUpperCase() + ".TXT"; if (FileExists(SYMBOL_FILE)) continue; URL = "https://stockzoa.com/ticker/$$$/"; URL = URL.split("$$$").join(CURRENT_SYMBOL); WINFOCUS(WEB_BROWSER_NAME); PRESS("+{TAB}"); // SHIFT+TAB PRESS("{TAB}"); // TAB PRESS(URL); // ENTER NEW URL PRESS("{ENTER}"); // LOAD NEW ADDRESS WAIT(7); // WAIT FOR PAGE LOAD PRESS("^{a}"); // SELECT ALL PRESS("^{INSERT}"); // COPY SELECTED TEXT DATA = ReadClipboardText(); Process_and_Save(DATA); TOTAL_COUNT++; } ALERT("PROCESSED " + TOTAL_COUNT + " STOCKS.\n\nSCRIPT ENDED."); EXIT(0); ///////////////////////////////// function Process_and_Save(DATA) { if (DATA.indexOf("Page seized") >= 0) { NEW_LINE = CURRENT_SYMBOL + ",--,--,--\n"; AppendFile(OUTPUT_FILE, NEW_LINE); return; } DATA = cut(DATA, "TIP: ACCESS POSITIONS", 0x1110); var NAME = cut(DATA, 'owns ', 1); NAME = Trim(cut(NAME, '?', 0x10)); var SYMBOL = cut(DATA, 'Ticker:', 1); SYMBOL = Trim(uc(cut(SYMBOL, "\n", 0x10))); var CUSIP = cut(DATA, 'CUSIP Number:', 1); CUSIP = Trim(uc(CUSIP.substr(1, 9))); var NEW_LINE = CURRENT_SYMBOL + "," + SYMBOL + "," + CUSIP + "," + NAME + "\n"; AppendFile(OUTPUT_FILE, NEW_LINE); // SAY(SYMBOL); } ////////////////////////////////////////////////// // // F U N C T I O N L I B R A R Y // function RegRead(REGKEY) { try { return WshShell.RegRead(REGKEY); } catch(e) { return ""; } } function RegWrite(REGKEY, VALUE, TYPE) { try { WshShell.RegWrite(REGKEY, VALUE, TYPE); } catch(e) {} } function RegDelete(REGKEY) { try { WshShell.RegDelete(REGKEY); } catch(e) {} } function DelReg(RegName) { try { WshShell.RegDelete(RegName); } catch(e) {} } function GetReg(RegName) { try { return WshShell.RegRead(RegName); } catch(e) { return ""; } } function SetReg(R) { R = R.split("|"); var PATH = R[0].split("\\"); var TYPE = R[1].toUpperCase(); var DATA = R[2]; if (PATH[0] == "HKLM") PATH[0] = "HKEY_LOCAL_MACHINE"; if (PATH[0] == "HKCU") PATH[0] = "HKEY_CURRENT_USER"; try { WshShell.RegWrite(PATH.join("\\"), DATA, TYPE); } catch(e) {} } function OpenBasicUserAccounts() { ShellApp.ControlPanelItem('NUSRMGR.CPL'); } function OpenSystemProperties() { ShellApp.ControlPanelItem('SYSDM.CPL'); } function OpenWindowsUserAccounts() { Run('C:\\WINDOWS\\SYSTEM32\\RUNDLL32.EXE C:\\WINDOWS\\SYSTEM32\\NETPLWIZ.DLL,UsersRunDll'); } function OpenWindowsUserManager() { Run('LUSRMGR.MSC'); } function OpenWindowsComponents() { Run('C:\\WINDOWS\\SYSTEM32\\RUNDLL32.EXE SHELL32.DLL,Control_RunDLL APPWIZ.CPL,,2'); } function OpenScreenSaverSettings() { Run('C:\\WINDOWS\\SYSTEM32\\RUNDLL32.EXE SHELL32.DLL,Control_RunDLL DESK.CPL,,1'); } function OpenBgPictureSettings() { Run('C:\\WINDOWS\\SYSTEM32\\RUNDLL32.EXE SHELL32.DLL,Control_RunDLL DESK.CPL,,0'); } function OpenMouseSettings() { Run('C:\\WINDOWS\\SYSTEM32\\RUNDLL32.EXE SHELL32.DLL,Control_RunDLL MAIN.CPL,,1'); } function OpenKeyboardSettings() { Run('C:\\WINDOWS\\SYSTEM32\\RUNDLL32.EXE SHELL32.DLL,Control_RunDLL MAIN.CPL @1'); } function OpenSoundsSettings() { Run('C:\\WINDOWS\\SYSTEM32\\RUNDLL32.EXE SHELL32.DLL,Control_RunDLL MMSYS.CPL,,1'); } function OpenFoldersSettings() { Run('C:\\WINDOWS\\SYSTEM32\\CONTROL.EXE folders'); } function Abort_Script_If_Numlock_Is_OFF() { if (GetNumlockState() == 0) EXIT(0); } function PlayMP3(FILENAME) { WshShell.Run(QUOTE("C:\\BIN\\COMMAND\\PLAYMP3.EXE") + " " + QUOTE(FILENAME)); } function WINFOCUS(W) { Abort_Script_If_Numlock_Is_OFF(); WshShell.AppActivate(W); } function WAIT(MS) { Abort_Script_If_Numlock_Is_OFF(); MS *= 500; WScript.Sleep(MS); Abort_Script_If_Numlock_Is_OFF(); } function Run(CMD) { Abort_Script_If_Numlock_Is_OFF(); WshShell.Run(CMD, 9); } function SAY(TEXT) { Abort_Script_If_Numlock_Is_OFF(); var VOICE = WScript.CreateObject("SAPI.SpVoice"); VOICE.Volume = 100; VOICE.Speak(TEXT); } function EXIT(E) { WordObj.Quit(); if (typeof(E) === "undefined") E = 0; WScript.Quit(E); } function PRESS(KEYCODE) { WAIT(0.1); WshShell.SendKeys(KEYCODE); Abort_Script_If_Numlock_Is_OFF(); } function TYPE(TEXT) { for (var i = 0; i < TEXT.length; i++) WshShell.SendKeys("{" + TEXT.charAt(i) + "}"); } function ALERT(MSG) { WScript.Echo(MSG); } function QUOTE(S) { return '"' + S + '"'; } function DEBUG(S) { ALERT("DEBUG:|" + S + "|"); } ////////////////////////////////////////////////// // v2021.1.18 // This function resizes the main window // and positions it in the center of the screen. // Usage: CENTER(WINDOW_WIDTH, WINDOW_HEIGHT) // function CENTER(W, H) { var WinNT = RegRead("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\CurrentVersion"); // Some earlier versions of Windows will say, // "Runtime Error: Access is Denied" if we try to // resize the window immediately when it pops up, // so we'll wait a little if necessary... if (WinNT < 6) WScript.Sleep(300); var X = Math.round((screen.width - W) / 2 - 15); var Y = Math.round((screen.height - H) / 2 - 60); if (X < 0) X = 0; if (Y < 0) Y = 0; self.moveTo(X, Y); self.resizeTo(W, H); } ////////////////////////////////////////////////// // v2021.3.16 // Deletes a file. Returns: 0=Success 1=Failure // This function also modifies the value of the global // variable $a. When an error occurs, $a will hold an // error message. Otherwise it will say "SUCCESS" // Usage: INTEGER = DeleteFile(FILENAME) // function DeleteFile(FILENAME) { $a = ""; var Delete_If_Possible = 0; var Delete_Even_If_File_Is_Read_Only = 1; try { FSO.DeleteFile(FILENAME, Delete_Even_If_File_Is_Read_Only); if (FSO.FileExists(FILENAME)) { $a = "File still exists!"; return 1; } $a = "SUCCESS"; return 0; } catch(e) { $a = e.message; } return 1; } ////////////////////////////////////////////////// /* Most ASCII characters can be represented by the character itself. E.g, the key sequence FRED can be represented by "FRED". Some special keys, such as the control keys, function keys etc are encoded in a string enclosed by {braces} See the table below Key/Character SendKey Description ~ {~} Send a tilde (~) ! {!} Send an exclamation point (!) ^ {^} Send a caret (^) + {+} Send a plus sign (+) Backspace {BACKSPACE} or {BKSP} or {BS} Send a Backspace keystroke Break {BREAK} Send a Break keystroke Caps Lock {CAPSLOCK} Press the Caps Lock Key (toggle on or off) Clear {CLEAR} Clear the field Delete {DELETE} or {DEL} Send a Delete keystroke Insert {INSERT} or {INS} Send an Insert keystroke Cursor control arrows {LEFT} / {RIGHT} / {UP} / {DOWN} Send a Left/Right/Up/Down Arrow End {END} Send an End keystroke Enter {ENTER} or ~ Send an Enter keystroke Escape {ESCAPE} Send an Esc keystroke F1 through F16 {F1} through {F16} Send a Function keystroke Help {HELP} Send a Help keystroke Home {HOME} Send a Home keystroke Numlock {NUMLOCK} Send a Num Lock keystroke Page Down Page Up {PGDN} {PGUP} Send a Page Down or Page Up keystroke Print Screen {PRTSC} Send a Print Screen keystroke Scroll lock {SCROLLLOCK} Press the Scroll lock Key (toggle on or off) TAB {TAB} Send a TAB keystroke To specify keys combined with any combination of SHIFT, CTRL, and ALT keys, precede the key code with one or more of the following: For SHIFT prefix with + For CTRL prefix with ^ For ALT prefix with % Example ' Open notepad Set WshShell = WScript.CreateObject("WScript.Shell") WshShell.Run "notepad.exe", 9 ' Give Notepad time to load WScript.Sleep 500 ' Type in Hello World WshShell.SendKeys "Hello World!" WshShell.SendKeys "{ENTER}" ' Add the date WshShell.SendKeys "{F5}" */ ////////////////////////////////////////////////// // v2021.4.11 // Creates and overwrites a file in binary mode. // Returns 0 on success or 1 if an error occurred. // Usage: INTEGER = CreateFile(FILENAME, STRING) // function CreateFile(FILENAME, STRING) { var LEN = STRING.length; var ASCII_Format = 0, UNICODE_Format = 1, CreateNew = 1, DoNotCreateNew = 0; try { var FSO = new ActiveXObject("Scripting.FileSystemObject"); var F = FSO.CreateTextFile(FILENAME, CreateNew, ASCII_Format); FILE.Write(ConvertFileString(STRING, 'WRITE')); FILE.Close(); FILE = FSO.GetFile(FILENAME); // Double-check what we have done. return (FILE.Size == LEN) ? 0 : 1 } catch (e) {} return 1; } ////////////////////////////////////////////////// // v2022.7.30 // Reads an entire binary file or part of a file and // returns its contents as a string. // // The second argument (START) moves the file pointer // before reading. The third argument (LENGTH) tells // how many bytes to read. When LENGTH is zero, // it reads the entire file. // // Usage: STRING = ReadFile(FILENAME, [START, [LENGTH]]) // function ReadFile(FILENAME, START, LENGTH) { START |= 0; LENGTH |= 0; var FSO, FILE, SIZE, DATA = ''; try { FSO = new ActiveXObject('Scripting.FileSystemObject'); if (!FSO.FileExists(FILENAME)) return ''; SIZE = FSO.GetFile(FILENAME).Size; if (START < 0) START = 0; if (START >= SIZE) return ''; if (LENGTH <= 0) LENGTH = SIZE; // Usage: FileObject = FSO.OpenTextFile(FILENAME, MODE, [CREATE, [FORMAT]]) // MODE : 1=Reading 2=Writing 8=Appending // FORMAT : 0=Open as ASCII -1=Open as Unicode // CREATE : 0=Don't create file 1=Create file if it doesn't exist yet FILE = FSO.OpenTextFile(FILENAME, 1, 0, 0); if (START) FILE.Skip(START); DATA = FILE.Read(LENGTH); // Read all the data we need. FILE.Close(); // Close file. } catch (e) {} return ConvertFileString(DATA, 'READ'); } ////////////////////////////////////////////////// // v2022.7.30 // The FSO.OpenTextFile() and FileObject.Read() // functions are specifically designed to work with // text files and will produce "garbage" when // trying to read binary files. // // In reality, what happens is certain bytes are // converted into 16-bit characters. And in order to // get normal data that makes sense, we have to // convert these 16-bit characters back to normal // 8-bit ASCII character set. // This conversion has to occur both after we read // binary files and before we write them. // // The MODE argument must contain the words // "READ" OR "WRITE": // // Trying to write certain binary characters to a // file using the FileObject.Write() will throw an // error unless the characters are first converted. // So, the MODE argument should be "WRITE" when // preparing a binary string for writing. // // After a string is read from a binary file, it needs // to be converted back into 8-bit characters. The MODE // argument needs contain the word "READ" // when we want to do that. // // Usage: STRING = ConvertFileString(STRING, MODE) // function ConvertFileString(STR, MODE) { MODE += ''; var ASCII_Table = ".\x8c\x8a\x9a\x9f\x8e\x9e\x9c\x83\x88\x98\x96\x97\x91\x92\x82\x93\x94\x84\x86\x87\x95\x85\x89\x8b\x9b\x80\x99", i, c, Unicode_Table = "\u0152\u0160\u0161\u0178\u017D\u017E\u0153\u0192\u02C6\u02DC\u2013\u2014\u2018\u2019\u201A\u201C\u201D\u201E\u2020\u2021\u2022\u2026\u2030\u2039\u203A\u20AC\u2122"; STR = STR.split(''); // Convert string to an array if (MODE.indexOf('READ') >= 0) { for (i = 0; i < STR.length; i++) if (STR[i].charCodeAt(0) > 255) STR[i] = ASCII_Table.charAt(Unicode_Table.indexOf(STR[i].charAt(0)) + 1); } else for (i = 0; i < STR.length; i++) { c = STR[i].charCodeAt(0); if (c > 127 && c < 160) if ((c = ASCII_Table.indexOf(STR[i].charAt(0))) > 0) STR[i] = Unicode_Table.charAt(c - 1); } return STR.join(''); } ////////////////////////////////////////////////// // v2022.7.31 // This function gets executed when the user clicks // on the Browse file button. If a file has been chosen, // the named text field will be updated on the MAIN form. // function BrowseForFile(UPDATE_TEXT_FIELD) { var SELECTION = false; try { var BROWSER = new ActiveXObject("UserAccounts.CommonDialog"); BROWSER.Filter = "All Files|*.*"; BROWSER.FilterIndex = 1; BROWSER.InitialDir = CURDIR; SELECTION = BROWSER.ShowOpen(); } catch (e) { Alert("Sorry, the \"Browse\" button doesn't work.\n\nYou must type or paste the file name and path."); eval("document.MAIN." + UPDATE_TEXT_FIELD + ".focus();"); return; } // User must have canceled. if (SELECTION = false) return; var F = BROWSER.FileName; if (F == "") return; eval("document.MAIN." + UPDATE_TEXT_FIELD + ".value = F;"); } ////////////////////////////////////////////////// // v2022.7.31 // This function opens a Browse for Folder window and allows // the user to select a folder... If a folder has been chosen, // the named text field will be updated on the MAIN form. // function BrowseForFolder(SEARCHING_FOR, UPDATE_TEXT_FIELD) { var oShell = new ActiveXObject("Shell.Application"); var F = oShell.BrowseForFolder(0, "You are looking for : " + SEARCHING_FOR + "\nBe careful, you can accidentally move folders by\ngrabbing them and pulling them onto another folder.", 1); if (F == null) { // Return empty string if user pressed ESC or clicked on CANCEL. eval("document.MAIN." + UPDATE_TEXT_FIELD + ".focus();"); return ""; } eval("document.MAIN." + UPDATE_TEXT_FIELD + ".value = F.Self.path;"); return F; } ////////////////////////////////////////////////// // Create ASCII text file and write string. Return 0 on success or an error message. // function WriteFile(FILENAME, STRING) { try { var FSO = new ActiveXObject("Scripting.FileSystemObject"); var F = FSO.CreateTextFile(FILENAME, true, false); F.Write(STRING); F.Close(); return 0; } catch (e) { return e.message; } } ////////////////////////////////////////////////// // This function splits string into two parts // along the first occurrence of substring. // Returns the first part if CMD is 0x10. // Returns the second part if CMD is 1. // If substring is not found, returns the original // string if CMD is 0x100. Ignores case when // CMD is 0x1000. Starts searching from end of // string when CMD is 0x10000. // function cut(STR, SUB, CMD) { if (typeof(CMD) === "undefined") CMD = 0x111; STR += ""; SUB += ""; var P; if (CMD & 0x1000) P = (CMD & 0x10000) ? STR.toUpperCase().lastIndexOf(SUB) : STR.toUpperCase().indexOf(SUB); else P = (CMD & 0x10000) ? STR.lastIndexOf(SUB) : STR.indexOf(SUB); $a = $b = ""; if (P < 0) return (CMD & 256) ? STR : ""; $a = STR.substr(0, P); $b = STR.slice(P + SUB.length); return (CMD & 16 ? $a : '') + (CMD & 1 ? $b : ''); } // function cut(STR, SUB, CMD) { if (typeof(CMD) === "undefined") CMD = 0x111; STR += ""; SUB += ""; var P = (CMD & 0x1000) ? (CMD & 0x10000 ? STR.toUpperCase().lastIndexOf(SUB) : STR.toUpperCase().indexOf(SUB)) : (CMD & 0x10000 ? STR.lastIndexOf(SUB) : STR.indexOf(SUB)); return (P < 0) ? (CMD & 256 ? STR : "") : (CMD & 16 ? STR.substr(0, P) : '') + (CMD & 1 ? STR.slice(P + SUB.length) : ''); } // function cut(STR, SUBSTR, MASK) { if (typeof(MASK) === "undefined") MASK = 0x110; if (MASK & 0x10000) P = (MASK & 0x1000) ? STR.toUpperCase().lastIndexOf(SUBSTR) : STR.toUpperCase().indexOf(SUBSTR); else P = (MASK & 0x1000) ? STR.lastIndexOf(SUBSTR) : STR.indexOf(SUBSTR); if (P < 0) return (MASK & 256) ? STR : ""; return (MASK & 16 ? STR.substr(0, P) : "") + (MASK & 1 ? STR.slice(P + SUBSTR.length) : ""); } ////////////////////////////////////////////////// // v2021.3.15 // This function removes all characters from STR // that do not appear anywhere in CHARSET, forcing // string to be only made up of the given characters. // Example: tr("cabbage cake", " abc") --> "cabba ca" // [This function has not been optimized yet.] // Usage: STRING = tr(STRING, STRING) // function tr(STR, CHARSET) { STR += ""; STR = STR.split(""); for (var i = 0; i < STR.length; i++) if (CHARSET.indexOf(STR[i]) < 0) STR[i] = ""; return STR.join(""); } ////////////////////////////////////////////////// // v2022.7.30 // Finds the first non-ASCII character in a string // and returns the character pointer where it is found. // If the input string contains nothing but pure // ASCII characters (0-255), -1 is returned. // // Usage: INTEGER = NonASCII(STRING) // function NonASCII(STR) { if (typeof(STR) === 'undefined') return -1; STR += ''; for (var i = 0; i < STR.length; i++) if (STR.charCodeAt(i) & 0xffffff00) return i; return -1; } ////////////////////////////////////////////////// // v2021.3.15 // This function returns 1 when Numlock is ON. // Returns 0 when Numlock is OFF. // Usage: INTEGER = GetNumlockState() // function GetNumlockState() { return (WordObj.NumLock) & 1; } ////////////////////////////////////////////////// // v2021.3.15 // This function returns 1 if the file exists. // Returns 0 if the file doesn't exist. // Usage: INTEGER = FileExists(FILENAME) // function FileExists(FILENAME) { var FSO, E = 0; try { FSO = new ActiveXObject("Scripting.FileSystemObject"); E = FSO.FileExists(FILENAME); } catch (e) {} return E; } ////////////////////////////////////////////////// // This function copies an object's text content // to the clipboard. Example: // CopyToClipboard(document.MAIN.TEXTAREA_NAME) // function CopyToClipboard(OBJECT) { var RANGE = OBJECT.createTextRange(); RANGE.execCommand('Copy'); OBJECT.select(); } ////////////////////////////////////////////////// // v2021.3.16 // This function copies all text from the clipboard. // We accomplish this by launching Internet Explorer // in the background. We create a document with a // textbox for user input. We paste whatever is // on the clipboard into the textarea, and then // we read its content and return the string. // This process takes about 200ms. // // Usage: STRING = ReadClipboardText() // function ReadClipboardText() { var MSIE = WScript.CreateObject("InternetExplorer.Application"); MSIE.Visible = 0; MSIE.Navigate("about:blank"); /* MSIE.ToolBar = 0; MSIE.StatusBar = 0; MSIE.FullScreen = 1; MSIE.RegisterAsDropTarget = 0; WScript.Sleep(100); MSIE.Width = 400; MSIE.Height = 175; MSIE.Left = (MSIE.document.parentWindow.screen.availWidth - MSIE.Width) / 2; MSIE.Top = (MSIE.document.parentWindow.screen.availHeight - MSIE.Height) / 2; */ var HTML = "
"; MSIE.Document.open(); MSIE.Document.write(HTML); MSIE.Document.close(); WScript.Sleep(100); PRESS("+{INSERT}"); WScript.Sleep(60); var TEXT = MSIE.Document.MAIN.INPUT.value; MSIE.Quit(); return TEXT; } ////////////////////////////////////////////////// // This function outputs a string. If the input is undefined or null, returns an empty string. (v2021.3.28) function MakeString(S) { return (typeof(S) == "string") ? S : (typeof(S) === "undefined" || S == null) ? "" : S + ""; } // This function converts anything to a number. Returns 0 if the input is undefined, null or NaN. function MakeNumber(S) { if (typeof(S) === "undefined" || S == null || isNaN(S)) return 0; return (typeof(S) == "number") ? S : S * 1; } // Perl function: Convert string to uppercase. function uc(s) { return MakeString(s).toUpperCase(); } // Perl function: Convert string to lowercase. function lc(s) { return MakeString(s).toLowerCase(); } // QBASIC function: Converts a string to uppercase. function UCASE$(s) { return MakeString(s).toUpperCase(); } // QBASIC function: Converts a string to lowercase. function LCASE$(s) { return MakeString(s).toLowerCase(); } // Capitalizes the first LETTER of string S and returns a new string. function Capitalize(S) { var i, c; S = S.toLowerCase().split(""); for (i = 0; i < S.length; i++) { c = S[i].charCodeAt(0); if (c > 96 && c < 123) { S[i] = S[i].toUpperCase(); break; } } return S.join(""); } // Capitalizes the first letter of every word, and returns a new string. function TitleCase(S) { S = S.toLowerCase().split(""); var i, F = 1, WS = " .,:;!?/\()[]{}<>|-+=\t\n\r\xFF"; for (i = 0; i < S.length; i++) { if (WS.indexOf(S[i]) >= 0) F = 1; else if (F == 1) { S[i] = S[i].toUpperCase(); F = 0; } } return S.join(""); } // Capitalizes the first letter of each sentence and returns a new string. function SentenceCase(S) { S = S.toLowerCase().split(""); var i, N = 1, SP = " ,:;/\()[]{}<>|-+=\t\r\n\xFF"; for (i = 0; i < S.length; i++) { if (SP.indexOf(S[i]) >= 0); else if (".!?".indexOf(S[i]) >= 0) N = 1; else if (N) { S[i] = S[i].toUpperCase(); N = 0; } } return S.join(""); } // Capitalizes every other letter of string S and returns a new string. function EveryOther(S) { S = S.toLowerCase().split(""); for (var i = 1; i < S.length; i += 2) S[i] = S[i].toUpperCase(); return S.join(""); } // Reverses uppercase letters with lowercase and vice versa. function ReverseCase(S) { S = S.split(""); var i, c; for (i = 0; i < S.length; i++) { c = S[i].charCodeAt(0); if (c < 65 || c > 122) continue; if (c > 90 && c < 97) continue; S[i] = String.fromCharCode(c ^ 32); } return S.join(""); } // Capitalizes each instance of the word W in string S. function MatchWord(S, W) { return S.toLowerCase().split(W.toLowerCase()).join(W.toUpperCase()); } ////////////////////////////////////////////////// // // EXCEL AND CSV SPREADSHEET I/O // ////////////////////////////////////////////////// ////////////////////////////////////////////////// // CSV | v2021.4.22 // Splits a single line from a CSV file into an array of columns. // Usage: ARRAY = SplitCSV(LINE) // function SplitCSV(LINE) { if (typeof(LINE) === "undefined" || LINE == null) return []; LINE += ","; if (LINE.length < 2) return []; var i, c, QT = 0, START = -1, A = []; for (i = 0; i < LINE.length; i++) { c = LINE.charCodeAt(i); if (c == 44) // Comma { if (QT < 3) { c = (START < 0) ? "" : LINE.substring(START, i); if (QT == 2) { START = c.indexOf('"') + 1; c = c.slice(START); START = c.lastIndexOf('"'); c = c.substr(0, START); c = c.replace(/\"\"/g, '"'); } else c = Trim(c); A.push(c); START = -1; QT = 0; } } else { if (c == 34) QT = (QT & 1) ? 2 : 3; // Double quote if (START < 0) START = i; } } if (QT == 3) { // WE GET HERE IF THERE IS AN UNEXPECTED END OF LINE // BECAUSE OF AN UNMATCHED " CHARACTER: // Try to make sense of this mess QT = 0; var SAVE = []; for (var END = i = LINE.length - 1; i > START; i--) { c = LINE.charCodeAt(i); if (c == 44) // Comma { if (QT < 3) { c = LINE.substring(i, END); if (QT == 2) { END = c.indexOf('"') + 1; c = c.slice(END); END = c.lastIndexOf('"'); c = c.substr(0, END); c = c.replace(/\"\"/g, '"'); } else c = Trim(c); SAVE.push(c); END = i - 1; QT = 0; } } else if (c == 34) QT = (QT & 1) ? 2 : 3; // Double quote } while (SAVE.length) A.push(SAVE.pop()); } return A; } ////////////////////////////////////////////////// // v2021.4.26 // If the first argument is a letter, this function // returns the column number. If the first argument // is a number, then it returns the column letter. // Usage: INTEGER = Column(STRING) // STRING = Column(INTEGER) // function Column(c) { return (typeof(c) == "string") ? GetColumnNumber(c) : GetColumnLetter(c); } ////////////////////////////////////////////////// // v2021.4.25 // This function returns the previous column label // when the current one is already known. // Spreadsheet columns are usually labeled as // A, B, C, ... AA, AB, ... AAA, AAB, etc, so for // example, PrevColumn("ABC") returns => "ABB" // After this function is down to "A", // it returns an empty string. // Usage: STRING = PrevColumn(STRING) // function PrevColumn(LETTER) { if (typeof(LETTER) === "undefined" || LETTER == null) return "A"; LETTER = (LETTER + "").toUpperCase().split(""); var i = LETTER.length, CARRY = 0, SUB = 1; while (i--) { c = LETTER[i].charCodeAt(0) - CARRY - SUB; if (c >= 65) { LETTER[i] = String.fromCharCode(c); CARRY = 0; } else if (c == 64) { LETTER[i] = (i) ? String.fromCharCode(90) : ""; CARRY = 1; } SUB = 0; } return LETTER.join(""); } ////////////////////////////////////////////////// // v2021.4.25 // This function returns the next column label // when the previous one is already known. // Spreadsheet columns are usually labeled as // A, B, C, ... AA, AB, ... AAA, AAB, etc. // Usage: STRING = NextColumn(STRING) // function NextColumn(LETTER) { if (typeof(LETTER) === "undefined" || LETTER == null) return "A"; LETTER = (LETTER + "").toUpperCase().split(""); var i = LETTER.length, CARRY = 0, ADD = 1; while (i--) { c = LETTER[i].charCodeAt(0) + CARRY + ADD; if (c > 90) { c = 65; CARRY = 1; } else { CARRY = 0; } LETTER[i] = String.fromCharCode(c); ADD = 0; } return (CARRY ? "A" : "") + LETTER.join(""); } ////////////////////////////////////////////////// // v2021.4.25 // This function converts an integer (0-18278) to // a column letter. Spreadsheet columns are usually // labeled as A, B, C, ... AA, AB, ... AAA, AAB, etc. // If N is negative or NaN, the letter "A" is returned. // Usage: STRING = GetColumnLetter(INTEGER) // function GetColumnLetter(N) { N |= 0; if (N < 1) return "A"; if (N < 26) return String.fromCharCode(N + 65); if (N < 702) return String.fromCharCode(((N / 26) | 0) + 64) + String.fromCharCode(N % 26 + 65); if (N < 18278) { var prev = 702; var LIMIT = 1378; for (var i = 0; i < 26; i++) { if (N < LIMIT) { N -= prev; return String.fromCharCode(i + 65) + String.fromCharCode(((N / 26) | 0) + 65) + String.fromCharCode(N % 26 + 65); } prev = LIMIT; LIMIT += 676; } } return "AAAA"; } ////////////////////////////////////////////////// // v2021.4.25 // This function converts a column letter to a // numeric value. A=0 B=1 C=2 AA=26 AB=27 etc... // If the letter turns out to be an invalid // character, then zero is returned. // Usage: INTEGER = GetColumnNumber(LETTER) // function GetColumnNumber(LETTER) { if (typeof(LETTER) === "undefined" || LETTER == null) return 0; LETTER = (LETTER + "").toUpperCase(); var c, i, V = [], MUL = 1, RET = 0; if (LETTER.length <= 1) { c = LETTER.charCodeAt(0); return (c > 64 && c < 91) ? c - 65 : 0; } for (i = 0; i < LETTER.length; i++) { c = LETTER.charCodeAt(i); if (c > 64 && c < 91) V.push(c - 65); } if (V.length) V[0]++; if (V.length > 2) V[1]++; if (V.length > 3) V[2]++; for (i = V.length - 1; i >= 0; i--) { RET += V[i] * MUL; MUL *= 26; } return RET; } ////////////////////////////////////////////////// function toCSV(A) { var i; var $ = []; for (i = 0; i < A.length; i++) { $[i] = A[i]; if ($[i].indexOf(",") >= 0 || $[i].indexOf('"') >= 0) $[i] = '"' + $[i].split('"').join('""') + '"'; } return $.join(","); } ////////////////////////////////////////////////// // v2021.3.16 // This function adds a string to the end of a // file in ASCII mode. Return 0 on success or // returns 1 if something went wrong. The global // variable $a will hold a text string "SUCCESS" // if everything went well or an error message. // Usage: INTEGER = AppendFile(FILENAME, CONTENT) // function AppendFile(FILENAME, STRING) { $a = ""; var ForReading = 2; var ForWriting = 4; var ForAppending = 8; var inASCII_Format = 0; var inUNICODE_Format = -1; var Create_If_File_Doesnt_Exist = 1; var Do_Not_Create_If_File_Doesnt_Exist = 0; try { var FSO = new ActiveXObject("Scripting.FileSystemObject"); var F = FSO.OpenTextFile(FILENAME, ForAppending, Create_If_File_Doesnt_Exist, inASCII_Format); F.Write(STRING); F.Close(); return 0; } catch (e) { $a = e.message; } return 1; } ////////////////////////////////////////////////// // // This function removes whitespace before and after // text T and returns a new string. // Usage: STRING = Trim(STRING) // function Trim(T) { T += ""; var i, j, x; for (x = i = j = 0, i--; x < T.length; x++) if (T.charCodeAt(x) > 32) { if (i < 0) i = x; j = x + 1; } return T.slice(i, j); } ////////////////////////////////////////////////// // This function returns the last element of array A without modifying the array. function Last(A) { return A[A.length - 1]; } // This function returns a new array full of zeros. A second argument may be provided to initialize the array with something other than zeros. function InitArray(SIZE) { var i, A = new Array(SIZE), InitValue = (arguments.length > 1) ? arguments[1] : 0; for (i = 0; i < SIZE; i++) A[i] = InitValue; return A; } // This function returns the length of the longest string in an array. function LongestWordIn(A) { var L = 0, X, i = A.length; while(i--) { X = (A[i]).toString().length; if (X > L) L = X; } return L; } // This function returns the length of the shortest string in an array. function ShortestWordIn(A) { var L = 0x7FFFFFFF, X, i = A.length; while(i--) { X = (A[i]).toString().length; if (L > X) L = X; } return L; } // This function copies elements of array B into array A without creating more duplicates. This function runs a case-sensitive search and does not sort the contents of either arrays. function MergeArray(A, B) { var i, j, N = 0; for (i = 0; i < B.length; i++) { for (j = 0; j < A.length; j++) if (A[j] == B[i]) { j = -1; break; } if (j >= 0) { A.push(B[i]); N++; } } return N; } // This function returns part of an array and reduces the length of the original array. It works just like the slice() method on strings, but this operates on arrays only. This function will change the size of array A. function ArraySlice(A, X) { var R = []; if (X < 0) X += A.length; if (X < 0 || X > A.length) return R; for (var i = X; i < A.length; i++) R.push(A[i]); A.length = X; return R; } ////////////////////////////////////////////////// // v2019.12.27 // This function splits string S into N-byte sized // chunks and returns an array. If a third argument // is given, it will use as padding. The padding must // be either one byte or two bytes. If it is one byte, // it will be added in front of the last group. // If it is two bytes, the second byte will be added // at the end of the last group. // Usage: ARRAY = Group(STRING, LENGTH, [PADDING]) // Example: Group('abcd', 3) -> ['abc', 'd'] // Group('abcd', 3, '-') -> ['abc', '--d'] // Group('abcd', 3, ' -') -> ['abc', 'd--'] // function Group(S, N, PADDING) { var i, j = -1, A = []; if (S.length == 0) return A; for (i = 0; i < S.length; i += N) A[++j] = S.substr(i, N); if (typeof(PADDING) === "string") { if (PADDING.length == 1) while (A[j].length < N) A[j] = "" + PADDING + A[j]; if (PADDING.length == 2) while (A[j].length < N) A[j] += "" + PADDING.charAt(1); } return A; } // This function converts a string to an array of ASCII character codes. function charCodeArray(S) { var i, A = []; for (i = 0; i < S.length; i++) A[i] = S.charCodeAt(i); return A; } // This function assembles a string from an array of ASCII character codes. It's the opposite of charCodeArray() with one important difference: 16-bit and 32-bit numbers are converted into multiple bytes. For example, 0x20 becomes a space character. But 0x4020 becomes a "@" followed by a space character! And 0x41424344 becomes a string "ABCD". Now, this function won't know the size of the desired output if the input array holds just one zero. It can't tell whether that stands for 2 zero bytes or just one or four, because there's no difference between 0x00 and 0x0000. So, in that case, it will assume that Zero stands for just one byte. For example, this works: STRING = fromCharCodeArray( [0x33, 0x00414243, 0x204748, 0x20, 0x49] ); -- zero character becomes omitted. function fromCharCodeArray(ARRAY) { var i, N, S = []; for (i = 0; i < ARRAY.length; i++) { N = ARRAY[i]; if (N <= 0xff) S[i] = String.fromCharCode(N); else if (N <= 0xffff) S[i] = String.fromCharCode((N>> 8) & 0xff) + "" + String.fromCharCode(N & 0xff); else if (N <= 0xffffff) S[i] = String.fromCharCode((N >> 16) & 0xff) + "" + String.fromCharCode((N >> 8) & 0xff) + "" + String.fromCharCode(N & 0xff); else S[i] = String.fromCharCode((N >> 24) & 0xff) + "" + String.fromCharCode((N >> 16) & 0xff) + "" + String.fromCharCode((N >> 8) & 0xff) + "" + String.fromCharCode(N & 0xff); } return S.join(""); } // This function trims each element of array A and removes empty strings elements. This function shortens the original array. function RemoveBlank(A) { var L, i, j = 0; for (i = 0; i < A.length; i++) { L = Trim(A[i]); if (L.length) { if (j < i) A[j] = L; j++; } } A.length = j; } // This function sorts array A and removes duplicate elements. function RemoveDuplicates(A) { var i, P = ""; A.sort(); for (i = 0; i < A.length; i++) if (A[i] == P) { P = A[i]; A[i] = ""; } else P = A[i]; RemoveBlank(A); } // This function removes duplicate items from an array and returns a new array containing the items that have been removed. The scan is case sensitive. This function also sorts the array. //function ExtractDuplicates(A) { if (A.length < 2) return 0; A.sort(); var i = 0, j = 1, D = []; while (j < A.length) { if (A[i] == A[j]) { A.splice(j, 1); D.push(A[i]); } else { i++; j++; } } return D; } // This function extracts elements of small array B from big array A. This function reduces the size of array A. function ExtractFrom(A, B) { var i, j; for (i = 0; i < A.length; i++) for (j = 0; j < B.length; j++) if (A[i] == B[j]) { A[i] = ""; break; } } // This function looks for string S in array A and returns the index where it is found. The scan is non-case sensitive. function FindInArray(S, A) { S = S.toUpperCase(); for (var i = 0; i < A.length; i++) if (A[i].toUpperCase().indexOf(S) >= 0) return i; return -1; } // This function returns the first matching index // where A[index] is an exact match with string S. // LookUp() is case-sensitive: will treat upper/lower case letters differently // LOOKUP() is non-case-sensitive: will match upper/lower case letters function LookUp(S, A) { S = S + ""; for (var i = 0; i < A.length; i++) if (S == A[i]) return i; return -1; } function LOOKUP(S, A) { S = S.toUpperCase(); for (var i = 0; i < A.length; i++) if (S == A[i].toUpperCase()) return i; return -1; } // This function swaps two elements of array A. function Swap(A, x, y) { var T = A[x]; A[x] = A[y]; A[y] = T; } // This function is designed to sort a two-dimensional array. ROW tells which row to sort by. This function rearranges the contents of ARRAY. function SortBy(ARRAY, ROW) { function COMPARE(A, B) { if (isNaN(A[ROW]) || isNaN(B[ROW])) { if (A[ROW] > B[ROW]) return 1; if (A[ROW] < B[ROW]) return -1; return 0; } return A[ROW] - B[ROW]; } ARRAY = ARRAY.sort(COMPARE); } // QSort algorithm written in JavaScript. I took this code from a QBasic program written by Ethan Winer and translated it to JavaScript. In Chrome and Safari, qsort runs 2X faster than the builtin sort() method. In KMeleon, qsort is 8X faster! The only browsers where qsort is actually slower is QupZilla and Internet Explorer. In QupZilla, the difference is barely noticeable, however in IE6, the old sort() method is 6X faster. Most people, however, don't use IE6 anymore, so I think, we can ignore that. Example : SortArrays(AGE, NAME, HEIGHT, SCORE) would rearrange all four arrays by age. function SortArrays(A) { var i, j, k, m, x, Q = [], First = 0, Last = A.length - 1; for (;;) { do { m = A[((First+Last)/2)|0]; i = First; j = Last; do { while (A[i] < m) i++; while (A[j] > m) j--; if (i > j) break; if (i < j) { for (k = 0; k < arguments.length; k++) { x = arguments[k][i]; arguments[k][i] = arguments[k][j]; arguments[k][j] = x; } } i++; j--; } while (i <= j); if (i < Last) { Q.push(i); Q.push(Last); } Last = j; } while (First < Last); if (Q.length == 0) break; Last = Q.pop(); First = Q.pop(); } } _ = ""; HEX = "0123456789ABCDEF".split(""); B64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/+'; BIN4 = "0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111".split(" "); // Converts a decimal number to hexadecimal format. Limit: 0 to 255 function toHex(D) {if(isNaN(D)||D<1)return"00";if(D>254)return"ff";D&=255;return(D<16?"0":"")+D.toString(16);} // Converts a decimal number to hexadecimal format. Limit: 0 to 65536 function toHexWord(N) { if (N > 65534) return "ffff"; var Z = "0000"; if (N < 1) return Z; N = N.toString(16); return Z.substr(0, 4 - N.length) + N; } // This function converts a 32-bit signed integer to 8-digit hex format. function toHexLong(N) { N |= 0; var i, X = ""; for (i = 0; i < 32; i += 4) X = "0123456789ABCDEF".charAt((N >> i) & 15) + X; return X; } // Converts a binary string to a number. Limit: 0xFFFFFFFF function Bin2Int(B) { var i = B.length, V = 0, N = 1; while (i-- > 0) { V += ((B.charAt(i) == "1") ? N : 0); if (N >= 0x80000000) break; N += N; } return V; } // Converts a binary string to hex string. No limit. // This function arranges binary digits into groups of eight // before converting them. If the last group doesn't have // eight digits, zeros are added to the end. function Bin2Hex(B) { var c, i = 0, V = 0, N = 8, X = []; while (i < B.length) { c = B.charCodeAt(i++) & 255; if (c < 48 || c > 49) continue; if (c == 49) V += N; if (N > 1) N >>= 1; else { X.push(HEX[V]); V = 0; N = 8; } } if (N < 8) X.push(HEX[V]); if (X.length & 1) X.push("0"); return X.join(""); } ////////////////////////////////////////////////// // v2019.12.27 // Converts a series of binary numbers to a raw string. // Usage: STRING = Bin2Str(STRING) // function Bin2Str(B) { B = Group(B, 8, ".0"); for (var i = 0; i < B.length; i++) B[i] = String.fromCharCode(parseInt(B[i], 2)); return B.join(""); } ////////////////////////////////////////////////// // v2019.12.27 // Converts a raw string to series of binary numbers. // Usage: STRING = Str2Bin(STRING) // function Str2Bin(S) { var i = 0, C, OUTPUT = []; for (; i < S.length; i++) { C = S.charCodeAt(i).toString(2); OUTPUT[i] = "00000000".slice(C.length) + C; } return OUTPUT.join(""); } ////////////////////////////////////////////////// // Converts string S to a series of hex numbers. Faster than toString(16) function Str2Hex(S) { var c, i, x = []; for(i = 0; i < S.length; i++) { c = S.charCodeAt(i) & 255; x.push(HEX[c >> 4] + HEX[c & 15]); } return x.join(_); } // Converts a hex string to binary string. No Limit! function Hex2Bin(X) { var i, c, B = []; for (i = 0; i < X.length; i++) { c = X.charCodeAt(i); if (c < 48 || c > 102) continue; c |= 32; if (c > 96) c -= 87; else c -= 48; B.push(BIN4[c]); } return B.join(""); } // Converts a series of hexadecimal numbers to a raw string. function Hex2Str(X) { var i, $ = []; X += ""; for (i = 0; i < X.length; i += 2) $.push(String.fromCharCode(parseInt(X.substr(i, 2), 16))); return $.join(""); } // Converts a hexadecimal string to a number. function Hex2Int(H) { if (H.length < 8) return parseInt(H, 16); H = H.toUpperCase(); var C, D = 0, S = 1, i = H.length; while (i--) { C = "0123456789ABCDEF".indexOf(H.charAt(i)); if (C < 0) return D; else { if (C) D += C * S; S *= 16; } } return D; } //function Hex2Int(X) { return parseInt(X, 16); } // Converts a large positive integer to a 14-byte hex string. Valid range: 0 to 9,007,199,254,740,992 function Int2Hex(N) { if (typeof(N)==="undefined") return "0"; if (isNaN(N)) return "0"; if (N < 1) return "0"; N = Math.floor(N); if (N <= 4294967295) return N.toString(16); if (N > 9007199254740991) return "20000000000000"; var LOW = (N & 0x0FFFFFFF).toString(16); if (LOW.length < 7) LOW = "0000000".slice(LOW.length) + LOW; return (Math.floor(N/268435456) & 0x0FFFFFFF).toString(16) + "" + LOW; } // Encodes a binary string to Base64 string function EncodeB64(S) { var i, j, k = -4, SHIFT = 6, $ = []; for (i = j = 0; i < S.length; i++, j++) { if (SHIFT > 5) { SHIFT = 0; k += 4; $[k] = 0; j++; } SHIFT += 2; $[j] = S.charCodeAt(i); $[k] += ($[j] & 0xC0) >> SHIFT; $[j] = $[j] & 63; } while (--j >= 0) $[j] = String.fromCharCode($[j] + 63); return $.join(""); } // Decodes a Base64 string to binary string function DecodeB64(S) { var i, c, H, $ = []; for (i = 0; i < S.length; i++) { c = S.charCodeAt(i) - 63; c = (c < 0) ? 0 : c & 63; if (i % 4) { H <<= 2; $.push(String.fromCharCode(c + (H & 0xC0))); } else H = c; } return $.join(""); } ////////////////////////////////////////////////// // String | v2022.11.13 // This function converts a string to text using the // standard Base64 encoding algorithm. // // The first argument should be a string. // The second argument MAY contain a custom 65-byte // character set. The 65th byte will be used for padding. // // The second argument MAY also be 0 or 1: // 0 = Use standard Base64 encoding which ends with +/ (default) // 1 = Use web-safe Base64 encoding which ends with -_ // // Usage: STRING = EncodeBase64(STRING, [CHARSET]) // function EncodeBase64(S, BASE64) { if (typeof(S) == "undefined") return ""; S += ""; // Prepare character set. var TYPE = 2; var PADDING = "="; if (typeof(BASE64) == "undefined") BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; else if (BASE64.length >= 65) { TYPE = 0; PADDING = BASE64.substr(64, 1); } else if (typeof(BASE64) == "number") TYPE = BASE64; if (TYPE) BASE64 += (TYPE == 1) ? "-_" : "+/"; // Get string reference. var i = 0, p = 0, A, B, C, DIFF, OUTPUT = []; while (i < S.length) { // Read 3 bytes. A = S.charCodeAt(i++); B = S.charCodeAt(i++); C = S.charCodeAt(i++); // Write 4 bytes. OUTPUT[p++] = BASE64.charAt(A >> 2); OUTPUT[p++] = BASE64.charAt(((A & 3) << 4) | (B >> 4)); OUTPUT[p++] = BASE64.charAt(((B & 15) << 2) | ((C >> 6) & 3)); OUTPUT[p++] = BASE64.charAt(C & 63); } // Replace last couple of bytes with padding. DIFF = i - S.length; while (DIFF--) OUTPUT[p++] = PADDING; return OUTPUT.join(""); } ////////////////////////////////////////////////// // String | v2022.11.4 // This function converts some Base64 text to a string // using the standard Base64 converter algorithm. // // The first argument should be a string. // The second argument MAY contain a custom 64-byte // character set. // // Usage: STRING = DecodeBase64(STRING, [CHARSET]) // function DecodeBase64(S, BASE64) { var i = 0, p = 0, A, B, C, D, DIFF, OUTPUT = [], LUT = []; // Create lookup table. for (i = 0; i < 256; i++) LUT[i] = 0; if (typeof(BASE64) == "undefined" || BASE64.length < 64) { BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; LUT[45] = 62; // Add these two: -_ LUT[95] = 63; } for (i = 0; i < BASE64.length; i++) LUT[BASE64.charCodeAt(i)] = i; // Decode Base64 string. i = 0; while (i < S.length) { // Read 4 bytes. A = LUT[S.charCodeAt(i++)]; B = LUT[S.charCodeAt(i++)]; C = LUT[S.charCodeAt(i++)]; D = LUT[S.charCodeAt(i++)]; // Write 3 bytes. OUTPUT[p++] = String.fromCharCode(((A << 2) | ((B >> 4) & 3)) & 255); OUTPUT[p++] = String.fromCharCode(((B << 4) | (C >> 2)) & 255); OUTPUT[p++] = String.fromCharCode((((C & 3) << 6) | D) & 255); } DIFF = !C + !D; OUTPUT.length -= DIFF; return OUTPUT.join(""); } ////////////////////////////////////////////////// // Converts an integer to Base64 character(s). function Int2B64(N) { var B = []; do { B.push(B64.charAt(N & 63)); N >>>= 6; } while (N > 0); return B.reverse().join(""); } // This function converts a 2-byte string (big endian) to an unsigned int. function StrInt(S) {return S.charCodeAt(0)<<8|S.charCodeAt(1);} // This function converts an integer to a 2-byte string (big endian format). function IntStr(N) {return String.fromCharCode(N>>>8&255)+String.fromCharCode(N&255);} // This function converts a 4-byte string (big endian) to a long int. function StrLong(S) {return S.charCodeAt(0)<<24|S.charCodeAt(1)<<16|S.charCodeAt(2)<<8|S.charCodeAt(3);} // This function converts a 32-bit long to a 4-byte string (big endian format). function LongStr(N) {return String.fromCharCode(N>>>24&255)+String.fromCharCode(N>>>16&255)+String.fromCharCode(N>>>8&255)+String.fromCharCode(N&255);} // This function converts a positive integer N to any base using digits listed in string S. function Num2Set(N, S) {var Z=S.charAt(0);if(typeof(N)==="undefined")return Z;if(isNaN(N))return Z;if(N<1)return Z;N=Math.floor(N);if(N==1)return S.charAt(1);if(N>9007199254740991)N=9007199254740992;var L=S.length;var $=[];while(N>1){C=N%L;$.push(S.charAt(C));N=Math.floor((N-C)/L);}if(N)$.push(S.charAt(N));return $.reverse().join("");} // This function converts string N from any base to a positive integer. Digit set must be provided in string S. function Set2Num(N, S) {var D,PWR=1,X=0,i=N.length,L=S.length;while(i--){D=S.indexOf(N.charAt(i));if(D<0)return X;else{if(D)X+=D*PWR;PWR*=L;}}return X;} // NOTE: The Array2Double() and Double2Array() functions // will work with Chrome 7, Firefox 4, MSIE10, Edge, // Safari 5.1, Vivaldi 1, QupZilla 1.8.6, KMeleon 7.5. // They won't work in Opera 7.54, IE6, and KMeleon 1.5.4. // To use these functions in older web browsers, try // using _Float2Array() and _Array2Float() instead. // This function converts an array of 8 integers between 0-255 to a native JavaScript number (IEEE-754 double format). The input array must have at least 8 elements!!! function Array2Double(A) { var F = new ArrayBuffer(8); var B = new Uint8Array(F); var N = new Float64Array(F); for (var i = 0; i < 8; i++) B[i] = A[i]; return N[0]; } // This function converts a JavaScript number to an array of 8 integers between 0-255. function Double2Array(V) { var F = new ArrayBuffer(8); var B = new Uint8Array(F); var N = new Float64Array(F); N[0] = V; var i, A = []; for (i = 0; i < 8; i++) A[i] = B[i]; return A; } // This function converts an array of 8 numbers (0-255) to a limited JavaScript float. Note: This function will not work with all double-precision numbers. It will only work when there's no exponent. Use _SmallFloat() to make sure it will work. function _Array2Float(A) { var N = 0, M = 1, i = 7; while (i) { N += A[i--] * M; M *= 256; } if ((M = A[0] & 127)) { N = "0000000000" + N; N = N.substr(0, N.length - M) + "." + N.substr(N.length - M); } return N * (A[0] & 128 ? -1 : 1); } // This function converts a JavaScript float number to an array of 8 numbers (0-255). Note: This function will not work with all double-precision numbers. It will only work when there's no exponent. Use _SmallFloat() to make sure it will work. function _Float2Array(V) { var i = 7, A = [0]; if (V < 0) { A[0] = 128; V = -V; } V = (V+".").split("."); A[0] |= V.length > 2 ? V[1].length : 0; V = V.join(""); while (i) { A[i--] = V & 255; V = Math.floor(V / 256); } return A; } // This function reduces the size of a double-precision JavaScript number to a safe float that only has 15 significant digits and no exponent. function _SmallFloat(N) { var S = (N < 0) ? -1 : 1; N += ""; if (S < 0) N = N.slice(1); N = N.split("."); var L = N[0].length; if (L > 15) N[0] = N[0].substr(0, 15); else if (L + N[1].length > 15) N[1] = N[1].substr(0, 15 - L); return S * N.join(".").toUpperCase().split("E")[0]; } // Returns the last N bytes of a string. function sliceLast(S, N) {if(S.length==0)return"";if(typeof(N)=="undefined")return"";if(N<1)return"";if(N>=S.length)return S;return S.substr(S.length-N,N);} // This function repeats a string N number of times. function Repeat(S, N) { return (new Array(N+1)).join(S); } // This function overwrites a part of string S with character C at byte position X and returns a new string. Example: vec("ABCDEF", 2, 42) --> "AB*DEF" //function vec(S, X, C) { X |= 0; S += ""; if (X < 0) return S; C = String.fromCharCode(C & 255); if (X == 0) return C + S.slice(1); if (X < S.length) return S.substr(0, X) + "" + C + S.slice(X+1); while (S.length < X) S += " "; return S + "" + C; } // This function overwrites the input string with one character and returns a new string. function vec(STRING, INDEX, CHARCODE) { if (typeof(STRING) === "undefined") return ""; if (STRING == null) return ""; STRING += ""; if (typeof(INDEX) === "undefined") return STRING; if (typeof(CHARCODE) === "undefined") return STRING; var C = String.fromCharCode(CHARCODE & 255); INDEX |= 0; if (INDEX < 0) return STRING; if (INDEX == 0) return C + STRING.slice(1); if (INDEX == STRING.length) return STRING + C; if (INDEX < STRING.length) return STRING.substr(0, INDEX) + C + STRING.slice(INDEX+1); if (STRING.length == 0) return (new Array(INDEX+1)).join(" ") + C; return STRING + (new Array(INDEX - STRING.length+1)).join(" ") + C; } // Adds padding characters C to string S on the left. Returns a string that is exactly L bytes long. function _LEFT(S, C, L) {S=S.toString();if(S.length>L)return S.slice(S.length-L);while(S.lengthL)return S.slice(S.length-L);while(S.length 32) { if (i < 0) i = x; j = x + 1; } return T.slice(i, j); } // This function removes whitespace from the left and returns a new string. function LTRIM$(T) { T += ""; var i = 0; while (T.charCodeAt(i) < 33) i++; return T.slice(i); } // This function removes whitespace from the right and returns a new string. function RTRIM$(T) { T += ""; var i = T.length; while (T.charCodeAt(--i) < 33); return T.substr(0, i+1); } // Converts all adjacent whitespace characters to a single space. function CollapseWhitespace(S) { S = S.split(""); var i, x, c = 0; for (i = 0; i < S.length; i++) { x = c; c = S[i].charCodeAt(0); if (c < 14) c = 32; if (c == 32) S[i] = (x == 32) ? "" : " "; } return S.join(""); } // This function trims text T and removes excess characters from the end and adds "..." function Truncate(T, MAXLEN) { T = Trim(T); if (T.length <= MAXLEN) return T; return T.substr(0, MAXLEN - 3) + "..."; } // This function removes all characters found in string L from string S and returns what's left of string S. function RemoveChars(S, L) { var i, c; for (i = 0; i < L.length; i++) { c = L.charAt(i); S = S.split(c).join(""); } return S; } // This function calculates a revolver index for strings. A revolver index means it wraps around. For example, if the string is 5 bytes long and you want to grab byte 7, then the index wraps around, so you'll get byte 2. This function returns 2. And if you want to grab the last byte of the string, you simply reach for -1 and this function will return the index to the last byte of string. function rvx(INDEX, LEN) { INDEX %= LEN; if (INDEX < 0) INDEX += LEN; return INDEX; } // This function returns a character from string S using revolver index X. function CharAt(S, X) { return S.charAt(rvx(X, S.length)); } // This function returns a character at position X. If X is longer than the length of string, it wraps around. If X is a negative index, it will start counting from the end of string S. function CharCodeAt(S, X) { return S.charCodeAt(rvx(X, S.length)); } // Returns 1 if the first byte of string S is a letter of the alphabet. function isLetter(S) { var c = S.charCodeAt(0) & 223; return (c > 64 && c < 91) ? 1 : 0; } // This function extracts a section from string S that lies between string L and R. // Returns an empty string if either L or R is not found. function Between(S, L, R) { var p1 = S.indexOf(L); if (p1 < 0) return ""; var p2 = S.lastIndexOf(R); if (p2 <= p1) return ""; return S.substring(p1 + L.length, p2); } // This function returns a section of string S that comes before the first occurrence of string M. The match is case sensitive. function StrBefore(S, M) { var E = S.indexOf(M); return (E > 0) ? S.substr(0, E) : ""; } // This function returns a section of string S that comes after the first occurrence of string M. The match is case sensitive. function StrAfter(S, M) { var E = S.indexOf(M); return (E > 0) ? S.slice(E + M.length) : ""; } // This function counts how many times string M occurs in string S and returns an integer. function StrCount(S, M) { return S.split(M).length - 1; } // Returns 1 if string S starts with string M. function StartsWith(S, M) { return (S.indexOf(M) == 0) ? 1 : 0; } // Returns 1 if string S ends with string M. function EndsWith(S, M) { return (S.lastIndexOf(M) == S.length - M.length) ? 1 : 0; } // Ensures string S starts with prefix X. function EnsureStart(S, X) { S += ""; X += ""; return (S.indexOf(X) == 0) ? S : X + S; } // Ensures string S ends with suffix X. function EnsureEnd(S, X) { S += ""; X += ""; return (S.lastIndexOf(M) == S.length - X.length) ? S : S + X; } // Returns 1 if string S contains letters only. function isLettersOnly(S) { S += ""; var i, c; for (i = 0; i < S.length; i++) { c = S.charCodeAt(i); if (c < 65 || c > 122) return 0; if (c > 90 && c < 97) return 0; } return 1; } // Returns 1 if string S contains letters and numbers only. function isAlphaNumberic(S) { S += ""; var i, c; for (i = 0; i < S.length; i++) { c = S.charCodeAt(i); if (c < 48 || c > 122) return 0; if (c > 90 && c < 97) return 0; if (c > 57 && c < 65) return 0; } return 1; } // Returns 1 if string S is solely composed of whitespace or is null/undefined. function isEmpty(S) { if (typeof S === "undefined") return 1; if (S == null) return 1; S += ""; var i, c; for (i = 0; i < S.length; i++) { c = S.charCodeAt(i); if (c < 14 || c == 32); else return 0; } return 1; } // Returns 1 if string S is lower case only. function isLower(S) { S += ""; return (S == S.toLowerCase()) ? 1 : 0; } // Returns 1 if string S is upper case only. function isUpper(S) { S += ""; return (S == S.toUpperCase()) ? 1 : 0; } // Returns 1 if string S contains 0123456789 digits only. function isNumeric(S) { S += ""; var i, c; for (i = 0; i < S.length; i++) { c = S.charCodeAt(i); if (c < 48 || c > 57) return 0; } return 1; } // This function splits string S at pointer X and puts the first half of the string into global variable $A and the second half into $B. When X is a negative index, it starts counting from the end of string S. This function always returns the length of $A. function SplitAt(S, X) { if (X >= S.length) { $A = S; $B = ""; return S.length; } if (X == 0 || X <= -S.length) { $A = ""; $B = S; return 0; } $A = S.substr(0, (X < 0) ? S.length + X : X); $B = S.slice(X); return $A.length; } // This function splits string S into two parts along the first occurrence of pattern P. The two parts will be stored in global variables named $A and $B. This function returns 1 if the pattern was found, or zero if it was not found. function SplitAB(S, P) { var N = S.indexOf(P); if (N < 0) { $A = S; $B = ""; return 0; } $A = S.slice(0, N); $B = S.slice(N + P.length); return 1; } // This function splits string S into two parts along the last occurrence of pattern P. The two parts will be stored in global variables named $A and $B. This function returns 1 if the pattern was found, or zero if it was not found. function LastSplitAB(S, P) { var N = S.lastIndexOf(P); if (N < 0) { $A = S; $B = ""; return 0; } $A = S.slice(0, N); $B = S.slice(N + P.length); return 1; } // This function scans string S and replaces every occurrence of string A with B and returns a new string. Case sensitive search. function StrReplace(S, A, B) { return S.split(A).join(B); } // This function uses replace() with RegExp() to run a non-case-sensitive replace. function StrReplaceAll(S, A, B) { return S.replace(RegExp(A, "gi"), B); } // This function reverses string S. function StrReverse(S) { return S.split("").reverse().join(""); } // This function returns the first N characters of string S. function StrLeft(S, N) { if (N < 1) return ""; return S.substr(0, N); } // This function returns the last N characters of string S. function StrRight(S, N) { if (N < 1) return ""; if (N >= S.length) return S; return S.slice(S.length - N); } // This function is similar to the original split() method, however this will treat // space, tab, new line, return, comma, semicolon, and period as separator characters. // Also, the result will be all uppercase letters! function Split(TEXT) { var i, A = [], C, START = null; TEXT = TEXT.toUpperCase() + "\n"; for (i = 0; i < TEXT.length; i++) { C = TEXT.charAt(i); if (C == ' ' || C == '\t' || C == '\n' || C == '\r' || C == ',' || C == ';' || C == '.') { if (START != null) A.push(TEXT.substring(START, i)); START = null; } else if (START == null) START = i; } return A; } // This function splits a string along new-line characters and returns an array. // Recognizes \r\n \n\n \r\r function SplitLines(S) { if (S.indexOf("\r") < 0) return S.split("\n"); if (S.indexOf("\n") < 0) return S.split("\r"); return S.split("\r\n"); } ////////////////////////////////////////////////////// // // This function splits a string, stuffing digits and // non-digits into alternating elements of an array. // Example: // SplitNumbers("34DX5g") -> ["34", "DX", "5", "g"] // SplitNumbers("-x39.4") -> ["-x", "39", ".", "4"] // function SplitNumbers(S) { var A = [], p = 0, m = -1, i, d; for (i = 0; i < S.length; i++) { d = S.charCodeAt(i); d = d > 47 && d < 58; if (m == d) { A.push(S.substring(p, i)); p = i; } m = !d; } A.push(S.substring(p, i)); return A; } ////////////////////////////////////////////////////// // // This function extracts digits from a string and // returns them in an array. // Example: // SplitNumbers("34DX5g") -> ["34", "5"] // SplitNumbers("-x39.4") -> ["39", "4"] // function GetNumbers(S) { var A = [], p = -1, i, c; for (i = 0; i <= S.length; i++) { c = S.charCodeAt(i); if (c < 48 || c > 57) { if (p >= 0) A.push(S.substring(p, i)); p = -1; } else if (p < 0) p = i; } return A; } ////////////////////////////////////////////////////// // // This function extracts digits from strings and // returns them in an array. // Usage: ARRAY = GetNumberList(STRING, [STRING]...) // Example: // GetNumberList("34DX5g", 55, "a41") -> ["34", "5", "55", "41"] // GetNumberList("-x39.4") -> ["39", "4"] // function GetNumberList() { var A = [], S, p = -1, i = 0, c; while (i < arguments.length) A.push(arguments[i++] + "/"); S = A.join(""); A = []; for (i = 0; i < S.length; i++) { c = S.charCodeAt(i); if (c < 48 || c > 57) { if (p >= 0) A.push(S.substring(p, i)); p = -1; } else if (p < 0) p = i; } return A; } ////////////////////////////////////////////////////// // This function counts the letters in a string. // If an optional second argument is passed: if it's zero, returns // the number of vowels, otherwise returns the number of consonants. function LetterCount(S) { var c, n = 0, v = 0, i = S.length; while (i-- > 0) { c = S.charCodeAt(i) | 32; if (c < 97 || c > 122) continue; if (c == 97 || c == 101 || c == 105 || c == 111 || c == 117) v++; else n++; } if (arguments.length > 1) return (arguments[1]) ? n : v; return n+v; } // This function encodes or decodes a string using a password string, and returns the result. function XOR(STRING, PW) { var i, j, r, OUTPUT = [""]; for (r = i = j = 0; i < STRING.length; i++, j++) { if (j > PW.length) j = 0; OUTPUT[r] += String.fromCharCode(STRING.charCodeAt(i) ^ PW.charCodeAt(j)); if (OUTPUT[r].length > 100) { r++; OUTPUT[r] = ""; } } return OUTPUT.join(""); } // Replaces SEARCHSTR with PASTE globally (not case sensitive) function REP(STRING, SEARCHSTR, PASTE) { document.write(A.replace(RegExp(SEARCHSTR, "gi"), PASTE)); } // Inserts string B into A starting at offset N. // If N > 0, then inserts from the beginning of string. // If N < 0, then inserts from the end of string. function StrInsert(A, B, N) { A += ""; B += ""; if (A.length == 0) return B; if (B.length == 0) return A; if (N > A.length) N = A.length; if (N < 0) N += A.length; if (N < 0) N = 0; var PART1 = A.substr(0, N); var PART2 = A.slice(N); return PART1 + B + PART2; } ////////////////////////////////////////////////// // v2019.12.27 // This function compresses a text to binary string // by removing the highest 0 bit from every byte // thus shrinking the output by 8:7 ratio. // Usage: STRING = Compress8to7(TEXT) // function Compress8to7(T) { var i, j, L = T.length, BINARY = [(((L-1) & 7) == 0) || (((L-2) & 7) == 0) ? '1' : '0']; for (i = j = 0; i < L; i++) BINARY[++j] = toBin(T.charCodeAt(i) & 127, 7); BINARY = BINARY.join(""); // This line is really unnecessary. // It is here just for clarification only: // while (BINARY.length & 7) BINARY += '0'; return Bin2Str(BINARY); } ////////////////////////////////////////////////// // v2019.12.27 // This function expands a binary string to a text // by inserting a '0' in the high bit of each byte, // thus expanding the output by a 7:8 ratio. // Usage: TEXT = Expand7to8(STRING) // function Expand7to8(S) { var BINARY = Str2Bin(S); var L = BINARY.length - 1; var OUTPUT = []; for (i = 1; i < L; i += 7) OUTPUT.push(String.fromCharCode(parseInt(BINARY.substr(i, 7), 2))); if (BINARY.charCodeAt(0) == 48) OUTPUT.pop(); return OUTPUT.join(""); } ////////////////////////////////////////////////// // // LZW-compress a string // [This function was copied from LZ-String.js] // function LzwCompress(s) { var dict = {}; var data = (s + "").split(""); var out = []; var currChar; var phrase = data[0]; var code = 256; for (var i=1; i 1 ? dict[phrase] : phrase.charCodeAt(0)); dict[phrase + currChar] = code; code++; phrase=currChar; } } out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0)); for (var i=0; i
Character Statistics
"]; var A = CharCount(S); var max = Math.max.apply(0, A) >> 8; A.reverse(); function HTMLCHR(c) { var B = String.fromCharCode(c); if (B == " ") return " "; if (B == "&") return "&"; if (B == "<") return "<"; if (B == ">") return ">"; return (c < 32 || c == 173 || (c > 126 && c < 161)) ? "." : B; } for (i = 0; i < 256; i++) { X = A.shift(); C = X & 0xFF; N = (X & 0xFFFFFF00) >> 8; X = HTMLCHR(C); if (N == 0) break; HTML.push("
0x" + toHex(C).toUpperCase() + " = 
" + C + "
 = \"" + X + "\" " + N + " " + Repeat("▒", Math.floor(40 * N / max))); } HTML.push("

The following characters never occur in the string:
"); A.sort(function(a, b) {return a-b}); for (N = 0; i < A.length; i++) { C = A[i] & 0xFF; X = HTMLCHR(C); if (!(N++ % 10)) HTML.push("
"); HTML.push(" 0x" + toHex(C).toUpperCase() + "=" + X + ""); } HTML.push("

Length of input string : " + S.length + " bytes


"); document.write(HTML.join("")); } // This function returns a section of a full character set. A full character set always contains 256 characters from 0 to 255. But this function returns only a certain segment of that set defined by MIN and MAX. If MIN is smaller than MAX, then you get a normal character set starting at MIN and ending at MAX. Example: charSet(97, 99) --> "abc" However, if MIN is greater than MAX, then you get the inverse character set that includes every character EXCEPT those defined by MIN and MAX. function charRange(MIN, MAX) { var A = []; if (MIN > MAX) MIN++; else MAX++; MIN &= 255; MAX &= 255; while (MIN != MAX) { A.push(String.fromCharCode(MIN++)); MIN &= 255; } return A.join(""); } // This function returns the inverse set of characters that are not found anywhere in string S. // Example: inverseCharSet("YELLOW") will take a 256-byte long character set and remove the letters Y E L O W from the set and return what's left. function inverseCharSet(S) { var i, A = []; for (i = 0; i < 256; i++) A.push(String.fromCharCode(i)); for (i = 0; i < S.length; i++) A[S.charCodeAt(i)] = ""; return A.join(""); } // This function lists the characters that are used in string S and returns a sorted string. function regularCharSet(S) { S += ""; if (S.length == 0) return ""; var A = [], i = S.length; while (i-- > 0) A[S.charCodeAt(i)] = 2; while (i < 256) { A[i] = (A[i] == 2) ? String.fromCharCode(i) : ""; i++; } return A.sort().join(""); } // This function returns 1 if string S is strictly made up of // characters listed in string KNOWN. Returns 0 if string S // contains any "unknown" characters. function isFromCharSet(S, KNOWN) { S += ""; for (var i = 0; i < S.length; i++) if (KNOWN.indexOf(S.charAt(i)) < 0) return 0; return 1; } // This function translates each character of string S according to new character table NEWSET. // Example: // ConvertCharSet("aacb", "abc", "123") --> "1132" // ConvertCharSet("hello", "abcdefghijklmno", "-+0123456789XYZ") --> "5299Z" function ConvertCharSet(S, OLDSET, NEWSET) { var i, P; S = S.split(""); for (i = 0; i < S.length; i++) { P = OLDSET.indexOf(S[i].charAt(0)); S[i] = (P >= 0) ? NEWSET.charAt(P) : ""; } return S.join(""); } B64SET = "?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; URLSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz|_"; // This function takes any kind of binary string and converts it to a safe string that can be passed as an argument in the URL. function EncodeURL(S) { return ConvertCharSet(EncodeB64(S), B64SET, URLSET); } // This function takes an URL-safe string that contains letters and numbers only and returns a binary string. function DecodeURL(S) { return DecodeB64(ConvertCharSet(S, URLSET, B64SET)); } // This function converts a binary string (can be HTML or JavaScript) to a safe string that can be used in a HTML file within JavaScript tags. function EncodeHTML(S) { var i, C; S = S.split(""); for (i = 0; i < S.length; i++) { C = S[i].charCodeAt(0); if (C == 7) S[i] = "\\t"; else if (C == 10) S[i] = "\\r"; else if (C == 13) S[i] = "\\n"; else if (C == 92) S[i] = "\\\\"; else if (C == 34 || C == 38 || C == 39 || C == 60 || C == 62 || C < 32 || C > 126) S[i] = "\\x" + toHex(C); } return '"' + S.join("") + '"'; } // This function converts a Js safe string with quotation marks around it to its original source. It's the opposite of EncodeHTML() function DecodeHTML(S) { S += ""; if (S.length > 1) { if (S.charAt(0) == '"' || S.charAt(0) == "'") S = S.slice(1, -1); } S = S.split("\\t").join("\t").split("\\r").join("\r").split("\\n").join("\n").split("\\\\").join("\\").split("\\x"); for (var i = 1; i < S.length; i++) S[i] = String.fromCharCode(parseInt(S[i].substr(0, 2), 16)) + S[i].slice(2); return S.join(""); } // This function returns 1 if S is a valid hex number. function isHex(S) { return isFromCharSet(S, "0123456789abcdefABCDEF"); } // This function returns 1 if S contains digits only. function isDec(S) { return isFromCharSet(S, "0123456789"); } // This function returns 1 if string S is a valid binary number. function isBin(S) { return isFromCharSet(S, "01"); } // This function returns a hex string. // It filters string S and only allows hex digits to pass through. function ForceHex(S) { return strFilter(S, "0123456789abcdefABCDEF").toUpperCase(); } // This function filters string S and only allows digits to pass through. function ForceDec(S) { return strFilter(S, "0123456789"); } // This function returns a binary number. // It filters string S and only allows ones and zeros to pass through. function ForceBin(S) { return strFilter(S, "01"); } // This function converts number N to a positive integer that is exactly X number of bytes long. It does that by either chopping off some of the first few digits or putting some zeros in the front. function FIX(X, N) { if (isNaN(N) || N == null) N = "0"; else N = Math.floor(Math.abs(N)) + ""; if (N.length > X) return N.substr(N.length - X, X); while (N.length < X) N = "0" + N; return N; } // This function extracts the last whole number from string s and returns that number function lastNumber(s) { var i, c, L = 0, p = -1; for (i = s.length - 1; i >= 0; i--) { c = s.charCodeAt(i); if (c > 47 && c < 58) { if (p < 0) p = i; L++; } else { if (L > 0) break; } } return s.substr(p - L + 1, L); } // This function splits binary string S into groups of 8 and removes the first digit of each group and returns a new string. This function can remove the first N digits if a second argument is provided. // Example: // DiscardHighBit("1000000010000000"); --> "00000000000000" // DiscardHighBit("1100000011000000", 2); --> "000000000000" // DiscardHighBit("1110000011100000", 3); --> "0000000000" function DiscardHighBit(S) { S = Group(S, 8); var i, N = (arguments.length == 2) ? arguments[1] : 1; for (i = 0; i < S.length; i++) S[i] = S[i].slice(N); return S.join(""); } // This function is the opposite of DiscardHighBit() function. If a string is provided as a second argument, this string will be inserted at the beginning of every group. // Example: // InsertHighBit("11111111111111"); --> "0111111101111111" // InsertHighBit("1111111111", "000"); --> "0001111100011111" // InsertHighBit("00000000", "1111"); --> "1111000011110000" function InsertHighBit(S) { var BITS = (arguments.length > 1) ? arguments[1] : "0"; var N = (8 - BITS.length); S = Group(S, N); for (var i = 0; i < S.length; i++) S[i] = BITS + S[i]; return S.join(""); } // TIME FUNCTIONS NOW = new Date(); TIMEZONE = Math.round(Math.abs(NOW.getTimezoneOffset() / 60)); LOADTIME = now(); // Current time in milliseconds since Jan 1970 // Returns the number of milliseconds since Jan 1970. function now() { return (new Date()).getTime(); } // Returns the milliseconds portion of current time (0-1000) function M() { return (new Date()).getMilliseconds(); } // Returns the number of seconds since Jan 2019 in a 4-byte binary string. function MakeTimeStamp() {return LongStr(Math.floor(((new Date()).getTime()-1546300800000)/2000));} // Converts 4-byte TimeStamp string to milliseconds since Jan 1970. function ReadTimeStamp(S) {return StrLong(S)*2000+1546300800000;} // This function returns a text string that says how long // ago time T was recorded. Example: "5 minutes ago" function TimeAgo(T) { var DIFF = Math.abs(now() - T); if (DIFF < 70000) return "just now"; if (DIFF < 120000) return "1 minute ago"; if (DIFF < 3000000) return Math.round(DIFF / 60000) + " minutes ago"; if (DIFF < 6000000) return "about an hour ago"; if (DIFF < 86400000) return Math.floor(DIFF / 3600000) + " hours ago"; if (DIFF < 604800000) return Math.floor(DIFF / 86400000) + " days ago"; if (DIFF < 950400000) return "last week"; if (DIFF < 2298240000) return Math.floor(DIFF / 604800000) + " weeks ago"; if (DIFF < 3110400000) return "last month"; if (DIFF < 3110400000) return Math.floor(DIFF / 2635200000) + " months ago"; if (DIFF < 59918400000) return "a year ago"; return Math.round(DIFF / 31536000000) + " years ago"; } // This function is called by CreateTimeAgo() function UpdateTimeAgo(OBJECT_ID, T) { document.getElementById(OBJECT_ID).innerText = TimeAgo(T); } // This function creates a text label that gets updated every 15 seconds showing how long ago it was created. function CreateTimeAgo(OBJECT_ID, T) { var DIFF = Math.abs(now() - T); UpdateTimeAgo(OBJECT_ID, T); if (DIFF < 86400000) setInterval("UpdateTimeAgo('" + OBJECT_ID + "', " + T + ");", 15100); } ////////////////////////////////////////////////// // v2022.7.31 // This function returns the current date in this format: // Sunday, July 31, 2022 // // Usage: STRING = NiceDate() // function NiceDate() { var D = new Date(); var DAY = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]; var MONTH = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; return DAY[D.getDay()] + ", " + MONTH[D.getMonth()] + " " + D.getDate() + ", " + D.getFullYear(); } ////////////////////////////////////////////////// // Converts 3 decimal numbers to hex color code. function toColor(R, G, B) { return toHex(R) + toHex(G) + toHex(B); } // WARNING: This function overwrites global variables: R,G,B // Converts a hex color code to individual R, G, B numbers. function GetRGB(C) { C = Hex2Int(C); R = (C & 0xFF0000) >>> 16; G = (C & 0xFF00) >>> 8; B = C & 0xFF; } // WARNING: This function overwrites global variables: R,G,B // This function returns the opposite color of C in hex format function InvertColor(C) { GetRGB(C); return toColor(255-R, 255-G, 255-B); } // WARNING: This function overwrites global variables: R,G,B,R1,G1,B1,R2,G2,B2,RX,GX,BX // Returns an array of colors which is a transition from C1 to C2 in N steps function GetColorShades(C1, C2, N) { var i, A = [C1]; if (N > 2) { CalculateColorGain(C1, C2, N); for (i = 0; i < N-2; i++) { R1 += RX; G1 += GX; B1 += BX; A.push(toColor(R1, G1, B1)); } } A.push(C2); return A; } // WARNING: This function overwrites global variables: R,G,B,R1,G1,B1,R2,G2,B2,RX,GX,BX // This function calculates how much R, G, B values need to change // in order go from color C1 to color C2 in N steps. // Side effects: C1 ---> R,G,B function CalculateColorGain(C1, C2, N) { GetRGB(C2); R2=R; G2=G; B2=B; GetRGB(C1); R1=R; G1=G; B1=B; RX = (R2 - R1) / (N - 1); GX = (G2 - G1) / (N - 1); BX = (B2 - B1) / (N - 1); } // WARNING: This function overwrites global variables: R,G,B,R1,G1,B1,R2,G2,B2,RX,GX,BX // Prints each letter in a different color from C1 to C2. function WriteInColor(S, C1, C2) { var i, c; CalculateColorGain(C1, C2, S.length); for (i = 0; i < S.length; i++) { c = S.charCodeAt(i); if (c < 33) PRINT(" "); else { if (c == 38) c = "&"; else if (c == 60) c = "<"; else if (c == 62) c = ">"; else c = S.charAt(i); PRINT(""+c+""); } R += RX; G += GX; B += BX; } } // WARNING: This function overwrites global variables: R,G,B // This function converts Hue, Saturation, and Luminance to RGB values // Source: www.rapidtables.com/convert/color/hsv-to-rgb.htm function HSL2RGB(H, S, L) { H = H * 1; if (H < 0) H = 0; if (H > 360) H = 359; H = H / 60; S = S * 1; if (S < 0) S = 0; if (S > 100) S = 100; S /= 100; L = L * 1; if (L < 0) L = 0; if (L > 100) L = 100; L /= 100; R = 0; G = 0; B = 0; var C = L * S; var M = L - C; var X = C * (1 - Math.abs(H % 2 - 1)); if (H >= 0 && H < 1) { R = C; G = X; } else if (H >= 1 && H < 2) { R = X; G = C; } else if (H >= 2 && H < 3) { G = C; B = X; } else if (H >= 3 && H < 4) { G = X; B = C; } else if (H >= 4 && H < 5) { R = X; B = C; } else { R = C; B = X; } R += M; R *= 255; R = Math.round(R); G += M; G *= 255; G = Math.round(G); B += M; B *= 255; B = Math.round(B); } // This function converts RGB values to HSL format and returns // these three values in an array: [Hue, Saturation, Luminance] // Source: www.javascripter.net/faq/rgb2hsv.htm function RGB2HSL(R, G, B) { R = R * 1; if (R < 0) R = 0; if (R > 255) R = 255; R = R / 255; G = G * 1; if (G < 0) G = 0; if (G > 255) G = 255; G = G / 255; B = B * 1; if (B < 0) B = 0; if (B > 255) B = 255; B = B / 255; var minRGB = Math.min(R, Math.min(G, B)); var maxRGB = Math.max(R, Math.max(G, B)); if (minRGB == maxRGB) return [0, 0, minRGB]; var S = (maxRGB - minRGB) / maxRGB; var D = (R == minRGB) ? G - B : ((B == minRGB) ? R - G : B - R); var H = (R == minRGB) ? 3 : ((B == minRGB) ? 1 : 5); H = 60 * (H - D / (maxRGB - minRGB)); return [H, S, maxRGB]; } // This function can increase or decrease R-G-B brightness of a color and return a new color. function ColorGain(C, R_GAIN, G_GAIN, B_GAIN) { GetRGB(C); R += R_GAIN; G += G_GAIN; B += B_GAIN; return toColor(R, G, B); } function Alert(S) {if(window)alert(S);else WScript.Echo(S);} function DebugURL() {var i,X=[],L="SELF PATH FILE HOST BOOKMARK ONLINE ARGS ARGC ARGN ARGV".split(" ");for(i=0;i=0){BOOKMARK=URL.slice(P+1);SELF=URL.substr(0,P);}P=SELF.indexOf("?");if(P>=0){ARGS=SELF.slice(P+1);SELF=SELF.substr(0,P);A=unescape(ARGS).split("&");for(i=0;i=0){ARGN[ARGC]=A[i].substr(0,P).toUpperCase();ARGV[ARGC++]=A[i].slice(P+1);}}}SELF=SELF.split("\\").join("/");P=SELF.lastIndexOf("/");PATH=SELF.substr(0,P+1);FILE=SELF.slice(P+1);P=PATH.indexOf(":///");if(P>=0)PATH=PATH.slice(P+4);P=PATH.indexOf("://");if(P>=0)PATH=PATH.slice(P+3);PATH=unescape(PATH);P=PATH.indexOf("/");if(ONLINE){HOST=(P>0)?PATH.substr(0,P):PATH;if(HOST.substr(0,4).toUpperCase()=="WWW.")HOST=HOST.slice(4);}else HOST="localhost";} // BOOKMARK holds whatever comes after the # sign in the URL // ARGS holds location.search without the ? mark // ARGC holds the argument count (number of values) // ARGN holds the names for each value // ARGV holds the corresponding values // FILE holds the name of the current web page (file name only) // SELF holds the URL of the current web page without arguments // PATH holds the current working directory, always ending with a / // HOST holds the hostname of the current domain without the www. part // This function returns the value of the named argument. If undefined, DEFAULT is returned. function GetArgStr(NAME, DEFAULT) { NAME = NAME.toUpperCase(); for (var i = 0; i < ARGC; i++) if (ARGN[i] == NAME) return ARGV[i]; return DEFAULT; } // This function returns the named argument as an integer. If undefined, DEFAULT is returned. If two more optional arguments are provided, the return value will be an integer between those two values. function GetArgInt(NAME, DEFAULT) { var MAX = 0x7FFFFFFF; var MIN = -MAX; if (arguments.length > 2) MIN = arguments[2]; if (arguments.length > 3) MAX = arguments[3]; var P = "_TRUE_YES_ALL_ON_", $ = GetArgStr(NAME, DEFAULT); if (isNaN($)) if (P.indexOf(("_"+$.toUpperCase()+"_")) >= 0) $ = 1; if (isNaN($)) $ = 0; $ = Math.round($); if ($ < MIN) $ = MIN; if ($ > MAX) $ = MAX; return $|0; } // This function loads a given URL address. function Goto(URL) { location.href = URL; } // This function extracts email addresses from a string and returns them in an array. function ExtractEmails(S) { var A = S.match(/([a-zA-Z0-9._\-+]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/gi); return A ? A : []; } // This function returns 1 if the given URL does not contain // any tabs, spaces, or illegal characters such as É Ñ µ ƒ ¥ £ ¡ function isValidURL(URL) { var c, i = URL.length; while (i-- > 0) { c = URL.charCodeAt(i); if (c < 33 || c > 126) return 0; } return 1; } // This function returns 1 if the given email address has valid format, otherwise returns 0. function isValidEmail(E) { var L = E.length; if (L < 3 || L > 253) return 0; var i, c, ATS = 0, DOT = 0, DOTS = 0, LTRS = 0; for (i = 0; i < L; i++) { c = E.charCodeAt(i); if (c > 57 && c < 61) return 0; if (c > 90 && c < 94) return 0; if (c < 33) return 0; if (c == 62 || c == 34 || c == 44) return 0; if (c == 46) { if (DOT == i) return 0; DOT = i+1; DOTS++; continue; } if (c == 64) { if (DOT == i) return 0; DOT = i+1; ATS++; if (i == 0 || ATS > 1) return 0; continue; } LTRS++; } if (ATS != 1 || DOTS == 0 || DOT == i || LTRS < 2) return 0; return 1; } // This function returns 1 if the person's name provided has valid format, otherwise returns 0. function isValidName(N) { var L = N.length; if (N < 2 || N > 64) return 0; var i, c; for (i = 0; i < L; i++) { c = N.charCodeAt(i); if (c < 33) return 0; if (c > 33 && c < 38) return 0; if (c > 39 && c < 44) return 0; if (c > 46 && c < 65) return 0; if (c > 90 && c < 97) return 0; if (c > 122 && c < 128) return 0; } return 1; } // BITWISE ROTATE // This function performs bitwise rotate of a byte by N bits. // If N is a positive number, it rotates right by N bits. // If N is a negative number, it rotates left by N bits. //function ROR8(BYTE, N) { N &= 7; if (N == 0) return (BYTE & 0xFF); var MASK = [0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F]; var BITS = BYTE & MASK[N]; BITS <<= (8 - N); BYTE >>>= N; return BYTE + BITS; } function ROL8(C,N){if(N&=7){var M=[,127,63,31,15,7,3,1][N];C=((C&M)<>(8-N));}return C&255;} // This function rotates byte C to the RIGHT by N number of bits. function ROR8(C,N){return ROL8(C,8-N);} // This function performs bitwise rotate right on a 16-bit word. function ROR16(WORD, N) { N &= 15; if (N == 0) return (WORD & 0xFFFF); var MASK = [0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF]; var BITS = WORD & MASK[N]; BITS <<= (16 - N); WORD >>>= N; return WORD + BITS; } // This function performs bitwise rotate right on a 32-bit long. function ROR32(LONG, N) { N &= 31; if (N == 0) return (LONG & 0xFFFFFFFF); var MASK = [0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF]; var BITS = LONG & MASK[N]; BITS <<= (32 - N); LONG >>>= N; return LONG + BITS; } // This function performs bitwise rotate on a string segment // marked by StartBit and EndBit. Rotates to the right by N bits. function RORS(S, N, StartBit, EndBit) { var LEFT = (N < 0) ? 0 : 1; if (StartBit >= EndBit) return S; N = Math.abs(N) % (EndBit - StartBit); if (N == 0) return S; var B = Str2Bin(S); if (EndBit > B.length) return ""; var UNCH1 = B.substr(0, StartBit); var UNCH2 = B.slice(EndBit); B = B.substring(StartBit, EndBit); if (LEFT) N = B.length - N; var PART1 = B.substr(0, N); var PART2 = B.slice(N); return Bin2Str(UNCH1 + PART2 + PART1 + UNCH2); } // BINARY ARRAY I/O // Each 32-bit integer in an array can hold 4 bytes of data. // The following functions allow us to access all the bits and bytes of an array. // For example, we could store the word "GOLDSTAR" in an array of 2 elements. // If memory usage is of concern but speed is not, then we // This function reads one bit from an array of 32-bit integers. function ReadBIT(ARRAY, BIT_INDEX) { var LONG = ARRAY[BIT_INDEX >> 5]; var X = BIT_INDEX & 31; if (X) LONG >>>= X; return LONG & 1; } // This function returns one byte-size int from an array of 32-bit integers. function ReadBYTE(ARRAY, BYTE_INDEX) { var SHIFT = [0, 8, 16, 24]; var LONG = ARRAY[BYTE_INDEX >> 2]; var X = BYTE_INDEX & 3; if (X) LONG >>>= SHIFT[X]; return LONG & 255; } // This function overwrites one bit in an array of 32-bit integers. function WriteBIT(ARRAY, BIT_INDEX, BIT) { BIT &= 1; var INDEX = BIT_INDEX >> 5; var LONG = ARRAY[INDEX]; var MASK = 1 << (BIT_INDEX & 31); if (BIT) LONG |= MASK; else LONG &= (~MASK); ARRAY[INDEX] = LONG; } // This function writes one byte (int) to an array of 32-bit integers. function WriteBYTE(ARRAY, BYTE_INDEX, BYTE) { BYTE &= 255; var INDEX = BYTE_INDEX >> 2; var LONG = ARRAY[INDEX]; var MASK = [0xFFFFFF00, 0xFFFF00FF, 0xFF00FFFF, 0x00FFFFFF]; var X = BYTE_INDEX & 3; if (X) BYTE <<= (X << 3); LONG &= MASK[X]; LONG += BYTE; ARRAY[INDEX] = LONG; } // This function writes a word (int) to an array of 32-bit integers. function WriteWORD(ARRAY, WORD_INDEX, WORD) { WORD &= 0xFFFF; var MASK = [0xFFFF0000, 0x0000FFFF]; var INDEX = WORD_INDEX >> 1; var LONG = ARRAY[INDEX]; var X = WORD_INDEX & 1; if (X) WORD <<= 16; LONG &= MASK[X]; LONG += WORD; ARRAY[INDEX] = LONG; } // This function writes a string into an array of 32-bit integers. See Also: fromCharCodeArray() function WriteSTRING(ARRAY, BYTE_INDEX, STRING) { var i, C; for (i = 0; i < STRING.length; i++) { C = STRING.charCodeAt(i) & 255; WriteBYTE(ARRAY, BYTE_INDEX++, C); } } // This function replaces each letter, number, $, and _ character with a different character from the same set and returns a new string. Uses the XOR operator. What this function does is more like plain encoding than encryption. function tXt(S) {var c,P,i=S.length,$=[],A="0123456789$ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_",L=37;while(i--){c=S.charAt(i);P=A.indexOf(c);if(P>=0){P^=((i&3)*77+(i&3)+L++);c=A.charAt(P&63);}$[i]=c;}return $.join("");} // This function calculates the checksum on a string and returns a 32-bit integer. function Checksum(S) { var C = 0x55555555, i = S.length; while (i--) { C += ((S.charCodeAt(i) + 1) << ((i & 3) << 3)); C = ((C >> 31) & 1) | ((C << 1) & 0xFFFFFFFe); } return C & 0xFFFFFFFF; } ////////////////////////////////////////////////// ////////////////////////////////////////////////// ///////////// ///////////// ///////////// COOKIE FUNCTIONS ///////////// ///////////// // // NOTE: Cookies expire; localStorage items do not. // The most important difference between cookies and // localStorage is that cookies are sent over the // internet with each request, therefore the size of // all cookies together on a page cannot exceed 5KB. // LocalStorage is not automatically sent over the // wire, therefore its capacity can be much larger // (usually 10MB). // ////////////////////////////////////////////////// // v2021.1.17 // Displays all cookies saved in the browser. // Usage: CookieReport() // function CookieReport() { var T = "TESTING123", DATA = ALLCHARS + COOKIEJAR + ALLCHARS; StoreXStr(T, DATA); var RESULT = (LoadXStr(T) == DATA) ? "OK" : "FAILED"; DeleteXStr(T); var i, E, NAME, VALUE, K = GetCookieNames(); for (i = 0; i < K.length; i++) { if (K[i].charCodeAt(0) == 95) { E = 1; NAME = XORName(K[i].slice(1)); VALUE = LoadXStr(NAME); } else { E = 0; NAME = K[i]; VALUE = GetCookie(NAME); } K[i] = (E ? "*" : "-") + " |" + NAME + "| = |" + VALUE + "|"; } alert("COOKIE TEST " + RESULT + ".\n\n" + document.cookie + "\n\n" + K.join("\n")); } ////////////////////////////////////////////////// // v2021.1.17 // This function saves a cookie in the browser which // will expires in 5 years (if no expiration is given). // When the expiration is given, it must be specified // in seconds. // Returns 1 on success, or 0 if the cookie could not be saved. // Usage: INTEGER = SetCookie(NAME, VALUE, EXPIRATION) // function SetCookie(NAME, VALUE, EXPIRATION) { var DATE = new Date(); var COOKIE = NAME + "=" + (typeof(VALUE) === "undefined" ? "" : VALUE); DATE.setTime(DATE.getTime() + (typeof(EXPIRATION) === "undefined" ? 157680000000 : EXPIRATION * 1000)); document.cookie = COOKIE + ";Expires=" + DATE.toGMTString(); return document.cookie.indexOf(COOKIE) < 0 ? 0 : 1; } ////////////////////////////////////////////////// // v2021.1.17 // Returns the value of a cookie. Cookie names are // always case sensitive. If the cookie could not // be found, an empty string is returned. // Usage: STRING = GetCookie(NAME) // function GetCookie(NAME) { NAME = "; " + NAME + "="; var K = "; " + document.cookie + ";", P = K.indexOf(NAME); if (P < 0) return ""; P += NAME.length; var E = K.indexOf(";", P); return K.substring(P, E < 0 ? K.length : E); } // // // THIS IS A NICER SOLUTION BUT NOT EFFICIENT: // v2020.12.29 // // function GetCookie(NAME) // { // var i, s, COOKIE = document.cookie.split(";"); // for (i = 0; i < COOKIE.length; i++) // if ((s = COOKIE[i].indexOf(NAME + "=")) >= 0) // return COOKIE[i].slice(s + NAME.length + 1); // return ""; // } // ////////////////////////////////////////////////// // v2021.1.17 // Deletes a cookie from the browser's storage. // Usage: DeleteCookie(NAME) // function DeleteCookie(NAME) { document.cookie = NAME + "=;Expires=Jan 01 1970 01:01:01 GMT"; } ////////////////////////////////////////////////// // v2021.1.17 // Returns the names of all saved cookies. // Usage: ARRAY = GetCookieNames() // function GetCookieNames() { var i, c, S, K = ";" + document.cookie, A = []; for (i = 0; i < K.length; i++) { c = K.charCodeAt(i); if (c == 61) { A.push(K.substring(S, i)); S = 0; } else if (c == 59) S = -1; else if (S < 0 && c > 32) S = i; } return A; } // // // THIS IS NICER BUT SLOWER: // v2020.12.29 // // function GetCookieNames() // { // var i, P, COOKIE = document.cookie.split(";"), A = []; // for (i = 0; i < COOKIE.length; i++) // if ((P = COOKIE[i].indexOf("=")) >= 0) // A.push(Trim(COOKIE[i].substr(0, P))); // return A; // } // ////////////////////////////////////////////////// // v2020.12.29 // Completely erases all cookies. // Returns the number of cookies removed. // Usage: INTEGER = DeleteAllCookies() // function DeleteAllCookies() { var K = GetCookieNames(), i = K.length; while (i--) DeleteCookie(K[i]); return K.length; } ////////////////////////////////////////////////// // v2021.1.17 // This function returns 0 when cookies are disabled. // Returns 1 when cookies are enabled yet new cookies // cannot be saved. Returns 2 when cookies can be // saved and retrieved without a problem. // Usage: INTEGER = TestCookies() // function TestCookies() { if (SetCookie("TEST", COOKIEJAR)) { DeleteCookie("TEST"); return 2; } return navigator.cookieEnabled ? 1 : 0; } ////////////////////////////////////////////////// // v2021.1.17 // This function saves a string in localStorage. // Returns 1 on success, or 0 if the value could not be saved. // Usage: INTEGER = SetItem(STRING, STRING) // function SetItem(NAME, VALUE) { VALUE = (typeof(VALUE) === "undefined" || VALUE == null) ? "" : VALUE + ""; try { with(window.localStorage) { setItem(NAME, VALUE); if (getItem(NAME) == VALUE) return 1; } } catch(e) {} return 0; } ////////////////////////////////////////////////// // v2020.12.30 // Retrieves a binary string from localStorage. // If the named value is not found, // an empty string is returned. // Usage: STRING = GetItem(NAME) // function GetItem(NAME) { try { var S = window.localStorage.getItem(NAME); return (S == null) ? "" : S + ""; } catch(e) {} return ""; } ////////////////////////////////////////////////// // v2021.1.17 // This function returns the names of values // saved in localStorage. // Usage: ARRAY = GetItemNames() // function GetItemNames() { var i, A = []; try { for (i = 0; i < localStorage.length; i++) A[i] = localStorage.key(i); } catch(e) {} return A; } ////////////////////////////////////////////////// // v2020.12.29 // Deletes one item from localStorage. // Returns 1 on success. // Returns 0 if the operation failed. // Usage: INTEGER = DeleteItem(NAME) // function DeleteItem(NAME) { try { with(window.localStorage) { setItem(NAME, ""); removeItem(NAME); } return 1; } catch(e) {} return 0; } ////////////////////////////////////////////////// // v2021.1.17 // Completely erases all values from localStorage. // On success, returns the number of items removed. // On failure, returns 0. // Usage: INTEGER = DeleteAllItems() // function DeleteAllItems() { try { var L = window.localStorage.length; window.localStorage.clear(); return L; } catch(e) {} return 0; } ////////////////////////////////////////////////// // v2020.12.13 // This function returns 2 when localStorage is // enabled and values can be saved and retrieved // with no problem. Returns 1 when localStorage is // enabled, yet for some reason new values cannot be // saved. Returns 0 when localStorage is not supported. // Usage: INTEGER = TestLocalStorage() // function TestLocalStorage() { var T = "TEST", STATUS = 0; try { with (window.localStorage) { setItem(T, ALLCHARS); STATUS = 1; if (getItem(T) == ALLCHARS) { removeItem(T); STATUS = 2; } } } catch (e) {} return STATUS; } ////////////////////////////////////////////////// // v2020.12.31 // Erases all cookies and localStorage items. // Usage: FlushBrowserStorage(); // function FlushBrowserStorage() { DeleteAllItems(); DeleteAllCookies(); } ////////////////////////////////////////////////// // v2021.1.17 // This function saves an encrypted binary string // in localStorage, and if that fails, then // it tries to save it as a cookie instead. // Returns 2 if the value was saved in localStorage. // Returns 1 if the value was saved in cookies. // Returns 0 if the value could not be saved. // Usage: INTEGER = StoreXStr(NAME, VALUE) // function StoreXStr(NAME, VALUE) { function addnum(V, N) { N = Num2Set(N, COOKIEJAR); return COOKIEJAR.charAt(N.length) + "" + N + V; } VALUE += ""; NAME = "_" + XORName(NAME); var T = Math.round(TIME() / 1000) - 1576800000; VALUE = addnum(VALUE, T); VALUE = addnum(VALUE, CRC(VALUE)); // Try localStorage first if (SetItem(NAME, StrXOR(VALUE, B64SET))) return 2; // Try cookies next if (isFromCharSet(VALUE, COOKIEJAR)) VALUE = "-" + VALUE; else { ESCAPED = EscapeString(VALUE, COOKIEJAR); if (VALUE.length * 1.33333333 < ESCAPED.length) VALUE = "B" + EncodeB64(VALUE); else VALUE = "E" + ESCAPED; } // Encode cookie value var c, i, r = VALUE.length, $ = []; for (i = 0; i < VALUE.length; i++) { c = COOKIEJAR.indexOf(VALUE.charAt(i)); if (c < 0) continue; r = (r * 133) % 179; c -= r; while (c < 0) c += COOKIEJAR.length; $.push(COOKIEJAR.charAt(c)); } return SetCookie(NAME, $.join("")); } ////////////////////////////////////////////////// // v2021.1.17 // This function retrieves a string saved earlier // by the StoreXStr() function. If the value // is not found or could not be retrieved, // then an empty string is returned. // Usage: STRING = LoadXStr(NAME) // function LoadXStr(NAME) { function getnum() { var NUMBER_LENGTH = COOKIEJAR.indexOf(VALUE.charAt(0)); var NUMBER = VALUE.substr(1, NUMBER_LENGTH); VALUE = VALUE.slice(NUMBER_LENGTH + 1); return Set2Num(NUMBER, COOKIEJAR); } // Try localStorage first NAME = "_" + XORName(NAME); // Try to get localStoage item first var CHECK, VALUE = GetItem(NAME); if (VALUE != null && VALUE.length > 4) { VALUE = StrXOR(VALUE, B64SET); } else // Try to get cookie { VALUE = GetCookie(NAME); if (VALUE.length < 4) return ""; // Decode cookie var i, c, r = VALUE.length, $ = []; for (i = 0; i < VALUE.length; i++) { c = COOKIEJAR.indexOf(VALUE.charAt(i)); r = (r * 133) % 179; c = (c + r) % COOKIEJAR.length; $.push(COOKIEJAR.charAt(c)); } VALUE = $.join(""); var METHOD = VALUE.charCodeAt(0); VALUE = VALUE.slice(1); if (METHOD == 66) VALUE = DecodeB64(VALUE); if (METHOD == 69) VALUE = UnescapeString(VALUE, COOKIEJAR); } var THIS_CRC = getnum(); if (THIS_CRC != CRC(VALUE)) return ""; // CRC ERROR getnum(); return VALUE; } ////////////////////////////////////////////////// // v2021.1.17 // Deletes an encrypted value both from localStorage and cookies. // Usage: DeleteXStr(NAME) // function DeleteXStr(NAME) { NAME = "_" + XORName(NAME); DeleteItem(NAME); DeleteCookie(NAME); } ////////////////////////////////////////////////// // v2020.12.29 // Returns the names of all the encrypted cookies // and localStorage items. // Usage: ARRAY = GetXNames() // function GetXNames() { var A, i, $ = []; A = GetCookieNames(); for (i = 0; i < A.length; i++) if (A[i].charCodeAt(0) == 95) $.push(XORName(A[i].slice(1))); A = GetItemNames(); for (i = 0; i < A.length; i++) if (A[i].charCodeAt(0) == 95) $.push(XORName(A[i].slice(1))); return $; } ////////////////////////////////////////////////// // v2021.1.5 // This function adds to the ASCII value of each // character, shifting values either up or down // depending on the DIRECTION value. CHARSET // defines what characters are allowed in the set. // The DIRECTION value should be either a positive // or a negative value depending on which way the // values are desired to be shifted. // Usage: STRING = ShiftRStr(STRING, DIRECTION, CHARSET) // function ShiftRStr(S, DIR, SET) { S += ""; var c, i, $ = []; var SEED = Math.abs(DIR); var NEG = (DIR < 0) ? 1 : 0; for (i = 0; i < S.length; i++) { c = SET.indexOf(S.charAt(i)); if (c < 0) c = 0; SEED = (SEED * 539 + 5321) & 0xFFFF; ADD = (SEED >> 4) & 63; if (NEG) c += SET.length - ADD; else c += ADD; c %= SET.length; $[i] = SET.charAt(c); } return $.join(""); } // SHORT VERSION: // This function adds to the ASCII value of each character, shifting values either up or down. CHARSET defines what characters are allowed in the set. DIRECTION should be either a positive or a negative value. // function ShiftRStr(S, DIR, SET) { S += ""; var c, i, $ = []; var SEED = Math.abs(DIR); var NEG = (DIR < 0) ? 1 : 0; for (i = 0; i < S.length; i++) { c = SET.indexOf(S.charAt(i)); if (c < 0) c = 0; SEED = (SEED * 539 + 5321) & 0xFFFF; ADD = (SEED >> 4) & 63; if (NEG) c += SET.length - ADD; else c += ADD; c %= SET.length; $[i] = SET.charAt(c); } return $.join(""); } // ////////////////////////////////////////////////// // Extracts a version number from string S starting after pattern A function ExtractVersion(S, A) { var i, C, P = S.indexOf(A); if (P < 0) return ""; P += A.length + 1; for (i = P; i < S.length; i++) { C = S.charCodeAt(i); if (C < 46 || C > 57) break; } return S.substring(P, i); } HTML = []; function PRINT(L) { if (typeof(HTML) === "undefined") HTML = [L]; else HTML.push(L); } function FLUSH() { if (!(typeof(HTML) === "undefined")) document.write(HTML.join("")); HTML = []; } function CLS() { HTML = [" "]; RENDER(); } function RENDER() { document.getElementById("SLIDE").innerHTML = HTML.join(""); HTML = []; } function BUTTON(LABEL, W, H, HANDLE, ACTION, BGCOLOR, TEXTCOLOR) { var BTN_FONT_SIZE = 20; if (WX > 1000 || HX > 1000) BTN_FONT_SIZE = SIZE(6); PRINT(""); BUTTONS++; } // Changes the transparency of an object. Usage: SetOpacity(ID, ALPHA) function SetOpacity(E, A) { A = Math.round(A); if (A > 100) A = 100; if (A < 0) A = 0; E = document.getElementById(E); E.style.opacity = A / 100; E.style.filter = "alpha(opacity="+A+")"; } // Causes an object to float and changes its coordinates. function SetObjCoords(E, LEFT, TOP) { E = document.getElementById(E); LEFT = Math.round(LEFT); TOP = Math.round(TOP); E.style.position = "ABSOLUTE"; E.style.top = TOP; E.style.left = LEFT; } function FadeIn(E) { for (var i = 0; i <= 100; i += 10) setTimeout("SetOpacity('" + E + "', " + i + ");", 7*i); } function FadeOut(E) { for (var i = 0; i <= 100; i += 10) setTimeout("SetOpacity('" + E + "', " + i + ");", 7*(100-i)); } // DIV or B is a lot faster than TABLE function DrawBox(LEFT, TOP, WIDTH, HEIGHT, COLOR) { PRINT(""); } function DrawFrame(LEFT, TOP, WIDTH, HEIGHT, BORDER_WIDTH, COLOR) { PRINT("
"); } function DrawPixel(LEFT, TOP, COLOR) { PRINT("
"); } function DrawLine(WIDTH, THICKNESS, COLOR, MARGIN) { PRINT("
"); } function DrawCover(LEFT, TOP, WIDTH, HEIGHT) { var ETC = (arguments.length > 4) ? arguments[4] : ""; PRINT(""); } function DrawNiceBox(C1, C2, THICKNESS, CONTENT) { var i, $ = [], C = GetColorShades(C1, C2, THICKNESS); for (i = 0; i < THICKNESS; i++) $.push(""); PRINT($.join("
") + CONTENT); for (i = 0; i < THICKNESS; i++) PRINT("
"); } // This function estimates the approximate width of each character printed on the screen and returns a number. function EstimateWidth(TEXT) { // CHARSET: !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ var Z = "00122320002201011011111111002321333333333123332323323223323010230111110110010211110101121111013"; var $ = TEXT.length; var i = $, c; while (i--) { c = TEXT.charCodeAt(i); $ += (c < 32 || c > 126) ? 0 : Z.charCodeAt(c-32) - 47; } return $; } ///////////// QBASIC FUNCTIONS ///////////// ///////////// function SPACE$(n) { s = ""; while (s.length < n) s += " "; return s; } function STRING$(n, x) { s = ""; while (n--) s += x; return s; } function OCT$(n) { return n.toString(8); } function HEX$(n) { return n.toString(16); } function INPUT(s) { s = prompt(s, ""); return (s == null) ? '' : s; } function PRINT() { for (var i = 0; i < arguments.length; i++) document.write(arguments[i] + " "); } function VAL(n) { return n * 1; } function STR$(n) { return n + ""; } function LEN(s) { return (s + "").length; } function SGN(n) { return (n > 0) ? 1 : (n < 0) ? -1 : 0; } function ABS(n) { return Math.abs(n); } function FIX(n) { n += "."; return n.substr(0, n.indexOf(".")) * 1; } function INT(n) { return Math.floor(n); } function LOG(n) { return Math.log(x); } function EXP(n) { return Math.exp(x); } function SQR(n) { return Math.sqrt(n); } function ATN(n) { return Math.atan(x); } function TAN(n) { return Math.tan(x); } function SIN(n) { return Math.sin(x); } function COS(n) { return Math.cos(x); } function CINT(n) { return Math.round(n); } function CLNG(n) { return Math.round(n); } function CSNG(n) { return Math.round(n * 10000) / 10000; } function CDBL(n) { return Math.round(n * 10000000) / 10000000; } function UCASE$(s) { return s.toUpperCase(); } function LCASE$(s) { return s.toLowerCase(); } // This function draws a line or rectangle. // Color is the rrggbb color of the line. // mode == 0 draws a line // mode == 1 draws a dotted line // mode == 2 draws a rectangle // mode == 3 draws a filled box function LINE(x1, y1, x2, y2, color, mode) { var t; // Swap some values when necessary x1 = Math.round(x1); x2 = Math.round(x2); y1 = Math.round(y1); y2 = Math.round(y2); if (x1 > x2) { t = x1; x1 = x2; x2 = t; } if (y1 > y2) { t = y1; y1 = y2; y2 = t; } if (typeof(mode) == "undefined") mode = 0; if (mode == 3) // Draw a filled box { PRINT("\x3CDIV STYLE='POSITION:ABSOLUTE; PADDING:0; MARGIN:0; BORDER:NONE; TOP:"+y1+"; LEFT:"+x1+"; WIDTH:"+(x2-x1+1)+"; HEIGHT:"+(y2-y1)+"; FONT-SIZE:1PX; BACKGROUND-COLOR:"+color+"'>\x3C/DIV>"); } else if (mode == 2) // Draw a rectangle { PRINT("\x3CDIV STYLE='POSITION:ABSOLUTE; PADDING:0; MARGIN:0; BORDER:NONE; TOP:"+y1+"; LEFT:"+x1+"; WIDTH:1; HEIGHT:"+(y2-y1)+"; FONT-SIZE:1PX; BACKGROUND-COLOR:"+color+"'>\x3C/DIV>"); PRINT("\x3CDIV STYLE='POSITION:ABSOLUTE; PADDING:0; MARGIN:0; BORDER:NONE; TOP:"+y1+"; LEFT:"+x2+"; WIDTH:1; HEIGHT:"+(y2-y1)+"; FONT-SIZE:1PX; BACKGROUND-COLOR:"+color+"'>\x3C/DIV>"); PRINT("\x3CDIV STYLE='POSITION:ABSOLUTE; PADDING:0; MARGIN:0; BORDER:NONE; TOP:"+y1+"; LEFT:"+x1+"; WIDTH:"+(x2-x1)+"; HEIGHT:1; FONT-SIZE:1PX; BACKGROUND-COLOR:"+color+"'>\x3C/DIV>"); PRINT("\x3CDIV STYLE='POSITION:ABSOLUTE; PADDING:0; MARGIN:0; BORDER:NONE; TOP:"+y2+"; LEFT:"+x1+"; WIDTH:"+(x2-x1)+"; HEIGHT:1; FONT-SIZE:1PX; BACKGROUND-COLOR:"+color+"'>\x3C/DIV>"); } else if (x1 == x2) // Draw a vertical line { PRINT("\x3CDIV STYLE='POSITION:ABSOLUTE; PADDING:0; MARGIN:0; BORDER:NONE; TOP:"+y1+"; LEFT:"+x1+"; WIDTH:1; HEIGHT:"+(y2-y1)+"; FONT-SIZE:1PX; BACKGROUND-COLOR:"+color+"'>\x3C/DIV>"); } else if (y1 == y2) // Draw a horizontal line { PRINT("\x3CDIV STYLE='POSITION:ABSOLUTE; PADDING:0; MARGIN:0; BORDER:NONE; TOP:"+y1+"; LEFT:"+x1+"; WIDTH:"+(x2-x1+1)+"; HEIGHT:1; FONT-SIZE:1PX; BACKGROUND-COLOR:"+color+"'>\x3C/DIV>"); } else // Draw a slanted line { var WIDTH = x2 - x1; var HEIGHT = y2 - y1; var SLOPE = WIDTH / HEIGHT; var x = x1; for (var y = y1; y < y2; y++) { if (mode == 0 || mode == 1 && y & 2) PRINT("\x3CDIV STYLE='POSITION:ABSOLUTE; PADDING:0; MARGIN:0; BORDER:NONE; TOP:"+y+"; LEFT:"+x+"; WIDTH:" + (SLOPE > 1 ? Math.ceil(SLOPE) : 1) + "; HEIGHT:" + (SLOPE < 1 ? Math.ceil(SLOPE) : 1) + "; FONT-SIZE:1PX; BACKGROUND-COLOR:"+color+"'>\x3C/DIV>"); x += SLOPE; } } } // // integer = INSTR([start_offset], String1, String2) // function INSTR() { var A = 0; var START = (arguments.length > 2) ? arguments[A++] - 1 : 0; var STR1 = arguments[A++]; var STR2 = arguments[A++]; return STR1.indexOf(STR2, START) + 1; } // NewString = MID$(String, Start, [Length]) // function MID$(String, Start) { var Len = (arguments.length > 2) ? arguments[2] : String.length; return String.substr(Start - 1, Len); } // NewString = MID$(String, String_to_Insert, Start, [Length]) // function _MID$(String, InsertString, Start) { var Len = (arguments.length > 3) ? arguments[3] : String.length; return String.substr(Start - 1, Len); } // This function takes a list of arguments and evaluates each // as either true or false, and returns a string containing 1s and 0s. // For each true value, it adds a '1' and for each false value, // it adds '0' to the output string. // Usage: STRING = PackBits(VALUE1, [VALUE2, [VALUE3...]] function PackBits() { var $ = ""; for (var i = 0; i < arguments.length; i++) $ += arguments[i] ? '1' : '0'; return $; } // This function assembles and encodes the URL string. function EncodeURLStr(URL, SAVE, INC, DEC) { SAVE = EscapeString(SAVE, B64SET); if (typeof(SAVE) === "undefined") SAVE = ""; if (typeof(INC) === "undefined") INC = ""; if (typeof(DEC) === "undefined") DEC = ""; var MYARGS = []; if (SAVE.length) MYARGS.push("s=" + SAVE); if (INC.length) MYARGS.push("i=" + INC); if (DEC.length) MYARGS.push("d=" + DEC); return URL + "?" + MYARGS.join("&"); } function RunPerl(FILE, ARGS) { ARGS = EscapeString(ARGS, SHELLSET); var CMD = "C:\\BIN\\PERL\\PERL.BAT PAUSE! \"" + FILE + "\" " + ARGS; alert("Execute: " + CMD); System(CMD); } function System(CMD) { try { var WSH = new ActiveXObject("WScript.Shell"); WSH.Run(CMD); } catch (e) {} } // Changes the transparency of an object. Usage: SetOpacity(ID, ALPHA) function SetOpacity(E, A) { A = Math.round(A); if (A > 100) A = 100; if (A < 0) A = 0; E = document.getElementById(E); E.style.opacity = A / 100; E.style.filter = "alpha(opacity="+A+")"; } // Causes an object to float and changes its coordinates. function SetObjCoords(E, LEFT, TOP) { E = document.getElementById(E); LEFT = Math.round(LEFT); TOP = Math.round(TOP); E.style.position = "ABSOLUTE"; E.style.top = TOP; E.style.left = LEFT; } function FadeIn(E) { for (var i = 0; i <= 100; i += 10) setTimeout("SetOpacity('" + E + "', " + i + ");", 7*i); } function FadeOut(E) { for (var i = 0; i <= 100; i += 10) setTimeout("SetOpacity('" + E + "', " + i + ");", 7*(100-i)); } // Flushes HTML buffer when content is ready. function FLUSH() { if (!(typeof(HTML) === "undefined")) document.write(HTML.join("")); HTML = []; } // Converts any binary or HTML/JavaScript mix into HTML-safe string. function toSafeHTML(S) { var i, C, LAST = 0, $ = []; function Esc(BYTES) { if (LAST >= 0) $.push(S.substring(LAST, i)); $.push(BYTES); LAST = -1; } for (i = 0; i < S.length; i++) { C = S.charCodeAt(i); if (C == 38) Esc("&"); else if (C == 60) Esc("<"); else if (C == 62) Esc(">"); else if (C == 10) Esc("
"); else if (C == 9) Esc("     "); else if (C == 13) continue; else if (C < 16 || C > 126) Esc("&#x" + C.toString(16) + ";"); else if (LAST < 0) LAST = i; } Esc(""); return $.join(""); } // Escapes a string using a custom character set. The first character of CHARSET will be used as an escape character. The rest of the characters will not be escaped. function EscapeString(STR, SET) { var i, c, P, $ = []; for (i = 0; i < STR.length; i++) { c = STR.charAt(i); P = SET.indexOf(c, 1); if (P >= 0) { $[i] = c; continue; } c = STR.charCodeAt(i); c = (c < 16 ? "0" : "") + c.toString(16); $[i] = SET.charAt(0) + c; } return $.join(""); } // This function is the reverse of EscapeString() function UnescapeString(STR, SET) { STR = STR.split("%").join("%25"); STR = STR.split(SET.charAt(0)).join("%"); return unescape(STR); } //function EscapeString(STR, SET) { var i, c, P, $ = []; if (typeof(SET) === "undefined") SET = COOKIEJAR; for (i = 0; i < STR.length; i++) { c = STR.charAt(i); P = SET.indexOf(c, 1); if (P >= 0) { $[i] = c; continue; } $[i] = SET.charAt(0) + toHex(STR.charCodeAt(i)); } return $.join(""); } //function UnescapeString(STR, SET) { if (typeof(SET) === "undefined") SET = COOKIEJAR; STR = STR.split("%").join("%25"); STR = STR.split(SET.charAt(0)).join("%"); return unescape(STR); } // This function encrypts or decrypts a plain text name or label using the XOR operator with a fixed password. The output is going to be plain text. function XORName(S) { var $ = [], i = S.length, A = "8ODpmr0l1o9qGMRsNeZP_uLzB2cb6S4UfjwWIatHh$ExVAdFCQ5XyJnKY7vkg3iT"; while (i--) $[i] = A.charAt(((A.indexOf(S.charAt(i)) & 63) ^ A.charCodeAt(i & 63)) & 63); return $.join(""); } // This function encrypts or decrypts a string using a random number series generated with the seed provided. The SEED acts as a password. function RndXOR(STRING, SEED) { var i, $ = []; if (typeof(SEED) === "undefined") SEED = 39.7287167553; SEED += STRING.length; for (i = 0; i < STRING.length; i++) { SEED = (SEED * 1882.03 + 3917.485 + i) % 5931; $[i] = String.fromCharCode(STRING.charCodeAt(i) ^ (SEED & 255)); } return $.join(""); } // Shuffles a string in a way that it can be unshuffled later! function ForwardShuffle(S, SEED) { if (typeof(SEED) === "undefined") SEED = 1416; var L = S.length; var A = S.split(""); for (var i = 0; i < L; i++) { SEED = (SEED * 3771 + 533) & 0xFFFF; Swap(A, (SEED * L) >> 16, i); } return A.join(""); } // This function unshuffles a string that has been shuffled by the ForwardShuffle() function. function BackwardShuffle(S, SEED) { if (typeof(SEED) === "undefined") SEED = 1416; var L = S.length, R = []; var A = S.split(""); for (var i = 0; i < L; i++) { SEED = (SEED * 3771 + 533) & 0xFFFF; R[i] = (SEED * L) >> 16; } for (L--; L >= 0; L--) Swap(A, R[L], L); return A.join(""); } // This function returns a simple 16-bit CRC. function CRC(S) { var i = S.length, SEED = i + 431; while (i--) SEED = (SEED * 1852 + S.charCodeAt(i) + 3917) & 0xFFFF; return SEED; } // Encodes a binary string to Base64 string function EncodeB64(S) { var i, j, k = -4, SHIFT = 6, $ = []; for (i = j = 0; i < S.length; i++, j++) { if (SHIFT > 5) { SHIFT = 0; k += 4; $[k] = 0; j++; } SHIFT += 2; $[j] = S.charCodeAt(i); $[k] += ($[j] & 0xC0) >> SHIFT; $[j] = $[j] & 63; } while (--j >= 0) $[j] = String.fromCharCode($[j] + 63); return $.join(""); } // Decodes a Base64 string to binary string function DecodeB64(S) { var i, c, H, $ = []; for (i = 0; i < S.length; i++) { c = S.charCodeAt(i) - 63; c = (c < 0) ? 0 : c & 63; if (i % 4) { H <<= 2; $.push(String.fromCharCode(c + (H & 0xC0))); } else H = c; } return $.join(""); } // This function saves a binary string in localStorage or cookies. function StoreXStr(NAME, VALUE) { VALUE += ""; NAME = XORName(NAME); if (SetItem(NAME, ForwardShuffle(RndXOR(VALUE)))) return SetCookie(NAME, EncodeCookie(VALUE)); return 2; } // This function retrieves a string saved earlier by the StoreXStr() function. If the value is not found or could not be retrieved, an empty string is returned. function LoadXStr(NAME) { NAME = XORName(NAME); var VALUE = GetItem(NAME); if (VALUE == null || VALUE == "") return DecodeCookie(GetCookie(NAME)); return RndXOR(BackwardShuffle(VALUE)); } // Returns the decrypted names of all items saved both in cookies and localStorage. function GetXNames() { var A, i, $ = []; A = GetCookieNames(); for (i = 0; i < A.length; i++) $.push(XORName(A[i])); A = GetItemNames(); for (i = 0; i < A.length; i++) $.push(XORName(A[i])); return $; } // Deletes an encrypted value both from localStorage and cookies. function DeleteX(NAME) { NAME = XORName(NAME); DeleteItem(NAME); DeleteCookie(NAME); } // Erases all cookies and localStorage items. function FlushBrowserStorage() { DeleteAllItems(); DeleteAllCookies(); } // Returns the value of a cookie. If the cookie could not be found, an empty string is returned. function GetCookie(NAME) { var i, s, COOKIE = document.cookie.split(";"); for (i = 0; i < COOKIE.length; i++) if ((s = COOKIE[i].indexOf(NAME + "=")) >= 0) return COOKIE[i].slice(s + NAME.length + 1); return ""; } // Deletes a cookie from the browser's storage. function DeleteCookie(NAME) { document.cookie = NAME + "=;Expires=Jan 01 1970 01:01:01 GMT"; } // Returns the names of all saved cookies. function GetCookieNames() { var i, P, COOKIE = document.cookie.split(";"), A = []; for (i = 0; i < COOKIE.length; i++) if ((P = COOKIE[i].indexOf("=")) >= 0) A.push(Trim(COOKIE[i].substr(0, P))); return A; } // Erases all cookies, and returns the number of cookies deleted. function DeleteAllCookies() { var i, COOKIE = GetCookieNames(); for (i = 0; i < COOKIE.length; i++) DeleteCookie(COOKIE[i]); return COOKIE.length; } // This function returns 0 when cookies are disabled. Returns 1 when cookies are enabled yet new cookies cannot be saved. Returns 2 when cookies can be saved and retrieved without a problem. function TestCookies() { var TEST_NAME = "XXTEST123XX"; var TEST_VALUE = "Blessed are the pure in heart, for they shall see God. Matthew 5:8 (NKJV)"; SetCookie(TEST_NAME, TEST_VALUE); if (GetCookie(TEST_NAME) == TEST_VALUE) { DeleteCookie(TEST_NAME); return 2; } return navigator.cookieEnabled ? 1 : 0; } // This function saves a string in localStorage. Returns 1 if the value could not be saved. Returns 0 on success. function SetItem(NAME, VALUE) { if (typeof(VALUE) === "undefined" || VALUE == null) VALUE = ""; try { with(window.localStorage) { setItem(NAME, VALUE); if (getItem(NAME) == VALUE) return 0; } } catch(e) {} return 1; } // Retrieves a string from localStorage. If the named value is not found, an empty string is returned. function GetItem(NAME) { try { var X = localStorage.getItem(NAME); return (X == null) ? "" : X; } catch(e) {} return ""; } // This function returns the names of values saved in localStorage. function GetItemNames() { var i, A = []; try { for (i = 0; i < localStorage.length; i++) A[i] = localStorage.key(i); } catch(e) {} return A; } // Deletes one item from localStorage. Returns 1 on success. Returns 0 if the operation failed. function DeleteItem(NAME) { try { with(window.localStorage) { setItem(NAME, ""); removeItem(NAME); } return 1; } catch(e) {} return 0; } // Completely erases all values from localStorage. On success, returns the number of items removed. On failure, returns -1. function DeleteAllItems() { try { var L = window.localStorage.length; window.localStorage.clear(); return L; } catch(e) {} return -1; } // This function returns 2 when localStorage is enabled and values can be saved and retrieved with no problem. Returns 1 when localStorage is enabled, yet for some reason new values cannot be saved. Returns 0 when localStorage is not supported. function TestLocalStorage() { var STATUS = 0; var TEST_NAME = "XXTEST123XX"; var TEST_VALUE = "Blessed are the peacemakers, for they shall be called sons of God. Matthew 5:9 (NKJV)"; try { localStorage.setItem(TEST_NAME, TEST_VALUE); STATUS = 1; if (localStorage.getItem(TEST_NAME) == TEST_VALUE) { localStorage.removeItem(TEST_NAME); STATUS = 2; }} catch (e) {} return STATUS; } // Converts a list of numbers into a string of 1s and 0s. function PushBits(LENGTH, INT) { var i, OUTPUT = []; for (i = 0; i < arguments.length; i++) { LENGTH = arguments[i++]; INT = arguments[i]; OUTPUT.push(toBin(INT, LENGTH)); } return OUTPUT.join(""); } // Returns the smallest number from a list of arguments that is bigger than the START_VALUE. function FindLowest(START_VALUE) { var i, A, MIN = START_VALUE; for (i = 1; i < arguments.length; i++) { A = arguments[i]; if (typeof(A) === "undefined") continue; if (A == null || A < 55) continue; if (MIN > A) MIN = A; } return MIN; } // This function assembles and encodes the URL string. function EncodeURLStr(URL, ARG, FORMAT, COLORS) { var SEED = (Math.random() * 999) | 0; ARG = escape(ForwardShuffle(ARG, SEED)); return URL + "?s=" + SEED + "&c=" + CRC(ARG) + "&d=" + ARG + "&f=" + FORMAT + ((typeof(COLORS) === "undefined") ? "" : "&colors=" + COLORS); } ////////////////////////////////////////////////// // Returns 1 if a character is a digit. function isDigit(c) { if (c > 47 && c < 58) return 1; return 0; } ////////////////////////////////////////////////// // // This function opens a browse window and allows // the user to select a file to work with. // Usage: STRING = BrowseForFile() // function BrowseForFile() { // create an instance of the File Browser var U = new ActiveXObject("UserAccounts.CommonDialog"); // setup the File Browser specifics U.Filter = "All Files|*.*"; U.FilterIndex = 3; U.InitialDir = PATH; // Show the file browser and return the selection (or lack of) to InitFSO var InitFSO = U.ShowOpen(); return (InitFSO) ? U.FileName + "" : ""; } ////////////////////////////////////////////////// // This function creates a button that acts like a SELECT object // and can has multiple faces. Each click changes the state of the button. function AddButtonSwitch(HANDLE, FACE) { eval("BTN_" + HANDLE + " = FACE.split('|');"); // SAVE FACE VALUES eval("BTNS_" + HANDLE + " = 0;"); // SAVE BUTTON STATE FACE = FACE.split("|"); document.write("\x3CINPUT STYLE='WIDTH:130;' NAME='" + HANDLE + "' TYPE=BUTTON VALUE=\"" + FACE[0] + "\" onClick='nextBtn(this);' onDblClick='nextBtn(this);'>"); } // This function is called whenever the user clicks on a button switch... function nextBtn(HANDLE) { var FACE = eval("BTN_" + HANDLE.name); var STATE = eval("BTNS_" + HANDLE.name) + 1; if (STATE >= FACE.length) STATE = 0; HANDLE.value = FACE[STATE]; eval("BTNS_" + HANDLE.name + " = STATE;"); } ////////////////////////////////////////////////// // This function reads all files in a directory and // returns the results in an array. // Usage: ARRAY = ReadDIR(PATH) // function ReadDIR(PATH) { var FILELIST = []; var FC, File, FileName, FolderName; if (typeof(RECURSIVE_MODE) === "undefined") RECURSIVE_MODE = 0; var F = FSO.GetFolder(PATH); for (FC = new Enumerator(F.SubFolders); !FC.atEnd(); FC.moveNext()) { FolderName = FC.item(); Folder = FSO.GetFolder(FolderName); FILELIST.push(FolderName + ":0:" + Folder.Attributes + ":" + Date.parse(Folder.DateCreated) + ":" + Date.parse(Folder.DateLastModified)); if (RECURSIVE_MODE) FILELIST = FILELIST.concat(ReadDIR(FolderName)); } for (FC = new Enumerator(F.files); !FC.atEnd(); FC.moveNext()) { FileName = FC.item(); File = FSO.GetFile(FileName); FILELIST.push(FileName + ":" + File.Size + ":" + File.Attributes + ":" + Date.parse(File.DateCreated) + ":" + Date.parse(File.DateLastModified)); } return FILELIST; } ////////////////////////////////////////////////// // // Renames a file. // function RenameFile(OLD_FULLNAME, NEW_NAMEONLY) { var F = FSO.GetFile(OLD_FULLNAME); F.name = NEW_NAMEONLY; } ////////////////////////////////////////////////// // Closes a window. function CloseWin() { self.close(); } ////////////////////////////////////////////////// // // CUSTOM ALERT BOX FOR JAVASCRIPT // // BUTTON TYPE VALUES: // 0 = OK // 1 = OK, Cancel // 2 = Abort, Ignore, Retry // 3 = Yes, No, Cancel // 4 = Yes, No // 5 = Retry, Cancel // ADD THE FOLLOWING TO CHANGE THE TYPE OF MESSAGE: // 16 = Critical // 32 = Question // 48 = Exclamation // 64 = Information // RETURN VALUES: // 1 = OK button clicked // 2 = Cancel // 3 = Abort // 4 = Retry // 5 = Ignore // 6 = Yes // 7 = No // -1 = None, message box was dismissed or automatically timeout function CustomAlert(MSG, INTERVAL, TITLE, TYPE) { var R = 0; try { return WshShell.Popup(MSG, INTERVAL, TITLE, TYPE); } catch(e) {} return R; } ////////////////////////////////////////////////// // v2021.1.19 // Converts base 10 positive number N to a string // of 1s and 0s. No Limit!!! // // Usage: STRING = toBin(NUMBER, LENGTH) // function toBin(N, L) { if (typeof(L) === "undefined") L = 32; var $ = []; var Z = (N+"").length; var M = [1, 2, 4, 8, 16, 32, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000]; if (Z < 17) // TREAT AS FLOAT { // TREAT AS 32-BIT INT if (L < 33 || (N >= -2147483648 && N <= 4294967295)) { N |= 0; while (L--) $.push((N & M[L]) ? 1 : 0); return $.join(""); } if (N <= 9007199254740991) { N = Math.floor(N); $ = (N & 0x0FFFFFFF).toString(2); while ($.length < 28) $ = "0" + $; $ = (Math.floor(N/268435456) & 0x0FFFFFFF).toString(2) + "" + $; while ($.length < L) $ = "0" + $; return $.slice(-L); } } $ = BigInt2Bin(N); while ($.length < L) $ = "0" + $; return $.slice(-L); } ////////////////////////////////////////////////// // v2019.9.27 // This function converts a big integer from base 10 // to base 2. Both the input and the output are strings. // // Usage: STRING = BigInt2Bin(STRING) // function BigInt2Bin($N) { // Calculate powers of two, as many as we need... var $X; // Power of two var $i = 0; // Ptr to current power of two var $BIN = ''; // This will be our return value var $PWR = ['1']; // Powers of two while ($i++ < 3000) // Max digits = 3000 { $X = $PWR[$i - 1]; $X = $PWR[$i] = ADD($X, $X); if (CMP($N, $X) != 1) break; // $N <= $PWR ? } // Convert decimal number to binary // starting with the most significant digit while ($i--) { if ( CMP($N, $PWR[$i]) == 2) { $BIN += '0'; } else { $BIN += '1'; $N = DIFF($N, $PWR[$i]); } } return $BIN; } ////////////////////////////////////////////////// // v2019.9.27 // This function adds two large positive integers. // // Both numbers must be in base 10. The numbers may // not contain any character other than digits (0-9). // Two additional arguments may be provided to shift // the input numbers left or right before being added. // A negative shift moves digits to the right // discaring the least significant digits, while // a positive shift moves digits to the left // (it's the same as multiplying by 10, 100, or 1000). // Usage: STRING = ADD(STRING, STRING, [INTEGER, [INTEGER]]) // Example: ADD('1111', '222', -1, 2) --> '22311' // function ADD($A, $B, $AL, $BL) { $A += ""; $B += ""; if (typeof($AL) === "undefined") $AL = 0; $AL += $A.length; if (typeof($BL) === "undefined") $BL = 0; $BL += $B.length; var $i = ($AL > $BL) ? $AL : $BL; var $CARRY = 0; var $SUM = '0'; var $X; while ($i-- > 0) { $X = $AL ? $A.charCodeAt(--$AL) : 48; $X += ($BL ? $B.charCodeAt(--$BL) : 48) + $CARRY; $CARRY = $X > 105 ? 1 : 0; $SUM = vec($SUM, $i, $X - ($CARRY ? 58 : 48)); } return ($CARRY ? '1' : '') + $SUM; } ////////////////////////////////////////////////// // v2019.9.27 // This function returns the difference between two // large positive integers in base 10. These // "large integers" are strings that hold digits // only (0-9) and nothing else. No spaces, tabs, // line breaks, or letters allowed! The return value // of this function will always be a string // containing a positive integer. // Tested with TinyPerl 5.8.0 and Perl 5.004 for DOS. // Usage: STRING = DIFF(STRING, STRING) // function DIFF($A, $B) { $A += ""; $B += ""; var $T; var $AL = $A.length; var $BL = $B.length; var $DIFF = 0; var $i = 0; // Swap A and B if B is greater if ($AL == $BL) { if ($A == $B) return '0'; while ($DIFF == 0) // Check if B is greater { $DIFF = $B.charCodeAt($i) - $A.charCodeAt($i++); } } if ($BL > $AL || $DIFF > 0) { $T = $A; $A = $B; $B = $T; // Swap A and B } // At this point, we know that $A > $B var $AX; // Current digit from integer A var $BX = 0; // Current digit from integer B + carry var $START = 0; // Start trim $DIFF = ''; // This will be our return value $AL = $A.length; $BL = $B.length; var $MAXLEN = ($AL > $BL) ? $AL : $BL; $i = $MAXLEN; while ($i--) // Loop until max($AL, $BL) { $AX = $AL ? $A.charCodeAt(--$AL) : 48; $BX += $BL ? $B.charCodeAt(--$BL) : 48; // Get new digit + Add carry $AX -= $BX; // Subtract $BX = $AX < 0 ? 1 : 0; // Carry 1 or 0 $AX += $BX ? 58 : 48; // Convert digit to ASCII code '0' - '9' $DIFF = vec($DIFF, $i, $AX); // Write digit if ($AX != 48) $START = $i; // Keep track of last non-zero digit } return $DIFF.slice($START); // Remove initial zeros } ////////////////////////////////////////////////// // v2020.06.30 // Compares two large positive integers. // The integers can be binary, octal, // decimal, or hexadecimal. // // NOTE: Both numbers must be in the same base. // // Returns: 0 if they are equal // 1 if the first one is greater // 2 if the second one is greater // // Special cases: // * When comparing an undefined value against // an empty string or zero, they will be equal. // * Minus signs are ignored, therefore // -5 and +5 are treated as equal. // // Usage: INTEGER = CMP(STRING, STRING) // function CMP($A, $B) { $A2 = $A.length; $B2 = $B.length; var $A1 = 0, $B1 = 0, $CA = 48, $CB = 48, $DIFF = 0; // SHOW WHAT'S HAPPENING: //print "\n\nString1=|$A|\nString2=|$B| RET="; // Find the first significant digit or starting pointer for each string. // We will call this A1 and B1. In case the string starts with zeros, // spaces, tabs, new line characters, - and + signs, or other special // characters, we skip through those. We ignore them. while ($A1 < $A2 && $A.charCodeAt($A1) < 49) { $A1++; } while ($B1 < $B2 && $B.charCodeAt($B1) < 49) { $B1++; } // Find last significant digit or ending pointer for each string. // We will call this A2 and B2. while ($A2 > $A1 && $A.charCodeAt(--$A2) < 48) {} $A2++; while ($B2 > $B1 && $B.charCodeAt(--$B2) < 48) {} $B2++; // Calculate the number of digits in each number. var $AL = $A2 - $A1; var $BL = $B2 - $B1; // Are both numbers the same length? if ($AL == $BL) { // Compare from left to right, incrementing // pointers A1 and B1 as we walk through all the digits. while ($A1 < $A2) { $CA = $A.charCodeAt($A1++); // Get digit from string A $CB = $B.charCodeAt($B1++); // Get digit from string B $DIFF = $CA - $CB; if ($DIFF) { return $DIFF < 0 ? 2 : 1; } } return 0; } if ($AL > $BL) return 1; if ($AL < $BL) return 2; return 0; } ////////////////////////////////////////////////// function Str2Txt(S) { var i, c = -1, P, prev_char, prev_esc, output_char, ESC = 0, REPEAT = 0, OUT = []; for (i = 0; i < S.length; i++) { prev_char = c; c = S.charCodeAt(i); if (c == prev_char) { if (++REPEAT < 2) OUT.push(output_char); else { OUT.length--; OUT.push(TX.charAt(ESC + 697)); REPEAT = 0; } } else { REPEAT = 0; P = TX.charCodeAt(c + 256); if (P < 0) ESC = P = 0; else { prev_esc = ESC; ESC = (P / 57) & 7; P -= ESC * 57; if (ESC != prev_esc) OUT.push(TX.charAt(ESC + 697)); output_char = TX.charAt(P + 640); OUT.push(output_char); } } } return OUT.join(""); } function Txt2Str(S) { var output_char = '', prev_esc, i, c, P, ESC = 0, OUT = []; for (i = 0; i < S.length; i++) { c = S.charCodeAt(i); P = TX.charCodeAt(c + 512); if (P < 0) { prev_esc = ESC; ESC = 0; c = 0; } if (P >= 57) { prev_esc = ESC; ESC = P - 57; if (prev_esc == ESC) { OUT.push(output_char); OUT.push(output_char); } } else { P = ESC * 57 + P; output_char = (P < 256) ? TX.charAt(P) : " "; OUT.push(output_char); } } return OUT.join(""); } function Bin2B64(BIN) { BIN += ""; while (BIN.length % 6) BIN += "0"; var i, c, MASK = 32, BYTE = 0, $ = []; for (i = 0; i < BIN.length; i++) { c = BIN.charCodeAt(i); if (c == 48) MASK >>= 1; if (c == 49) { BYTE += MASK; MASK >>= 1; } if (MASK == 0) { $.push(B64SET.charAt(BYTE)); MASK = 32; BYTE = 0; } } return $.join(""); } function PackInts(LENGTH, INT) { var i, OUTPUT = []; for (i = 0; i < arguments.length; i++) { LENGTH = arguments[i++]; INT = arguments[i]; OUTPUT.push(toBin(INT, LENGTH)); } return OUTPUT.join(""); } function GetWebAddressOnly(URL){URL=cut(URL,"?",0x0110);URL=cut(URL,"#",0x1110);return URL;} function GetArgInt(ARGS,NAME,DEFAULT){if(typeof(DEFAULT)==="undefined")DEFAULT=0;var VALUE=GetArgStr(ARGS,NAME);return(isNaN(VALUE)||VALUE=="")?DEFAULT:Math.round(VALUE);} function GetArgStr(ARGS,NAME,DEFAULT){if(typeof(DEFAULT)==="undefined")DEFAULT="";ARGS=cut(ARGS,"?",0x0101);ARGS=cut(ARGS,"#",0x1110);ARGS=cut("&"+ARGS+"&","&"+NAME+"=",1);if(ARGS.length==0)return DEFAULT;return cut(ARGS,"&",0x10);} function Quit(MSG, TITLE) { if (typeof(TITLE) === "undefined") TITLE = "Good Bye"; WshShell.Popup(MSG, 0, TITLE, 0); WScript.Quit(0); } function RequireWindowsXP_or_Exit() { try { // If this is not Windows XP, then quit. if (RegRead("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProductName") != "Microsoft Windows XP") Quit("This program will only work with Windows XP."); } catch (e) {} } ////////////////////////////////////////////////// // // This function clears a file's attributes to Archive. // Writes error message in global variable $a. // Returns: 0=Success 1=Failure // Usage: INTEGER = ResetFileAttrib(FILENAME, [NEW_ATTRIBUTES]) // function ResetFileAttrib(FILENAME, NEW_ATTRIBUTES) { // Set Archive attribute and clear S-H-R attributes by default. if (typeof(NEW_ATTRIBUTES) === "undefined") NEW_ATTRIBUTES = 32; $a = ""; try { var FSO = new ActiveXObject("Scripting.FileSystemObject"); var F = FSO.GetFile(FILENAME); F.Attributes = NEW_ATTRIBUTES; $a = "SUCCESS"; return 0; } catch (e) { $a = e.message; } return 1; } ////////////////////////////////////////////////// // This is probably not the best solution. // Create a BAT script with copy commands and // execute it rather than doing it this way: function CopyFile(SRC, DST) { var F = FSO.GetFile(SRC); F.Copy(DST); } ////////////////////////////////////////////////// function ShortAlert(MSG) { WshShell.Popup(MSG, 3, "Alert", 0); } ////////////////////////////////////////////////// // v2021.3.16 // This function reads the screen width and height // and sets certain global variables: // Usage: ReadDeviceDetails() // function ReadDeviceDetails() { var MSIE = WScript.CreateObject("InternetExplorer.Application"); MSIE.Visible = 0; MSIE.Navigate("about:blank"); WScript.Sleep(10); WX = MSIE.document.parentWindow.screen.width; HX = MSIE.document.parentWindow.screen.height; CC = MSIE.document.parentWindow.screen.colorDepth; LANDSCAPE = WX > HX ? 1 : 0; var _WX = WX, _HX = HX; if (!LANDSCAPE) { _WX = HX; _HX = WX; } ASPECT_RATIO = Math.round(_WX / _HX * 100) / 100; MSIE.Quit(); } //////////////////////////////////////////////////