/* ** ZLIB JavaScript Function Library. ** Written by Zsolt N. Perry in Pensacola, Fla. ** April 2023 Edition ** ** This script can be used either as part of a HTML document ** or as a stand-alone JS script on Windows. Both applications ** will have different environments, and some functions will ** only work in one specific environment. ** *******************************************************/ INIT(); ALERT(LocalTimeD()); EXIT(); function KEYPRESS(K) { if (K == 113) // F2 was pressed {} if (K == 114) // F3 was pressed {} if (K == 119) // F8 was pressed {} window.status = K; } ////////////////////////////////////////////////// // // This function runs some tests and // initializes a bunch of global variables. // function INIT() { var $, W1, W2, W3, W4, W5, H1, H2, H3, H4, H5; T1 = TIME(); HTML = []; LANDSCAPE = 1; LANGUAGE = 'ENUS'; ONLINE = MOBILE = BROWSER_VERSION = X64 = WX = HX = Wx = Hx = 0; MSIE = OPERA = FIREFOX = SAFARI = CHROME = EDGE = SEAMONKEY = 0; FILESYS = COOKIES = STORAGE = 0; JAVA = WASM = CANVAS = FATARROW = FUNCDEF = EXPORT = ASYNC = LET = BIGINT = 0; BROWSER_NAME = PF = UA = DEVICE = ''; SEED = 1; RANDOM = []; RND = [55]; // String testing functions require this line: CX = [512,0,0,0,0,0,0,0,0,520,520,0,512,520,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,632,9464,1192,1272,1257,1272,1264,1240,9464,9464,13560,7416,1272,13560,13560,15608,14840,14840,14840,14840,14840,14840,14840,14840,14840,14840,9464,1144,1264,1144,1264,9464,1256,47613,31229,31229,31229,47613,31229,30973,30973,47357,30973,30973,30973,30973,30973,47357,30973,30973,30973,30973,30973,47357,30973,30973,30973,30973,30973,9464,1160,9464,1272,9465,1272,47611,31227,31227,31227,47611,31227,30971,30971,47355,30971,30971,30971,30971,30971,47355,30971,30971,30971,30971,30971,47355,31483,30971,30971,30971,30971,9464,1272,9464,1272,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,1,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,3,3,3,3,3,1,3,3,3,3,3,3,0,3]; ALLCHARS = CharRange(0, 255, 1); // DO NOT CHANGE THIS LINE! This function creates an array of characters from 0 to 255. // SET UP SOME GLOBAL VARIABLES $ = BROWSER = typeof(document) == 'undefined' || typeof(window) == 'undefined' ? 0 : 1; SELF = BROWSER ? location.href : WScript.ScriptFullName; DOMAIN = BROWSER ? document.domain : ''; CURDIR = GetCurrentDirectory(); // Initialize Str2Txt() and Txt2Str() lookup tables TX = Hex2Str('47696F3164497142674F626534726153486E43636B3875456D57554E54684D767C746C70463641373220392F782E7752664479507330334C35595E0A804B3B277E860D882D60897A584A295D243A237B847D2C8B8540268E82515A216A005B5C1B223E2881833F875F2A093D252B568C8A3C04A98D8F08A71D129593A3A29A0B989F1A0E9E1C1F160F9611170119079997A69B101505A09C7F0C1E90181406139DA59194AA0302A1A492A8BDB2E3C7B7D4DFC8ADD0ACCBCDC9D7D9CAC5BCD6B4CCB9BEE0DAB8D5C0BBB5E2C1CED1ABDED3BFDBB3CFAFD8BADCAEB0C3C4C2D2C6DDE1B6B1F7F6FFFCE9E8EEEDEFF4F3E4F5E5EAFAECF2F8F0E7FBFEEBE6FDF1F95D8CA6A572959E8E766A3B7F99428388938A799F9D94878B9C8D826085789A86295B614E4C6C563F634A696D52442D2B350328360C382527152A4D3E716B626655260712311724001005493D371E1B0933592F0F1C1A6E1948395A5E5F4B3A68450E0A13040B30081D015C142218110223060D3421161F2E2C32474F205140983C64586550544167434670536F7457759BA2A97BA37A8990808F7E9297A0848196A77D7CA8A19177AA73A4CEB5B3D9D5DAE3ACD3BFC9E2AFC5C1D7C8BDABC2D1C7CBDDDBDCBCDFAEB2B8BBB6C0B7CCD4B4CDDED0B0C6BEB9D6BAC4D2D8E0CFB1C3E1CAADEFF1FCF8E9E8F2FBF4EBEAECF7FEF5EEEDF0E5E4F6FFF3F9E7FDFAE6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000263706110C0F3102072500000000000000130E3C1D011A031C050A2F172B142718152100293A302D0820320000000000001028193D0D16342E380B3912232C2A1F332236041B0924353B1E0000000000534537477449323858764A6A3465423561336C414E51664C5063467548447A705952726D7739304F62546F4D6E57684B56365A7167787331696B55794364'); if (BROWSER) { // PREVENT PAGE HIJACKING if (top.location != self.location) top.location = self.location; // HOOK KEYPRESS document.onkeydown = function(e) { e = e ? e:typeof event != 'undefined' ? event : null; if (!e) return 0; KEYPRESS(e.keyCode); } // DETECT MOBILE DEVICE PF = navigator.platform; UA = navigator.userAgent; DEVICE = UA + ' ' + PF; MOBILE = /PHONE|MOBILE|TABLET|IPOD|IPAD|BLACKBERRY|LUMIA|ANDROID|WEBOS|PLAYBOOK|BB10|MINI|CRMO|OPERA MINI|OPERA MOBI|PALM|WINDOWS CE|XOOM|SCH-I800|KINDLE/i.test(DEVICE) | 0; ONLINE = (location.href.substr(0, 4).toUpperCase() == 'HTTP') | 0; // DETECT 64-BIT CPU X64 = /X86_64|X86-64|WIN64|X64|AMD64|WOW64|IA64|SPARC64|PPC64/i.test(DEVICE) | 0; // SETUP FORM, CANVAS TEST, SLIDE, AND PIX IMAGE FOR PAGE COUNTER. document.write("
 
"); // DETECT WEB BROWSER // Opera 8.0+ / Firefox 0.8+ / Safari 3+ / GoogleChrome 1+ / IE6 / Edge 20+ function testCSS(prop) { return prop in document.documentElement.style; } if (!!(window.opera && window.opera.version) || (!!window.opr && !!opr.addons) || /OPERA|OPR\//i.test(UA)) { $ = "OPERA"; OPERA = 2; } else if (Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0) { $ = "SAFARI"; SAFARI = 4; } else if ((testCSS('MozBoxSizing') || typeof InstallTrigger !== 'undefined')) { $ = "FIREFOX"; FIREFOX = 8; } else if (testCSS('WebkitTransform') || (!!window.chrome && !!window.chrome.webstore)) { $ = "CHROME"; CHROME = 16; } else if (/*@cc_on!@*/false || testCSS('msTransform') || !!document.documentMode) { $ = "MSIE"; MSIE = 32; } else if (!!window.StyleMedia) { $ = "EDGE"; EDGE = 64; } if (/SEAMONKEY/i.test(UA)) { $ = "SEAMONKEY"; SEAMONKEY = 128; } BROWSER |= OPERA | SAFARI | FIREFOX | CHROME | MSIE | EDGE | SEAMONKEY; BROWSER_NAME = $; // EXTRACT BROWSER VERSION if (SAFARI) $ = "VERSION"; BROWSER_VERSION = ExtractVersion(UA, $); // DETECT OS OS = PF; if (PF == "") OS = "FirefoxOS"; if (PF == null) OS = "Android"; if (($ = ExtractVersion(UA, "WINDOWS NT"))) { if ($ == 5) $ = 2000; else if ($ == 5.1) $ = "XP"; else if ($ == 6.0) $ = "Vista"; else if ($ == 6.1) $ = 7; else if ($ == 6.2) $ = 8; else if ($ == 6.3) $ = 8; OS = "Win" + $; } // DETECT STORAGE COOKIES = TestCookies(); STORAGE = TestLocalStorage(); // GET SCREEN RESOLUTION Wx = WX = screen.width; Hx = HX = screen.height; RES = WX * HX; LANDSCAPE = (WX > HX) ? 1 : 0; ASPECT_RATIO = (HX == 0) ? 1 : WX / HX; W1 = W2 = W3 = W4 = W5 = H1 = H2 = H3 = H4 = H5 = 0; try { W1 = window.innerWidth; H1 = window.innerHeight; } catch (e) {} try { W2 = window.outerWidth; H2 = window.outerHeight; } catch (e) {} try { W3 = document.body.offsetWidth; H3 = document.body.offsetHeight; } catch (e) {} try { W4 = document.body.clientWidth; H4 = document.body.clientHeight; } catch (e) {} try { W5 = document.documentElement.offsetWidth; H5 = document.documentElement.offsetHeight; } catch (e) {} Wx = FindLowest(WX, W1, W2, W3, W4, W5); Hx = FindLowest(HX, H1, H2, H3, H4, H5); if (!LANDSCAPE) { $ = HX; HX = WX; WX = $; $ = Hx; Hx = Wx; Wx = $; } SMALL_SCREEN = (WX < 640) ? 1 : 0; // smartphone display detected HIGH_RES = (RES >= 1920000) ? 1 : 0; // 1600x1200 or higher WIDE_SCREEN = (WX > 1000 && ASPECT_RATIO >= 1.6) ? 1 : 0; if (SMALL_SCREEN || !LANDSCAPE) MOBILE = 1; // DETERMINE BROWSER WINDOW SIZE Wx = FindLowest(screen.width, window.innerWidth, window.outerWidth, document.body.offsetWidth, document.body.clientWidth, document.documentElement.offsetWidth); Hx = FindLowest(screen.height, window.innerHeight, window.outerHeight, document.body.offsetHeight, document.body.clientHeight, document.documentElement.offsetHeight); // GET BROWSER LANGUAGE LANGUAGE = (navigator.userLanguage || navigator.language).toUpperCase().replace(/[^A-Z]/g, ''); // DETECT JAVASCRIPT FEATURES JAVA = navigator.javaEnabled() ? 256 : 0; WASM = 0; try { if (typeof(WebAssembly) === "object" && typeof(WebAssembly.instantiate) === "function") { M = new WebAssembly.Module(Uint8Array.of(0, 0x61, 0x73, 0x6d, 0x01, 0, 0, 0)); WASM = (M instanceof WebAssembly.Module) ? 2 : 1; } } catch (e) {} CANVAS = 0; try { var C = document.getElementById("CVTEST").getContext("2d"); CANVAS = 4; } catch (e) {} FATARROW = 0; try { eval("const MUL$$2 = (x, y) => x * y;"); FATARROW = 8; } catch (e) {} FUNCDEF = 0; try { eval("MM = function _$Mul(x, y) { return x * y; };"); FUNCDEF = 16; } catch (e) {} EXPORT = 0; try { eval("export const XXXTESTXXX = 1;"); EXPORT = 32; } catch (e) {} ASYNC = 0; try { eval("async function _$BTEST() { return; }"); ASYNC = 64; } catch (e) {} BIGINT = 0; try { eval("sx$ = 999999999999999999999n;"); BIGINT = 128; } catch(e) {} LET = 0; try { eval("let _$TEST = 4;"); LET = 256; } catch (e) {} } else { MSIE = 32; BROWSER_VERSION = 6; BROWSER_NAME = 'MSIE'; try { FSO = WScript.CreateObject("Scripting.FileSystemObject"); FILESYS = 1; } catch (e) { EXIT("Cannot access File System."); } try { WordObj = WScript.CreateObject("Word.Application"); } catch (e) {} try { WshShell = WScript.CreateObject("WScript.Shell"); } catch (e) {} ReadDeviceDetails(); } // GET TIMEZONE TIMEZONE = Math.round((new Date().getTimezoneOffset() / 60)); NUM = "0123456789"; HEX = "0123456789ABCDEF".split(""); ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; B64 = ABC + NUM + '/+'; VOWELS = "AEIOUaeiou"; CONSONANTS = "BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz"; WHITESPACE = " \t\r\n\0"; BIN4 = "0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111".split(" "); B64SET = "?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; URLSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz|_"; // The following characters can be used in a cookie name or value: COOKIEJAR = "^0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz$@!?*|#&%~+:-., []{}()_/\\><\"'`"; } ////////////////////////////////////////////////// // // // GENERAL BASIC FUNCTIONS // // // Displays an alert message box. function ALERT(S) { if (typeof(document) == 'undefined') WScript.Echo(S); else alert(S); } // Returns the number of milliseconds since Jan 1 1970. function TIME() { return (new Date()).getTime(); } // This function suspends execution of the script for N milliseconds. function WAIT(N) { if (BROWSER == 0) WScript.Sleep(N); } // This function displays an error message and terminates the script. function EXIT(MSG) { if (typeof(MSG) != "undefined") ALERT(MSG); if (BROWSER) return; WordObj.Quit(); WScript.Quit(0); } // 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); } function Abort_Script_If_Numlock_Is_OFF() { if (BROWSER) return; if (GetNumlockState() == 0) EXIT(); } ////////////////////////////////////////////////// // // // HTML FUNCTIONS // // function CLS() { HTML = [' ']; RENDER(); } function PRINT(X) { HTML.push(X); } function FLUSH() { if (BROWSER) document.write(HTML.join('')); HTML = []; } function RENDER() { if (BROWSER) document.getElementById('SLIDE').innerHTML = HTML.join(''); HTML = []; } ////////////////////////////////////////////////// // // // ARGUMENT PROCESSING FUNCTIONS // // 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";} SplitURL(location.href); /* ARGC = 0; ARGN = []; ARGV = []; ARGS = ""; LastSplitAB(location.href, "#"); SELF = $A; BOOKMARK = $B; if (SplitAB(SELF, "?")) { SELF = $A; ARGS = $B; A = unescape(ARGS).split("&"); for (i = 0; i < A.length; i++) if (SplitAB(A[i], "=")) { ARGN.push($A.toUpperCase()); ARGV.push($B); ARGC++; } } SELF = StrReplace(SELF, "\\", "/"); LastSplitAB(SELF, "/"); PATH = $A; FILE = $B; 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); */ // 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; } //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);} // This function returns a string argument from the provided URL. If the argument is missing, an empty string is returned. // function GetArgStr(ARGS, NAME) { ARGS = cut(ARGS, "?", 0x0101); ARGS = cut(ARGS, "#", 0x1110); ARGS = cut("&" + ARGS, "&" + NAME + "=", 1); if (ARGS.length == 0) return ""; return cut(ARGS, "&", 0x110); } // // This function returns the named integer argument from the provided URL. If the argument is missing, zero is returned. // function GetArgInt(ARGS, NAME, MAXVALUE) { return toInt(GetArgStr(ARGS, NAME), MAXVALUE); } ////////////////////////////////////////////////// // v2021.2.10 // This function expects to receive a full URL, // and it returns the web address only without // the arguments and bookmark. // Usage: STRING = GetWebAddressOnly(URL) // function GetWebAddressOnly(URL) { URL = cut(URL, "?", 0x0110); // Cut the first "?" and everything after it if it's found URL = cut(URL, "#", 0x1110); // Cut the last "#" and everything after it if it's found return URL; } ////////////////////////////////////////////////// // // // EXCEL FUNCTIONS // // ////////////////////////////////////////////////// // CSV | v2021.4.22 // Splits a single line of a CSV file into an array. // Each column will be a separate array element. // // 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; } ////////////////////////////////////////////////// // CSV | v2023.3.13 // This function joins an array to form a single // line of a CSV file. Elements will be separated // with a comma. // Usage: STRING = JoinCSV(ARRAY) // function JoinCSV(A) { var i; var $ = []; for (i = 0; i < A.length; i++) { if (typeof(A[i]) === "undefined" || A[i] == null) { A[i] = ""; continue; } $[i] = A[i] + ""; if ($[i].indexOf(",") >= 0 || $[i].indexOf('"') >= 0) $[i] = '"' + $[i].split('"').join('""') + '"'; } return $.join(","); } ////////////////////////////////////////////////// // // // COOKIE FUNCTIONS // // // This function saves a cookie that expires in 5 years (if the expiration is not specified). The expiration must be given in seconds, which tells the browser how long the cookie will exist. This function returns 1 on success. Returns 0 if the cookie could not be saved. function SetCookie(NAME, VALUE, EXPIRATION) { var DATE = new Date(); var COOKIE = NAME + "=" + (typeof(VALUE) === "undefined" ? "" : VALUE); DATE.setTime(DATE.getTime() + 1000 * (typeof(EXPIRATION) === "undefined" ? 157680000 : EXPIRATION)); document.cookie = COOKIE + ";Expires=" + DATE.toGMTString() + ";"; return document.cookie.indexOf(COOKIE) < 0 ? 0 : 1; } // 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; } ////////////////////////////////////////////////// // // // LOCALSTORAGE FUNCTIONS // // // 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; } ////////////////////////////////////////////////// // // // OS DEPENDENT FUNCTIONS // // // This function positions our window in the center of the screen. function PRESS(KEYCODE) { if (BROWSER) return; WAIT(100); try { var WSH = new ActiveXObject("WScript.Shell"); WSH.SendKeys(KEYCODE); } catch (e) {} } function PlayMP3(FILENAME) { if (BROWSER) return; RUN(QUOTE("C:\\BIN\\COMMAND\\PLAYMP3.EXE") + " " + QUOTE(FILENAME)); } function WinFocus(W) { if (BROWSER) return; try { var WSH = new ActiveXObject("WScript.Shell"); WSH.AppActivate(W); } catch (e) {} } function RunPerl(FILE, ARGS) { if (BROWSER) return; RUN("C:\\BIN\\PERL\\PERL.BAT PAUSE! \"" + FILE + "\" " + EscapeString(ARGS, '#0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!?*-._')); } function RunNotepad(NAME) { RUN("C:\\WINDOWS\\NOTEPAD.EXE \"" + NAME + '"'); } function RUN(CMD) { if (BROWSER) return; try { var WSH = new ActiveXObject("WScript.Shell"); WSH.Run(CMD); } catch (e) {} } function TYPE(TEXT) { if (BROWSER) return; var i, t; for (i = 0; i < TEXT.length; i++) { t = TEXT.charAt(i); WAIT(20); if (i > 5) { t = TEXT.slice(i); i = TEXT.length; } PRESS(t); } } function ShortAlert(MSG) { WshShell.Popup(MSG, 3, "Alert", 0); } 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 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 GetReg(r) { try { return WshShell.RegRead(ExpandRegPath(r)); } catch(e) {} return ""; } function DelReg(r) { try { WshShell.RegDelete(ExpandRegPath(r)); } catch(e) {} } function SetReg(r) { r = r.split("|"); var PATH = ExpandRegPath(r[0]); var TYPE = r[1].toUpperCase(); var VALUE = r[2]; try { WshShell.RegWrite(PATH, VALUE, TYPE); } catch(e) {} } ////////////////////////////////////////////////// function ExpandRegPath(r) { r = r.split("/").join("\\"); var $ = r.slice(4); var X = r.substr(0, 4).toUpperCase(); if (X == "HKCU") return "HKEY_CURRENT_USER" + $; if (X == "HKCR") return "HKEY_CLASSES_ROOT" + $; if (X == "HKLM") return "HKEY_LOCAL_MACHINE" + $; if (X == "HKCC") return "HKEY_CURRENT_CONFIG" + $; return r; } ////////////////////////////////////////////////// function DIR(p) { var FILES = []; var PATH_LENGTH = p.length + ((p.slice(-1) == '\\') ? 0 : 1); var F = FSO.GetFolder(p), FC, File, FullName; function DateOf(f) { return ('0000000000' + (f.DateLastModified * 1)).slice(-13).substr(0, 10) + ' '; } function SizeOf(f) { return ('00000000000' + f.Size + ' ').slice(-12); } function Shorten(n) { return (n + '').slice(PATH_LENGTH); } for (FC = new Enumerator(F.SubFolders); !FC.atEnd(); FC.moveNext()) { FullName = FC.item(); File = FSO.GetFolder(FullName); FILES.push('+' + DateOf(File) + Shorten(FullName)); } for (FC = new Enumerator(F.files); !FC.atEnd(); FC.moveNext()) { FullName = FC.item(); File = FSO.GetFile(FullName); FILES.push(SizeOf(File) + DateOf(File) + Shorten(FullName)); } return FILES; } ////////////////////////////////////////////////// // This function tries to detect the Windows version. // Returns 0 = Unknown // 1 = Windows 95 // 2 = Windows 98 // 3 = Windows Me // 4 = Windows 2000 // 5 = Windows XP // 6 = Windows Vista // 7 = Windows 7 // 8 = Windows 8 // 10 = Windows 10 // function WinVer() { var X = GetReg("HKLM/SOFTWARE/Microsoft/Windows/CurrentVersion/VersionNumber"); if (X.indexOf("4.00.950") >= 0) return 1; var V = GetReg("HKLM/SOFTWARE/Microsoft/Windows/CurrentVersion/Version").toUpperCase(); if (V.indexOf("MILLENNIUM") >= 0) return 3; if (X || V) return 2; V = GetReg("HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion/CurrentVersion"); if (V == "5.0") return 4; if (V == "5.1" || V == "5.2") return 5; if (V == "6.0") return 6; if (V == "6.1") return 7; if (V == "6.2" || V == "6.3") return 8; if (V == "10.0") return 10; return 0; } ////////////////////////////////////////////////// function BrowseForFile(DIR) { var FBROWSER, SELECTION = false; try { FBROWSER = new ActiveXObject("UserAccounts.CommonDialog"); FBROWSER.Filter = "All Files|*.*"; FBROWSER.FilterIndex = 1; FBROWSER.InitialDir = DIR; SELECTION = FBROWSER.ShowOpen(); } catch (e) { ALERT("Sorry, the \"Browse\" button doesn't work.\n\nYou must type or paste the directory path."); return ""; } // User must have canceled. if (SELECTION = false) return ""; var F = FBROWSER.FileName; if (F == "") return ""; return F; } ////////////////////////////////////////////////// // This function opens a Browse for Folder window // and allows the user to select a folder and returns the selected folder... function BrowseForFolder(SEARCHING_FOR) { try { var SHELL = new ActiveXObject("Shell.Application"); var F = SHELL.BrowseForFolder(0, "You are looking for : " + SEARCHING_FOR + "\nDid you know, you can move folders by simply pulling them onto another folder?", 1); } catch (e) { return ""; } // Error. Didn't work. if (F == null) return ""; // ESC or CANCEL return F.self.Path; // SUCCESS } ////////////////////////////////////////////////// function OpenFileDialog() { var InitFSO = 0, U, FILENAME = ''; try { // create an instance of the File Browser 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 InitFSO = U.ShowOpen(); } catch (e) {} if (InitFSO) FILENAME = U.FileName + ""; return FILENAME; } ////////////////////////////////////////////////// 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) {} } ////////////////////////////////////////////////// // 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(); } ////////////////////////////////////////////////// /* The MsgBox() function displays a popup message box regardless of which host executable file is running (WScript.exe or CScript.exe). If DELAY is 0 or undefined, the pop-up message box remains visible until closed by the user. If DELAY is greater than zero, the pop-up message box closes after that many seconds. If you do not supply the argument TITLE, the title of the pop-up message box defaults to "Windows Script Host." The following tables shows the values and their meanings for TYPE. You can combine values in these tables. Type Values: -------------------------------------- 0 = Show OK button. 1 = Show OK and Cancel buttons. 2 = Show Abort, Retry, and Ignore buttons. 3 = Show Yes, No, and Cancel buttons. 4 = Show Yes and No buttons. 5 = Show Retry and Cancel buttons. -------------------------------------- 16 = Show "Stop Mark" icon. 32 = Show "Question Mark" icon. 48 = Show "Exclamation Mark" icon. 64 = Show "Information Mark" icon. -------------------------------------- Possible return values: -------------------------------------- 1 = OK button 2 = Cancel button 3 = Abort button 4 = Retry button 5 = Ignore button 6 = Yes button 7 = No button -------------------------------------- */ function MsgBox(Msg, Title, Expire, Type) { var A = -1; if (typeof(WshShell) == "undefined") { ALERT(Msg); return -1; } if (typeof(Type) == "undefined") Type = 0; if (typeof(Title) == "undefined") Title = "Windows Script Host"; if (typeof(Expire) == "undefined") Expire = 0; try { A = WshShell.Popup(Msg, Expire, Title, Type); } catch (e) {} return A; } ////////////////////////////////////////////////// // 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) { if (BROWSER) return; 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) WAIT(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 // This function copies all text from the clipboard. // This is done by creating an Internet Explorer // document in the background that contains a form // and a textbox for input. After pasting whatever // is on the clipboard into the textarea, we can // reads its contents and return the string. // This takes about 200ms. // // Usage: STRING = ReadClipboardText() // function ReadClipboardText() { var MSIE = WScript.CreateObject("InternetExplorer.Application"); MSIE.Visible = 0; MSIE.ToolBar = 0; MSIE.StatusBar = 0; MSIE.FullScreen = 1; MSIE.Navigate("about:blank"); /* MSIE.RegisterAsDropTarget = 0; WScript.Sleep(100); MSIE.Width = 600; MSIE.Height = 400; MSIE.Left = (MSIE.document.parentWindow.screen.availWidth - MSIE.Width) / 2; MSIE.Top = (MSIE.document.parentWindow.screen.availHeight - MSIE.Height) / 2; */ var HTML = "