From 1812d5781aae3cc4686a8cb01dde47676e5aa28d Mon Sep 17 00:00:00 2001 From: Fenris Wolf Date: Thu, 8 Feb 2024 16:57:40 +0100 Subject: [PATCH] [upd] plankton --- lib/plankton/plankton.d.ts | 239 ++++++++ lib/plankton/plankton.js | 1056 ++++++++++++++++++++++++++++++++++++ tools/update-plankton | 2 + 3 files changed, 1297 insertions(+) diff --git a/lib/plankton/plankton.d.ts b/lib/plankton/plankton.d.ts index f856bdc..9857f91 100644 --- a/lib/plankton/plankton.d.ts +++ b/lib/plankton/plankton.d.ts @@ -1350,3 +1350,242 @@ declare namespace lib_plankton.args { }): string; } } +declare var plain_text_to_html: (text: string) => string; +/** + * @desc makes a valid + */ +declare var format_sentence: (str: string, rtl?: boolean, caseSense?: boolean) => string; +declare var fill_string_template: (template_string: string, object: any, fabric: Function, delimiter: string, default_string: string, sloppy: boolean) => string; +declare var make_string_template: (_template: string, _fabrics?: Object) => (object: { + [key: string]: string; +}) => string; +declare var make_eml_header: (object: { + [key: string]: string; +}) => string; +declare var make_eml_body: Object; +declare namespace lib_plankton.string { + /** + * @author neuc,frac + */ + function empty(str: string): boolean; + /** + * @desc returns a unique string + * @param {string} prefix an optional prefix for the generated string + * @return {string} + * @author fenris + */ + function generate(prefix?: string): string; + /** + * @author fenris + */ + function join(parts: Array, glue?: string): string; + /** + * @desc splits a string, but returns an empty list, if the string is empty + * @param {string} chain + * @param {string} separator + * @return {Array} + * @author fenris + */ + function split(chain: string, separator?: string): Array; + /** + * @author neu3no + */ + function explode(str: string, needle: string, max: int): Array; + /** + * @desc concats a given word with itself n times + * @param {string} word + * @param {int} + * @return {string} + * @author fenris + */ + function repeat(word: string, count: int): string; + /** + * @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: string, length: int, symbol?: string, mode?: string): string; + /** + * @desc checks if a given string conttains a certain substring + * @param {string} string + * @param {string} part + * @return {boolean} + * @author fenris + */ + function contains(chain: string, part: string): boolean; + /** + * @desc checks if a given string starts with a certain substring + * @param {string} string + * @param {string} part + * @return {boolean} + * @author fenris + */ + function startsWith(chain: string, part: string): boolean; + /** + * @desc checks if a given string ends with a certain substring + * @param {string} string + * @param {string} part + * @return {boolean} + * @author fenris + */ + function endsWith(chain: string, part: string): boolean; + /** + * @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: string, needle_string: string, check_escape: boolean): int; + /** + * @author fenris + */ + function replace(str: string, replacements: Array<{ + from: string; + to: string; + }>, options?: {}): string; + /** + * @desc replaces occurences of "{{name}}" in a string by the corresponding values of an argument object + * @author fenris + */ + function coin(str: string, args: { + [id: string]: string; + }, options?: { + legacy?: boolean; + open?: string; + close?: string; + }): string; + /** + * @author fenris + * @deprecated use limit + */ + function cut(str: string, length: int, delimiter?: string): string; + /** + */ + function limit(str: string, options?: { + length?: int; + indicator?: string; + }): string; + /** + */ + function slice(str: string, size: int): Array; +} +/** + * @deprecated + */ +declare namespace lib_string { + const empty: typeof lib_plankton.string.empty; + const generate: typeof lib_plankton.string.generate; + const split: typeof lib_plankton.string.split; + const explode: typeof lib_plankton.string.repeat; + const repeat: typeof lib_plankton.string.repeat; + const pad: typeof lib_plankton.string.pad; + const contains: typeof lib_plankton.string.contains; + const startsWith: typeof lib_plankton.string.startsWith; + const endsWith: typeof lib_plankton.string.endsWith; + const count_occourrences: typeof lib_plankton.string.count_occourrences; + const coin: typeof lib_plankton.string.coin; + const stance: typeof lib_plankton.string.coin; + const cut: typeof lib_plankton.string.cut; +} +declare namespace lib_plankton.string { + /** + * an implementation of c sprintf + * @param {string} string format string + * @param {array} args arguments which should be filled into + * @returns {string} + */ + var sprintf: (input: string, args?: Array, original?: any) => string; + /** + * an implementation of c printf + * @param {string} string format string + * @param {array} args arguments which should be filled into + * @returns {string} + */ + function printf(format: any, args: any): void; +} +declare var sprintf: (input: string, args?: Array, original?: any) => string; +declare var printf: typeof lib_plankton.string.printf; +declare var eml_log: any; +declare var track_exports: any; +declare var make_logger: (prefix: any, current_loglevel: any) => (obj: any, lvl: any) => void; +/** + * @author fenris + */ +declare namespace lib_plankton.xml { + /** + * @author fenris + */ + abstract class class_node { + /** + * @author fenris + */ + abstract compile(depth?: int): string; + } + /** + * @author fenris + */ + class class_node_text extends class_node { + /** + * @author fenris + */ + protected content: string; + /** + * @author fenris + */ + constructor(content: string); + /** + * @author fenris + */ + compile(depth?: int): string; + } + /** + * @author fenris + */ + class class_node_comment extends class_node { + /** + * @author fenris + */ + protected content: string; + /** + * @author fenris + */ + constructor(content: string); + /** + * @author fenris + */ + compile(depth?: int): string; + } + /** + * @author fenris + */ + class class_node_complex extends class_node { + /** + * @author fenris + */ + protected name: string; + /** + * @author fenris + */ + protected attributes: { + [key: string]: string; + }; + /** + * @author fenris + */ + protected children: Array; + /** + * @author fenris + */ + constructor(name: string, attributes?: { + [key: string]: string; + }, children?: any[]); + /** + * @author fenris + */ + compile(depth?: int): string; + } +} diff --git a/lib/plankton/plankton.js b/lib/plankton/plankton.js index bdf56cf..05d0204 100644 --- a/lib/plankton/plankton.js +++ b/lib/plankton/plankton.js @@ -3776,3 +3776,1059 @@ var lib_plankton; args.class_handler = class_handler; })(args = lib_plankton.args || (lib_plankton.args = {})); })(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:string«. + +Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 . + */ +var plain_text_to_html = function (text) { + let ret = text; + ret = ret.replace(/ /g, "  "); // convert multiple whitespace to forced ones + ret = ret.split("\n").join("
"); + return ret; +}; +/** + * @desc makes a valid + */ +var format_sentence = function (str, rtl = false, caseSense = true) { + if (str === "") { + return str; + } + else { + let marks = { + ".": true, + "?": true, + "!": true + }; + let default_mark = "."; + let 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 = function (object, key) { return object[key]; }, delimiter = "%", default_string = null, sloppy) { + function get_tags(str) { + let 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) { + let 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) { + let 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 = {}) { + 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 () { + let _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 () { + let 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: "

foo

" }, {...}] + exports["body_boundrary"] = function (parts, boundrary) { + let _template = ""; + _template += "--%boundrary%\n"; + _template += "Content-Type: %contenttype%\n\n%body%\n\n"; + //_template += "--%boundrary%--\n\n"; + let 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) { + let _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"; + let 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) { + let 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) { + let ret = ""; + let 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-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 . + */ +var lib_plankton; +(function (lib_plankton) { + var string; + (function (string) { + /** + * @author fenris + */ + const hexdigits = 4; + /** + * @author fenris + */ + const index_max = (1 << (4 * hexdigits)); + /** + * @author fenris + */ + var index_is = 0; + /** + * @author neuc,frac + */ + function empty(str) { + return (str.trim() === ""); + } + 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 = "string_") { + if (index_is > index_max) { + throw (new Error("[string_generate] out of valid indices")); + } + else { + return string.sprintf(prefix + "%0" + hexdigits.toString() + "X", [index_is++]); + } + } + string.generate = generate; + /** + * @author fenris + */ + function join(parts, glue = " ") { + if (parts.length == 0) { + return ""; + } + else { + return parts.join(glue); + } + } + string.join = join; + /** + * @desc splits a string, but returns an empty list, if the string is empty + * @param {string} chain + * @param {string} separator + * @return {Array} + * @author fenris + */ + function split(chain, separator = " ") { + if (chain.length == 0) { + return []; + } + else { + return chain.split(separator); + } + } + string.split = split; + /** + * @author neu3no + */ + function explode(str, needle, max) { + let temp = str.split(needle); + const right = temp.splice(max - 1); + temp.push(right.join(needle)); + return temp; + } + 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))); + let result = ""; + for (let n = 0; n < count; n += 1) { + result += word; + } + return result; + } + 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 = "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 + let 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: { + const message = ("unhandled mode '" + mode + "'"); + console.warn(message); + return word; + break; + } + } + } + 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); + } + 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)); + } + 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)); + } + 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) { + let cnt = 0; + let 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); + } + string.count_occourrences = count_occourrences; + /** + * @author fenris + */ + function replace(str, replacements, options = {}) { + options = Object.assign({}, options); + let result = str; + replacements.forEach(replacement => { + lib_plankton.log.debug("lib_plankton.string.replace", { + "from": replacement.from, + "to": replacement.to, + }); + result = result.replace(new RegExp(replacement.from, "g"), replacement.to); + }); + return result; + } + string.replace = replace; + /** + * @desc replaces occurences of "{{name}}" in a string by the corresponding values of an argument object + * @author fenris + */ + function coin(str, args, options = {}) { + options = Object.assign({ + "legacy": false, + "open": "{{", + "close": "}}", + }, options); + Object.keys(args).forEach((key) => { + // old syntax + { + if (options.legacy) { + const value = args[key]; + const regexp_argument = new RegExp("\\${" + key + "}", "g"); + lib_plankton.log.debug("lib_plankton.string.coin", { + "key": key, + "regex": regexp_argument.toString(), + "value": value, + }); + str = str.replace(regexp_argument, value); + } + } + // new syntax + { + const value = args[key]; + const regexp_argument = new RegExp(options.open + key + options.close, "g"); + lib_plankton.log.debug("lib_plankton.string.coin", { + "key": key, + "regex": regexp_argument.toString(), + "value": value, + }); + str = str.replace(regexp_argument, value); + } + }); + return str; + } + string.coin = coin; + /** + * @author fenris + * @deprecated use limit + */ + function cut(str, length, delimiter = "…") { + if (str.length <= length) { + return str; + } + else { + return (str.slice(0, length - delimiter.length) + delimiter); + } + } + string.cut = cut; + /** + */ + function limit(str, options = {}) { + options = Object.assign({ + "length": 120, + "indicator": "…", + }, options); + return ((str.length <= options.length) + ? str + : (str.slice(0, options.length - options.indicator.length) + options.indicator)); + } + string.limit = limit; + /** + */ + function slice(str, size) { + let slices = []; + let rest = str; + while (rest.length > 0) { + slices.push(rest.slice(0, size)); + rest = rest.slice(size); + } + return slices; + } + string.slice = slice; + })(string = lib_plankton.string || (lib_plankton.string = {})); +})(lib_plankton || (lib_plankton = {})); +/** + * @deprecated + */ +var lib_string; +(function (lib_string) { + lib_string.empty = lib_plankton.string.empty; + lib_string.generate = lib_plankton.string.generate; + lib_string.split = lib_plankton.string.split; + lib_string.explode = lib_plankton.string.repeat; + lib_string.repeat = lib_plankton.string.repeat; + lib_string.pad = lib_plankton.string.pad; + lib_string.contains = lib_plankton.string.contains; + lib_string.startsWith = lib_plankton.string.startsWith; + lib_string.endsWith = lib_plankton.string.endsWith; + lib_string.count_occourrences = lib_plankton.string.count_occourrences; + lib_string.coin = lib_plankton.string.coin; + lib_string.stance = lib_plankton.string.coin; + lib_string.cut = lib_plankton.string.cut; +})(lib_string || (lib_string = {})); +/* +This file is part of »bacterio-plankton:string«. + +Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 . + */ +var lib_plankton; +(function (lib_plankton) { + var string; + (function (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} + */ + string.sprintf = function (input, args = [], 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) + + 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(string.sprintf(format, args)); + } + string.printf = printf; + })(string = lib_plankton.string || (lib_plankton.string = {})); +})(lib_plankton || (lib_plankton = {})); +var sprintf = lib_plankton.string.sprintf; +var printf = lib_plankton.string.printf; +/* +This file is part of »bacterio-plankton:string«. + +Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 . + */ +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 = 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; +})(); +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +/* +This file is part of »bacterio-plankton:xml«. + +Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:xml« 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:xml« 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:xml«. If not, see . + */ +/** + * @author fenris + */ +var lib_plankton; +(function (lib_plankton) { + var xml; + (function (xml) { + /** + * @author fenris + */ + function string_repeat(symbol, count) { + return ((count <= 0) ? "" : (string_repeat(symbol, count - 1) + symbol)); + } + /** + * @author fenris + */ + var class_node = /** @class */ (function () { + function class_node() { + } + return class_node; + }()); + xml.class_node = class_node; + /** + * @author fenris + */ + var class_node_text = /** @class */ (function (_super) { + __extends(class_node_text, _super); + /** + * @author fenris + */ + function class_node_text(content) { + var _this = _super.call(this) || this; + _this.content = content; + return _this; + } + /** + * @author fenris + */ + class_node_text.prototype.compile = function (depth) { + if (depth === void 0) { depth = 0; } + return (string_repeat("\t", depth) + this.content + "\n"); + }; + return class_node_text; + }(class_node)); + xml.class_node_text = class_node_text; + /** + * @author fenris + */ + var class_node_comment = /** @class */ (function (_super) { + __extends(class_node_comment, _super); + /** + * @author fenris + */ + function class_node_comment(content) { + var _this = _super.call(this) || this; + _this.content = content; + return _this; + } + /** + * @author fenris + */ + class_node_comment.prototype.compile = function (depth) { + if (depth === void 0) { depth = 0; } + return (string_repeat("\t", depth) + "" + "\n"); + }; + return class_node_comment; + }(class_node)); + xml.class_node_comment = class_node_comment; + /** + * @author fenris + */ + var class_node_complex = /** @class */ (function (_super) { + __extends(class_node_complex, _super); + /** + * @author fenris + */ + function class_node_complex(name, attributes, children) { + if (attributes === void 0) { attributes = {}; } + if (children === void 0) { children = []; } + var _this = _super.call(this) || this; + _this.name = name; + _this.attributes = attributes; + _this.children = children; + return _this; + } + /** + * @author fenris + */ + class_node_complex.prototype.compile = function (depth) { + var _this = this; + if (depth === void 0) { depth = 0; } + var output = ""; + var attributes = (Object.keys(this.attributes) + .filter(function (key) { return (_this.attributes[key] !== null); }) + .map(function (key) { return (" " + key + "=" + ("\"" + _this.attributes[key] + "\"")); }) + .join("")); + output += (string_repeat("\t", depth) + "<" + this.name + attributes + ">" + "\n"); + this.children.forEach(function (child) { return (output += child.compile(depth + 1)); }); + output += (string_repeat("\t", depth) + "" + "\n"); + return output; + }; + return class_node_complex; + }(class_node)); + xml.class_node_complex = class_node_complex; + })(xml = lib_plankton.xml || (lib_plankton.xml = {})); +})(lib_plankton || (lib_plankton = {})); diff --git a/tools/update-plankton b/tools/update-plankton index 2934da0..169a714 100755 --- a/tools/update-plankton +++ b/tools/update-plankton @@ -13,6 +13,8 @@ modules="${modules} call" modules="${modules} json" modules="${modules} file" modules="${modules} args" +modules="${modules} string" +modules="${modules} xml" ## exec