git.schokokeks.org
Repositories
Help
Report an Issue
fs-words.git
Code
Commits
Branches
Tags
Suche
Strukturansicht:
565e59b
Branches
Tags
develop-client_server
master
typescript
fs-words.git
client
lib
plankton
string
logic-impl.js
[upd] client:lib:plankton
Christian Fraß
commited
565e59b
at 2021-03-12 22:00:08
logic-impl.js
Blame
History
Raw
/* This file is part of »bacterio-plankton:string«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' <info@greenscale.de> »bacterio-plankton:string« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:string« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:string«. If not, see <http://www.gnu.org/licenses/>. */ var plain_text_to_html = function (text) { var ret = text; ret = ret.replace(/ /g, " "); // convert multiple whitespace to forced ones ret = ret.split("\n").join("<br/>"); return ret; }; /** * @desc makes a valid */ var format_sentence = function (str, rtl, caseSense) { if (rtl === void 0) { rtl = false; } if (caseSense === void 0) { caseSense = true; } if (str === "") { return str; } else { var marks = { ".": true, "?": true, "!": true }; var default_mark = "."; var ret = str.split(""); if (!rtl) { ret[0] = ret[0].toLocaleUpperCase(); if (!(ret[ret.length - 1] in marks)) { ret.push(default_mark); } } else { ret[ret.length - 1] = ret[ret.length - 1].toLocaleUpperCase(); if (!(ret[0] in marks)) { ret.unshift(default_mark); } } return ret.join(""); } }; var fill_string_template = function (template_string, object, fabric, delimiter, default_string, sloppy) { if (fabric === void 0) { fabric = function (object, key) { return object[key]; }; } if (delimiter === void 0) { delimiter = "%"; } if (default_string === void 0) { default_string = null; } function get_tags(str) { var r = new RegExp(delimiter + "[^\\s^" + delimiter + "]+" + delimiter, "gi"); return ((str.match(r) || []).map(function (e) { return e.slice(delimiter.length, e.length - delimiter.length); })); } function replace_tag(str, tag, value) { var r = new RegExp(delimiter + tag + delimiter, "gi"); return str.replace(r, value); } function replace_tags(str, obj) { return (get_tags(str).reduce(function (ret, key) { var value = ""; try { value = fabric(obj, key); if ((!sloppy && (value === void 0)) || (sloppy && (value == void 0))) { value = default_string; } } catch (e) { console.warn("invalid placeholder " + key); value = default_string; } return replace_tag(ret, key, value); }, str)); } return replace_tags(template_string, object); }; var make_string_template = function (_template, _fabrics) { if (_fabrics === void 0) { _fabrics = {}; } function replace_tag(str, tag, value) { var r = new RegExp("%" + tag + "%", "gi"); return str.replace(r, value); } function replace_tags(str, obj) { return (Object.keys(obj).reduce(function (ret, key) { return replace_tag(ret, key, _fabrics[key] || obj[key]); }, str)); } return (function (tags) { return replace_tags(_template, tags); }); }; var make_eml_header = (function () { var _template = ""; _template += "From: %from%\n"; _template += "To: %recipient%\n"; _template += "Subject: %subject%\n"; _template += "X-Mailer: greenscale-plankton.emlgen\n"; return make_string_template(_template); })(); var make_eml_body = (function () { var exports = {}; exports["simple_body"] = make_string_template("Content-Type: %contenttype%\n\n%body%\n\n"); // very basic implementation // parts = [{contenttype:"text/html; charset=UTF-8", body: "<h1>foo</h1>" }, {...}] exports["body_boundrary"] = function (parts, boundrary) { var _template = ""; _template += "--%boundrary%\n"; _template += "Content-Type: %contenttype%\n\n%body%\n\n"; //_template += "--%boundrary%--\n\n"; var maker = make_string_template(_template); return (parts.reduce(function (prev, curr) { curr.boundrary = boundrary; return [prev, maker(curr)].join(""); }, "")); }; // body must be base64 encoded! exports["attachment_boundrary"] = function (parts, boundrary) { var _template = ""; _template += "--%boundrary%\n"; _template += "Content-Type: %contenttype%\n"; _template += "Content-Transfer-Encoding: base64\n"; _template += "Content-Disposition: %disposition%; filename=\"%name%\"\n\n"; _template += "%body%\n\n"; //_template += "--%boundrary%--\n\n"; var maker = make_string_template(_template); return (parts.reduce(function (prev, curr) { curr.boundrary = boundrary; if (curr.disposition === void 0) curr.disposition = "inline"; return [prev, maker(curr)].join(""); }, "")); }; exports["gen_boundrary"] = function () { return ("xxxxxxxxxxxxxxxxxxxxxx".replace(/[xy]/g, function (c) { var r = crypto.getRandomValues(new Uint8Array(1))[0] % 16 | 0, v = c == "x" ? r : (r & 0x3 | 0x8); return v.toString(16); })); }; // simple implementation without alternatives (old rfc) exports["complete_boundrary"] = function (bodyparts, attachments) { var ret = ""; var boundrary = exports["gen_boundrary"](); ret += exports["body_boundrary"](bodyparts, boundrary); ret += exports["attachment_boundrary"](attachments, boundrary); ret += "--" + boundrary + "--\n\nINVISIBLE!!!!"; return (exports["simple_body"]({ "contenttype": sprintf("multipart/mixed; boundary=%s", [boundrary]), "body": ret })); }; return exports; })(); /* This file is part of »bacterio-plankton:string«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' <info@greenscale.de> »bacterio-plankton:string« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:string« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:string«. If not, see <http://www.gnu.org/licenses/>. */ var lib_string; (function (lib_string) { /** * @author fenris */ var hexdigits = 4; /** * @author fenris */ var index_max = (1 << (4 * hexdigits)); /** * @author fenris */ var index_is = 0; /** * @author neuc,frac */ function empty(str) { return (str.trim() === ""); } lib_string.empty = empty; /** * @desc returns a unique string * @param {string} prefix an optional prefix for the generated string * @return {string} * @author fenris */ function generate(prefix) { if (prefix === void 0) { prefix = "string_"; } if (index_is > index_max) { throw (new Error("[string_generate] out of valid indices")); } else { return lib_string.sprintf(prefix + "%0" + hexdigits.toString() + "X", [index_is++]); } } lib_string.generate = generate; /** * @desc splits a string, but returns an empty list, if the string is empty * @param {string} chain * @param {string} separator * @return {Array<string>} * @author fenris */ function split(chain, separator) { if (separator === void 0) { separator = " "; } if (chain.length == 0) { return []; } else { return chain.split(separator); } } lib_string.split = split; /** * @author neu3no */ function explode(str, needle, max) { var temp = str.split(needle); var right = temp.splice(max - 1); temp.push(right.join(needle)); return temp; } lib_string.explode = explode; /** * @desc concats a given word with itself n times * @param {string} word * @param {int} * @return {string} * @author fenris */ function repeat(word, count) { // return ((count == 0) ? "" : (word + repeat(word, count-1))); var result = ""; for (var n = 0; n < count; n += 1) { result += word; } return result; } lib_string.repeat = repeat; /** * @desc lengthens a string by repeatedly appending or prepending another string * @param {string} word the string to pad * @param {int} length the length, which the result shall have * @param {string} symbol the string, which will be added (multiple times) * @param {boolean} [prepend]; whether to prepend (~true) or append (~false); default: false * @return {string} the padded string * @author fenris */ function pad(word, length, symbol, mode) { if (symbol === void 0) { symbol = " "; } if (mode === void 0) { mode = "append"; } switch (mode) { case "prepend": { // insert symbols only at the beginning while (word.length < length) word = symbol + word; return word.substring(word.length - length); break; } case "append": { // insert symbols only at the end while (word.length < length) word = word + symbol; return word.substring(0, length); break; } case "widen": { // insert symbols at both sides var left = (((length - word.length) & 1) === 0); while (word.length < length) { word = (left ? (symbol + word) : (word + symbol)); left = (!left); } return word.substring(0, length); break; } default: { var message = ("unhandled mode '" + mode + "'"); console.warn(message); return word; break; } } } lib_string.pad = pad; /** * @desc checks if a given string conttains a certain substring * @param {string} string * @param {string} part * @return {boolean} * @author fenris */ function contains(chain, part) { if (typeof (chain) !== "string") { return false; } return (chain.indexOf(part) >= 0); } lib_string.contains = contains; /** * @desc checks if a given string starts with a certain substring * @param {string} string * @param {string} part * @return {boolean} * @author fenris */ function startsWith(chain, part) { if (typeof (chain) !== "string") { return false; } // return (string.indexOf(part) === 0); return ((function (m, n) { if (n === 0) { return true; } else { if (m === 0) { return false; } else { return ((chain[0] == part[0]) && startsWith(chain.substring(1), part.substring(1))); } } })(chain.length, part.length)); } lib_string.startsWith = startsWith; /** * @desc checks if a given string ends with a certain substring * @param {string} string * @param {string} part * @return {boolean} * @author fenris */ function endsWith(chain, part) { if (typeof (chain) !== "string") { return false; } // return (string.lastIndexOf(part) === string.length-part.length); return ((function (m, n) { if (n === 0) { return true; } else { if (m === 0) { return false; } else { // console.info(("(" + string[m-1] + " == " + part[n-1] + ")") + " = " + String(string[m-1] == part[n-1])); return ((chain[m - 1] === part[n - 1]) && endsWith(chain.substring(0, m - 1), part.substring(0, n - 1))); } } })(chain.length, part.length)); } lib_string.endsWith = endsWith; /** * @desc count the occourrences of a string in a string * @param string haystack_string the string wich should be examined * @param string needle_string the string which should be counted * @author neuc */ function count_occourrences(haystack_string, needle_string, check_escape) { var cnt = 0; var pos = -1; do { pos = haystack_string.indexOf(needle_string, pos + 1); if ((!check_escape) || (haystack_string[pos - 1] != "\\")) { cnt++; } } while (pos >= 0); return (cnt - 1); } lib_string.count_occourrences = count_occourrences; /** * @desc replaces occurences of "${name}" in a string by the corresponding values of an argument object * @author fenris */ function coin(str, args) { Object.keys(args).forEach(function (key) { // old syntax { var value = args[key]; var regexp_argument = new RegExp("\\${" + key + "}"); str = str.replace(regexp_argument, value); } // new syntax { var value = args[key]; var regexp_argument = new RegExp("{{" + key + "}}"); str = str.replace(regexp_argument, value); } }); return str; } lib_string.coin = coin; /** * @author fenris */ lib_string.stance = coin; /** * @author fenris */ function cut(str, length, delimiter) { if (delimiter === void 0) { delimiter = "…"; } if (str.length <= length) { return str; } else { return (str.slice(0, length - delimiter.length) + delimiter); } } lib_string.cut = cut; })(lib_string || (lib_string = {})); /* This file is part of »bacterio-plankton:string«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' <info@greenscale.de> »bacterio-plankton:string« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:string« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:string«. If not, see <http://www.gnu.org/licenses/>. */ var lib_string; (function (lib_string) { var pattern = /%([-+#0 ]*)([0-9]*)[\.]{0,1}([0-9]*)([\w]{1})/; var gpattern = /%([-+#0 ]*)([0-9]*)[\.]{0,1}([0-9]*)([\w]{1})/g; function split_format(format) { var tmp = format.match(pattern); if (tmp === null) return null; return { 'flags': tmp[1].split(""), 'width': Number(tmp[2]), 'precision': tmp[3] === '' ? null : Number(tmp[3]), 'specifier': tmp[4], 'string': format }; } function make_err(format, arg, should) { return ("[sprintf]" + " " + "argument for '" + format.string + "' has to be '" + should + "' but '" + arg + "' is '" + typeof arg + "'!"); } function test_arg(format, arg, should) { if (typeof arg !== should) { console.warn(make_err(format, arg, should)); return false; } return true; } function string_fill(str, char, len, left) { while (str.length < len) { if (left) { str += char; } else { str = char + str; } } return str; } /** * the known_parameters are used to parse the different identifiers for the welln known syntax: * flag width precision identifier * %{[0#+- ]}{[0-9]*}.{[0-9]*}[fFdiueEgGsoxXaAsn] * flags: * 0 - fill with '0' instead of ' ' if the string length < width * # - not implemented * - - left-justified -> fill on the right side to reach width * + - force using '+' on positive numbers * ' ' - add a single space before positive numbers * * identifiers * %f, %F - interpret given number as float, width: the minimal total width (fill with ' ' or '0' if the * resulting string is too short, precision: cut more then given decimal places * %d, %i, %u - interpret number as integer, decimal places will be cut. width: like float, precision: * fill with '0' on right side until length given in precision is reached * %e - interpret as float and write as scientifical number, width & precision like in float * %E - same es %e but uppercase 'E' * %g - use the shortest string of %f or %e * %G - use the shortest string of %E or %E * %s - simply print a string * %o - print the given number in octal notation * %x - print the given number in hex notation * %X - same as %x but with uppercase characters * %a - alias to %x * %A - alias to %X * %n - just print nothing * @type {{}} */ var known_params = {}; known_params["f"] = function (format, arg) { if (!test_arg(format, arg, "number")) return "Ø"; var tmp = Math.abs(arg); var sign = (arg < 0) ? -1 : 1; var tmp_result = null; if (format.precision !== null) { tmp = Math.floor(Math.pow(10, format.precision) * tmp) / Math.pow(10, format.precision); var tmp_ = (tmp * sign).toString().split("."); if (tmp_.length === 1) tmp_.push(""); tmp_[1] = string_fill(tmp_[1], "0", format.precision, true); tmp_result = tmp_.join("."); } else { tmp_result = (sign * tmp).toString(); } if ((format.flags.indexOf(" ") >= 0) && (arg >= 0)) { tmp_result = " " + tmp; } else if ((format.flags.indexOf("+") >= 0) && (arg >= 0)) { tmp_result = "+" + tmp; } tmp_result = string_fill(tmp, (format.flags.indexOf("0") >= 0) ? "0" : " ", format.width, (format.flags.indexOf("-") >= 0)); return tmp_result; }; known_params["F"] = known_params["f"]; known_params["d"] = function (format, arg) { if (!test_arg(format, arg, 'number')) return 'Ø'; var tmp = (((arg < 0 && format.specifier !== 'u') ? -1 : 1) * Math.floor(Math.abs(arg))).toString(); if ((format.specifier === 'd' || format.specifier === 'i') && format.flags.indexOf(' ') >= 0 && arg >= 0) { tmp = ' ' + tmp; } else if ((format.specifier === 'd' || format.specifier === 'i') && format.flags.indexOf('+') >= 0 && arg >= 0) { tmp = '+' + tmp; } tmp = string_fill(tmp, format.flags.indexOf('0') >= 0 ? '0' : ' ', format.width, format.flags.indexOf('-') >= 0); tmp = string_fill(tmp, '0', format.precision === null ? 0 : format.precision, false); return tmp; }; known_params["i"] = known_params["d"]; known_params["u"] = known_params["d"]; known_params["e"] = function (format, arg) { if (!test_arg(format, arg, 'number')) return 'Ø'; var tmp = arg.toExponential(format.precision === null ? undefined : format.precision).toString(); if (format.flags.indexOf(' ') >= 0 && arg >= 0) { tmp = ' ' + tmp; } else if (format.flags.indexOf('+') >= 0 && arg >= 0) { tmp = '+' + tmp; } tmp = string_fill(tmp, format.flags.indexOf('0') >= 0 ? '0' : ' ', format.width, format.flags.indexOf('-') >= 0); return tmp; }; known_params["E"] = function (format, arg) { return known_params["e"](format, arg).toUpperCase(); }; known_params["g"] = function (format, arg) { if (!test_arg(format, arg, 'number')) return 'Ø'; var tmpf = known_params["f"](format, arg); var tmpe = known_params["e"](format, arg); if (tmpf.length < tmpe.length) { return tmpf; } else { return tmpe; } }; known_params["G"] = function (format, arg) { return known_params["g"](format, arg).toUpperCase(); }; known_params["s"] = function (format, arg) { if (!test_arg(format, arg, 'string')) return 'o.O'; var tmp = format.precision !== null ? arg.substr(0, format.precision) : arg; tmp = string_fill(tmp, format.flags.indexOf('0') >= 0 ? '0' : ' ', format.width, format.flags.indexOf('-') >= 0); return tmp; }; known_params["o"] = function (format, arg) { if (!test_arg(format, arg, 'number')) return 'Ø'; var tmp = Math.floor(Math.round(Math.abs(arg))) * ((arg < 0) ? -1 : 1); return known_params["s"](format, tmp.toString(8)); }; known_params["x"] = function (format, arg) { if (!test_arg(format, arg, 'number')) return 'Ø'; var tmp = Math.floor(Math.round(Math.abs(arg))) * ((arg < 0) ? -1 : 1); return known_params["s"](format, tmp.toString(16)); }; known_params["a"] = known_params["x"]; known_params["X"] = function (format, arg) { if (!test_arg(format, arg, 'number')) return 'Ø'; return known_params["x"](format, arg).toUpperCase(); }; known_params["A"] = known_params["X"]; known_params["c"] = function (format, arg) { var tmp = ""; if (typeof arg === "number") { tmp = String.fromCharCode(arg); } else if ((typeof arg === "string") && (arg.length === 1)) { tmp = arg[0]; } else { console.warn(make_err(format, arg, "number|string") + " and if string it needs to have the length of 1!"); } return known_params["s"](format, tmp); }; known_params["n"] = function () { return ""; }; var decompose = function (chain, regexp) { var result = regexp.exec(chain); if (result == null) { return null; } else { var front = chain.substring(0, result.index); var back = chain.substring(result.index + result[0].length); return { "front": front, "match": result[0], "back": back }; } }; /** * an implementation of c sprintf * @param {string} string format string * @param {array} args arguments which should be filled into * @returns {string} */ lib_string.sprintf = function (input, args, original) { if (args === void 0) { args = []; } if (original === void 0) { original = null; } if (original == null) original = input; var components = decompose(input, pattern); if (components == null) { if (args.length > 0) { console.warn("[sprintf] superfluous arguments while formatting '" + original + "': ", args); } return input; } else { var arg; var rest; if (args.length > 0) { arg = args[0]; rest = args.slice(1); } else { console.warn("[sprintf] out of arguments while formatting '" + original + "'"); arg = null; rest = []; return input; } var fmt = split_format(components["match"]); return (components["front"] + known_params[fmt.specifier](fmt, arg) + lib_string.sprintf(components["back"], rest, original)); } }; /** * an implementation of c printf * @param {string} string format string * @param {array} args arguments which should be filled into * @returns {string} */ function printf(format, args) { console.log(lib_string.sprintf(format, args)); } lib_string.printf = printf; })(lib_string || (lib_string = {})); var sprintf = lib_string.sprintf; var printf = lib_string.printf; /* This file is part of »bacterio-plankton:string«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' <info@greenscale.de> »bacterio-plankton:string« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:string« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:string«. If not, see <http://www.gnu.org/licenses/>. */ var make_logger = (function () { var _loggers = {}; var make_logger = function (prefix, current_loglevel) { var log = []; var level = [ "LOG", "INFO", "WARNING", "DEBUG" ]; var logger = function (obj, lvl) { var txt = obj.txt || obj; if (lvl == void 0) lvl = 0; var date = new Date(); log.push({ "message": sprintf("%s [%s:%s] %s", [date.toString(), level[lvl], prefix, txt]), "timeStamp": +(date) }); if (lvl <= current_loglevel) { var msg = ["[" + prefix + "]", txt]; if (obj.arg) msg = ["[" + prefix + "]"].concat(Array.prototype.slice.call(obj.arg)); if (lvl === 0) console["_log"].apply(console, msg); else if (lvl === 1) console["_info"].apply(console, msg); else if (lvl === 2) console["_warn"].apply(console, msg); else if (lvl >= 3) console["_log"].apply(console, msg); } }; _loggers[prefix] = { "logger": logger, "log": log }; return logger; }; make_logger["loggers"] = _loggers; make_logger["complete_log"] = function () { var logs = Object.keys(_loggers) .reduce(function (p, c) { return [].concat(p, _loggers[c].log); }, []); logs.sort(function (x, y) { return ((x.timeStamp > y.timeStamp) ? -1 : +1); }); return logs.map(function (x, i, a) { return x.message; }); }; if ( /*!track_exports*/true) { var _log_all = function (log, lvl, next) { if (next === void 0) { next = function () { }; } return function () { var msg = []; for (var i = 0; i < arguments.length; i++) { if (typeof arguments[i] === "string") { msg.push(arguments[i]); } else { msg.push(JSON.stringify(arguments[i])); } } var obj = { txt: msg.join("\t"), arg: arguments }; log(obj, lvl); next(); }; }; { var __warn = make_logger("deprecated console.warn", 99); var __error = make_logger("deprecated console.error", 99); var __log = make_logger("deprecated console.log", 99); var __info = make_logger("deprecated console.info", 99); // bad ass console["_log"] = console.log; console["_error"] = console.error; console["_warn"] = console.warn; console["_info"] = console.info; /* console["log"] = _log_all(__log, 0); console["error"] = _log_all(__error, 2); console["warn"] = _log_all(__warn, 2); console["info"] = _log_all(__info, 0); */ } /* { make_logger["send_log"] = function(){ eml_log( function () { alert("fehlerbericht wurde gesendet!"); } ); }; var error_log = make_logger("global.error", 99); window.onerror = _log_all( error_log, 1, function(){ if (global_config == undefined) { return false; } if (global_config.report_error) { make_logger["send_log"](); } } ); } */ } return make_logger; })();