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:base«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base« 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:base« 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:base«. If not, see . */ // } /* This file is part of »bacterio-plankton:base«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base« 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:base« 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:base«. If not, see . */ ; /* declare class console { static log(...args : any[]) : void; static info(...args : any[]) : void; static warn(...args : any[]) : void; static error(...args : any[]) : void; }; */ var lib_plankton; (function (lib_plankton) { var base; (function (base) { /** * @author fenris */ function environment() { return "web"; } base.environment = environment; })(base = lib_plankton.base || (lib_plankton.base = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:base«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base« 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:base« 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:base«. If not, see . */ /** * @author fenris */ /*export*/ function pseudopointer_null() { return { "value": null }; } /** * @author fenris */ /*export*/ function pseudopointer_make(value) { return { "value": value }; } /** * @author fenris */ /*export*/ function pseudopointer_isset(pseudopointer) { return (pseudopointer.value != null); } /** * @author fenris */ /*export*/ function pseudopointer_read(pseudopointer) { if (pseudopointer.value != null) { return pseudopointer.value; } else { var message = "nullpointer dereferencation"; throw (new Error(message)); } } /** * @author fenris */ /*export*/ function pseudopointer_write(pseudopointer, value) { pseudopointer.value = value; } /* This file is part of »bacterio-plankton:base«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base« 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:base« 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:base«. If not, see . */ /** * @author fenris */ var instance_verbosity = 0; /** * @author fenris */ function instance_collate(value1, value2) { if (typeof (value1) === "object") { if (value1 == null) { return (value2 == null); } else { if ("_collate" in value1) { return value1["_collate"](value2); } else { throw (new Error("[collate]" + " " + "object has no such method")); } } } else { if (instance_verbosity >= 1) { // lib_plankton.log.warn("[collate]" + " " + "primitive value; using default implementation"); } return (value1 === value2); } } /** * @author fenris */ function instance_compare(value1, value2) { if (typeof (value1) === "object") { if ("_compare" in value1) { return value1["_compare"](value2); } else { throw (new Error("[compare]" + " " + "object has no such method")); } } else { if (instance_verbosity >= 1) { // lib_plankton.log.warn("[compare]" + " " + "primitive value; using default implementation"); } return (value1 <= value2); } } /** * @author fenris */ function instance_clone(value) { if (typeof (value) === "object") { if ("_clone" in value) { return value["_clone"](); } else { throw (new Error("[clone]" + " " + "object has no such method")); } } else { if (instance_verbosity >= 1) { // lib_plankton.log.warn("[clone]" + " " + "primitive value; using default implementation"); } return value; } } /** * @desc the ability to generate a string out of the element, which identifies it to a high degree * @author fenris */ function instance_hash(value) { if (typeof (value) === "object") { if ("_hash" in value) { return value["_hash"](); } else { throw (new Error("[hash]" + " " + "object has no such method")); } } else { if (instance_verbosity >= 1) { // lib_plankton.log.warn("[hash]" + " " + "primitive value; using default implementation"); } return String(value); } } /** * @desc the ability to map the element to a textual representation (most likely not injective) * @author fenris */ function instance_show(value) { if (typeof (value) === "object") { if (value == null) { return "NULL"; } else { if ("_show" in value) { return value["_show"](); } else { // throw (new Error("[show]" + " " + "object has no such method")); return JSON.stringify(value); } } } else { if (instance_verbosity >= 1) { // lib_plankton.log.warn("[show]" + " " + "primitive value; using default implementation"); } return String(value); } } /* This file is part of »bacterio-plankton:base«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base« 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:base« 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:base«. If not, see . */ /** * @author frac */ var class_observer = /** @class */ (function () { /** * @author frac */ function class_observer() { this.counter = 0; this.actions = {}; this.buffer = []; } /** * @author frac */ class_observer.prototype.empty = function () { return (Object.keys(this.actions).length == 0); }; /** * @author frac */ class_observer.prototype.flush = function () { this.actions = {}; }; /** * @author frac */ class_observer.prototype.set = function (id, action) { this.actions[id] = action; }; /** * @author frac */ class_observer.prototype.del = function (id) { delete this.actions[id]; }; /** * @author frac */ class_observer.prototype.add = function (action) { this.set((this.counter++).toString(), action); }; /** * @author frac */ class_observer.prototype.notify = function (information, delayed) { var _this = this; if (information === void 0) { information = {}; } if (delayed === void 0) { delayed = false; } if (delayed) { this.buffer.push(information); } else { Object.keys(this.actions).forEach(function (id) { return _this.actions[id](information); }); } }; /** * @author frac */ class_observer.prototype.rollout = function () { var _this = this; this.buffer.forEach(function (information) { return _this.notify(information, false); }); this.buffer = []; }; return class_observer; }()); /** * @author frac */ /* export interface interface_readable { |** * @author frac *| read() : type_executor; } */ /** * @author frac */ /* export interface interface_writeable { |** * @author frac *| write(value : type_value) : type_executor; } */ /* This file is part of »bacterio-plankton:base«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base« 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:base« 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:base«. If not, see . */ /** * @author frac */ var class_error = /** @class */ (function (_super) { __extends(class_error, _super); /** * @author frac */ function class_error(message, suberrors) { if (suberrors === void 0) { suberrors = []; } var _this = _super.call(this, message) || this; _this.suberrors = suberrors; _this.mess = message; return _this; } /** * @override * @author frac */ class_error.prototype.toString = function () { return ( /*super.toString()*/this.mess + " " + ("[" + this.suberrors.map(function (x) { return x.toString(); }).join(",") + "]")); }; return class_error; }(Error)); var lib_plankton; (function (lib_plankton) { var base; (function (base) { /** * returns the current UNIX timestamp * * @author fenris */ function get_current_timestamp(rounded) { if (rounded === void 0) { rounded = false; } var x = (Date.now() / 1000); return (rounded ? Math.round(x) : x); ; } base.get_current_timestamp = get_current_timestamp; /** */ function object_merge(core, mantle) { return Object.assign(core, mantle); } base.object_merge = object_merge; })(base = lib_plankton.base || (lib_plankton.base = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:pod«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:pod« 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:pod« 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:pod«. If not, see . */ var lib_plankton; (function (lib_plankton) { var pod; (function (pod_1) { /** * @author fenris */ function make_empty() { return { "kind": "empty" }; } pod_1.make_empty = make_empty; /** * @author fenris */ function make_filled(value) { return { "kind": "filled", "value": value }; } pod_1.make_filled = make_filled; /** * whether the pod is filled * * @author fenris */ function is_filled(pod) { return (pod.kind === "filled"); } pod_1.is_filled = is_filled; /** * return the value, stored in the pod-wrapper * * @author fenris */ function cull(pod) { if (!is_filled(pod)) { throw (new Error("cull from empty")); } else { return pod.value; } } pod_1.cull = cull; /** * to pass on a empty-pod or to use a filled-pod * * @author fenris */ function propagate(pod, function_) { if (!is_filled(pod)) { return make_empty(); } else { return make_filled(function_(pod.value)); } } pod_1.propagate = propagate; /** * @author fenris */ function distinguish(pod, function_empty, function_filled) { return ((!is_filled(pod)) ? function_empty() : function_filled(pod.value)); } pod_1.distinguish = distinguish; /** */ function show(pod, options = {}) { options = Object.assign({ "show_value": value => String(value), }, options); if (!is_filled(pod)) { return "<·>"; } else { return ("<- " + options.show_value(pod.value) + " ->"); } } pod_1.show = show; })(pod = lib_plankton.pod || (lib_plankton.pod = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:pod«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:pod« 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:pod« 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:pod«. If not, see . */ var lib_plankton; (function (lib_plankton) { var pod; (function (pod) { /** */ class class_pod { constructor(subject) { this.subject = subject; } is_empty() { return (!pod.is_filled(this.subject)); } is_filled() { return pod.is_filled(this.subject); } cull() { return pod.cull(this.subject); } show(show_value = undefined) { return pod.show(this.subject, show_value); } toString() { return this.show(); } propagate(function_) { return new class_pod(pod.propagate(this.subject, function_)); } distinguish(function_empty, function_filled) { return pod.distinguish(this.subject, function_empty, function_filled); } } pod.class_pod = class_pod; })(pod = lib_plankton.pod || (lib_plankton.pod = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:call«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:call« 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:call« 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:call«. If not, see . */ /** * might be completely obsolete */ var lib_plankton; (function (lib_plankton) { var call; (function (call) { /** * @author fenris */ function promise_reject(reason) { return Promise.reject(reason); } call.promise_reject = promise_reject; /** * @author fenris */ function promise_resolve(result) { return Promise.resolve(result); } call.promise_resolve = promise_resolve; /** * @author fenris */ function promise_make(executor) { return (new Promise(executor)); } call.promise_make = promise_make; /** * @author fenris */ function promise_then_close(promise, resolver, rejector) { promise.then(resolver, rejector); } call.promise_then_close = promise_then_close; /** * @author fenris */ function promise_then_append(promise, resolver, rejector = null) { if (rejector == null) { rejector = (reason) => promise_reject(reason); } return (promise.then(resolver, rejector)); } call.promise_then_append = promise_then_append; /** * @author fenris */ function promise_all(promises) { return Promise.all(promises); } call.promise_all = promise_all; /** * @author fenris */ function promise_chain(promises, start = undefined) { return (promises.reduce((chain, promise) => promise_then_append(chain, promise), promise_resolve(start))); } call.promise_chain = promise_chain; /** * @author fenris */ function promise_condense(promises) { return (promise_chain(promises.map(promise => result => promise_then_append(promise(), element => promise_resolve(result.concat([element])))), [])); } call.promise_condense = promise_condense; /** * @author fenris */ function promise_group(promises, options = { "serial": false, }) { const decorate = function (promise, name) { return (() => promise_then_append(promise(), value => promise_resolve({ "key": name, "value": value }))); }; if (options.serial) { return (promise_then_append(promise_condense(Object.keys(promises) .map(name => decorate(promises[name], name))), list => promise_resolve(Object.fromEntries(list.map(({ "key": key, "value": value }) => ([key, value])))))); } else { return (promise_then_append(promise_all(Object.keys(promises) .map(name => decorate(promises[name], name)) .map(promise => promise())), list => promise_resolve(Object.fromEntries(list.map(({ "key": key, "value": value }) => ([key, value])))))); } } call.promise_group = promise_group; /** * @author fenris */ function promise_wrap(promise, transformator_result, transformator_reason = lib_plankton.call.id) { return (promise_make((resolve, reject) => { promise_then_close(promise, result => resolve(transformator_result(result)), reason => reject(transformator_reason(reason))); })); } call.promise_wrap = promise_wrap; /** * @author fenris */ /* export function promise_show(label : string) : (result : type_result)=>type_promise { return ( result => promise_make( (resolve, reject) => { // lib_plankton.log.info(label + ": " + instance_show(result)); process.stdout.write(label + ": " + instance_show(result)); resolve(result); } ) ); } */ /** * @author fenris */ /* export function promise_log(result : type_result) : (result : type_result)=>type_promise { return promise_show("log"); } */ /** * @author fenris */ function promise_attach(state, promise, name) { return (promise_wrap(promise, result => { state[name] = result; return state; })); } call.promise_attach = promise_attach; /** * @author fenris */ function promise_delay(promise, delay) { return promise_make((resolve, reject) => { call.timeout(() => { promise_then_close(promise, resolve, reject); return null; }, delay); }); } call.promise_delay = promise_delay; })(call = lib_plankton.call || (lib_plankton.call = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:call«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:call« 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:call« 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:call«. If not, see . */ var lib_plankton; (function (lib_plankton) { var call; (function (call) { /** */ class CancellablePromise extends Promise { /** */ constructor(executor) { super((resolve, reject) => { }); this.subject = (new Promise((resolve, reject) => { Promise.race([ new Promise(executor), new Promise((resolve_, reject_) => { this.interval = setInterval(() => { if (!this.cancelled) { // do nothing } else { reject_(new Error("cancelled")); this.clear(); } }, 0); }), ]) .then(resolve, reject); })); this.cancelled = false; this.interval = null; } /** */ clear() { if (this.interval === null) { // do nothing } else { clearInterval(this.interval); this.interval = null; } } /** */ then(onfulfilled, onrejected) { this.clear(); return this.subject.then(onfulfilled, onrejected); } /** */ catch(x) { this.clear(); return this.subject.catch(x); } /** */ cancel() { this.cancelled = true; this.clear(); } } call.CancellablePromise = CancellablePromise; })(call = lib_plankton.call || (lib_plankton.call = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:call«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:call« 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:call« 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:call«. If not, see . */ /** * initializer might be obsolete, since promises are reusable after having been resolved or rejected */ var lib_plankton; (function (lib_plankton) { var call; (function (call) { /** * @author fenris */ let enum_initializer_state; (function (enum_initializer_state) { enum_initializer_state[enum_initializer_state["initial"] = 0] = "initial"; enum_initializer_state[enum_initializer_state["waiting"] = 1] = "waiting"; enum_initializer_state[enum_initializer_state["successful"] = 2] = "successful"; enum_initializer_state[enum_initializer_state["failed"] = 3] = "failed"; })(enum_initializer_state = call.enum_initializer_state || (call.enum_initializer_state = {})); /** * @author fenris */ function initializer_make(fetcher) { let subject = { "fetcher": fetcher, "state": enum_initializer_state.initial, "queue": [], "result": undefined, "reason": undefined, }; return subject; } call.initializer_make = initializer_make; /** * @author fenris */ function initializer_actuate(subject) { switch (subject.state) { case enum_initializer_state.successful: { subject.queue.forEach(entry => entry.resolve(subject.result)); break; } case enum_initializer_state.failed: { subject.queue.forEach(entry => entry.reject(subject.reason)); break; } default: { throw (new Error(`unhandled state ${subject.state}`)); break; } } } /** * @author fenris */ function initializer_reset(subject) { subject.state = enum_initializer_state.initial; subject.queue = []; } call.initializer_reset = initializer_reset; /** * @author fenris */ function initializer_state(subject) { return subject.state; } call.initializer_state = initializer_state; /** * @author fenris */ function initializer_get(subject) { switch (subject.state) { case enum_initializer_state.initial: { subject.state = enum_initializer_state.waiting; return (call.promise_make((resolve, reject) => { subject.queue.push({ "resolve": resolve, "reject": reject }); subject.fetcher().then(result => { subject.state = enum_initializer_state.successful; subject.result = result; initializer_actuate(subject); }, reason => { subject.state = enum_initializer_state.failed; subject.reason = reason; initializer_actuate(subject); }); })); break; } case enum_initializer_state.waiting: { return (call.promise_make((resolve, reject) => { subject.queue.push({ "resolve": resolve, "reject": reject }); })); break; } case enum_initializer_state.successful: { return (call.promise_resolve(subject.result)); break; } case enum_initializer_state.failed: { return (call.promise_reject(subject.reason)); break; } default: { throw (new Error(`unhandled state ${subject.state}`)); break; } } } call.initializer_get = initializer_get; /** * @author fenris */ function initializer_get_sync(subject) { switch (subject.state) { case enum_initializer_state.successful: { return subject.result; break; } case enum_initializer_state.failed: { throw subject.reason; break; } default: { throw (new Error(`unhandled state ${subject.state}`)); break; } } } /** * @author fenris */ function initializer_set_sync(subject, result) { switch (subject.state) { case enum_initializer_state.successful: { subject.result = result; break; } case enum_initializer_state.failed: { subject.state = enum_initializer_state.successful; subject.result = result; break; } default: { throw (new Error(`unhandled state ${subject.state}`)); break; } } } })(call = lib_plankton.call || (lib_plankton.call = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:call«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:call« 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:call« 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:call«. If not, see . */ var lib_plankton; (function (lib_plankton) { var call; (function (call) { /* The core idea of this library is to provide means for asynchronous program flow. The old-school way to do is, is to use callbacks. While this approach is simple and easy to understand, it has some disadvantages. As an attempt to relief and improve this, the promise-system was introduced. In principle it solves most of the problems found in the callback-approach; however it has some downsides as well: - Convolution of multiple principles Promises unite the ideas of asynchronous program flow and error handling. - Instant execution Creating a promise results in the instant execution of the given executor prodecure. While this might be convenient in some cases, it can be quite disturbing and counter-intuitive in others. - Broken typing The Promise system doesn't distinguish between an appending "then" (i.e. passing a function, which returns a new promise) and a closing "then" (i.e. passing a function, which has no return value). On top of that it allows returning simple values in an appending "then", which results in an implicit call of the executors "resolve"-function. The price for these "pragmatic" features is that the whole system can't be typed well. And even though JavaScript is not a strictly typed language, it was a quite questionable decision to design the promise system in a way, which breaks typing from the start. The deferral-system forseeks to solve these issues while retaining the advantages of the promise-system. */ /** * @author fenris * @desc activates the deferral and handles its output according to a given procedure * @param {(value : type_value)=>void} procedure a function which receives the output of the deferral as argument */ function deferral_use(deferral, input, procedure) { deferral.representation(input).then(value => { procedure(value); }, reason => { throw reason; }); } call.deferral_use = deferral_use; /** * @author fenris * @desc creates a deferral-subject (similar to "new Promise", where "convey" reflects "resolve"/"reject") */ function deferral_make(handler) { return ({ "representation": ((input) => (new Promise((resolve, reject) => { handler(input, resolve); }))) }); } call.deferral_make = deferral_make; /** * @author fenris * @desc wraps a simple function into a deferral (similar to "Promise.resolve"/"Promise.reject") */ function deferral_wrap(function_) { return (deferral_make((input, convey) => convey(function_(input)))); } call.deferral_wrap = deferral_wrap; /** * @author fenris */ function deferral_id() { return (deferral_make((input, convey) => convey(input))); } call.deferral_id = deferral_id; /** * @author fenris */ function deferral_const(value) { return (deferral_make((input, convey) => convey(value))); } call.deferral_const = deferral_const; /** * @author fenris */ function deferral_delay(output, delay) { return (deferral_make((input, convey) => { setTimeout(() => convey(output), delay); })); } call.deferral_delay = deferral_delay; /** * @author fenris * @desc connects two deferrals to form a new one; the output of the first is taken as input for the second * (similar to "Promise.then" when passing a function which returns a new promise) * @param {type_deferral} first a simple deferral * @param {(value1 : type_value1)=>type_deferral} second a function depending from a value returning a deferral */ function deferral_compose_serial(first, second) { return { "representation": ((input) => first.representation(input).then((between) => second.representation(between))) }; } call.deferral_compose_serial = deferral_compose_serial; /** * @author fenris */ function deferral_compose_parallel({ "left": deferral_left, "right": deferral_right, }) { return (deferral_make((input, convey) => { let object = { "left": lib_plankton.pod.make_empty(), "right": lib_plankton.pod.make_empty(), }; let finish = function () { if (lib_plankton.pod.is_filled(object.left) && lib_plankton.pod.is_filled(object.right)) { let result = { "left": lib_plankton.pod.cull(object.left), "right": lib_plankton.pod.cull(object.right), }; convey(result); } else { // do nothing } }; deferral_use(deferral_left, input, output_left => { object.left = lib_plankton.pod.make_filled(output_left); finish(); }); deferral_use(deferral_right, input, output_right => { object.right = lib_plankton.pod.make_filled(output_right); finish(); }); })); } call.deferral_compose_parallel = deferral_compose_parallel; /** * @author fenris * @desc repeatedly applied serial composition */ function deferral_chain(members) { return (members.reduce( // (result, current) => deferral_compose_serial(result, current), deferral_compose_serial, deferral_id())); } call.deferral_chain = deferral_chain; /** * @author fenris */ /* export function deferral_bunch( members : {[name : string] : type_deferral} ) : type_deferral { } */ })(call = lib_plankton.call || (lib_plankton.call = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:call«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:call« 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:call« 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:call«. If not, see . */ var lib_plankton; (function (lib_plankton) { var call; (function (call) { /** * @author fenris */ class class_deferral { /** * @author fenris */ constructor(subject) { this.subject = subject; } /** * @author fenris */ static _cram(subject) { return (new class_deferral(subject)); } /** * @author fenris */ static _tear(instance) { return instance.subject; } /** * @author fenris */ static make(handler) { return (class_deferral._cram(call.deferral_make(handler))); } /** * @author fenris */ use(input, procedure) { return (call.deferral_use(class_deferral._tear(this), input, procedure)); } /** * @author fenris */ compose_serial(second) { return (class_deferral._cram(call.deferral_compose_serial(class_deferral._tear(this), class_deferral._tear(second)))); } /** * @author fenris */ static chain(members) { return (class_deferral._cram(call.deferral_chain(members.map(member => class_deferral._tear(member))))); } /** * @author fenris */ static wrap(function_) { return (class_deferral._cram(call.deferral_wrap(function_))); } /** * @author fenris */ static const_(value) { return (class_deferral._cram(call.deferral_const(value))); } /** * @author fenris */ static delay(output, delay) { return (class_deferral._cram(call.deferral_delay(output, delay))); } } call.class_deferral = class_deferral; })(call = lib_plankton.call || (lib_plankton.call = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:call«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:call« 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:call« 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:call«. If not, see . */ var lib_plankton; (function (lib_plankton) { var call; (function (call) { /** * converts the "arguments"-map into an array * * @param {Object} args * @author fenris */ function args2list(args) { return Object.keys(args).map(key => args[key]); } call.args2list = args2list; /** * just the empty function; useful for some callbacks etc. * * @author fenris */ function nothing() { } call.nothing = nothing; /** * just the identity; useful for some callbacks etc.; defined as function instead of const for using type parameters * * @author fenris */ function id(x) { return x; } call.id = id; /** * just the identity; useful for some callbacks etc. * * @author fenris */ function const_(x) { return (y => x); } call.const_ = const_; /** * composes two functions (i.e. returns a function that return the result of the successive execution of both input-functions) * * @param {function} function_f * @param {function} function_g * @author fenris */ function compose(function_f, function_g) { return (function (x) { // return function_g(function_f(x)); return function_g(function_f.apply(function_f, args2list(arguments))); }); } call.compose = compose; /** * @author fenris */ function curryfy_real(f, n) { switch (n) { case 0: { throw (new Error("[curryfy] impossible")); // break; } case 1: { return f; // break; } default: { return (function (x) { return (curryfy_real(function () { return f.apply(f, [x].concat(args2list(arguments))); }, n - 1)); }); // break; } } } /** * transforms a function with sequential input to a function with leveled input; example: add(2,3) = curryfy(add)(2)(3) * * @param {function} f * @return {function} the currified version of the in put function * @author fenris */ function curryfy(f) { return curryfy_real(f, f.length); } call.curryfy = curryfy; /** * @author fenris */ function convey(value, functions) { let result = value; functions.forEach(function_ => { result = function_(result); }); return result; } call.convey = convey; /** * @author fenris */ function timeout(procedure, delay_in_seconds) { return ( /*window.*/ setTimeout(procedure, Math.floor(delay_in_seconds * 1000))); } call.timeout = timeout; /** * Promise version of "setTimeout" * * @author fenris */ function defer(seconds, action) { return (new Promise((resolve, reject) => { setTimeout(() => resolve(action()), Math.floor(seconds * 1000)); })); } call.defer = defer; /** * a definition for a value being "defined" * * @author neuc */ function is_def(obj, options = {}) { options = Object.assign({ "null_is_valid": false, }, options); return (!((typeof (obj) === "undefined") || (!options.null_is_valid && (obj === null)))); } call.is_def = is_def; /** * returns the value if set and, when a type is specified, if the type is correct, if not return default_value * * @author neuc */ function def_val(value, default_value, options = {}) { options = Object.assign({ "type": null, "null_is_valid": false, }, options); if (is_def(value, { "null_is_valid": options.null_is_valid }) && (is_def(options.type) ? ((typeof (value) === options.type) || ((value === null) && options.null_is_valid)) : true)) { return value; } else { return default_value; } } call.def_val = def_val; ; /** * provides the call for an attribute of a class as a regular function; useful for processing lists of objects * * @param {string} name the name of the attribute * @return {function} * @author fenris */ function attribute(name) { return (object => object[name]); } call.attribute = attribute; /** * provides a method of a class as a regular function; useful for processing lists of objects * * @param {string} name the name of the method * @return {function} * @author fenris */ function method(name) { return (function (object) { return object[name].apply(object, args2list(arguments).slice(1)); }); } call.method = method; /** * @author fenris */ function distinguish(coproduct, handlers, options = {}) { options = Object.assign({ "fallback": null, }, options); if (coproduct.kind in handlers) { const handler = handlers[coproduct.kind]; return handler(coproduct.data); } else { const message = ("unhandled kind '" + coproduct.kind + "'"); if (options.fallback !== null) { console.warn(message); return options.fallback(coproduct); } else { throw (new Error(message)); } } } call.distinguish = distinguish; /** * rate limiting algorithm, based on the idea of mana (magic power) in video games: * - an actor has a fixed mana capacity, i.e. the maximum amount of available power * - an actor has a fixed rate of mana regeneration, i.e. how fast the power is filled up (linear growth) * - an action has a defined mana heft, i.e. how much power is required and deducted in order to execute it * - mana states are represented by snapshots, i.e. the amount of power at a certain point in time * * @author fenris */ async function rate_limit_check(setup, heft) { if (heft > setup.capacity) { return Promise.resolve({ "granted": false, "seconds": null, }); } else { // get current value const current_timestamp = (Date.now() / 1000); const old_snapshot_raw = (await setup.get_snapshot()); const old_snapshot = (old_snapshot_raw ?? { "timestamp": current_timestamp, "value": setup.capacity }); const seconds_passed = (current_timestamp - old_snapshot.timestamp); const current_value = Math.min(setup.capacity, (old_snapshot.value + (setup.regeneration_rate * seconds_passed))); // analyze if (current_value < heft) { // too less const seconds_needed = ((setup.regeneration_rate <= 0) ? null : ((heft - old_snapshot.value) / setup.regeneration_rate)); return Promise.resolve({ "granted": false, "seconds": ((seconds_needed === null) ? null : (seconds_needed - seconds_passed)), }); } else { // enough -> update snapshot const new_value = (current_value - heft); // set_snapshot if (old_snapshot_raw === null) { await setup.set_snapshot({ "timestamp": current_timestamp, "value": new_value }); } else { await setup.update_snapshot(current_timestamp, (new_value - old_snapshot.value)); } return Promise.resolve({ "granted": true, "seconds": 0, }); } } } call.rate_limit_check = rate_limit_check; })(call = lib_plankton.call || (lib_plankton.call = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:file«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:file« 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:file« 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:file«. If not, see . */ var lib_plankton; (function (lib_plankton) { var file; (function (file) { /** * @author fenris */ function read(path) { return (fetch("/" + path) .then(function (result) { return result.text(); })); } file.read = read; /** * @author fenris */ function write(path, content) { return Promise.reject(new Error("not implemented / not possible")); } file.write = write; /** * @author fenris */ function blob_read_text(blob) { return (lib_plankton.call.promise_make(function (resolve, reject) { var reader = (new FileReader()); reader.addEventListener("load", function (event) { resolve((reader.result)); }); reader.addEventListener("error", function (event) { reject(new Error("reading file failed")); }); reader.addEventListener("abort", function (event) { reject(new Error("reading file aborted")); }); reader.readAsText(blob); })); } file.blob_read_text = blob_read_text; /** * @author fenris */ function blob_read_arraybuffer(blob) { return (lib_plankton.call.promise_make(function (resolve, reject) { var reader = (new FileReader()); reader.addEventListener("load", function (event) { resolve((reader.result)); }); reader.addEventListener("error", function (event) { reject(new Error("reading file failed")); }); reader.addEventListener("abort", function (event) { reject(new Error("reading file aborted")); }); reader.readAsArrayBuffer(blob); })); } file.blob_read_arraybuffer = blob_read_arraybuffer; /** * @author fenris */ function blob_read_dataurl(blob) { return (lib_plankton.call.promise_make(function (resolve, reject) { var reader = new FileReader(); reader.addEventListener("load", function (event) { resolve((reader.result)); }); reader.addEventListener("error", function (event) { reject(new Error("reading file failed")); }); reader.addEventListener("abort", function (event) { reject(new Error("reading file aborted")); }); reader.readAsDataURL(blob); })); } file.blob_read_dataurl = blob_read_dataurl; /** * @author fenris */ function blob_write_text(text) { var blob = (new Blob([text], { "type": "text/plain" })); return lib_plankton.call.promise_resolve(blob); } file.blob_write_text = blob_write_text; })(file = lib_plankton.file || (lib_plankton.file = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:code«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:code« 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:code« 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:code«. If not, see . */ /* This file is part of »bacterio-plankton:code«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:code« 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:code« 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:code«. If not, see . */ /* This file is part of »bacterio-plankton:code«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:code« 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:code« 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:code«. If not, see . */ var lib_plankton; (function (lib_plankton) { var code; (function (code) { /** * @author fenris */ function inverse_encode(decode, to) { return decode(to); } code.inverse_encode = inverse_encode; /** * @author fenris */ function inverse_decode(encode, from) { return encode(from); } code.inverse_decode = inverse_decode; })(code = lib_plankton.code || (lib_plankton.code = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:code«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:code« 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:code« 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:code«. If not, see . */ var lib_plankton; (function (lib_plankton) { var code; (function (code) { /** * @author fenris */ var class_code_inverse = /** @class */ (function () { /** * @author fenris */ function class_code_inverse(subject) { this.subject = subject; } /** * @implementation * @author fenris */ class_code_inverse.prototype.encode = function (to) { var _this = this; return code.inverse_encode(function (x) { return _this.subject.decode(x); }, to); }; /** * @implementation * @author fenris */ class_code_inverse.prototype.decode = function (from) { var _this = this; return code.inverse_decode(function (x) { return _this.subject.encode(x); }, from); }; return class_code_inverse; }()); code.class_code_inverse = class_code_inverse; })(code = lib_plankton.code || (lib_plankton.code = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:code«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:code« 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:code« 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:code«. If not, see . */ var lib_plankton; (function (lib_plankton) { var code; (function (code) { /** * @author fenris */ function pair_encode(encode_first, encode_second, from) { var between = encode_first(from); var to = encode_second(between); return to; } code.pair_encode = pair_encode; /** * @author fenris */ function pair_decode(decode_first, decode_second, to) { var between = decode_second(to); var from = decode_first(between); return from; } code.pair_decode = pair_decode; })(code = lib_plankton.code || (lib_plankton.code = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:code«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:code« 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:code« 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:code«. If not, see . */ var lib_plankton; (function (lib_plankton) { var code; (function (code) { /** * @author fenris */ var class_code_pair = /** @class */ (function () { /** * @author fenris */ function class_code_pair(first, second) { this.first = first; this.second = second; } /** * @implementation * @author fenris */ class_code_pair.prototype.encode = function (from) { var _this = this; return code.pair_encode(function (x) { return _this.first.encode(x); }, function (x) { return _this.second.encode(x); }, from); }; /** * @implementation * @author fenris */ class_code_pair.prototype.decode = function (to) { var _this = this; return code.pair_decode(function (x) { return _this.first.decode(x); }, function (x) { return _this.second.decode(x); }, to); }; return class_code_pair; }()); code.class_code_pair = class_code_pair; })(code = lib_plankton.code || (lib_plankton.code = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:code«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:code« 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:code« 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:code«. If not, see . */ var lib_plankton; (function (lib_plankton) { var code; (function (code) { /** * @author fenris */ function chain_encode(encode_links, from) { var value = from; encode_links .forEach(function (link) { value = link(value); }); return value; } code.chain_encode = chain_encode; /** * @author fenris */ function chain_decode(decode_links, to) { var value = to; decode_links .reverse() .forEach(function (link) { value = link(value); }); return value; } code.chain_decode = chain_decode; })(code = lib_plankton.code || (lib_plankton.code = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:code«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:code« 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:code« 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:code«. If not, see . */ var lib_plankton; (function (lib_plankton) { var code; (function (code) { /** * @author fenris */ var class_code_chain = /** @class */ (function () { /** * @author fenris */ function class_code_chain(links) { this.links = links; } /** * @implementation * @author fenris */ class_code_chain.prototype.encode = function (from) { return code.chain_encode(this.links.map(function (link) { return (function (x) { return link.encode(x); }); }), from); }; /** * @implementation * @author fenris */ class_code_chain.prototype.decode = function (to) { return code.chain_decode(this.links.map(function (link) { return (function (x) { return link.decode(x); }); }), to); }; return class_code_chain; }()); code.class_code_chain = class_code_chain; })(code = lib_plankton.code || (lib_plankton.code = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:code«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:code« 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:code« 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:code«. If not, see . */ var lib_plankton; (function (lib_plankton) { var code; (function (code) { /** * @author Christian Fraß */ function flatten_encode(from, keys) { if (keys === void 0) { keys = null; } if (keys === null) { if (from.length > 0) { keys = Object.keys(from[0]); } else { throw (new Error("encoding impossible")); } } return { "keys": keys, "data": from.map(function (line) { return keys.map(function (name) { return line[name]; }); }) }; } code.flatten_encode = flatten_encode; /** * @author Christian Fraß */ function flatten_decode(to) { return (to.data .map(function (dataset) { var dataset_ = {}; dataset .forEach(function (value, index) { var name = to.keys[index]; dataset_[name] = value; }); return dataset_; })); } code.flatten_decode = flatten_decode; })(code = lib_plankton.code || (lib_plankton.code = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:code«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:code« 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:code« 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:code«. If not, see . */ var lib_plankton; (function (lib_plankton) { var code; (function (code) { /** * @author fenris */ var class_code_flatten = /** @class */ (function () { /** * @author fenris */ function class_code_flatten() { } /** * @implementation * @author fenris */ class_code_flatten.prototype.encode = function (x) { return code.flatten_encode(x); }; /** * @implementation * @author fenris */ class_code_flatten.prototype.decode = function (x) { return code.flatten_decode(x); }; return class_code_flatten; }()); code.class_code_flatten = class_code_flatten; })(code = lib_plankton.code || (lib_plankton.code = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:json«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:json« 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:json« 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:json«. If not, see . */ var lib_plankton; (function (lib_plankton) { var json; (function (json) { /** * @author fenris */ function encode(x, formatted = false) { return JSON.stringify(x, undefined, formatted ? "\t" : undefined); } json.encode = encode; /** * @author fenris */ function decode(x) { return JSON.parse(x); } json.decode = decode; })(json = lib_plankton.json || (lib_plankton.json = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:json«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:json« 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:json« 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:json«. If not, see . */ var lib_plankton; (function (lib_plankton) { var json; (function (json) { /** * @author fenris */ class class_json { /** * @author fenris */ constructor() { } /** * @implementation * @author fenris */ encode(x) { return json.encode(x); } /** * @implementation * @author fenris */ decode(x) { return json.decode(x); } } json.class_json = class_json; })(json = lib_plankton.json || (lib_plankton.json = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:base64«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base64« 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:base64« 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:base64«. If not, see . */ var lib_plankton; (function (lib_plankton) { var base64; (function (base64) { /** * @author fenris */ function encode(x) { return btoa(x); } base64.encode = encode; /** * @author fenris */ function decode(x) { return atob(x); } base64.decode = decode; })(base64 = lib_plankton.base64 || (lib_plankton.base64 = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:base64«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base64« 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:base64« 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:base64«. If not, see . */ var lib_plankton; (function (lib_plankton) { var base64; (function (base64) { /** * @author fenris */ class class_base64 { /** * @author fenris */ constructor() { } /** * @implementation * @author fenris */ encode(x) { return base64.encode(x); } /** * @implementation * @author fenris */ decode(x) { return base64.decode(x); } } base64.class_base64 = class_base64; })(base64 = lib_plankton.base64 || (lib_plankton.base64 = {})); })(lib_plankton || (lib_plankton = {})); 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:log«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:log« 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:lang« 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:log«. If not, see . */ var lib_plankton; (function (lib_plankton) { var log; (function (log) { /** */ var enum_level; (function (enum_level) { enum_level[enum_level["debug"] = 0] = "debug"; enum_level[enum_level["info"] = 1] = "info"; enum_level[enum_level["notice"] = 2] = "notice"; enum_level[enum_level["warning"] = 3] = "warning"; enum_level[enum_level["error"] = 4] = "error"; })(enum_level = log.enum_level || (log.enum_level = {})); ; /** */ function level_order(level1, level2) { return (level1 <= level2); } log.level_order = level_order; /** */ function level_show(level) { switch (level) { case enum_level.debug: return "debug"; case enum_level.info: return "info"; case enum_level.notice: return "notice"; case enum_level.warning: return "warning"; case enum_level.error: return "error"; default: return "(unknown)"; } } log.level_show = level_show; })(log = lib_plankton.log || (lib_plankton.log = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:log«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:log« 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:lang« 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:lang«. If not, see . */ /** * @deprecated * @todo remove */ var lib_plankton; (function (lib_plankton) { var log; (function (log) { /** * @author fenris */ /*export*/ var level_stack = [0]; function level_push(level) { level_stack.push(level); } log.level_push = level_push; function level_pop() { if (level_stack.length > 1) { level_stack.pop(); } } log.level_pop = level_pop; function level_get() { return level_stack.slice(-1)[0]; } /* export function level_inc() : void {level_push(level_get()+1);} export function level_dec() : void {level_push(level_get()-1);} */ /** * @author fenris */ var indent_stack = [0]; function indent_push(indent) { indent_stack.push(indent); } log.indent_push = indent_push; function indent_pop() { if (indent_stack.length > 1) { indent_stack.pop(); } } log.indent_pop = indent_pop; function indent_get() { return level_stack.slice(-1)[0]; } function indent_inc() { level_push(level_get() + 1); } log.indent_inc = indent_inc; function indent_dec() { level_push(level_get() - 1); } log.indent_dec = indent_dec; /** * @author fenris */ function write(_a) { var message = _a["message"], _b = _a["type"], type = _b === void 0 ? null : _b, _c = _a["prefix"], prefix = _c === void 0 ? null : _c, _d = _a["level"], level = _d === void 0 ? 0 : _d, _e = _a["indent"], indent = _e === void 0 ? 0 : _e; var entry = { "level": ((type === null) ? lib_plankton.log.enum_level.info : { "debug": lib_plankton.log.enum_level.debug, "info": lib_plankton.log.enum_level.info, "notice": lib_plankton.log.enum_level.notice, "warning": lib_plankton.log.enum_level.warning, "error": lib_plankton.log.enum_level.error }[type]), "incident": message, "details": { "prefix": prefix, "level": level, "indent": indent } }; lib_plankton.log.add(entry); } log.write = write; })(log = lib_plankton.log || (lib_plankton.log = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:log«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:log« 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:lang« 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:log«. If not, see . */ var lib_plankton; (function (lib_plankton) { var log; (function (log) { /** */ var class_channel = /** @class */ (function () { function class_channel() { } return class_channel; }()); log.class_channel = class_channel; })(log = lib_plankton.log || (lib_plankton.log = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:log«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:log« 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:lang« 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:log«. If not, see . */ var lib_plankton; (function (lib_plankton) { var log; (function (log) { /** * output for writing log entries to web console */ var class_channel_console = /** @class */ (function (_super) { __extends(class_channel_console, _super); function class_channel_console() { return _super !== null && _super.apply(this, arguments) || this; } /** */ class_channel_console.prototype.add = function (entry) { var _a; var renderers = (_a = {}, _a[log.enum_level.debug] = { "renderer": function (i, d) { return console.log(i, d); }, "show_level": true }, _a[log.enum_level.info] = { "renderer": function (i, d) { return console.info(i, d); }, "show_level": false }, _a[log.enum_level.notice] = { "renderer": function (i, d) { return console.log(i, d); }, "show_level": true }, _a[log.enum_level.warning] = { "renderer": function (i, d) { return console.warn(i, d); }, "show_level": false }, _a[log.enum_level.error] = { "renderer": function (i, d) { return console.error(i, d); }, "show_level": false }, _a); var setting = renderers[entry.level]; setting.renderer(((setting.show_level ? ("[" + log.level_show(entry.level) + "]" + " ") : "") + ("" + entry.incident + "")), entry.details); }; return class_channel_console; }(log.class_channel)); log.class_channel_console = class_channel_console; })(log = lib_plankton.log || (lib_plankton.log = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:log«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:log« 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:lang« 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:log«. If not, see . */ var lib_plankton; (function (lib_plankton) { var log; (function (log) { /** * decorator for filtering out log entries below a certain level threshold */ var class_channel_minlevel = /** @class */ (function (_super) { __extends(class_channel_minlevel, _super); /** */ function class_channel_minlevel(core, threshold) { var _this = _super.call(this) || this; _this.core = core; _this.threshold = threshold; return _this; } /** */ class_channel_minlevel.prototype.add = function (entry) { if (!log.level_order(this.threshold, entry.level)) { // do nothing } else { this.core.add(entry); } }; return class_channel_minlevel; }(log.class_channel)); log.class_channel_minlevel = class_channel_minlevel; })(log = lib_plankton.log || (lib_plankton.log = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:log«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:log« 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:lang« 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:log«. If not, see . */ var lib_plankton; (function (lib_plankton) { var log; (function (log) { /** */ function translate_level(level_string) { return { "debug": log.enum_level.debug, "info": log.enum_level.info, "notice": log.enum_level.notice, "warning": log.enum_level.warning, "error": log.enum_level.error }[level_string]; } /** */ function channel_make(description) { var _a; switch (description.kind) { default: { throw (new Error("unhandled log channel kind: " + description.kind)); break; } case "console": { return (new log.class_channel_minlevel(new log.class_channel_console(), translate_level((_a = description.data["threshold"]) !== null && _a !== void 0 ? _a : "debug"))); break; } } } log.channel_make = channel_make; /** */ function conf_default() { return [ new log.class_channel_minlevel(new log.class_channel_console(), log.enum_level.notice), ]; } log.conf_default = conf_default; })(log = lib_plankton.log || (lib_plankton.log = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:log«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:log« 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:lang« 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:log«. If not, see . */ var lib_plankton; (function (lib_plankton) { var log; (function (log) { /** */ var _channel_stack = null; /** * pushes a new configuration on the stack and activates it */ function conf_push(channels) { if (_channel_stack === null) { _channel_stack = []; } _channel_stack.push(channels); } log.conf_push = conf_push; /** * pops the current active configuration from the stack */ function conf_pop() { if (_channel_stack.length > 0) { _channel_stack.pop(); } else { // do nothing } } log.conf_pop = conf_pop; /** * makes the logging system ready */ function setup() { if (_channel_stack === null) { _channel_stack = []; conf_push(log.conf_default()); } else { // do nothing } } /** * consumes a log entry, i.e. sends it to the currently active outputs */ function add(entry) { setup(); _channel_stack.slice(-1)[0].forEach(function (channel) { return channel.add(entry); }); } log.add = add; /** */ function debug(incident, details) { if (details === void 0) { details = {}; } add({ "level": log.enum_level.debug, "incident": incident, "details": details }); } log.debug = debug; /** */ function info(incident, details) { if (details === void 0) { details = {}; } add({ "level": log.enum_level.info, "incident": incident, "details": details }); } log.info = info; /** */ function notice(incident, details) { if (details === void 0) { details = {}; } add({ "level": log.enum_level.notice, "incident": incident, "details": details }); } log.notice = notice; /** */ function warning(incident, details) { if (details === void 0) { details = {}; } add({ "level": log.enum_level.warning, "incident": incident, "details": details }); } log.warning = warning; /** */ function error(incident, details) { if (details === void 0) { details = {}; } add({ "level": log.enum_level.error, "incident": incident, "details": details }); } log.error = error; })(log = lib_plankton.log || (lib_plankton.log = {})); })(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; })(); /* This file is part of »bacterio-plankton:object«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:object« 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:object« 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:object«. If not, see . */ var lib_plankton; (function (lib_plankton) { var object; (function (object_1) { /** * @author fenris */ function fetch(object, fieldname, fallback, escalation) { if (fallback === void 0) { fallback = null; } if (escalation === void 0) { escalation = 1; } if ((fieldname in object) && (object[fieldname] !== undefined)) { return object[fieldname]; } else { switch (escalation) { case 0: { return fallback; break; } case 1: { var message = ("field '".concat(fieldname, "' not in structure")); message += ("; using fallback value '".concat(String(fallback), "'")); // console.warn(message); return fallback; break; } case 2: { var message = ("field '".concat(fieldname, "' not in structure")); throw (new Error(message)); break; } default: { throw (new Error("invalid escalation level ".concat(escalation))); break; } } } } object_1.fetch = fetch; /** * @author fenris */ function map(object_from, transformator) { var object_to = {}; Object.keys(object_from).forEach(function (key) { return (object_to[key] = transformator(object_from[key], key)); }); return object_to; } object_1.map = map; /** * @desc gibt ein Objekt mit bestimmten Einträgen des Eingabe-Objekts zurück * @author fenris */ function filter(object_from, predicate) { var object_to = {}; Object.keys(object_from).forEach(function (key) { var value = object_from[key]; if (predicate(value, key)) { object_to[key] = value; } }); return object_to; } object_1.filter = filter; /** * @desc wandelt ein Array mit Einträgen der Form {key,value} in ein entsprechendes Objekt um * @author fenris */ function from_array(array) { var object = {}; array.forEach(function (entry) { return (object[entry.key] = entry.value); }); return object; } object_1.from_array = from_array; /** * @desc wandelt ein Objekt in ein entsprechendes Array mit Einträgen der Form {key,value} um * @author fenris */ function to_array(object) { var array = []; Object.keys(object).forEach(function (key) { return array.push({ "key": key, "value": object[key] }); }); return array; } object_1.to_array = to_array; /** * @desc gibt eine Liste von Schlüsseln eines Objekts zurück * @author fenris */ function keys(object) { return Object.keys(object); } object_1.keys = keys; /** * @desc gibt eine Liste von Werten eines Objekts zurück * @author fenris */ function values(object) { return to_array(object).map(function (entry) { return entry.value; }); } object_1.values = values; /** * @desc liest ein Baum-artiges Objekt an einer bestimmten Stelle aus * @author fenris */ function path_read(object, path, fallback, escalation) { if (fallback === void 0) { fallback = null; } if (escalation === void 0) { escalation = 1; } var steps = ((path.length == 0) ? [] : path.split(".")); if (steps.length == 0) { throw (new Error("empty path")); } else { var position_1 = object; var reachable = (position_1 != null) && steps.slice(0, steps.length - 1).every(function (step) { position_1 = lib_plankton.object.fetch(position_1, step, null, 0); return (position_1 != null); }); if (reachable) { return lib_plankton.object.fetch(position_1, steps[steps.length - 1], fallback, escalation); } else { return lib_plankton.object.fetch({}, "_dummy_", fallback, escalation); } } } object_1.path_read = path_read; /** * @desc schreibt einen Wert an eine bestimmte Stelle in einem Baum-artigen Objekt * @author fenris */ function path_write(object, path, value, construct) { if (construct === void 0) { construct = true; } var steps = ((path.length == 0) ? [] : path.split(".")); if (steps.length == 0) { throw (new Error("empty path")); } else { var position_2 = object; var reachable = steps.slice(0, steps.length - 1).every(function (step) { var position_ = lib_plankton.object.fetch(position_2, step, null, 0); if (position_ == null) { if (construct) { position_2[step] = {}; position_2 = position_2[step]; return true; } else { return false; } } else { position_2 = position_; return true; } }); if (reachable) { position_2[steps[steps.length - 1]] = value; } else { var message = ("path '".concat(path, "' does not exist and may not be constructed")); throw (new Error(message)); } } } object_1.path_write = path_write; /** * @desc prüft ob ein Objekt einem bestimmten Muster entspricht * @param {Object} object das zu prüfende Objekt * @param {Object} pattern das einzuhaltende Muster * @param {Function} connlate eine Funktion zum Feststellen der Gleichheit von Einzelwerten * @author fenris */ function matches(object, pattern, collate) { if (collate === void 0) { collate = instance_collate; } return Object.keys(pattern).every(function (key) { return collate(pattern[key], object[key]); }); } object_1.matches = matches; /** * @desc erzeugt eine Projektion eines Baum-artigen Objekts in ein Listen-artiges Objekt * @param {string} [separator] welches Zeichen als Trenner zwischen zwei Pfad-Schritten verwendet werden soll * @author fenris */ function flatten(value, separator, key_for_element) { if (separator === void 0) { separator = "."; } if (key_for_element === void 0) { key_for_element = (function (index) { return ("element_" + index.toFixed(0)); }); } var integrate = function (result, key_, value_) { if (value_ == null) { result[key_] = value_; } else { // primitive Werte direkt übernehmen if (typeof (value_) != "object") { result[key_] = value_; } // sonst durch rekursiven Aufruf die flache Variante des Wertes ermitteln und einarbeiten else { var result_1 = flatten(value_); Object.keys(result_1) .forEach(function (key__) { var value__ = result_1[key__]; var key_new = (key_ + separator + key__); result[key_new] = value__; }); } } }; if ((value === null) || (value === undefined)) { return null; } else { var result_2 = {}; if (typeof (value) != "object") { result_2["value"] = value; } else { if (value instanceof Array) { var array = (value); array .forEach(function (element, index) { integrate(result_2, key_for_element(index), element); }); } else { var object_2 = (value); Object.keys(object_2) .forEach(function (key) { integrate(result_2, key, object_2[key]); }); } } return result_2; } } object_1.flatten = flatten; /** * @author fenris */ function clash(x, y, _a) { var _b = _a === void 0 ? {} : _a, _c = _b["overwrite"], overwrite = _c === void 0 ? true : _c, _d = _b["hooks"], _e = _d === void 0 ? {} : _d, _f = _e["existing"], hook_existing = _f === void 0 ? null : _f; if (hook_existing == null) { (function (key, value_old, value_new) { return console.warn("field ".concat(key, " already defined")); }); } var z = {}; Object.keys(x).forEach(function (key) { z[key] = x[key]; }); Object.keys(y).forEach(function (key) { if (key in z) { if (hook_existing != null) { hook_existing(key, z[key], y[key]); } if (overwrite) { z[key] = y[key]; } } else { z[key] = y[key]; } }); return z; } object_1.clash = clash; /** * @author fenris */ function patch(core, mantle, deep, path) { if (deep === void 0) { deep = true; } if (path === void 0) { path = null; } if (mantle == null) { console.warn("mantle is null; core was", core); } else { Object.keys(mantle).forEach(function (key) { var path_ = ((path == null) ? key : "".concat(path, ".").concat(key)); var value_mantle = mantle[key]; if (!(key in core)) { if ((typeof (value_mantle) == "object") && (value_mantle != null) && deep) { if (value_mantle instanceof Array) { core[key] = []; value_mantle.forEach(function (element) { if ((typeof (element) == "object") && (element != null)) { var element_ = {}; patch(element_, element); core[key].push(element_); } else { core[key].push(element); } }); } else { core[key] = {}; patch(core[key], value_mantle, deep, path_); } } else { core[key] = value_mantle; } } else { var value_core = core[key]; if (typeof (value_core) == typeof (value_mantle)) { if ((typeof (value_mantle) == "object") && (value_mantle != null) && deep) { patch(core[key], value_mantle, deep, path_); } else { core[key] = value_mantle; } } else { if ((value_core != null) && (value_mantle != null)) { var message = "objects have different shapes at path '".concat(path_, "'; core has type '").concat(typeof (value_core), "' and mantle has type '").concat(typeof (value_mantle), "'"); console.warn(message); } core[key] = value_mantle; // throw (new Error(message)); } } }); } } object_1.patch = patch; /** * @author fenris */ function patched(core, mantle, deep) { if (deep === void 0) { deep = undefined; } var result = {}; patch(result, core, deep); patch(result, mantle, deep); return result; } object_1.patched = patched; /** * @author fenris */ function attached(object, key, value) { var mantle = {}; mantle[key] = value; return patched(object, mantle, false); } object_1.attached = attached; /** * @author fenris */ function copy(object) { return patched({}, object); } object_1.copy = copy; })(object = lib_plankton.object || (lib_plankton.object = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:translate«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:translate« 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:translate« 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:translate«. If not, see . */ var lib_plankton; (function (lib_plankton) { var translate; (function (translate) { /** * @desc contains the sets of strings * @author fenris */ var _packages = {}; /** * @desc specifies in which order the languages shall be queried; if getting a string from language #0 fails, the * system tries to get it from language #1, and so on * @author fenris */ var _order = []; /** * @desc whether to automatically promote the language of a newly added package * @author fenris */ var _autopromote = false; /** * @desc the level of verbosity, specifiying how much output the system shall provide about its actions * @author fenris */ translate._verbosity = 1; /** * @desc which initial string to use for log-outputs * @author fenris */ var _logprefix = "[lib_translate]"; /** * @desc moves a language to the top of the order, making it the primary one * @author fenris */ function promote(identifier) { if (Object.keys(_packages).indexOf(identifier) < 0) { if (translate._verbosity >= 1) { console.warn(`${_logprefix} package '${identifier}' doesn't exist yet`); } } let position = _order.indexOf(identifier); if (position >= 0) { if (translate._verbosity >= 2) { console.info(`${_logprefix} '${identifier}' already in order; will promote it`); } _order.splice(position, 1); } _order.unshift(identifier); if (translate._verbosity >= 2) { console.info(`${_logprefix} order is now ${_order.toString()}`); } } translate.promote = promote; /** * @desc adds a package to the sytem * @author fenris */ function add(package_) { let identifier = package_.meta.identifier; if (identifier in _packages) { if (translate._verbosity >= 1) { console.warn(`${_logprefix} package '${identifier}' has already been added; will overwrite`); } } else { if (translate._verbosity >= 2) { console.log(`${_logprefix} got package '${identifier}'`); } } _packages[identifier] = package_; if (_autopromote) { promote(identifier); } } translate.add = add; /** * @desc integrates a package to the system, i.e. creates a new one if none existed so far or merges with an existing one * @author fenris */ function feed(package_) { let identifier = package_.meta.identifier; if (identifier in _packages) { lib_plankton.object.patch(_packages[identifier].tree, package_.tree, true); } else { if (translate._verbosity >= 2) { console.info(`${_logprefix} package '${identifier}' didn't exist so far; will create it now`); } add(package_); } } translate.feed = feed; /** * @desc tries to retrieve a translation for a specific package identifier * @author fenris */ function fetch(identifier, path, args = {}) { if (!(identifier in _packages)) { if (translate._verbosity >= 1) { console.warn(`${_logprefix} no package '${identifier}'`); } return (lib_plankton.pod.make_empty()); } else { // let str : string = lib_plankton.object.path_read(_packages[identifier].tree, path); let str = _packages[identifier].tree[path]; if (str == undefined) { if (translate._verbosity >= 1) { console.warn(`${_logprefix} string '${path}' missing in package '${identifier}'`); } return (lib_plankton.pod.make_empty()); } else { // resolve references { let regexp_reference = new RegExp("#\\(([\\w\\.]*)(?:\\?(\\w+)=(\\w+)(?:&(\\w+)=(\\w+))*)?\\)"); while (true) { let matching = regexp_reference.exec(str); if (matching != null) { let path_ = matching[1]; let args_ = {}; if (translate._verbosity >= 2) { // console.info(`${_logprefix} found reference to '${path_}' with args ${JSON.stringify(args_)}`); console.info(`${_logprefix} found reference to '${path_}'`); } // parse args { for (let index = 2; index <= matching.length - 1; index += 2) { let id = matching[index + 0]; let value = matching[index + 1]; if (id != undefined) { args_[id] = value; } } } // fetch referenced string { let result_ = fetch(identifier, path_, args_); if (lib_plankton.pod.is_filled(result_)) { let front = str.slice(0, matching.index); let back = str.slice(matching.index + matching[0].length); str = (front + lib_plankton.pod.cull(result_) + back); } else { return (lib_plankton.pod.make_empty()); break; } } } else { break; } } } // insert arguments { str = lib_plankton.string.coin(str, args); } return (lib_plankton.pod.make_filled(str)); } } } translate.fetch = fetch; /** * @desc retrieves a string by going through the order and trying to fetch it for the current entry * @author fenris */ function get(path, args = {}, fallback = null) { if (fallback == null) { fallback = `{${path}}`; } if (translate._verbosity >= 2) { console.info(`${_logprefix} getting translation for string '${path}' with arguments ${JSON.stringify(args)} …`); } let result = lib_plankton.pod.make_empty(); let found = _order.some(identifier => { if (translate._verbosity >= 2) { console.info(`${_logprefix} trying package '${identifier}' …`); } let result_ = fetch(identifier, path, args); if (lib_plankton.pod.is_filled(result_)) { result = result_; return true; } else { return false; } }); if (found) { let str = lib_plankton.pod.cull(result); if (translate._verbosity >= 3) { console.info(`${_logprefix} found translation: '${str}'`); } return str; } else { let str = fallback; if (translate._verbosity >= 1) { console.warn(`${_logprefix} no package provides a translation for string '${path}'; will use the fallback translation '${str}'`); } return str; } } translate.get = get; /** * @author fenris */ function list() { return lib_plankton.object.to_array(_packages).map(x => x.value.meta); } translate.list = list; /** * @author fenris * @todo get rid of this; it's currenly needed only for the cdh-internal lib_completion */ function paths() { return lib_plankton.object.keys(lib_plankton.object.flatten(_packages[_order[0]].tree)); } translate.paths = paths; /** * @author fenris */ function initialize({ "logprefix": logprefix = undefined, "verbosity": verbosity = undefined, "packages": packages = [], "order": order = undefined, "autopromote": autopromote = undefined, } = {}) { return (Promise.resolve(undefined) // set variables .then(_ => { if (logprefix != undefined) _logprefix = logprefix; if (verbosity != undefined) translate._verbosity = verbosity; // _packages = {}; if (order != undefined) _order = order; if (autopromote != undefined) _autopromote = autopromote; return Promise.resolve(undefined); }) // feed .then(_ => { packages.forEach(feed); return Promise.resolve(undefined); })); } translate.initialize = initialize; })(translate = lib_plankton.translate || (lib_plankton.translate = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:translate«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:translate« 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:translate« 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:translate«. If not, see . */ var lib_plankton; (function (lib_plankton) { var translate; (function (translate) { /** * @author fenris */ function iso_639_1_to_iso_639_2(iso6391) { let mapping = { "af": "afr", "ar": "ara", "bg": "bul", "cs": "ces", "da": "dan", "de": "deu", "el": "ell", "en": "eng", "eo": "epo", "es": "esp", "fa": "fas", "fi": "fin", "fr": "fra", "hi": "hin", "hr": "hrv", "hu": "hun", "is": "isl", "it": "ita", "ja": "jpn", "ko": "kor", "nb": "nob", "nl": "nld", "nn": "nno", "pt": "por", "pl": "pol", "ro": "ron", "ru": "rus", "sk": "slk", "sv": "swe", "zh": "zho", }; return mapping[iso6391]; } translate.iso_639_1_to_iso_639_2 = iso_639_1_to_iso_639_2; /** * @author fenris */ function stance(str) { let regexp = new RegExp("^translate:(.*)$"); let matching = regexp.exec(str); if (matching != null) { return translate.get(matching[1]); } else { return str; } } translate.stance = stance; })(translate = lib_plankton.translate || (lib_plankton.translate = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:database«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:database« 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:database« 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:database«. If not, see . */ var lib_plankton; (function (lib_plankton) { var database; (function (database) { /** */ let enum_type; (function (enum_type) { enum_type["boolean"] = "boolean"; enum_type["integer"] = "integer"; enum_type["string_short"] = "string_short"; enum_type["string_medium"] = "string_medium"; enum_type["string_long"] = "string_long"; enum_type["float"] = "float"; })(enum_type = database.enum_type || (database.enum_type = {})); })(database = lib_plankton.database || (lib_plankton.database = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:storage«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:storage« 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:storage« 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:storage«. If not, see . */ /* This file is part of »bacterio-plankton:storage«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:storage« 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:storage« 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:storage«. If not, see . */ /* This file is part of »bacterio-plankton:storage«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:storage« 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:storage« 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:storage«. If not, see . */ var lib_plankton; (function (lib_plankton) { var storage; (function (storage) { var memory; (function (memory) { /** * @author fenris */ function make(parameters) { return { "data": {} }; } memory.make = make; /** * @author fenris */ function clear(subject) { subject.data = {}; } memory.clear = clear; /** * @author fenris */ function write(subject, key, value) { var exists = (key in subject.data); subject.data[key] = value; return exists; } memory.write = write; /** * @author fenris */ function delete_(subject, key) { if (!(key in subject.data)) { throw (new Error("no value for key '" + key + "'")); } else { delete subject.data[key]; } } memory.delete_ = delete_; /** * @author fenris */ function read(subject, key) { if (!(key in subject.data)) { throw (new Error("no value for key '" + key + "'")); } else { return subject.data[key]; } } memory.read = read; /** * @author fenris */ function list(subject) { return Object.keys(subject.data); } memory.list = list; /** * @author fenris */ function search(subject, term) { return (list(subject) .map(function (key) { return ({ "key": key, "preview": key }); })); } memory.search = search; /** * @author fenris */ function implementation_chest(parameters) { function wrap(core) { return (new Promise(function (resolve, reject) { resolve(core()); })); } var subject = make(parameters); return { "setup": function (input) { return Promise.resolve(undefined); }, "clear": function () { return wrap(function () { return clear(subject); }); }, "write": function (key, value) { return wrap(function () { return write(subject, key, value); }); }, "delete": function (key) { return wrap(function () { return delete_(subject, key); }); }, "read": function (key) { return wrap(function () { return read(subject, key); }); }, "search": function (term) { return wrap(function () { return search(subject, term); }); } }; } memory.implementation_chest = implementation_chest; })(memory = storage.memory || (storage.memory = {})); })(storage = lib_plankton.storage || (lib_plankton.storage = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:storage«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:storage« 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:storage« 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:storage«. If not, see . */ var lib_plankton; (function (lib_plankton) { var storage; (function (storage) { var memory; (function (memory) { /** * @author fenris */ var class_chest = /** @class */ (function () { function class_chest(parameters) { this.subject = memory.make(parameters); } class_chest.prototype.setup = function (input) { return Promise.resolve(undefined); }; class_chest.prototype.clear = function () { memory.clear(this.subject); return Promise.resolve(undefined); }; class_chest.prototype.write = function (key, value) { return Promise.resolve(memory.write(this.subject, key, value)); }; class_chest.prototype["delete"] = function (key) { memory.delete_(this.subject, key); return Promise.resolve(undefined); }; class_chest.prototype.read = function (key) { return Promise.resolve(memory.read(this.subject, key)); }; class_chest.prototype.search = function (term) { return Promise.resolve(memory.search(this.subject, term)); }; return class_chest; }()); memory.class_chest = class_chest; })(memory = storage.memory || (storage.memory = {})); })(storage = lib_plankton.storage || (lib_plankton.storage = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:storage«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:storage« 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:storage« 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:storage«. If not, see . */ var lib_plankton; (function (lib_plankton) { var storage; (function (storage) { var localstorage; (function (localstorage) { /** * @author fenris */ function make(parameters) { parameters = Object.assign({ "corner": "plankton" }, parameters); return { "corner": parameters.corner }; } localstorage.make = make; /** */ function compose_full_key(subject, key) { return (subject.corner + "_" + key); } /** */ function decompose_full_key(subject, full_key) { var parts = full_key.split("_"); return ((parts[0] === subject.corner) ? parts.slice(1).join("_") : null); } /** * @author fenris */ function has(subject, key) { return localStorage.hasOwnProperty(compose_full_key(subject, key)); } /** * @author fenris */ function clear(subject) { (Object.keys(localStorage) .map(function (x) { return decompose_full_key(subject, x); }) .filter(function (x) { return (x !== null); }) .forEach(function (x) { return localStorage.removeItem(x); })); } localstorage.clear = clear; /** * @author fenris */ function write(subject, key, item) { var exists = has(subject, key); localStorage.setItem(compose_full_key(subject, key), item); return exists; } localstorage.write = write; /** * @author fenris */ function delete_(subject, key) { localStorage.removeItem(compose_full_key(subject, key)); } localstorage.delete_ = delete_; /** * @author fenris */ function read(subject, key) { var full_key = compose_full_key(subject, key); if (!localStorage.hasOwnProperty(full_key)) { throw (new Error("not found")); } else { return localStorage.getItem(full_key); } } localstorage.read = read; /** * @author fenris */ function list(subject) { return (Object.keys(localStorage) .map(function (x) { return decompose_full_key(subject, x); }) .filter(function (x) { return (x !== null); })); } localstorage.list = list; /** */ function implementation_chest(parameters) { function wrap(core) { return (new Promise(function (resolve, reject) { resolve(core()); })); } var subject = make(parameters); return { "setup": function (input) { return Promise.resolve(undefined); }, "clear": function () { return wrap(function () { return clear(subject); }); }, "write": function (key, item) { return wrap(function () { return write(subject, key, item); }); }, "delete": function (key) { return wrap(function () { return delete_(subject, key); }); }, "read": function (key) { return wrap(function () { return read(subject, key); }); }, "search": function (term) { return Promise.resolve(list(subject) .map(function (key) { return ({ "key": key, "preview": key }); })); } }; } localstorage.implementation_chest = implementation_chest; })(localstorage = storage.localstorage || (storage.localstorage = {})); })(storage = lib_plankton.storage || (lib_plankton.storage = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:storage«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:storage« 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:storage« 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:storage«. If not, see . */ var lib_plankton; (function (lib_plankton) { var storage; (function (storage) { var localstorage; (function (localstorage) { /** * uses the browsers localstorage as chest * * @author fenris */ var class_chest = /** @class */ (function () { function class_chest(parameters) { this.subject = localstorage.make(parameters); } class_chest.prototype.setup = function (input) { return Promise.resolve(undefined); }; class_chest.prototype.clear = function () { return Promise.resolve(localstorage.clear(this.subject)); }; class_chest.prototype.write = function (key, value) { return Promise.resolve(localstorage.write(this.subject, key, value)); }; class_chest.prototype["delete"] = function (key) { return Promise.resolve(localstorage.delete_(this.subject, key)); }; class_chest.prototype.read = function (key) { return Promise.resolve(localstorage.read(this.subject, key)); }; class_chest.prototype.search = function (term) { return Promise.resolve(localstorage.list(this.subject) .map(function (key) { return ({ "key": key, "preview": key }); })); }; return class_chest; }()); localstorage.class_chest = class_chest; })(localstorage = storage.localstorage || (storage.localstorage = {})); })(storage = lib_plankton.storage || (lib_plankton.storage = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-input«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . */ /* This file is part of »bacterio-plankton:zoo-input«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_input; (function (zoo_input) { /** * @author fenris */ class class_input_wrapped { /** */ constructor(core, wrap, unwrap, options = {}) { options = Object.assign({}, options); this.core = core; this.wrap = wrap; this.unwrap = unwrap; } /** * [implementation] */ setup(parent) { return this.core.setup(parent); } /** * [implementation] */ read() { return (this.core.read() .then(value_inner => Promise.resolve(this.wrap(value_inner)))); } /** * [implementation] */ write(value) { return this.core.write(this.unwrap(value)); } } zoo_input.class_input_wrapped = class_input_wrapped; })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-input«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_input; (function (zoo_input) { /** * @author fenris */ class class_input_hidden { /** */ constructor(options = {}) { options = Object.assign({ "initial_value": null, }, options); this.dom_input = null; this.value = options.initial_value; } /** * [implementation] */ setup(parent) { this.dom_input = document.createElement("input"); this.dom_input.setAttribute("type", "hidden"); parent.appendChild(this.dom_input); return Promise.resolve(undefined); } /** * [implementation] */ read() { return Promise.resolve(this.value); } /** * [implementation] */ write(value) { this.value = value; return Promise.resolve(undefined); } } zoo_input.class_input_hidden = class_input_hidden; })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-input«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_input; (function (zoo_input) { /** * @author fenris * @todo abstract */ class class_input_text { /** */ constructor(options = {}) { options = Object.assign({ "read_only": false, "pattern": null, // "autocompletion_list": null, }, options); this.read_only = options.read_only; this.pattern = options.pattern; // this.autocompletion_list = options.autocompletion_list; this.dom_input = null; } /** * [implementation] */ setup(parent) { this.dom_input = document.createElement("input"); this.dom_input.setAttribute("type", "text"); { if (!this.read_only) { // do nothing } else { this.dom_input.setAttribute("disabled", "disabled"); } } { if (this.pattern === null) { // do nothing } else { this.dom_input.setAttribute("pattern", this.pattern); } } { /* if (this.autocompletion_list === null) { // do nothing } else { const autocomplete : class_autocomplete = new class_autocomplete( this.dom_input, this.autocompletion_list ); autocomplete.init(); } */ } parent.appendChild(this.dom_input); return Promise.resolve(undefined); } /** * [implementation] */ read() { return Promise.resolve(this.dom_input.value); } /** * [implementation] */ write(value) { this.dom_input.value = value; return Promise.resolve(undefined); } } zoo_input.class_input_text = class_input_text; })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-input«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_input; (function (zoo_input) { /** * @author fenris */ class class_input_email { /** */ constructor() { this.dom_input = null; } /** * [implementation] */ setup(parent) { this.dom_input = document.createElement("input"); this.dom_input.setAttribute("type", "email"); parent.appendChild(this.dom_input); return Promise.resolve(undefined); } /** * [implementation] */ read() { return Promise.resolve(this.dom_input.value); } /** * [implementation] */ write(value) { this.dom_input.value = value; return Promise.resolve(undefined); } } zoo_input.class_input_email = class_input_email; })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-input«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_input; (function (zoo_input) { /** * @author fenris */ class class_input_textarea { /** */ constructor() { this.dom_textarea = null; } /** * [implementation] */ setup(parent) { this.dom_textarea = document.createElement("textarea"); parent.appendChild(this.dom_textarea); return Promise.resolve(undefined); } /** * [implementation] */ read() { return Promise.resolve(this.dom_textarea.value); } /** * [implementation] */ write(value) { this.dom_textarea.value = value; return Promise.resolve(undefined); } } zoo_input.class_input_textarea = class_input_textarea; })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-input«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_input; (function (zoo_input) { /** */ function value_decode(datestring) { const parts = datestring.split("-"); return { "year": parseInt(parts[0]), "month": parseInt(parts[1]), "day": parseInt(parts[2]), }; } /** */ function value_encode(date) { return lib_plankton.string.coin("{{year}}-{{month}}-{{day}}", { "year": date.year.toFixed(0).padStart(4, "0"), "month": date.month.toFixed(0).padStart(2, "0"), "day": date.day.toFixed(0).padStart(2, "0"), }); } /** * @author fenris */ class class_input_date { /** */ constructor(options = {}) { options = Object.assign({ "required": false, }, options); this.required = options.required; this.dom_input = null; } /** * [implementation] */ setup(parent) { this.dom_input = document.createElement("input"); this.dom_input.setAttribute("type", "date"); if (!this.required) { // do nothing } else { this.dom_input.setAttribute("required", "required"); } parent.appendChild(this.dom_input); return Promise.resolve(undefined); } /** * [implementation] */ read() { if (this.required && (!this.dom_input.reportValidity())) { return Promise.reject("required"); } else { return Promise.resolve((this.dom_input.value === "") ? null : value_decode(this.dom_input.value)); } } /** * [implementation] */ write(value) { this.dom_input.value = ((value === null) ? "" : value_encode(value)); return Promise.resolve(undefined); } } zoo_input.class_input_date = class_input_date; })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-input«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_input; (function (zoo_input) { /** * @author fenris * @todo abstract */ class class_input_number { /** */ constructor(options = {}) { options = Object.assign({ "read_only": false, "step": null, }, options); this.read_only = options.read_only; this.step = options.step; this.dom_input = null; } /** * [implementation] */ setup(parent) { this.dom_input = document.createElement("input"); this.dom_input.setAttribute("type", "number"); // readonly { if (!this.read_only) { // do nothing } else { this.dom_input.setAttribute("disabled", "disabled"); } } // step { if (this.step === null) { // do nothing } else { this.dom_input.setAttribute("step", this.step.toString()); } } parent.appendChild(this.dom_input); return Promise.resolve(undefined); } /** * [implementation] */ read() { return Promise.resolve(Number(this.dom_input.value)); } /** * [implementation] */ write(value) { this.dom_input.value = value.toString(); return Promise.resolve(undefined); } } zoo_input.class_input_number = class_input_number; })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-input«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_input; (function (zoo_input) { /** * @author fenris */ class class_input_checkbox { /** */ constructor(options = {}) { options = Object.assign({ "read_only": false, "hooks_change": [], }, options); this.read_only = options.read_only; this.dom_input = null; this.hooks_change = options.hooks_change; } /** * [implementation] */ setup(parent) { this.dom_input = document.createElement("input"); this.dom_input.setAttribute("type", "checkbox"); { if (this.read_only) { this.dom_input.setAttribute("disabled", "disabled"); } else { // do nothing } } this.dom_input.addEventListener("change", (event) => { const value = event.target.checked; this.hooks_change.forEach(procedure => { procedure(value); }); }); // this.dom_input.style.display = "initial"; // n3o!!! parent.appendChild(this.dom_input); return Promise.resolve(undefined); } /** * [implementation] */ read() { return Promise.resolve(this.dom_input.checked); } /** * [implementation] */ write(value) { this.dom_input.checked = value; return Promise.resolve(undefined); } } zoo_input.class_input_checkbox = class_input_checkbox; })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-input«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_input; (function (zoo_input) { /** * @author fenris */ class class_input_selection { /** */ constructor(options) { this.options = options; this.dom_select = null; } /** * [implementation] */ setup(parent) { this.dom_select = document.createElement("select"); this.options.forEach((option) => { let dom_option = document.createElement("option"); dom_option.setAttribute("value", option.value); dom_option.textContent = option.label; this.dom_select.appendChild(dom_option); }); parent.appendChild(this.dom_select); return Promise.resolve(undefined); } /** * [implementation] */ read() { return Promise.resolve(this.dom_select.value); } /** * [implementation] */ write(value) { this.dom_select.value = value; return Promise.resolve(undefined); } } zoo_input.class_input_selection = class_input_selection; })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-input«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_input; (function (zoo_input) { /** * @author fenris */ class class_input_enumeration { /** */ constructor(options) { this.options = options; this.dom_inputs = []; } /** * [implementation] * @todo unique name */ setup(parent) { let dom_container = document.createElement("div"); dom_container.classList.add("plankton_input_enumeration"); const name = "radio"; this.options.forEach((option) => { let dom_label = document.createElement("label"); let dom_input = document.createElement("input"); dom_input.setAttribute("type", "radio"); dom_input.setAttribute("name", name); dom_input.setAttribute("value", option.value); dom_label.appendChild(dom_input); let dom_span = document.createElement("span"); dom_span.textContent = option.label; dom_label.appendChild(dom_span); dom_container.appendChild(dom_label); this.dom_inputs.push(dom_input); }); parent.appendChild(dom_container); return Promise.resolve(undefined); } /** * [implementation] */ read() { const active = (this.dom_inputs .filter(dom_input => dom_input.checked) .map(dom_input => dom_input.value)); if (active.length != 1) { return Promise.reject("nothing picked"); } else { return Promise.resolve(active[0]); } } /** * [implementation] */ write(value) { this.dom_inputs.forEach(dom_input => { dom_input.checked = (value === dom_input.value); }); return Promise.resolve(undefined); } } zoo_input.class_input_enumeration = class_input_enumeration; })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-input«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_input; (function (zoo_input) { /** * @author fenris */ class class_input_list { /** */ constructor(element_input_factory, options = {}) { options = Object.assign({ "translations": { "add": "add", "remove": "remove", }, }, options); this.element_input_factory = element_input_factory; this.elements = []; this.elements_container_dom = null; this.translations = options.translations; } /** */ clear() { this.elements_container_dom.innerHTML = ""; this.elements = []; return Promise.resolve(undefined); } /** */ async add() { // model let element_dom = document.createElement("div"); const input = this.element_input_factory(); this.elements.push({ "dom": element_dom, "input": input }); // view & control { element_dom.classList.add("plankton_input_list_element"); // remover { let remover_dom = document.createElement("button"); remover_dom.classList.add("plankton_input_list_button"); remover_dom.classList.add("plankton_input_list_element_remover"); remover_dom.setAttribute("title", this.translations.remove); remover_dom.textContent = "x"; remover_dom.addEventListener("click", (event) => { event.preventDefault(); const index = this.elements.findIndex(element => (element.input === input)); const element = this.elements[index]; this.elements_container_dom.removeChild(element.dom); this.elements.splice(index, 1); }); element_dom.appendChild(remover_dom); } // input { let input_dom = document.createElement("div"); input_dom.classList.add("plankton_input_list_element_input"); await input.setup(input_dom); element_dom.appendChild(input_dom); } this.elements_container_dom.appendChild(element_dom); } return Promise.resolve(input); } /** * [implementation] */ setup(parent) { let container_dom = document.createElement("div"); container_dom.classList.add("plankton_input_list"); // elements { this.elements_container_dom = document.createElement("div"); this.elements_container_dom.classList.add("plankton_input_list_elements"); container_dom.appendChild(this.elements_container_dom); } // foot { let footer_dom = document.createElement("div"); footer_dom.classList.add("plankton_input_list_foot"); // adder { let adder_dom = document.createElement("button"); adder_dom.classList.add("plankton_input_list_button"); adder_dom.classList.add("plankton_input_list_adder"); adder_dom.setAttribute("title", this.translations.add); adder_dom.textContent = "+"; adder_dom.addEventListener("click", (event) => { event.preventDefault(); this.add(); }); footer_dom.appendChild(adder_dom); } container_dom.appendChild(footer_dom); } parent.appendChild(container_dom); return Promise.resolve(undefined); } /** * [implementation] */ read() { return (Promise.all(this.elements .map((element, index) => (element.input.read() .then((element_value) => Promise.resolve({ "index": index, "value": element_value, }))))) .then((elements) => Promise.resolve(elements .sort((x, y) => ((x.index <= y.index) ? 0 : 1)) .map(element => element.value)))); } /** * [implementation] */ write(value) { return (this.clear() .then(() => Promise.all(value .map((element_value) => (this.add() .then(element_input => element_input.write(element_value)))))) .then(() => Promise.resolve(undefined))); } } zoo_input.class_input_list = class_input_list; })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-input«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_input; (function (zoo_input) { /** * @author fenris */ class class_input_password { /** */ constructor() { this.dom_input = null; } /** * [implementation] */ setup(parent) { this.dom_input = document.createElement("input"); this.dom_input.setAttribute("type", "password"); parent.appendChild(this.dom_input); return Promise.resolve(undefined); } /** * [implementation] */ read() { return Promise.resolve(this.dom_input.value); } /** * [implementation] */ write(value) { this.dom_input.value = value; return Promise.resolve(undefined); } } zoo_input.class_input_password = class_input_password; })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-input«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_input; (function (zoo_input) { /** * @author fenris */ class class_input_switch { /** */ constructor() { this.dom_element = null; this.value = false; } /** * [implementation] */ setup(parent) { this.dom_element = document.createElement("input"); this.dom_element.setAttribute("type", "text"); this.dom_element.setAttribute("readonly", "readonly"); this.dom_element.addEventListener("click", (event) => { this.write(!this.value); }); parent.appendChild(this.dom_element); return Promise.resolve(undefined); } /** * [implementation] */ read() { return Promise.resolve(this.value); } /** * [implementation] */ write(value) { this.value = value; if (value) { this.dom_element.value = "✔"; } else { this.dom_element.value = " "; } return Promise.resolve(undefined); } } zoo_input.class_input_switch = class_input_switch; })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-input«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_input; (function (zoo_input) { /** */ function value_encode(time) { return lib_plankton.string.coin("{{hour}}:{{minute}}", { "hour": time.hour.toFixed(0).padStart(2, "0"), "minute": time.minute.toFixed(0).padStart(2, "0"), }); } /** */ function value_decode(timestring) { const parts = timestring.split(":"); return { "hour": parseInt(parts[0]), "minute": parseInt(parts[1]), "second": 0, }; } /** * @author fenris */ class class_input_time { /** */ constructor() { this.dom_input = null; } /** * [implementation] */ setup(parent) { this.dom_input = document.createElement("input"); this.dom_input.setAttribute("type", "time"); parent.appendChild(this.dom_input); return Promise.resolve(undefined); } /** * [implementation] */ read() { return Promise.resolve((this.dom_input.value === "") ? null : value_decode(this.dom_input.value)); } /** * [implementation] */ write(value) { this.dom_input.value = ((value === null) ? "" : value_encode(value)); return Promise.resolve(undefined); } } zoo_input.class_input_time = class_input_time; })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-input«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-input« 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:zoo-input« 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:zoo-input«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_input; (function (zoo_input) { /** * @author fenris */ class class_input_group { /** */ constructor(fields_raw) { this.fields = (fields_raw .map(field_raw => ({ "name": field_raw.name, "input": field_raw.input, "label": (field_raw.label ?? null), "help": (field_raw.help ?? null), }))); } /** * [implementation] */ async setup(parent) { let dom_group = document.createElement("div"); dom_group.classList.add("plankton_input_group"); await Promise.all(this.fields.map(async (field) => { let dom_field = document.createElement("div"); dom_field.classList.add("plankton_input_group_field"); dom_field.setAttribute("rel", field.name); await Promise.all([ // label new Promise((resolve, reject) => { if (field.label === null) { // do nothing } else { let dom_label = document.createElement("label"); dom_label.classList.add("plankton_input_group_field_label"); dom_label.textContent = field.label; dom_field.appendChild(dom_label); } resolve(undefined); }), // help new Promise((resolve, reject) => { if (field.help === null) { // do nothing } else { let dom_help = document.createElement("span"); dom_help.classList.add("plankton_input_group_field_help"); dom_help.textContent = "(?)"; dom_help.setAttribute("title", field.help); dom_field.appendChild(dom_help); } resolve(undefined); }), // input field.input.setup(dom_field), ]); dom_group.appendChild(dom_field); return Promise.resolve(undefined); })); parent.appendChild(dom_group); return Promise.resolve(undefined); } /** * [implementation] */ async read() { return (Promise.all(this.fields.map((field) => (field.input.read() .then((value) => Promise.resolve({ "key": field.name, "value": value }))))) .then(pairs => Promise.resolve(Object.fromEntries(pairs.map((pair) => ([pair.key, pair.value])))))); } /** * [implementation] */ write(value) { return (Promise.resolve(Object.entries(value).map(([key, value]) => ({ "key": key, "value": value }))) .then((pairs) => Promise.all(pairs.map((pair) => (Promise.all(this.fields.filter((field) => (field.name === pair.key)) .map((field) => field.input.write(pair.value))) .then(() => Promise.resolve(undefined)))))) .then(() => Promise.resolve(undefined))); } } zoo_input.class_input_group = class_input_group; })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-form«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-form« 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:zoo-form« 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:zoo-form«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_form; (function (zoo_form) { /** */ function make(method, fields, encode, decode, options = {}) { options = Object.assign({ "class_prefix": "plankton_form_", }, options); return { "method": method, "fields": fields.map(field_raw => ({ "name": field_raw.name, "type": field_raw.type, "label": (field_raw.label ?? null), })), "encode": encode, "decode": decode, "class_prefix": options.class_prefix, "root_element": null, }; } zoo_form.make = make; /** */ function make_simple(method, fields, options = {}) { options = Object.assign({ "class_prefix": "plankton_form_", }, options); return { "method": method, "fields": fields.map(field_raw => ({ "name": field_raw.name, "type": field_raw.type, "label": (field_raw.label ?? null), })), "encode": x => x, "decode": x => x, "class_prefix": options.class_prefix, "root_element": null, }; } zoo_form.make_simple = make_simple; /** */ function class_name(subject, name) { return lib_plankton.string.coin("{{class_prefix}}{{name}}", { "class_prefix": subject.class_prefix, "name": name, }); } /** */ function field_input(subject, field) { return subject.root_element.querySelector(lib_plankton.string.coin(".{{class}}[name=\"{{name}}\"]", { "class": class_name(subject, "input"), "name": field.name, })); } /** */ function clear(subject) { subject.fields.forEach(field => { switch (field.type) { default: { field_input(subject, field).value = ""; break; } case "checkbox": { field_input(subject, field).checked = false; break; } } }); } zoo_form.clear = clear; /** */ function write(subject, value) { let raw = subject.encode(value); subject.fields.forEach(field => { switch (field.type) { default: { field_input(subject, field).value = raw[field.name]; break; } case "checkbox": { field_input(subject, field).checked = (raw[field.name] === "on"); break; } } }); } zoo_form.write = write; /** */ function read(subject) { let raw = {}; subject.fields.forEach(field => { switch (field.type) { default: { raw[field.name] = field_input(subject, field).value; break; } case "checkbox": { raw[field.name] = (field_input(subject, field).checked ? "on" : "off"); break; } } }); const value = subject.decode(raw); return value; } zoo_form.read = read; /** */ async function render(subject, target) { let element_form = document.createElement("form"); element_form.classList.add(class_name(subject, "form")); subject.fields.forEach(field => { let element_field = document.createElement("div"); element_field.classList.add(class_name(subject, "field")); // label { let element_label = document.createElement("label"); element_label.classList.add(class_name(subject, "label")); element_field.appendChild(element_label); element_label.textContent = (field.label ?? field.name.split("_").join(" ")); } // input { let element_input = document.createElement("input"); element_input.classList.add(class_name(subject, "input")); element_input.setAttribute("name", field.name); element_input.setAttribute("type", field.type); element_field.appendChild(element_input); } element_form.appendChild(element_field); }); subject.root_element = element_form; target.appendChild(element_form); return Promise.resolve(undefined); } zoo_form.render = render; })(zoo_form = lib_plankton.zoo_form || (lib_plankton.zoo_form = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-form«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-form« 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:zoo-form« 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:zoo-form«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_form; (function (zoo_form) { /** * @author fenris */ class class_form { /** */ constructor(encode, decode, input, actions) { this.encode = encode; this.decode = decode; this.input = input; this.actions = actions; } /** */ async setup(parent) { let dom_form = document.createElement("form"); dom_form.classList.add("plankton_form"); // input { let dom_container = document.createElement("div"); dom_container.classList.add("plankton_form_input"); await this.input.setup(dom_container); dom_form.appendChild(dom_container); } // actions { let dom_container = document.createElement("div"); dom_container.classList.add("plankton_form_actions"); this.actions.forEach((action) => { let dom_button = document.createElement("button"); // dom_button.setAttribute("type", "submit"); dom_button.textContent = action.label; if (action.target !== undefined) { dom_button.setAttribute("formaction", action.target); } if (action.procedure !== undefined) { dom_button.addEventListener("click", (event) => { event.preventDefault(); action.procedure(() => this.input_read(), () => this.input_read_raw()); }); } dom_container.appendChild(dom_button); }); dom_form.appendChild(dom_container); } parent.appendChild(dom_form); } /** */ input_read_raw() { return this.input.read(); } /** */ async input_read() { return this.decode(await this.input.read()); } /** */ input_write(value) { return this.input.write(this.encode(value)); } } zoo_form.class_form = class_form; })(zoo_form = lib_plankton.zoo_form || (lib_plankton.zoo_form = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-search«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-search« 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:zoo-search« 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:zoo-search«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_search; (function (zoo_search) { /** */ function class_name(subject, name) { return lib_plankton.string.coin("{{class_prefix}}{{name}}", { "class_prefix": subject.class_prefix, "name": name, }); } /** */ function make(routine, options) { options = Object.assign({ "encode_item": (item) => JSON.stringify(item), "hooks_select": [], "hooks_begin": [], "hooks_end": [], "class_prefix": "plankton_search_", }, options); return { "routine": routine, "encode_item": options.encode_item, "hooks_select": options.hooks_select, "hooks_begin": options.hooks_begin, "hooks_end": options.hooks_end, "class_prefix": options.class_prefix, "root_element": null, "state": null, }; } zoo_search.make = make; /** */ function hook_begin(subject, action) { subject.hooks_begin.push(action); } zoo_search.hook_begin = hook_begin; /** */ function hook_end(subject, action) { subject.hooks_end.push(action); } zoo_search.hook_end = hook_end; /** */ function hook_select(subject, action) { subject.hooks_select.push(action); } zoo_search.hook_select = hook_select; /** */ function clear(subject) { // term { let term_element = subject.root_element.querySelector("." + class_name(subject, "input")); term_element.value = ""; } // list { let list_element = subject.root_element.querySelector("." + class_name(subject, "hits")); list_element.innerHTML = ""; } return Promise.resolve(undefined); } /** */ async function fill(subject, term) { subject.hooks_begin.forEach(action => { action(term); }); // term { let term_element = subject.root_element.querySelector("." + class_name(subject, "input")); term_element.setAttribute("placeholder", "search"); term_element.value = term; } // list { let list_element = subject.root_element.querySelector("." + class_name(subject, "hits")); list_element.innerHTML = "searching …"; const hits = await subject.routine(term); list_element.innerHTML = ""; hits.forEach(item => { let item_element = document.createElement("li"); item_element.classList.add(class_name(subject, "item")); item_element.textContent = subject.encode_item(item); item_element.addEventListener("click", () => { subject.hooks_select.forEach(action => { action(item); }); }); list_element.appendChild(item_element); }); } // external { subject.hooks_end.forEach(action => { action(); }); } return Promise.resolve(undefined); } /** */ async function set_state(subject, state) { if ((subject.state !== null) && (state.term === subject.state.term)) { // do nothing } else { subject.state = state; if (state.term === null) { await clear(subject); } else { await fill(subject, state.term); } } return Promise.resolve(undefined); } zoo_search.set_state = set_state; /** */ async function render(subject, target, options = {}) { options = Object.assign({ "state": { "term": null }, }, options); let container_element = document.createElement("div"); container_element.classList.add(class_name(subject, "search")); // form { let form_element = document.createElement("form"); // term { let term_element = document.createElement("input"); term_element.setAttribute("type", "search"); term_element.setAttribute("name", "term"); term_element.classList.add(class_name(subject, "input")); form_element.appendChild(term_element); } // submit { let submit_element = document.createElement("input"); submit_element.setAttribute("type", "submit"); submit_element.classList.add(class_name(subject, "submit")); form_element.appendChild(submit_element); } form_element.addEventListener("submit", (event) => { event.preventDefault(); const form_data = new FormData(form_element); const term = form_data.get("term"); set_state(subject, { "term": term }); }); container_element.appendChild(form_element); } // hits { let hits_element = document.createElement("ul"); hits_element.classList.add(class_name(subject, "hits")); container_element.appendChild(hits_element); } subject.root_element = container_element; target.appendChild(container_element); await set_state(subject, options.state); return Promise.resolve(undefined); } zoo_search.render = render; })(zoo_search = lib_plankton.zoo_search || (lib_plankton.zoo_search = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-editor«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-editor« 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:zoo-editor« 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:zoo-editor«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_editor; (function (zoo_editor) { /** */ let enum_mode; (function (enum_mode) { enum_mode["find"] = "find"; enum_mode["view"] = "view"; enum_mode["make"] = "make"; })(enum_mode = zoo_editor.enum_mode || (zoo_editor.enum_mode = {})); ; /** */ let enum_action; (function (enum_action) { enum_action["keep"] = "keep"; enum_action["save"] = "save"; enum_action["delete"] = "delete"; enum_action["find"] = "find"; enum_action["make"] = "make"; })(enum_action = zoo_editor.enum_action || (zoo_editor.enum_action = {})); ; /** */ let enum_function; (function (enum_function) { enum_function["seek"] = "seek"; enum_function["read"] = "read"; enum_function["create"] = "create"; enum_function["update"] = "update"; enum_function["delete"] = "delete"; })(enum_function = zoo_editor.enum_function || (zoo_editor.enum_function = {})); ; /** */ function make(store, form, options = {}) { options = Object.assign({ "functions": [ enum_function.seek, enum_function.read, enum_function.create, enum_function.update, enum_function.delete, ], "encode_hit": (hit) => lib_plankton.string.coin("[{{key}}] {{preview}}", { "key": JSON.stringify(hit.key), "preview": JSON.stringify(hit.preview), }), "hook_switch": null, "class_prefix": "plankton_editor_", }, options); return { "functions": options.functions, "store": store, /* // wrap store in order to restrict access according to allowed functions "store": new RestrictedStorage( store, ArrayListHelper::map( $this->functions, function (string $function): string {return self::$actionMap[$function];} ) ), */ "search": lib_plankton.zoo_search.make((term) => store.search(term), { "encode_item": options.encode_hit, }), "form": form, "hook_switch": options.hook_switch, "state": null, "class_prefix": options.class_prefix, "root_element": null, }; } zoo_editor.make = make; /** */ function class_name(subject, name) { return lib_plankton.string.coin("{{class_prefix}}{{name}}", { "class_prefix": subject.class_prefix, "name": name, }); } /** */ function map_function_to_store_action(function_) { switch (function_) { case enum_function.seek: return "seek"; case enum_function.read: return "read"; case enum_function.create: return "create"; case enum_function.update: return "update"; case enum_function.delete: return "delete"; } } /** */ function map_mode_to_functions(mode) { switch (mode) { case enum_mode.find: return [enum_function.seek]; case enum_mode.view: return [enum_function.read]; case enum_mode.make: return [enum_function.create]; } } /** */ function map_mode_to_actions(mode) { switch (mode) { case enum_mode.find: return [enum_action.make]; case enum_mode.view: return [enum_action.save, enum_action.delete, enum_action.find, enum_action.make]; case enum_mode.make: return [enum_action.keep, enum_action.find]; } } /** */ function map_action_to_class_body(action) { return ("action_" + action); } /** */ function wait(subject, mode) { subject.root_element.classList.toggle("waiting", mode); // loader { // view { subject.root_element.querySelector("." + class_name(subject, "loader")).style.display = (mode ? "" : "none"); } } /* // search { // view { ( subject.root_element.querySelector( "." + class_name(subject, "search") ) as HTMLElement ).style.display = ((! mode) ? "" : "none"); } } // form { // view { ( subject.root_element.querySelector( "." + class_name(subject, "form") ) as HTMLElement ).style.display = ((! mode) ? "" : "none"); } } // actions { // view { ( subject.root_element.querySelector( "." + class_name(subject, "actions") ) as HTMLElement ).style.display = ((! mode) ? "" : "none"); } } */ } /** */ async function set_state(subject, state) { const state_old = subject.state; subject.state = state; // container { if (state_old === null) { // do nothing } else { subject.root_element.classList.remove(state_old.mode); } subject.root_element.classList.add(state.mode); } // search { // model { await lib_plankton.zoo_search.set_state(subject.search, state.search_state); } // view { subject.root_element.querySelector("." + class_name(subject, "search")).style.display = ([enum_mode.find].includes(state.mode) ? "" : "none"); } } // form { // model { if (state.key === null) { lib_plankton.zoo_form.clear(subject.form); } else { lib_plankton.zoo_form.write(subject.form, await subject.store.read(state.key)); } } // view { subject.root_element.querySelector("." + class_name(subject, "form")).style.display = ([enum_mode.view, enum_mode.make].includes(state.mode) ? "" : "none"); } } // actions { // view { [ enum_action.keep, enum_action.save, enum_action.delete, enum_action.find, enum_action.make, ] .forEach(action => { subject.root_element.querySelector("." + class_name(subject, map_action_to_class_body(action))).style.visibility = (map_mode_to_actions(state.mode).includes(action) ? "" : "hidden"); }); } } // external { if (subject.hook_switch === null) { // do nothing } else { subject.hook_switch(state); } } } /** */ async function render(subject, target, options = {}) { options = Object.assign({ "state": { "mode": enum_mode.find, "key": null, "search_state": { "term": null }, }, }, options); subject.state = options.state; const element_all = document.createElement("div"); element_all.classList.add(class_name(subject, "container")); { // loader { const container_element = document.createElement("div"); container_element.classList.add(class_name(subject, "loader")); // text { const text_element = document.createElement("div"); text_element.textContent = "…"; container_element.appendChild(text_element); } element_all.appendChild(container_element); } // search { const container_element = document.createElement("div"); container_element.classList.add(class_name(subject, "search")); // search core { lib_plankton.zoo_search.hook_select(subject.search, async (hit) => { wait(subject, true); await set_state(subject, { "mode": enum_mode.view, "key": hit.key, "search_state": { "term": null }, }); wait(subject, false); }); lib_plankton.zoo_search.hook_begin(subject.search, (term) => { set_state(subject, { "mode": subject.state.mode, "key": subject.state.key, "search_state": { "term": term }, }); }); await lib_plankton.zoo_search.render(subject.search, container_element, { "state": options.state.search_state, }); } element_all.appendChild(container_element); } // form { const container_element = document.createElement("div"); container_element.classList.add(class_name(subject, "form")); // form core { await lib_plankton.zoo_form.render(subject.form, container_element); } element_all.appendChild(container_element); } // actions { let container_element = document.createElement("div"); container_element.classList.add(class_name(subject, "actions")); { [ { "value": enum_action.find, // TODO translate "label": "search", "procedure": async () => { wait(subject, true); set_state(subject, { "mode": enum_mode.find, "key": null, "search_state": { "term": null }, }); wait(subject, false); }, }, { "value": enum_action.make, // TODO translate "label": "new", "procedure": async () => { wait(subject, true); set_state(subject, { "mode": enum_mode.make, "key": null, "search_state": { "term": null }, }); wait(subject, false); }, }, { "value": enum_action.keep, // TODO translate "label": "save", "procedure": async () => { wait(subject, true); const value = lib_plankton.zoo_form.read(subject.form); const key = await subject.store.create(value); set_state(subject, { "mode": enum_mode.view, "key": key, "search_state": { "term": null }, }); wait(subject, false); }, }, { "value": enum_action.save, // TODO translate "label": "apply", "procedure": async () => { wait(subject, true); const value = lib_plankton.zoo_form.read(subject.form); await subject.store.update(subject.state.key, value); /* set_state( subject, { "mode": enum_mode.view, "key": subject.state.key, "search_state": {"term": null}, } ); */ wait(subject, false); }, }, { "value": enum_action.delete, // TODO translate "label": "delete", "procedure": async () => { if (confirm("sure?")) { wait(subject, true); await subject.store.delete(subject.state.key); set_state(subject, { "mode": enum_mode.find, "key": null, "search_state": { "term": null }, }); wait(subject, false); } else { // no nothing } }, }, ] .forEach(action => { let button_element = document.createElement("button"); button_element.classList.add(class_name(subject, "action")); button_element.classList.add(class_name(subject, map_action_to_class_body(action.value))); button_element.textContent = action.label; button_element.addEventListener("click", () => { action.procedure(); }); container_element.appendChild(button_element); }); } element_all.appendChild(container_element); } target.appendChild(element_all); } subject.root_element = element_all; set_state(subject, options.state); wait(subject, false); } zoo_editor.render = render; })(zoo_editor = lib_plankton.zoo_editor || (lib_plankton.zoo_editor = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:zoo-page«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:zoo-page« 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:zoo-page« 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:zoo-page«. If not, see . */ var lib_plankton; (function (lib_plankton) { var zoo_page; (function (zoo_page) { /** */ zoo_page._pool = {}; /** */ let _fallback = null; /** */ let _current = null; /** */ let _target_element = null; /** */ function encode(location) { return ("#" + ([location.name] .concat(Object.entries(location.parameters) .filter(([key, value]) => (value !== null)) .map(([key, value]) => (key + "=" + value))))); } zoo_page.encode = encode; /** */ function decode(encoded) { if (encoded === "") { return null; } else { if (!encoded.startsWith("#")) { return null; } else { const parts = encoded.slice(1).split(","); return { "name": parts[0], "parameters": Object.fromEntries(parts.slice(1) .map(part => { const parts_ = part.split("="); return [parts_[0], parts_[1]]; })), }; } } } /** * renders a page to the main element */ async function load(location) { // _target_element.innerHTML = "[loading …]"; _target_element.innerHTML = ""; if (location === null) { // do nothing } else { if (!(location.name in zoo_page._pool)) { _target_element.innerHTML = "not found"; } else { await zoo_page._pool[location.name](location.parameters, _target_element); _current = location; } } } /** */ function add_nav_entry(location, options = {}) { options = Object.assign({ "label": null, }, options); let ul_element = document.querySelector("nav > ul"); { let li_element = document.createElement("li"); { let a_element = document.createElement("a"); a_element.setAttribute("href", encode(location)); a_element.textContent = (options.label ?? location.name); li_element.appendChild(a_element); } ul_element.appendChild(li_element); } } zoo_page.add_nav_entry = add_nav_entry; /** * retrieves the location from the set URL */ function get() { return decode(window.location.hash); } /** * encodes a location in the URL and loads it */ function set(location) { window.location.hash = encode(location); } zoo_page.set = set; /** */ function register(location_name, handler, options = {}) { options = Object.assign({}, options); zoo_page._pool[location_name] = handler; } zoo_page.register = register; /** */ function init(target_element, options = {}) { options = Object.assign({ "pool": {}, "fallback": null, }, options); _target_element = target_element; _fallback = options.fallback; Object.entries(options.pool).forEach(([location_name, handler]) => { register(location_name, handler); }); window.addEventListener("hashchange", () => { const location_old = _current; const location_new = (get() ?? _fallback); if (((location_old === null) && (location_new !== null)) || ((location_old !== null) && (location_new !== null) && (location_old.name !== location_new.name))) { load(location_new); } else { // do nothing } }); } zoo_page.init = init; /** */ function start() { const location = (get() ?? _fallback); set(location); load(location); } zoo_page.start = start; })(zoo_page = lib_plankton.zoo_page || (lib_plankton.zoo_page = {})); })(lib_plankton || (lib_plankton = {}));