zeed 0.7.93 → 0.7.97
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-5RNW3KFD.js → chunk-7YV5VFZP.js} +2 -2
- package/dist/{chunk-5RNW3KFD.js.map → chunk-7YV5VFZP.js.map} +0 -0
- package/dist/chunk-BHQJ5YK3.js +5 -0
- package/dist/chunk-BHQJ5YK3.js.map +1 -0
- package/dist/{chunk-MD7M66DK.js → chunk-H5ICAAIH.js} +2 -2
- package/dist/{chunk-MD7M66DK.js.map → chunk-H5ICAAIH.js.map} +0 -0
- package/dist/index.all.cjs +8 -8
- package/dist/index.all.cjs.map +1 -1
- package/dist/index.all.d.ts +3 -3
- package/dist/index.all.js +1 -1
- package/dist/index.browser.cjs +3 -3
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.d.ts +2 -2
- package/dist/index.browser.js +1 -1
- package/dist/index.node.cjs +7 -7
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.d.ts +2 -2
- package/dist/index.node.js +1 -1
- package/dist/{log-colors-14b8f3f1.d.ts → log-colors-1600acaa.d.ts} +1 -1
- package/dist/{log-util-1f1d4daa.d.ts → log-util-0c3d62ff.d.ts} +1 -1
- package/dist/{uuid-3cbd91e7.d.ts → uuid-349b7a26.d.ts} +21 -7
- package/package.json +1 -1
- package/dist/chunk-A667DHTB.js +0 -5
- package/dist/chunk-A667DHTB.js.map +0 -1
package/dist/index.all.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.all.ts","../src/common/data/is.ts","../src/common/data/deep.ts","../src/common/log-filter.ts","../src/common/log-base.ts","../src/common/log-console.ts","../src/common/global.ts","../src/common/log.ts","../src/common/data/bin.ts","../src/common/crypto.ts","../src/common/csv.ts","../src/common/data/orderby.ts","../src/common/data/array.ts","../src/common/data/basex.ts","../src/common/data/camelcase.ts","../src/common/data/json.ts","../src/common/data/convert.ts","../src/common/data/currency.ts","../src/common/promise.ts","../src/common/data/day.ts","../src/common/data/html.ts","../src/common/data/math.ts","../src/common/data/path.ts","../src/common/data/regexp.ts","../src/common/data/sortable.ts","../src/common/data/url.ts","../src/common/data/utils.ts","../src/common/disposer.ts","../src/common/localhost.ts","../src/common/time.ts","../src/common/uuid.ts","../src/common/msg/emitter.ts","../src/common/msg/channel.ts","../src/common/msg/encoder.ts","../src/common/msg/messages.ts","../src/common/msg/pubsub.ts","../src/common/mutex.ts","../src/common/network.ts","../src/common/platform.ts","../src/common/pool.ts","../src/common/queue.ts","../src/common/storage/memstorage.ts","../src/common/throttle-debounce.ts","../src/node/crypto.ts","../src/node/env.ts","../src/node/filestorage.ts","../src/node/log-file.ts","../src/node/log-node.ts","../src/node/log-util.ts","../src/node/log-context-node.ts","../src/browser/base64.ts","../src/browser/gravatar.ts","../src/browser/localstorage.ts","../src/browser/log-colors.ts","../src/browser/log-browser.ts","../src/browser/log-browser-classic.ts","../src/browser/log-context-browser.ts"],"sourcesContent":["// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nexport * from \"./common\"\nexport * from \"./node\"\nexport * from \"./browser\"\n","// https://github.com/sindresorhus/is/ MIT\n// https://github.com/sindresorhus/ts-extras\n// https://github.com/sindresorhus/type-fest\n// https://github.com/antfu/utils\n\nexport type Primitive =\n | null\n | undefined\n | string\n | number\n | boolean\n | symbol\n | bigint\n\nexport function isObject(obj: unknown): obj is object {\n return obj != null && typeof obj === \"object\"\n}\n\nexport function isPrimitive(obj: unknown): obj is Primitive {\n return Object(obj) !== obj\n}\n\nexport function isArray(obj: unknown): obj is Array<any> {\n return Array.isArray(obj)\n}\n\nexport function isRecord(obj: unknown): obj is Record<string, any> {\n return isObject(obj) && !isArray(obj)\n}\n\nexport function isString(obj: unknown): obj is string {\n return typeof obj === \"string\"\n}\n\nexport function isNumber(obj: unknown): obj is number {\n return typeof obj === \"number\"\n}\n\nexport function isInteger(obj: unknown): obj is number {\n return typeof obj === \"number\" && Number.isInteger(obj)\n}\n\nexport function isSafeInteger(obj: unknown): obj is number {\n return typeof obj === \"number\" && Number.isSafeInteger(obj)\n}\n\nexport function isBoolean(obj: unknown): obj is boolean {\n return typeof obj === \"boolean\"\n}\n\nexport function isNullOrUndefined(obj: unknown): obj is null | undefined {\n return obj == null\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { isObject, isPrimitive } from \"./is\"\n\n// // https://stackoverflow.com/a/40294058/140927\n// // Handles cyclic references\n// export function deepClonePrimitives(obj, hash = new WeakMap()) {\n//\n// // primitives\n// if (Object(obj) !== obj) {\n// // log('Primitive', obj)\n// return obj\n// }\n//\n// // cyclic reference\n// if (hash.has(obj)) {\n// return hash.get(obj)\n// }\n//\n// let result\n//\n// // primitives as objects like new String(), new Number()\n// if (\n// obj instanceof String ||\n// obj instanceof Number ||\n// obj instanceof BigInt ||\n// obj instanceof Boolean ||\n// obj instanceof Symbol\n// ) {\n// result = new obj.constructor(obj.valueOf())\n// // hash.set(obj, result)\n// return result\n// }\n//\n// // log('Obj', obj)\n//\n// if (obj instanceof Set) {\n// result = new Set(obj)\n// } else if (obj instanceof Map) {\n// result = new Map(Array.from(obj, ([key, val]) => [key, deepClonePrimitives(val, hash)]))\n// } else if (obj instanceof Date) {\n// result = new Date(obj)\n// } else if (obj instanceof RegExp) {\n// result = new RegExp(obj.source, obj.flags)\n// } else if (Array.isArray(obj)) {\n// result = Array.from(obj, val => deepClonePrimitives(val, hash))\n// } else if (obj.constructor) {\n// result = new obj.constructor()\n// log('bj object', result)\n// } else if (obj instanceof Function || typeof obj === 'function') {\n// log('Keep object', obj, Object.getPrototypeOf(obj))\n// result = obj\n// } else {\n// result = Object.create(null)\n// }\n//\n// hash.set(obj, result)\n//\n// return Object.assign(result, ...Object.keys(obj).map(key => ({\n// [key]: deepClonePrimitives(obj[key], hash),\n// })))\n// }\n\nexport function deepEqual(a: any, b: any, hash = new WeakSet()) {\n // if both x and y are null or undefined and exactly the same\n if (a === b) {\n return true\n }\n\n // Cyclic\n if (hash.has(b)) {\n // console.log('cyclic')\n return true\n }\n\n if (!isPrimitive(b)) {\n hash.add(b)\n }\n\n // if they are not strictly equal, they both need to be Objects\n if (!(a instanceof Object) || !(b instanceof Object)) {\n return false\n }\n\n // they must have the exact same prototype chain, the closest we can do is\n // test there constructor.\n if (a.constructor !== b.constructor) {\n return false\n }\n\n // Shortcut to avoid to many loops\n if (a.length !== b.length) {\n return false\n }\n\n for (let p in a) {\n // other properties were tested using x.constructor === y.constructor\n if (!a.hasOwnProperty(p)) {\n continue\n }\n\n // allows to compare x[ p ] and y[ p ] when set to undefined\n if (!b.hasOwnProperty(p)) {\n return false\n }\n\n let aa = a[p]\n let bb = b[p]\n\n // if they have the same strict value or identity then they are equal\n // if (aa === bb) {\n // console.log('eq', typeof bb)\n // if (bb != null) hash.set(bb, true)\n // continue\n // }\n //\n // // Numbers, Strings, Functions, Booleans must be strictly equal\n // if (typeof (aa) !== 'object') {\n // return false\n // }\n\n // Objects and Arrays must be tested recursively\n if (!deepEqual(aa, bb, hash)) {\n return false\n }\n }\n\n // allows x[ p ] to be set to undefined\n for (let p in b) {\n if (b.hasOwnProperty(p) && !a.hasOwnProperty(p)) {\n return false\n }\n }\n\n return true\n}\n\nexport function deepMerge(target: any, ...sources: any[]) {\n for (let source of sources) {\n if (!isObject(target)) {\n target = {}\n }\n\n if (source == null) continue\n\n Object.keys(source).forEach((key) => {\n const targetValue = target[key]\n const sourceValue = source[key]\n\n if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {\n target[key] = targetValue.concat(sourceValue)\n } else if (isObject(targetValue) && isObject(sourceValue)) {\n target[key] = deepMerge(Object.assign({}, targetValue), sourceValue)\n } else {\n target[key] = sourceValue\n }\n })\n }\n\n return target\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { LogLevel, LogLevelAlias } from \"./log-base\"\n\ninterface NamespaceFilter {\n (name: string): boolean\n accept: RegExp[]\n reject: RegExp[]\n filter: string\n}\n\nexport function getNamespaceFilterString(defaultNamespaceFilter: any): string {\n if (\n defaultNamespaceFilter === true ||\n defaultNamespaceFilter === \"true\" ||\n defaultNamespaceFilter === \"1\" ||\n (typeof defaultNamespaceFilter === \"number\" && defaultNamespaceFilter !== 0)\n ) {\n defaultNamespaceFilter = \"*\"\n } else if (\n defaultNamespaceFilter === false ||\n defaultNamespaceFilter === \"false\" ||\n defaultNamespaceFilter === 0 ||\n defaultNamespaceFilter === \"0\" ||\n defaultNamespaceFilter == null ||\n defaultNamespaceFilter === \"null\" ||\n defaultNamespaceFilter === \"undefined\"\n ) {\n defaultNamespaceFilter = \"\"\n } else {\n defaultNamespaceFilter = String(defaultNamespaceFilter)\n }\n return defaultNamespaceFilter\n}\n\nconst defaultNamespaceFilter: string = getNamespaceFilterString(\n typeof process !== \"undefined\"\n ? process.env.ZEED ?? process.env.DEBUG\n : typeof localStorage !== \"undefined\"\n ? localStorage.zeed ?? localStorage.debug\n : \"*\"\n)\n\n/**\n * Filter as described here https://github.com/visionmedia/debug#wildcards\n *\n * @param filter Namespace filter\n * @returns Function to check if filter applies\n */\nexport function useNamespaceFilter(\n filter: string = defaultNamespaceFilter\n): NamespaceFilter {\n let fn: any // (name: string) => boolean\n let reject = [] as RegExp[]\n let accept = [] as RegExp[]\n\n if (!filter) {\n fn = function (name: string) {\n return false\n }\n } else if (filter === \"*\") {\n fn = function (name: string) {\n return true\n }\n } else {\n let i\n const split = filter.split(/[\\s,]+/)\n const len = split.length\n for (i = 0; i < len; i++) {\n if (!split[i]) {\n // ignore empty strings\n continue\n }\n let template = split[i].replace(/\\*/g, \".*?\")\n if (template[0] === \"-\") {\n reject.push(new RegExp(\"^\" + template.substr(1) + \"$\"))\n } else {\n accept.push(new RegExp(\"^\" + template + \"$\"))\n }\n }\n\n fn = function (name: string) {\n if (reject.length === 0 && accept.length === 0) {\n return true\n }\n let i, len\n for (i = 0, len = reject.length; i < len; i++) {\n if (reject[i].test(name)) {\n return false\n }\n }\n for (i = 0, len = accept.length; i < len; i++) {\n if (accept[i].test(name)) {\n return true\n }\n }\n return false\n }\n }\n fn.accept = accept\n fn.reject = reject\n fn.filter = filter\n return fn as NamespaceFilter\n}\n\nconst defaultLevelFilter: any =\n typeof process !== \"undefined\"\n ? process.env.ZEED_LEVEL ?? process.env.LEVEL ?? process.env.DEBUG_LEVEL\n : typeof localStorage !== \"undefined\"\n ? localStorage.zeed_level ?? localStorage.level ?? localStorage.debug_level\n : undefined\n\nexport function useLevelFilter(\n filter: string | number = defaultLevelFilter\n): (level: LogLevel) => boolean {\n let filterLevel: LogLevel = LogLevel.all\n if (typeof filter === \"string\") {\n const l = LogLevelAlias[filter.toLocaleLowerCase().trim()]\n if (l != null) filterLevel = l\n } else if (typeof filter === \"number\") {\n filterLevel = filter as number\n }\n return (level) => level >= filterLevel\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { deepEqual } from \"./data/deep\"\nimport { LoggerConsoleHandler } from \"./log-console\"\nimport { useNamespaceFilter } from \"./log-filter\"\n\nexport enum LogLevel {\n all = -1,\n debug = 0,\n info,\n warn,\n error,\n fatal,\n off = Infinity,\n}\n\nexport const LogLevelAlias: Record<string, LogLevel> = {\n \"*\": LogLevel.all,\n a: LogLevel.all,\n all: LogLevel.all,\n d: LogLevel.debug,\n dbg: LogLevel.debug,\n debug: LogLevel.debug,\n i: LogLevel.info,\n inf: LogLevel.info,\n info: LogLevel.info,\n w: LogLevel.warn,\n warn: LogLevel.warn,\n warning: LogLevel.warn,\n e: LogLevel.error,\n err: LogLevel.error,\n error: LogLevel.error,\n fatal: LogLevel.fatal,\n off: LogLevel.off,\n \"-\": LogLevel.off,\n}\n\nexport interface LogMessage {\n level: LogLevel\n name: string\n messages: any[]\n line?: number\n file?: string\n timestamp?: number\n}\n\nexport type LogHandler = (msg: LogMessage) => void\n\nexport interface LoggerInterface {\n (...messages: any[]): void\n\n /** @deprecated use .level = LogLevel.off or LogLevel.all */\n active: boolean\n\n level: LogLevel\n\n debug(...messages: any[]): void\n\n info(...messages: any[]): void\n\n warn(...messages: any[]): void\n\n error(...messages: any[]): void\n\n assert(cond: any, ...messages: any[]): void\n\n /** @deprecated use .assert */\n assertEqual(value: any, expected: any, ...args: any[]): void\n\n /** @deprecated use .assert */\n assertNotEqual(value: any, expected: any, ...args: any[]): void\n\n extend(prefix: string): LoggerInterface\n\n factory?: LoggerContextInterface\n}\n\nexport interface LoggerContextInterface {\n (name?: string): LoggerInterface\n registerHandler(handler: LogHandler): void\n setFilter(namespaces: string): void\n setHandlers(handlers?: (LogHandler | undefined | null)[]): void\n setLock(lock: boolean): void\n setLogLevel(level?: LogLevel): void\n setFactory(factory: (name?: string) => LoggerInterface): void\n}\n\nexport interface LogHandlerOptions {\n level?: LogLevel\n filter?: string\n colors?: boolean\n levelHelper?: boolean\n nameBrackets?: boolean\n padding?: number\n fill?: number\n stack?: boolean | number\n}\n\nexport function LoggerContext(prefix: string = \"\"): LoggerContextInterface {\n let logHandlers: LogHandler[] = [LoggerConsoleHandler()]\n let logAssertLevel: LogLevel = LogLevel.warn\n let logCheckNamespace = (name: string) => true\n let logLock = false\n let logFactory = LoggerBaseFactory\n\n function LoggerBaseFactory(name: string = \"\"): LoggerInterface {\n log.extend = function (prefix: string): LoggerInterface {\n return logFactory(name ? `${name}:${prefix}` : prefix)\n }\n\n const emit = (msg: LogMessage) => {\n if (log.active === true) {\n if (msg.level >= Logger.level && msg.level >= log.level) {\n if (logCheckNamespace(name)) {\n for (let handler of logHandlers) {\n if (handler) handler(msg)\n }\n }\n }\n }\n }\n\n function log(...messages: any[]) {\n emit({\n name,\n messages,\n level: LogLevel.debug,\n })\n }\n\n log.active = true\n log.level = LogLevel.all\n\n log.debug = function (...messages: any[]) {\n emit({\n name,\n messages,\n level: LogLevel.debug,\n })\n }\n\n log.info = function (...messages: any[]) {\n emit({\n name,\n messages,\n level: LogLevel.info,\n })\n }\n\n log.warn = function (...messages: any[]) {\n emit({\n name,\n messages,\n level: LogLevel.warn,\n })\n }\n\n log.error = function (...messages: any[]) {\n emit({\n name,\n messages,\n level: LogLevel.error,\n })\n }\n\n // fatal(...args: any[]) {\n // console.error(...args)\n // },\n\n log.assert = function (cond: any, ...messages: any[]) {\n if (!cond) {\n if (typeof console !== undefined) {\n if (console.assert) {\n // https://developer.mozilla.org/de/docs/Web/API/Console/assert\n console.assert(cond, ...messages)\n } else {\n console.error(`Assert did fail with: ${cond}`, ...messages)\n }\n }\n emit({\n name,\n messages: messages || [`Assert did fail with: ${cond}`],\n level: logAssertLevel,\n })\n // try {\n // if (typeof expect !== undefined) {\n // expect(cond).toBeTruthy()\n // }\n // } catch (err) {\n // methods.warn(...args)\n // }\n }\n }\n\n log.assertEqual = function (value: any, expected: any, ...args: any[]) {\n let equal = deepEqual(value, expected)\n if (!equal) {\n log.assert(\n equal,\n `Assert did fail. Expected ${expected} got ${value}`,\n expected,\n value,\n ...args\n )\n // } else {\n // methods.debug(`Passed equal`)\n }\n }\n\n log.assertNotEqual = function (value: any, expected: any, ...args: any[]) {\n let equal = deepEqual(value, expected)\n if (equal) {\n log.assert(\n equal,\n `Assert did fail. Expected ${expected} not to be equal with ${value}`,\n expected,\n value,\n ...args\n )\n // } else {\n // methods.debug(`Passed not equal check`)\n }\n }\n\n return log\n }\n\n function Logger(name: string = \"\"): LoggerInterface {\n return logFactory(name)\n }\n\n Logger.registerHandler = function (handler: LogHandler) {\n logHandlers.push(handler)\n }\n\n Logger.setFilter = function (namespaces: string) {\n logCheckNamespace = useNamespaceFilter(namespaces)\n }\n\n Logger.setLock = (lock: boolean = true) => (logLock = lock)\n\n Logger.setHandlers = function (handlers: LogHandler[] = []) {\n if (logFactory !== LoggerBaseFactory) {\n logFactory = LoggerBaseFactory\n }\n if (logLock) return\n logHandlers = [...handlers].filter((h) => typeof h === \"function\")\n }\n\n Logger.level = LogLevel.all\n\n /** @deprecated */\n Logger.setLogLevel = function (level: LogLevel = LogLevel.all) {\n if (logLock) return\n Logger.level = level\n }\n\n Logger.setFactory = function (\n factory: (name?: string) => LoggerInterface\n ): void {\n if (logLock) return\n logFactory = factory\n }\n\n return Logger\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { LogHandler, LogHandlerOptions, LogLevel, LogMessage } from \"./log-base\"\nimport { useLevelFilter, useNamespaceFilter } from \"./log-filter\"\n\n/**\n * Very basic logger. Please take a look at the browser and node\n * optimized loggers. This one is just the absolute fallback option.\n *\n * @param level Log level\n * @returns Logger\n */\nexport function LoggerConsoleHandler(opt: LogHandlerOptions = {}): LogHandler {\n const {\n level = undefined,\n filter = undefined,\n colors = true,\n levelHelper = false,\n nameBrackets = true,\n padding = 16,\n } = opt\n const matchesNamespace = useNamespaceFilter(filter)\n const matchesLevel = useLevelFilter(level)\n return (msg: LogMessage) => {\n if (!matchesLevel(msg.level)) return\n if (!matchesNamespace(msg.name)) return\n let name = msg.name ? `[${msg.name}]` : \"\"\n switch (msg.level) {\n case LogLevel.info:\n console.info(`I|* ${name}`, ...msg.messages)\n break\n case LogLevel.warn:\n console.warn(`W|** ${name}`, ...msg.messages)\n break\n case LogLevel.error:\n console.error(`E|*** ${name}`, ...msg.messages)\n break\n default:\n console.debug(`D| ${name}`, ...msg.messages)\n break\n }\n }\n}\n","// Global context across build systems etc.\n\ndeclare global {\n interface ZeedGlobalContext {}\n}\n\ninterface ZeedGlobalIntegration {\n _zeedGlobal?: ZeedGlobalContext\n}\n\nfunction _global(): ZeedGlobalIntegration {\n if (typeof self !== \"undefined\") return self as ZeedGlobalIntegration\n if (typeof window !== \"undefined\") return window as ZeedGlobalIntegration\n if (typeof global !== \"undefined\") return global as ZeedGlobalIntegration\n if (typeof globalThis !== \"undefined\")\n return globalThis as ZeedGlobalIntegration\n throw new Error(\"unable to locate global object\")\n}\n\nexport function getGlobalContext(): ZeedGlobalContext {\n let gcontext = _global()\n if (gcontext._zeedGlobal == null) {\n gcontext._zeedGlobal = {}\n }\n return gcontext._zeedGlobal\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { LoggerConsoleHandler } from \"./log-console\"\nimport { getGlobalContext } from \"./global\"\nimport { LoggerContext, LoggerContextInterface } from \"./log-base\"\n\n// Global logger to guarantee all submodules use the same logger instance\n\nlet globalLogger: LoggerContextInterface\n\ndeclare global {\n interface ZeedGlobalContext {\n logger?: any // Should be LoggerContextInterface, but avoid compiler issues this way\n }\n}\n\nfunction getLoggerContext() {\n let logger = LoggerContext()\n logger.setHandlers([LoggerConsoleHandler()])\n return logger\n}\n\ntry {\n let _global = getGlobalContext()\n if (_global != null) {\n if (_global?.logger == null) {\n globalLogger = getLoggerContext()\n _global.logger = globalLogger\n } else {\n globalLogger = _global.logger\n }\n } else {\n globalLogger = getLoggerContext()\n }\n} catch (e) {\n globalLogger = getLoggerContext()\n}\n\n// /** @deprecated Use `Logger` instead, it is global as well */\n// export const GlobalLogger = globalLogger\n\nexport const Logger = globalLogger\n","import { Logger } from \"../log\"\n\nconst log = Logger(\"bin\")\n\nexport type BinInput = Uint8Array | ArrayBuffer | string | number[]\n\n// if (typeof TextEncoder !== \"undefined\") {\n\nlet _textEncoder: TextEncoder | undefined\nexport function stringToUInt8Array(text: string): Uint8Array {\n if (typeof TextEncoder === \"undefined\") return new Uint8Array()\n const textEncoder = _textEncoder ?? (_textEncoder = new TextEncoder())\n return textEncoder.encode(text.normalize(\"NFC\"))\n}\n\nlet _textDecoder: TextDecoder | undefined\nexport function Uint8ArrayToString(bin: Uint8Array): string {\n if (typeof TextDecoder === \"undefined\") return \"\"\n const textDecoder =\n _textDecoder ??\n (_textDecoder = new TextDecoder(\"utf-8\", { ignoreBOM: true }))\n return textDecoder.decode(bin).normalize(\"NFC\")\n}\n\nexport function toUint8Array(data: BinInput): Uint8Array {\n if (data instanceof ArrayBuffer) return new Uint8Array(data)\n if (typeof data === \"string\") return stringToUInt8Array(data)\n if (data.length) return new Uint8Array(data)\n // @ts-ignore\n return data\n}\n\nexport function toHex(bin: BinInput): string {\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(toUint8Array(bin)).toString(\"hex\")\n }\n const h = \"0123456789abcdef\"\n let s = \"\"\n for (const v of [...toUint8Array(bin)]) {\n s += h[v >> 4] + h[v & 15]\n }\n return s\n}\n\nexport function toBase64(bin: BinInput): string {\n const bytes = toUint8Array(bin)\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(bytes).toString(\"base64\")\n }\n let s = \"\"\n for (let i = 0; i < bytes.byteLength; i++) {\n s += String.fromCharCode(bytes[i])\n }\n return btoa(s)\n}\n\nexport function toBase64Url(bin: BinInput): string {\n const bytes = toUint8Array(bin)\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(bytes).toString(\"base64url\")\n }\n let s = \"\"\n for (let i = 0; i < bytes.byteLength; i++) {\n s += String.fromCharCode(bytes[i])\n }\n return btoa(s).replace(/\\+/g, \"-\").replace(/\\//g, \"_\")\n}\n\n/** Compare contents of binary arrays */\nexport function equalBinary(\n a: ArrayBuffer | Uint8Array,\n b: ArrayBuffer | Uint8Array\n): boolean {\n if (a.byteLength !== b.byteLength) return false\n const aa = toUint8Array(a)\n const bb = toUint8Array(b)\n for (let i = 0; i < aa.length; i++) {\n if (aa[i] !== bb[i]) {\n return false\n }\n }\n return true\n}\n\nexport function jsonToUint8Array(json: any): Uint8Array {\n try {\n return stringToUInt8Array(JSON.stringify(json))\n } catch (err) {\n log.warn(\"jsonToUint8Array\", json)\n throw err\n }\n}\n\nexport function Uint8ArrayToJson<T = any>(data: Uint8Array): T {\n try {\n return JSON.parse(Uint8ArrayToString(data))\n } catch (err) {\n log.warn(\"Uint8ArrayToJson\", data)\n throw err\n }\n}\n","import { BinInput, equalBinary, toUint8Array } from \"./data/bin\"\n\n/* \n\n// Web Crypto polyfill for node 15+:\n// https://nodejs.org/api/webcrypto.html\n\nimport { webcrypto } from \"crypto\"\n\nif (globalThis.crypto == null) {\n globalThis.crypto = webcrypto\n}\n*/\n\n// todo: should fallback to node crypto\nexport function randomUint8Array(length: number = 16): Uint8Array {\n let randomBytes = new Uint8Array(length)\n if (typeof crypto !== \"undefined\" && crypto.getRandomValues) {\n crypto.getRandomValues(randomBytes)\n } else {\n for (let i = 0; i < length; i++) {\n // Math.random: \"...range 0 to less than 1 (inclusive of 0, but not 1)\"\n // 0.9... * 0xff < 255 therefore * 0x100\n randomBytes[i] = Math.floor(Math.random() * 0x100) // 0...255\n }\n }\n return randomBytes\n}\n\nconst DEFAULT_HASH_ALG = \"SHA-256\"\nconst DEFAULT_CRYPTO_ALG = \"AES-GCM\"\nconst DEFAULT_DERIVE_ALG = \"PBKDF2\"\n\nexport async function digest(\n message: BinInput,\n algorithm: AlgorithmIdentifier = DEFAULT_HASH_ALG\n): Promise<ArrayBuffer> {\n return await crypto.subtle.digest(algorithm, toUint8Array(message))\n}\n\nexport async function deriveKeyPbkdf2(\n secret: BinInput,\n opt: {\n iterations?: number\n salt?: BinInput\n } = {}\n): Promise<CryptoKey> {\n const secretBuffer = toUint8Array(secret)\n const keyMaterial = await crypto.subtle.importKey(\n \"raw\",\n secretBuffer,\n DEFAULT_DERIVE_ALG,\n false,\n [\"deriveKey\"]\n )\n return await crypto.subtle.deriveKey(\n {\n name: DEFAULT_DERIVE_ALG,\n salt: opt.salt ? toUint8Array(opt.salt) : new Uint8Array(0),\n iterations: opt.iterations ?? 100000,\n hash: DEFAULT_HASH_ALG,\n },\n keyMaterial,\n {\n name: DEFAULT_CRYPTO_ALG,\n length: 256,\n },\n true,\n [\"encrypt\", \"decrypt\"]\n )\n}\n\nconst MAGIC_ID = new Uint8Array([1, 1])\n\nexport async function encrypt(\n data: Uint8Array,\n key: CryptoKey\n): Promise<Uint8Array> {\n const iv = randomUint8Array(12)\n const cipher = await crypto.subtle.encrypt(\n { name: DEFAULT_CRYPTO_ALG, iv },\n key,\n data\n )\n const binCypher = new Uint8Array(cipher)\n const bufferLength = MAGIC_ID.length + iv.length + binCypher.length\n const buffer = new Uint8Array(bufferLength)\n let pos = 0\n buffer.set(MAGIC_ID, pos)\n pos += MAGIC_ID.length\n buffer.set(iv, pos)\n pos += iv.length\n buffer.set(binCypher, pos)\n return buffer\n}\n\nexport async function decrypt(\n data: Uint8Array,\n key: CryptoKey\n): Promise<Uint8Array> {\n let magic = data.subarray(0, 2)\n if (!equalBinary(magic, MAGIC_ID)) {\n return Promise.reject(`Unknown magic ${magic}`)\n }\n let iv = data.subarray(2, 2 + 12)\n let cipher = data.subarray(2 + 12, data.length)\n const plain = await crypto.subtle.decrypt(\n { name: DEFAULT_CRYPTO_ALG, iv },\n key,\n cipher\n )\n return new Uint8Array(plain)\n}\n","/*\n csv-express\n Forked and modified by John J Czaplewski <jczaplew@gmail.com>\n Copyright 2011 Seiya Konno <nulltask@gmail.com>\n MIT Licensed\n\n https://github.com/jczaplew/csv-express/blob/master/lib/csv-express.js\n */\n\n// Configurable settings\nconst separator = \",\"\nconst preventCast = false\nconst ignoreNullOrUndefined = true\n\n// Stricter parseFloat to support hexadecimal strings from\n// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/parseFloat#A_stricter_parse_function\nfunction filterFloat(value: string) {\n if (/^([-+])?([0-9]+(\\.[0-9]+)?|Infinity)$/.test(value)) {\n return Number(value)\n }\n return NaN\n}\n\nfunction escape(field: any) {\n if (ignoreNullOrUndefined && field == undefined) {\n return \"\"\n }\n if (preventCast) {\n return '=\"' + String(field).replace(/\"/g, '\"\"') + '\"'\n }\n if (!isNaN(filterFloat(field)) && isFinite(field)) {\n return parseFloat(field)\n }\n return '\"' + String(field).replace(/\"/g, '\"\"') + '\"'\n}\n\nexport function csv(data: any[], headerRow: string[]): string {\n let body = \"\"\n\n // Append the header row to the response if requested\n if (headerRow) {\n body = headerRow.join(separator) + \"\\r\\n\"\n }\n\n // Convert the data to a CSV-like structure\n for (let i = 0; i < data.length; i++) {\n body += data[i].map(escape).join(separator) + \"\\r\\n\"\n }\n\n return body\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nexport function parseOrderby(value: string = \"\"): {\n field: string\n orderby: string\n asc: boolean\n desc: boolean\n} {\n let [field = \"\", orderby = \"asc\"] = value.split(\" \")\n orderby = orderby.toLowerCase()\n return {\n field,\n orderby,\n asc: orderby !== \"desc\",\n desc: orderby === \"desc\",\n }\n}\n\nexport function composeOrderby(field: string, asc: boolean = true): string {\n return `${field} ${asc ? \"asc\" : \"desc\"}`\n}\n\n// Classic compare function with direction flag\nexport function cmp(a: any, b: any, asc: boolean = true): number {\n const aa = a || 0\n const bb = b || 0\n return aa > bb ? (asc ? 1 : -1) : aa < bb ? (asc ? -1 : 1) : 0\n}\n\nexport function sortedOrderby<T>(values: T[], ...orderby: string[]): T[] {\n if (orderby.length > 0) {\n let orderByList = orderby.map(parseOrderby)\n // let { field, asc } = parseOrderby(orderby)\n //if (field != null && typeof field === \"string\") {\n // let bigger = asc ? 1 : -1\n // let smaller = asc ? -1 : 1\n let sortValues = Array.from(values)\n sortValues.sort((a: any, b: any): number => {\n for (let { field, asc } of orderByList) {\n const result = cmp(a[field], b[field], asc)\n if (result !== 0) return result\n }\n return 0\n // const aa = a[field] || 0\n // const bb = b[field] || 0\n // return aa > bb ? bigger : aa < bb ? smaller : 0\n })\n return sortValues\n }\n return values\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { NestedArray } from \"../types\"\nimport { cmp } from \"./orderby\"\n\nexport function arrayUnique<T>(x: T[]): T[] {\n return x.filter((n: any, index: any) => x.indexOf(n) === index)\n}\n\nexport function arrayMinus<T>(x: T[], y: T[]): T[] {\n return arrayUnique(x.filter((n: any) => !y.includes(n)))\n}\n\nexport function arrayUnion<T>(...a: T[][]): T[] {\n return arrayUnique(a.reduce((acc: T[] = [], value) => acc.concat(value), []))\n}\n\n/** `[1,[2,3]]` becomes `[1,2,3]` */\nexport function arrayFlatten<T>(...list: NestedArray<T>[]): T[] {\n return list.flat(Infinity)\n}\n\nexport function arrayIntersection<T>(x: T[], y: T[]): T[] {\n return arrayUnique<T>(x).filter((n: any) => y.includes(n))\n}\n\nexport function arraySymmetricDifference<T>(x: T[], y: T[]): T[] {\n return arrayMinus(arrayUnion(x, y), arrayIntersection(x, y))\n // return arrayUnique(x.filter(n => !y.includes(n)).concat(y.filter(n => !x.includes(n))))\n}\n\n// export function arrayApply<T>(fn: any, a: T[]): T[] {\n// return a.reduce(fn, [])\n// }\n\nexport function arrayRemoveElement<T>(arr: T[], el: T): T[] {\n if (arr && Array.isArray(arr)) {\n let index\n while ((index = arr.indexOf(el)) !== -1) {\n // log(\"arrayRemoveElement remove\", index, el)\n arr.splice(index, 1)\n }\n // log(\"arrayRemoveElement result\", arr)\n return arr\n }\n // log(\"arrayRemoveElement no array\", arr, el)\n return []\n}\n\n/** Only have it once in the set */\nexport function arraySetElement<T>(arr: T[], el: T): T[] {\n if (!arr.includes(el)) arr.push(el)\n return arr\n}\n\n// via https://stackoverflow.com/a/49587869 and Erwin\nexport function arrayFilterInPlace<T>(array: T[], fn: (el: T) => boolean): T[] {\n array.splice(0, array.length, ...array.filter(fn))\n return array\n}\n\n// via https://stackoverflow.com/a/49587869 and Erwin\nexport function arrayToggleInPlace<T>(array: T[], el: T): T[] {\n const index = array.findIndex((e) => e === el)\n if (index >= 0) array.splice(index, 1)\n else array.push(el)\n return array\n}\n\nexport function arrayEmptyInPlace<T>(array: T[]): T[] {\n array.splice(0, array.length)\n return array\n}\n\nexport function arraySorted<T>(\n arr: Iterable<T> | ArrayLike<T>,\n cond: ((a: T, b: T) => number) | undefined = cmp\n): T[] {\n return Array.from(arr).sort(cond)\n}\n\nexport function arraySortedNumbers(arr: number[]): number[] {\n return arraySorted(arr, (l: number, r: number) => l - r)\n}\n\nexport function arrayIsEqual<T>(array1: T[], array2: T[]): boolean {\n return (\n array1.length === array2.length &&\n array1.every((value, index) => value === array2[index])\n )\n}\n\nexport function arrayShuffleInPlace<T>(array: T[]): T[] {\n array.sort(() => (Math.random() > 0.5 ? 1 : -1))\n\n // Alternative https://github.com/sindresorhus/array-shuffle/blob/main/index.js#L8\n // for (let index = array.length - 1; index > 0; index--) {\n // \tconst newIndex = Math.floor(Math.random() * (index + 1));\n // \t[array[index], array[newIndex]] = [array[newIndex], array[index]];\n // }\n\n return array\n}\n\nexport function arrayShuffle<T>(array: T[]): T[] {\n return arrayShuffleInPlace(Array.from(array))\n}\n\n/** Randomly shuffle the order of the array's elements. Force to have a different order if array has more than one element. */\nexport function arrayShuffleForce<T>(array: T[]): T[] {\n while (array.length > 1) {\n const copy = Array.from(array)\n arrayShuffleInPlace(copy)\n if (!arrayIsEqual(array, copy)) return copy\n }\n return array\n}\n\nexport function arrayRandomElement<T>(array: T[]): T {\n return array[Math.floor(Math.random() * array.length)]\n}\n\nexport function arrayMax<T>(...array: NestedArray<T>[]): T {\n // @ts-ignore\n return arrayFlatten(array).reduce(\n (acc, value) => (acc != null ? (value > acc ? value : acc) : value),\n undefined\n )\n}\n\nexport function arrayMin<T>(...array: NestedArray<T>[]): T {\n // @ts-ignore\n return arrayFlatten(array).reduce(\n (acc, value) => (acc != null ? (value < acc ? value : acc) : value),\n undefined\n )\n}\n\nexport function createArray<T>(\n size: number = 0,\n item?: T | ((index: number) => T)\n): T[] {\n if (size <= 0) return []\n let arr = new Array(size)\n for (let i = 0; i < size; i++) {\n arr[i] = item instanceof Function ? item(i) : item\n }\n return arr\n}\n","// Originial code at https://github.com/cryptocoinjs/base-x/blob/master/ts_src/index.ts\n//\n// base-x encoding / decoding\n// Copyright (c) 2018 base-x contributors\n// Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp)\n// Distributed under the MIT software license, see the accompanying\n// file LICENSE or http://www.opensource.org/licenses/mit-license.php.\n\n// \"Fast base encoding / decoding of any given alphabet using bitcoin style leading zero compression.\"\n// \"WARNING: This module is NOT RFC3548 compliant, it cannot be used for base16 (hex), base32, or base64 encoding in a standards compliant manner.\"\n\nimport { BinInput, toUint8Array } from \"./bin\"\nimport { Logger } from \"../log\"\n\nconst log = Logger(\"zeed:basex\")\n\nconst alphabets = {\n \"2\": \"01\",\n \"8\": \"01234567\",\n \"11\": \"0123456789a\",\n \"16\": \"0123456789abcdef\",\n \"32\": \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\",\n \"32-rfc\": \"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567\", // https://datatracker.ietf.org/doc/html/rfc4648#section-6\n \"32-hex\": \"0123456789ABCDEFGHIJKLMNOPQRSTUV\", // https://datatracker.ietf.org/doc/html/rfc4648#section-7\n \"32-zbase\": \"ybndrfg8ejkmcpqxot1uwisza345h769\", // https://en.wikipedia.org/wiki/Base32#z-base-32\n \"36\": \"0123456789abcdefghijklmnopqrstuvwxyz\",\n \"58\": \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\",\n // \"62\": \"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\", // The sort order is not kept!\n \"62\": \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\",\n \"64\": \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\",\n \"64-url\": \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\", // https://datatracker.ietf.org/doc/html/rfc4648#section-5\n \"66\": \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.!~\",\n \"85\": \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~\", // https://datatracker.ietf.org/doc/html/rfc1924#section-4.2\n}\n\nexport function useBase(alphaOrBase: string | number) {\n let ALPHABET: string\n if (typeof alphaOrBase === \"string\") {\n ALPHABET = alphaOrBase\n } else {\n // @ts-ignore\n ALPHABET = alphabets[alphaOrBase.toString()]\n if (ALPHABET == null) throw new Error(`Unknown base ${alphaOrBase}`)\n }\n\n if (ALPHABET.length >= 255) throw new TypeError(\"Alphabet too long\")\n\n const BASE_MAP = new Uint8Array(256)\n for (let j = 0; j < BASE_MAP.length; j++) {\n BASE_MAP[j] = 255\n }\n\n for (let i = 0; i < ALPHABET.length; i++) {\n const x = ALPHABET.charAt(i)\n const xc = x.charCodeAt(0)\n\n if (BASE_MAP[xc] !== 255) throw new TypeError(x + \" is ambiguous\")\n BASE_MAP[xc] = i\n }\n\n const BASE = ALPHABET.length\n const LEADER = ALPHABET.charAt(0)\n const FACTOR = Math.log(BASE) / Math.log(256) // log(BASE) / log(256), rounded up\n const iFACTOR = Math.log(256) / Math.log(BASE) // log(256) / log(BASE), rounded up\n\n function encode(source: BinInput, padToLength: number = -1): string {\n let data = toUint8Array(source)\n if (data.byteLength === 0) return \"\"\n\n // Skip & count leading zeroes.\n let length = 0\n let pbegin = 0\n const pend = data.byteLength\n\n while (pbegin !== pend && data[pbegin] === 0) pbegin++\n\n // Allocate enough space in big-endian base58 representation.\n const size = ((pend - pbegin) * iFACTOR + 1) >>> 0\n const dataEncoded = new Uint8Array(size)\n\n // Process the bytes.\n while (pbegin !== pend) {\n let carry = data[pbegin]\n\n // Apply \"dataEncoded = dataEncoded * 256 + ch\".\n let i = 0\n for (\n let it1 = size - 1;\n (carry !== 0 || i < length) && it1 !== -1;\n it1--, i++\n ) {\n carry += (256 * dataEncoded[it1]) >>> 0\n dataEncoded[it1] = carry % BASE >>> 0\n carry = (carry / BASE) >>> 0\n }\n\n if (carry !== 0) {\n log.warn(\"Non-zero carry\", data, padToLength, i, size)\n throw new Error(\"Non-zero carry\")\n }\n\n length = i\n pbegin++\n }\n\n let it2 = size - length\n\n // Skip leading zeroes\n while (it2 !== size && dataEncoded[it2] === 0) {\n it2++\n }\n\n // Translate the result into a string.\n let str = \"\"\n for (; it2 < size; ++it2) str += ALPHABET.charAt(dataEncoded[it2])\n\n if (padToLength > 0) {\n // const pad = Math.ceil(source.length * iFACTOR)\n return str.padStart(padToLength, LEADER)\n }\n return str\n }\n\n function decode(source: string, padToLength: number = -1): Uint8Array {\n if (typeof source !== \"string\") throw new TypeError(\"Expected String\")\n if (source.length === 0) return new Uint8Array()\n\n // Normalize\n source = source.replace(/\\s+/gi, \"\")\n\n let psz = 0\n let length = 0\n\n while (source[psz] === LEADER) {\n psz++\n }\n\n // Allocate enough space in big-endian base256 representation.\n const size = ((source.length - psz) * FACTOR + 1) >>> 0 // log(58) / log(256), rounded up.\n const dataDecoded = new Uint8Array(size)\n\n // Process the characters.\n while (source[psz]) {\n let carry = BASE_MAP[source.charCodeAt(psz)]\n\n // Invalid character\n if (carry === 255)\n throw new Error(`Unsupported character \"${source[psz]}\"`)\n\n let i = 0\n for (\n let it3 = size - 1;\n (carry !== 0 || i < length) && it3 !== -1;\n it3--, i++\n ) {\n carry += (BASE * dataDecoded[it3]) >>> 0\n dataDecoded[it3] = carry % 256 >>> 0\n carry = (carry / 256) >>> 0\n }\n\n if (carry !== 0) throw new Error(\"Non-zero carry\")\n length = i\n psz++\n }\n\n // Skip leading zeroes\n let it4 = size - length\n while (it4 !== size && dataDecoded[it4] === 0) {\n it4++\n }\n\n if (padToLength > 0) {\n return new Uint8Array([\n ...new Uint8Array(padToLength - dataDecoded.length + it4),\n ...dataDecoded.slice(it4),\n ])\n }\n\n return dataDecoded.slice(it4)\n }\n\n return {\n encode,\n decode,\n }\n}\n\n// Shortcuts\n\nexport const { encode: encodeBase16, decode: decodeBase16 } = useBase(16)\nexport const { encode: encodeBase32, decode: decodeBase32 } = useBase(32)\nexport const { encode: encodeBase58, decode: decodeBase58 } = useBase(58)\nexport const { encode: encodeBase62, decode: decodeBase62 } = useBase(62)\nexport const { encode: encodeBase64, decode: decodeBase64 } = useBase(62)\n","/*\nhttps://matthiashager.com/converting-snake-case-to-camel-case-object-keys-with-javascript\n\ncamelCase\nsnake_case\nkebab-case\nPascalCase // I won't be using this here, but it's only one small step further if you want to use it\n*/\n\nexport const toCamelCase = (s: string) => {\n // if only capital letters, convert to lower case\n if (s.length > 0) {\n if (/^[A-Z0-9_\\-\\ ]*$/g.test(s)) {\n s = s.toLowerCase()\n }\n s = s\n // strip trailing non chars\n .replace(/^[-_\\ ]+/gi, \"\")\n .replace(/[-_\\ ]+$/gi, \"\")\n // strip separators and upper case first char\n .replace(/[-_\\ ]+([a-z0-9])/gi, ($0, $1) => $1.toUpperCase())\n // lower case first char\n s = s[0].toLowerCase() + s.substring(1)\n }\n return s\n}\n\nexport function toCapitalize(s: string) {\n return s.charAt(0).toUpperCase() + s.toLowerCase().slice(1)\n}\n\nexport function toCapitalizeWords(s: string) {\n return s.replace(/\\w\\S*/g, toCapitalize)\n}\n\n// export function camelize(str: string) {\n// return str\n// .replace(/(?:^\\w|[A-Z]|\\b\\w)/g, (word: string, index: number) =>\n// index === 0 ? word.toLowerCase() : word.toUpperCase()\n// )\n// .replace(/\\s+/g, \"\")\n// }\n\nexport function fromCamelCase(str: string, separator: string = \"-\") {\n separator = typeof separator === \"undefined\" ? \"_\" : separator\n return str\n .replace(/([a-z\\d])([A-Z])/g, \"$1\" + separator + \"$2\")\n .replace(/([A-Z]+)([A-Z][a-z\\d]+)/g, \"$1\" + separator + \"$2\")\n .toLowerCase()\n}\n","// From https://github.com/moll/json-stringify-safe License ISC\n\ntype EntryProcessor = (key: string, value: any) => any\n\nfunction serializer(replacer: EntryProcessor, cycleReplacer?: EntryProcessor) {\n var stack: any[] = [],\n keys: string[] = []\n\n if (cycleReplacer == null)\n cycleReplacer = function (key, value) {\n if (stack[0] === value) return \"[Circular ~]\"\n return (\n \"[Circular ~.\" + keys.slice(0, stack.indexOf(value)).join(\".\") + \"]\"\n )\n }\n\n return function (this: EntryProcessor, key: string, value: any): any {\n if (stack.length > 0) {\n var thisPos = stack.indexOf(this)\n ~thisPos ? stack.splice(thisPos + 1) : stack.push(this)\n ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key)\n if (~stack.indexOf(value)) value = cycleReplacer?.call(this, key, value)\n } else stack.push(value)\n\n return replacer == null ? value : replacer.call(this, key, value)\n }\n}\n\n/**\n * Similar to JSON.stringify but can handle circular references\n */\nexport function jsonStringify(\n obj: any,\n replacer?: EntryProcessor | null,\n spaces?: string | number | null,\n cycleReplacer?: EntryProcessor\n): string {\n // @ts-ignore\n return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces)\n}\n\n//\n\n// From https://github.com/unjs/destr MIT\n// https://github.com/fastify/secure-json-parse\n// https://github.com/hapijs/bourne\nconst suspectProtoRx =\n /\"(?:_|\\\\u005[Ff])(?:_|\\\\u005[Ff])(?:p|\\\\u0070)(?:r|\\\\u0072)(?:o|\\\\u006[Ff])(?:t|\\\\u0074)(?:o|\\\\u006[Ff])(?:_|\\\\u005[Ff])(?:_|\\\\u005[Ff])\"\\s*:/\nconst suspectConstructorRx =\n /\"(?:c|\\\\u0063)(?:o|\\\\u006[Ff])(?:n|\\\\u006[Ee])(?:s|\\\\u0073)(?:t|\\\\u0074)(?:r|\\\\u0072)(?:u|\\\\u0075)(?:c|\\\\u0063)(?:t|\\\\u0074)(?:o|\\\\u006[Ff])(?:r|\\\\u0072)\"\\s*:/\n\nconst JsonSigRx = /^[\"{[]|^-?[0-9][0-9.]{0,14}$/\n\nfunction jsonParseTransform(key: string, value: any): any {\n if (key === \"__proto__\" || key === \"constructor\") {\n return\n }\n return value\n}\n\nexport default function jsonParse(val: string): any {\n if (typeof val !== \"string\") {\n return val\n }\n\n const _lval = val.toLowerCase()\n if (_lval === \"true\") {\n return true\n }\n if (_lval === \"false\") {\n return false\n }\n if (_lval === \"null\") {\n return null\n }\n if (_lval === \"nan\") {\n return NaN\n }\n if (_lval === \"infinity\") {\n return Infinity\n }\n if (_lval === \"undefined\") {\n return undefined\n }\n\n if (!JsonSigRx.test(val)) {\n return val\n }\n\n try {\n if (suspectProtoRx.test(val) || suspectConstructorRx.test(val)) {\n return JSON.parse(val, jsonParseTransform)\n }\n return JSON.parse(val)\n } catch (_e) {\n return val\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nconst TRUE_VALUES_LIST = [\"1\", \"true\", \"yes\", \"y\", \"on\"]\n\nexport function stringToBoolean(value?: string, defaultValue = false): boolean {\n if (value == null || typeof value !== \"string\") return defaultValue\n return TRUE_VALUES_LIST.includes(String(value).trim().toLowerCase())\n}\n\nexport function stringToInteger(value?: string, defaultValue = 0): number {\n if (value == null || typeof value !== \"string\") return defaultValue\n return parseInt(value.trim(), 10) ?? defaultValue\n}\n\nexport function stringToFloat(value?: string, defaultValue = 0.0): number {\n if (value == null || typeof value !== \"string\") return defaultValue\n return parseFloat(value.trim()) ?? defaultValue\n}\n\nexport function valueToBoolean(value?: any, defaultValue = false): boolean {\n if (value == null) return defaultValue\n if (typeof value === \"boolean\") return value\n if (typeof value === \"number\") return value !== 0\n return TRUE_VALUES_LIST.includes(String(value).trim().toLowerCase())\n}\n\nexport function valueToInteger(value?: any, defaultValue = 0): number {\n if (value == null) return defaultValue\n if (typeof value === \"boolean\") return value ? 1 : 0\n if (typeof value === \"number\") return Math.floor(value)\n return parseInt(String(value).trim(), 10) ?? defaultValue\n}\n\nexport function valueToFloat(value?: any, defaultValue = 0.0): number {\n if (value == null) return defaultValue\n if (typeof value === \"boolean\") return value ? 1 : 0\n if (typeof value === \"number\") return Math.floor(value)\n return parseFloat(String(value).trim()) ?? defaultValue\n}\n\nexport function valueToString(value?: any, defaultValue = \"\"): string {\n if (value == null) return defaultValue\n // if (value == \"\") return defaultValue // ???\n return String(value) ?? defaultValue\n}\n\n// todo: toDate, toTimestamp, toData(value, base=64)\n\n// export function mapToObject<T>(map: Map<string, T>): { [key: string]: T } {\n// return Object.fromEntries(map)\n// }\n\n// export function objectToMap<T>(obj: { [key: string]: T }): Map<string, T> {\n// return new Map(Object.entries(obj))\n// }\n\n// Shortcuts\n\nexport const toFloat = valueToFloat\nexport const toInt = valueToInteger\nexport const toString = valueToString\nexport const toBool = valueToBoolean\n\n// Strings\n\nimport { jsonStringify } from \"./json\"\n\nexport type RenderMessagesOptions = {\n trace?: boolean // = true\n pretty?: boolean // = true\n}\n\nexport function formatMessages(\n messages: any[],\n opt: RenderMessagesOptions = {}\n): any[] {\n const { trace = true, pretty = true } = opt\n return messages.map((obj) => {\n if (obj && typeof obj === \"object\") {\n if (obj instanceof Error) {\n if (!trace) {\n return `${obj.name || \"Error\"}: ${obj.message}`\n }\n return `${obj.name || \"Error\"}: ${obj.message}\\n${obj.stack}`\n }\n return pretty ? jsonStringify(obj, null, 2) : jsonStringify(obj)\n }\n return String(obj)\n })\n}\n\nexport function renderMessages(\n messages: any[],\n opt: RenderMessagesOptions = {}\n): string {\n return formatMessages(messages, opt).join(\" \")\n}\n\n//\n\n// Awesome trick from https://stackoverflow.com/a/5396742/140927\nexport function fixBrokenUth8String(brokenString: string): string {\n try {\n return decodeURIComponent(escape(brokenString))\n } catch (e) {\n // log.debug(\"fixString failed for\", s)\n }\n return brokenString\n}\n","// Original taken from https://github.com/scurker/currency.js\n// @ts-nocheck\n\nimport { arrayFlatten } from \"./array\"\n\nexport type CurrencyInput = number | string | Currency\n\ntype CurrencyFormat = (currency?: Currency, opts?: CurrencyOptions) => string\n\ninterface CurrencyOptions {\n symbol?: string\n separator?: string\n decimal?: string\n errorOnInvalid?: boolean\n precision?: number\n increment?: number\n useVedic?: boolean\n pattern?: string\n negativePattern?: string\n format?: CurrencyFormat\n fromCents?: boolean\n groups?: RegExp\n}\n\nconst defaults = {\n symbol: \"$\",\n separator: \",\",\n decimal: \".\",\n errorOnInvalid: false,\n precision: 2,\n pattern: \"!#\",\n negativePattern: \"-!#\",\n format,\n fromCents: false,\n}\n\nconst round = (v: number) => Math.round(v)\nconst pow = (p: number) => Math.pow(10, p)\nconst rounding = (value: number, increment: number) =>\n round(value / increment) * increment\n\nconst groupRegex = /(\\d)(?=(\\d{3})+\\b)/g\nconst vedicRegex = /(\\d)(?=(\\d\\d)+\\d\\b)/g\n\nexport function currency(\n value: CurrencyInput,\n opts: CurrencyOptions = {}\n): Currency {\n return new Currency(value, opts)\n}\n\n/**\n * Immuteable currency representation\n */\nexport class Currency {\n public readonly intValue: number\n public readonly value: number\n private readonly _settings: CurrencyOptions\n private readonly _precision: number\n\n constructor(value: CurrencyInput, opts: CurrencyOptions = {}) {\n let settings = Object.assign({}, defaults, opts)\n let precision = pow(settings.precision ?? 2)\n let v = parse(value, settings)\n\n this.intValue = v\n this.value = v / precision\n\n // Set default incremental value\n settings.increment = settings.increment || 1 / precision\n\n // Support vedic numbering systems\n // see: https://en.wikipedia.org/wiki/Indian_numbering_system\n if (settings.useVedic) {\n settings.groups = vedicRegex\n } else {\n settings.groups = groupRegex\n }\n\n // Intended for internal usage only - subject to change\n this._settings = settings\n this._precision = precision\n }\n\n add(number: CurrencyInput): Currency {\n let { intValue, _settings, _precision } = this\n return currency(\n (intValue += parse(number, _settings)) /\n (_settings.fromCents ? 1 : _precision),\n _settings\n )\n }\n\n subtract(number: CurrencyInput): Currency {\n let { intValue, _settings, _precision } = this\n return currency(\n (intValue -= parse(number, _settings)) /\n (_settings.fromCents ? 1 : _precision),\n _settings\n )\n }\n\n multiply(number: CurrencyInput): Currency {\n // todo\n let { intValue, _settings, _precision } = this\n return currency(\n (intValue *= number) / (_settings.fromCents ? 1 : pow(_precision)),\n _settings\n )\n }\n\n divide(number: CurrencyInput): Currency {\n let { intValue, _settings } = this\n return currency((intValue /= parse(number, _settings, false)), _settings)\n }\n\n distribute(count: number): number[] {\n let { intValue, _precision, _settings } = this,\n distribution = [],\n split = Math[intValue >= 0 ? \"floor\" : \"ceil\"](intValue / count),\n pennies = Math.abs(intValue - split * count),\n precision = _settings.fromCents ? 1 : _precision\n\n for (; count !== 0; count--) {\n let item = currency(split / precision, _settings)\n\n // Add any left over pennies\n pennies-- > 0 &&\n (item = item[intValue >= 0 ? \"add\" : \"subtract\"](1 / precision))\n\n distribution.push(item)\n }\n\n return distribution as any\n }\n\n dollars(): number {\n return ~~this.value\n }\n\n cents(): number {\n let { intValue, _precision } = this\n return ~~(intValue % _precision)\n }\n\n format(options: CurrencyOptions | Function) {\n let { _settings } = this\n if (typeof options === \"function\") {\n return options(this, _settings)\n }\n return _settings.format(this, Object.assign({}, _settings, options))\n }\n\n toString(): string {\n let { intValue, _precision, _settings } = this\n return rounding(intValue / _precision, _settings.increment).toFixed(\n _settings.precision\n )\n }\n\n toJSON(): number {\n return this.value\n }\n\n static zero = new Currency(0)\n static one = new Currency(1)\n\n static sum(...array: (CurrencyInput | CurrencyInput[])[]): Currency {\n return arrayFlatten(array).reduce(\n (acc, value) => currency(acc).add(value),\n this.zero\n )\n }\n\n static avg(...array: (CurrencyInput | CurrencyInput[])[]): Currency {\n let arr = arrayFlatten(array)\n return arr\n .reduce((acc, value) => currency(acc).add(value), this.zero)\n .divide(arr.length)\n }\n}\n\nfunction parse(\n value: CurrencyInput,\n opts: CurrencyOptions,\n useRounding = true\n): number {\n let v: any = 0,\n { decimal, errorOnInvalid, precision: decimals, fromCents } = opts,\n precision = pow(decimals),\n isNumber = typeof value === \"number\"\n\n if (value instanceof Currency && fromCents) {\n return value.intValue\n }\n\n if (isNumber || value instanceof Currency) {\n v = value instanceof Currency ? value.value : value\n } else if (typeof value === \"string\") {\n let regex = new RegExp(\"[^-\\\\d\" + decimal + \"]\", \"g\"),\n decimalString = new RegExp(\"\\\\\" + decimal, \"g\")\n v = value\n .replace(/\\((.*)\\)/, \"-$1\") // allow negative e.g. (1.99)\n .replace(regex, \"\") // replace any non numeric values\n .replace(decimalString, \".\") // convert any decimal values\n v = v || 0\n } else {\n if (errorOnInvalid) {\n throw Error(\"Invalid Input\")\n }\n v = 0\n }\n\n if (!fromCents) {\n v *= precision // scale number to integer value\n v = v.toFixed(4) // Handle additional decimal for proper rounding.\n }\n\n return useRounding ? round(v) : v\n}\n\nfunction format(currency: Currency, settings: CurrencyOptions): string {\n let { pattern, negativePattern, symbol, separator, decimal, groups } =\n settings,\n split = (\"\" + currency).replace(/^-/, \"\").split(\".\"),\n dollars = split[0],\n cents = split[1]\n\n return (currency.value >= 0 ? pattern : negativePattern)\n .replace(\"!\", symbol)\n .replace(\n \"#\",\n dollars.replace(groups, \"$1\" + separator) + (cents ? decimal + cents : \"\")\n )\n}\n\n// todo: percent calculations\n\n// From https://v2.dinerojs.com/docs/api/formatting/to-unit MIT\n\nexport type RoundingMode = (value: number) => number\n\nexport const isHalf = (value: number) => Math.abs(value) % 1 === 0.5\nexport const isEven = (value: number) => value % 2 === 0\n\nexport const roundUp: RoundingMode = (value) => Math.ceil(value)\nexport const roundDown: RoundingMode = (value) => Math.floor(value)\nexport const roundHalfUp: RoundingMode = (value) => Math.round(value)\n\n/**\n * Round a number with half values to nearest odd integer.\n */\nexport const roundHalfOdd: RoundingMode = (value) => {\n const rounded = Math.round(value)\n if (!isHalf(value)) {\n return rounded\n }\n return isEven(rounded) ? rounded - 1 : rounded\n}\n\n/**\n * Round a number with half values to nearest integer farthest from zero.\n */\nexport const roundHalfAwayFromZero: RoundingMode = (value) => {\n return isHalf(value)\n ? Math.sign(value) * Math.ceil(Math.abs(value))\n : Math.round(value)\n}\n\n/**\n * Round a number with half values down.\n */\nexport const roundHalfDown: RoundingMode = (value) =>\n isHalf(value) ? Math.floor(value) : Math.round(value)\n\n/**\n * Round a number with half values to nearest even integer.\n * https://wiki.c2.com/?BankersRounding\n */\nexport const roundHalfEven: RoundingMode = (value) => {\n const rounded = Math.round(value)\n if (!isHalf(value)) {\n return rounded\n }\n return isEven(rounded) ? rounded : rounded - 1\n}\n\n/**\n * Round a number with half values to nearest integer closest to zero.\n */\nexport const roundHalfTowardsZero: RoundingMode = (value) =>\n isHalf(value)\n ? Math.sign(value) * Math.floor(Math.abs(value))\n : Math.round(value)\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { Logger } from \"./log\"\n\nconst { warn } = Logger(\"zeed:promise\")\n\n/** Sleep for `milliSeconds`. Example 1s: `await sleep(1000)` */\nexport async function sleep(milliSeconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, milliSeconds))\n}\n\nexport async function immediate(): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, 0))\n}\n\nexport const timeoutReached = Symbol(\"timeout\")\n\ntype Unwrap<T> = T extends Promise<infer U>\n ? U\n : T extends (...args: any) => Promise<infer U>\n ? U\n : T extends (...args: any) => infer U\n ? U\n : T\n\nexport async function timeout<T>(\n promise: Promise<T>,\n milliSeconds: number,\n timeoutValue = timeoutReached\n): Promise<T | typeof timeoutValue> {\n return new Promise(async (resolve, reject) => {\n let done = false\n\n const timeout = setTimeout(() => {\n done = true\n resolve(timeoutValue)\n }, milliSeconds)\n\n try {\n let result = await promise\n clearTimeout(timeout)\n if (!done) resolve(result)\n } catch (err) {\n clearTimeout(timeout)\n if (!done) reject(err)\n }\n })\n}\n\nexport const timoutError = new Error(\"Timeout reached\")\n\nexport function isTimeout(value: any): boolean {\n return value === timeoutReached || value === timoutError\n}\n\nexport async function tryTimeout<T>(\n promise: Promise<T>,\n milliSeconds: number\n): Promise<T | undefined> {\n if (milliSeconds <= 0) {\n return await promise\n }\n return new Promise(async (resolve, reject) => {\n let done = false\n\n const timeout = setTimeout(() => {\n done = true\n reject(timoutError)\n }, milliSeconds)\n\n try {\n let result = await promise\n clearTimeout(timeout)\n if (!done) resolve(result)\n } catch (err) {\n clearTimeout(timeout)\n if (!done) reject(err)\n }\n })\n}\n\n/** Wait for `event` on `obj` to emit. Resolve with result or reject on `timeout` */\nexport function waitOn(\n obj: any,\n event: string,\n timeoutMS: number = 1000\n): Promise<any> {\n return new Promise((resolve, reject) => {\n let fn = (value: any) => {\n if (timer) {\n clearTimeout(timer)\n done()\n resolve(value)\n }\n }\n\n let done = () => {\n timer = null\n if (obj.off) {\n obj.off(event, fn)\n } else if (obj.removeEventListener) {\n obj.removeEventListener(event, fn)\n } else {\n warn(\"No remove listener method found for\", obj, event)\n }\n }\n\n let timer: any = setTimeout(() => {\n done()\n reject(new Error(`Did not response in time`))\n }, timeoutMS)\n\n if (obj.on) {\n obj.on(event, fn)\n } else if (obj.addEventListener) {\n obj.addEventListener(event, fn)\n } else {\n warn(\"No listener method found for\", obj)\n }\n })\n}\n\nexport function isPromise<T>(value: Promise<T> | T): value is Promise<T> {\n return Boolean(\n value &&\n (value instanceof Promise ||\n // @ts-ignore\n typeof value.then === \"function\")\n )\n}\n\n/** This is exactly what Prose.resolve(x) is supposed to be: return a Promise no matter what type x is */\nexport function promisify<T>(value: Promise<T> | T): Promise<T> {\n return Promise.resolve(value)\n // return isPromise(value) ? value : Promise.resolve(value)\n}\n\n// // https://github.com/unjs/items-promise\n\n// /**\n// * Run tasks one by one by calling fn(task, previous) in a promise chain.\n// * Return value is of type Promise<*> which resolves to the last fn result.\n// */\n// export async function serial(tasks: any, fn: any) {\n// return tasks.reduce(\n// (promise: Promise<any>, task: any) =>\n// promise.then((previous) => fn(task, previous)),\n// Promise.resolve(null)\n// )\n// }\n\n// /**\n// * Run all tasks in parallel by calling fn(tasks) and await using Promise.all.\n// * Return value is of type Promise<*[]> which resolves to results of all fns in an array.\n// */\n// export async function parallel(tasks: any[], fn: any): Promise<any[]> {\n// return Promise.all(tasks.map((task) => fn(task)))\n// }\n","import { isPromise } from \"../promise\"\n\nexport const DAY_MS = 1000 * 60 * 60 * 24\n\nexport type DayInput = number | string | Date | Day\n\nexport class Day {\n days: number\n\n constructor(days?: DayInput) {\n if (typeof days === \"number\") {\n this.days = days\n return\n }\n\n if (days != null) {\n days = Day.from(days)?.days\n }\n\n if (days == null) {\n const date = new Date()\n this.days =\n date.getFullYear() * 10000 +\n (date.getMonth() + 1) * 100 +\n date.getDate()\n } else {\n this.days = days\n }\n }\n\n static fromNumber(n: number): Day {\n return new Day(n)\n }\n\n static fromString(dateString: string): Day | undefined {\n return new Day(+dateString.replace(/[^0-9]/g, \"\"))\n }\n\n static fromDate(date: Date, gmt: boolean = false): Day {\n return (\n gmt\n ? Day.fromString(date.toISOString().substr(0, 10))\n : new Day(\n date.getFullYear() * 10000 +\n (date.getMonth() + 1) * 100 +\n date.getDate()\n )\n ) as Day\n }\n\n static fromDateGMT(date: Date): Day {\n return Day.fromDate(date, true)\n }\n\n static from(value: DayInput, gmt: boolean = false): Day | undefined {\n if (typeof value === \"number\") {\n return new Day(value)\n } else if (typeof value === \"string\") {\n return Day.fromString(value)\n } else if (value instanceof Date) {\n return Day.fromDate(value, gmt)\n } else if (value instanceof Day) {\n return value\n }\n }\n\n toNumber(): number {\n return this.days\n }\n\n // Transformer\n\n /** Just for future extensions */\n toJson() {\n return this.days\n }\n\n toString(sep: string = \"-\") {\n let baseString = String(this.days)\n return (\n baseString.slice(0, 4) +\n sep +\n baseString.slice(4, 6) +\n sep +\n baseString.slice(6, 8)\n )\n }\n\n toDate(gmt: boolean = false): Date {\n return gmt\n ? new Date(`${this.toString()}T00:00:00.000Z`)\n : new Date(\n this.days / 10000, // year\n ((this.days / 100) % 100) - 1, // month\n this.days % 100 // day\n )\n }\n\n toDateGMT() {\n return this.toDate(true)\n }\n\n // Calculations\n\n dayOffset(offset: number): Day {\n // Important! Don't use local time here due to summer/winter time days can\n // be longer or shorter!\n return Day.fromDateGMT(\n new Date(this.toDateGMT().getTime() + offset * DAY_MS)\n )\n }\n\n daysUntil(otherDay: DayInput): number {\n return Math.round(\n (new Day(otherDay)?.toDateGMT().getTime() - this.toDateGMT().getTime()) /\n DAY_MS\n )\n }\n\n // Shortcuts\n\n yesterday() {\n return this.dayOffset(-1)\n }\n\n tomorrow() {\n return this.dayOffset(+1)\n }\n}\n\nexport async function forEachDay(\n from: DayInput,\n to: DayInput,\n handler: (date: Day) => Promise<void> | void\n) {\n let start = Day.from(from)\n let end = Day.from(to)\n while (start && end && start?.days <= end?.days) {\n let result = handler(start)\n if (isPromise(result)) {\n await result\n }\n start = start.dayOffset(+1)\n }\n}\n\nexport function today(): Day {\n return new Day()\n}\n\nexport function day(days?: DayInput): Day {\n return new Day(days)\n}\n","export const escapeHTML = (s: string): string =>\n s\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/'/g, \"'\")\n .replace(/\"/g, \""\")\n\nexport const unescapeHTML = (s: string): string =>\n s\n .replace(/</gi, \"<\")\n .replace(/>/gi, \">\")\n .replace(/"/gi, '\"')\n .replace(/'/gi, \"'\")\n .replace(/&/gi, \"&\")\n","export function randomBoolean(bias = 0.25): boolean {\n return Math.random() < bias\n}\n\n/** max is not included, min is included */\nexport function randomInt(max = 100, min = 0): number {\n return min + Math.floor(Math.random() * (max - min))\n}\n\nexport function randomFloat(max = 100, min = 0): number {\n return min + Math.random() * (max - min)\n}\n\nexport function between(min: number, value: number, max: number): number {\n return Math.max(min, Math.min(max, value))\n}\n\n// export const clamp = (n: number, min: number, max: number) => Math.min(max, Math.max(min, n))\n","// https://github.com/sindresorhus/filenamify/blob/main/filenamify.js\n\nconst MAX_FILENAME_LENGTH = 100\n\nconst reControlChars = /[\\u0000-\\u001F\\u0080-\\u009F]/g // eslint-disable-line no-control-regex\nconst reRelativePath = /^\\.+/\nconst reTrailingPeriods = /\\.+$/\n\nfunction filenameReservedRegex() {\n return /[<>:\"/\\\\|?*\\u0000-\\u001F]/g\n}\n\nfunction windowsReservedNameRegex() {\n return /^(con|prn|aux|nul|com\\d|lpt\\d)$/i\n}\n\nexport function toValidFilename(string: string) {\n if (typeof string !== \"string\") {\n throw new TypeError(\"Expected a string\")\n }\n\n const replacement = \"_\"\n\n if (\n filenameReservedRegex().test(replacement) &&\n reControlChars.test(replacement)\n ) {\n throw new Error(\n \"Replacement string cannot contain reserved filename characters\"\n )\n }\n\n string = string\n .replace(filenameReservedRegex(), replacement)\n .replace(reControlChars, replacement)\n .replace(reRelativePath, replacement)\n .replace(reTrailingPeriods, \"\")\n\n string = windowsReservedNameRegex().test(string)\n ? string + replacement\n : string\n\n return string.slice(0, MAX_FILENAME_LENGTH)\n}\n","const rxEscape = /[\\\\\\-\\[\\]\\/{}()*+?.^$|]/g // Finds: \\ - [ ] / { } ( ) * + ? . ^ $ |\n\nexport function escapeRegExp(value: RegExp | string): string {\n if (!value) return \"\"\n if (value instanceof RegExp) {\n return value.source\n }\n return value.replace(rxEscape, \"\\\\$&\")\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\n// Get a sort_weight suitable for adding to top of list\n// Original idea https://holtwick.de/en/blog/smart-table-reordering\n\nexport interface SortableItem {\n sort_weight: number\n}\n\nexport function startSortWeight(items: SortableItem[]): number {\n return (\n items.reduce((acc, item) => Math.min(acc, item.sort_weight || 0), 0) -\n 1 -\n Math.random()\n )\n}\n\n// Get a sort_weight suitable for adding to end of list\nexport function endSortWeight(items: SortableItem[]): number {\n return (\n items.reduce((acc, item) => Math.max(acc, item.sort_weight || 0), 0) +\n 1 +\n Math.random()\n )\n}\n\n// The real magic\nexport function moveSortWeight(\n newIndex: number,\n oldIndex: number,\n items: SortableItem[]\n): number {\n let count = items.length\n\n const moveLower = newIndex < oldIndex\n if (count <= 0 || newIndex >= count - 1) {\n return endSortWeight(items)\n }\n if (newIndex <= 0) {\n return startSortWeight(items)\n }\n\n // Make sure they are sorted\n items = sortedItems([...items])\n\n const step = moveLower ? -1 : 0\n const lower = items[newIndex + step].sort_weight || 0\n const upper = items[newIndex + step + 1].sort_weight || 0\n const distance = upper - lower\n if (distance === 0) {\n // Ugly list with no presets, make the best guess\n if (moveLower) {\n return startSortWeight(items)\n }\n return endSortWeight(items)\n }\n const middle = lower + distance / 2\n const fuzzy = distance * 0.01 * (Math.random() - 0.5) // 1% fuzziness to avoid conflicts\n return middle + fuzzy\n}\n\nexport function sortedItems<T extends SortableItem>(items: T[]): T[] {\n items.sort((a, b) => (a.sort_weight || 0) - (b.sort_weight || 0))\n return items\n}\n","// https://mathiasbynens.be/demo/url-regex\n// https://gist.github.com/dperini/729294\n\nimport { escapeHTML } from \"./html\"\n\nconst findURL =\n /((?:(?:(?:https?|ftp):)?\\/\\/)(?:\\S+(?::\\S*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z0-9\\u00a1-\\uffff][a-z0-9\\u00a1-\\uffff_-]{0,62})?[a-z0-9\\u00a1-\\uffff]\\.)+(?:[a-z\\u00a1-\\uffff]{2,}\\.?))(?::\\d{2,5})?(?:[/?#]\\S*)?)/gim\n\nexport function linkifyPlainText(text: string): string {\n return text\n .split(findURL)\n .map((part, i) => {\n const escapedPart = escapeHTML(part)\n return i % 2\n ? `<a target=\"_blank\" href=\"${escapedPart}\">${toHumanReadableUrl(\n escapedPart\n )}</a>`\n : escapedPart\n })\n .join(\"\")\n}\n\nexport function toHumanReadableUrl(url: string): string {\n return url.replace(/^https?:\\/\\/(www\\.)?/, \"\").replace(/\\/$/, \"\")\n}\n\n//\n\nexport function encodeQuery(data: Record<string, any>) {\n let pairs = []\n for (let [key, value] of Object.entries(data)) {\n if (value != null) {\n if (!Array.isArray(value)) {\n value = [value]\n }\n for (let v of value) {\n if (v != null) {\n pairs.push(\n encodeURIComponent(key) +\n \"=\" +\n encodeURIComponent(v.toString() || \"\")\n )\n }\n }\n }\n }\n return pairs.join(\"&\")\n}\n\nexport function parseQuery(queryString: string) {\n let query: any = {}\n let pairs = (\n queryString[0] === \"?\" ? queryString.substr(1) : queryString\n ).split(\"&\")\n for (let i = 0; i < pairs.length; i++) {\n let pair = pairs[i].split(\"=\")\n let key = decodeURIComponent(pair[0])\n let value = decodeURIComponent(pair[1] || \"\")\n if (query[key] != null) {\n if (!Array.isArray(query[key])) {\n query[key] = [query[key]]\n }\n query[key].push(value)\n } else {\n query[key] = value\n }\n }\n return query\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { Json } from \"../types\"\n\nexport function size(obj: any) {\n if (obj != null) {\n if (obj.size != null) {\n return obj.size\n }\n if (obj.length != null) {\n return obj.length\n }\n return Object.keys(obj).length\n }\n return 0\n}\n\nexport function last<T>(array?: T[]): T | undefined {\n return array != null && array.length > 0 ? array[array.length - 1] : undefined\n}\n\n// True for [], {}, \"\", Map(), Set() and all primitives\nexport function empty(value: any): boolean {\n try {\n if (value != null) {\n if (Array.isArray(value)) {\n return value.length <= 0\n } else if (typeof value === \"string\") {\n return value.length <= 0\n } else if (value?.size != null) {\n return value.size <= 0\n } else {\n return Object.keys(value).length <= 0\n }\n }\n } catch (err) {\n console.error(\"Failed to check if empty for\", value, err)\n }\n return true\n}\n\n// Also see common/data/deep.ts\nexport function cloneObject<T>(obj: T): T {\n // Primitives are immutable anyway\n if (Object(obj) !== obj) return obj\n\n // Rude but very efficient way to clone\n return JSON.parse(JSON.stringify(obj))\n}\n\n// Also see common/data/deep.ts\nexport function cloneJsonObject<T = Json>(obj: T): T {\n // Primitives are immutable anyway\n if (Object(obj) !== obj) return obj\n\n // Rude but very efficient way to clone\n return JSON.parse(JSON.stringify(obj))\n}\n\n// export function cloneStructuredObject<T>(obj: T): T {\n// // Primitives are immutable anyway\n// if (Object(obj) !== obj) return obj\n\n// // https://developer.mozilla.org/en-US/docs/Web/API/structuredClone\n// // @ts-ignore\n// return typeof structuredClone !== \"undefined\"\n// ? // @ts-ignore\n// structuredClone(obj)\n// : // Rude but very efficient way to clone\n// JSON.parse(JSON.stringify(obj))\n// }\n","import { arrayFilterInPlace } from \"./data/array\"\nimport { promisify, isPromise } from \"./promise\"\n\n// https://blog.hediet.de/post/the_disposable_pattern_in_typescript\n\nexport type DisposerFunction = () => void | Promise<void>\n\nexport type Disposer =\n | DisposerFunction\n | {\n dispose?: Function | Promise<unknown>\n cleanup?: Function | Promise<unknown> // deprecated, but used often in my old code\n }\n\nexport interface Disposable {\n dispose(): void | Promise<void>\n}\n\n/** Different kinds of implementations have grown, this should unify them */\nexport async function callDisposer(disposable: Disposer): Promise<void> {\n if (typeof disposable === \"function\") {\n await promisify(disposable())\n } else if (isPromise(disposable)) {\n await disposable\n } else if (typeof disposable.dispose === \"function\") {\n await promisify(disposable.dispose())\n } else if (isPromise(disposable.dispose)) {\n await disposable.dispose\n } else if (typeof disposable.cleanup === \"function\") {\n await promisify(disposable.cleanup())\n } else if (isPromise(disposable.cleanup)) {\n await disposable.cleanup\n }\n}\n\n// export function disposeFn()\n\nexport function useDisposer() {\n let tracked: Disposer[] = []\n\n const untrack = async (disposable: Disposer) => {\n if (tracked.includes(disposable)) {\n arrayFilterInPlace(tracked, (el) => el !== disposable)\n await callDisposer(disposable)\n }\n }\n\n const dispose = async () => {\n while (tracked.length > 0) {\n await untrack(tracked[0]) // LIFO\n }\n }\n\n const track = (obj: Disposer): DisposerFunction => {\n tracked.unshift(obj) // LIFO\n return () => untrack(obj)\n }\n\n return Object.assign(dispose, {\n track,\n untrack,\n dispose,\n getSize() {\n return tracked.length\n },\n })\n}\n\nexport function useTimeout(\n fn: Function,\n timeout: number = 0\n): DisposerFunction {\n let timeoutHandle: any = setTimeout(fn, timeout)\n return () => {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle)\n timeoutHandle = undefined\n }\n }\n}\n\nexport function useInterval(fn: Function, interval: number): DisposerFunction {\n let intervalHandle: any = setInterval(fn, interval)\n return () => {\n if (intervalHandle) {\n clearInterval(intervalHandle)\n intervalHandle = undefined\n }\n }\n}\n\nexport function useEventListener(\n emitter: any,\n eventName: string,\n fn: (ev?: any) => void,\n ...args: any[]\n): DisposerFunction {\n if (emitter == null) return () => {}\n\n if (emitter.on) {\n emitter.on(eventName, fn, ...args)\n } else if (emitter.addEventListener) {\n emitter.addEventListener(eventName, fn, ...args)\n }\n\n return () => {\n if (emitter.off) {\n emitter.off(eventName, fn, ...args)\n } else if (emitter.removeEventListener) {\n emitter.removeEventListener(eventName, fn, ...args)\n }\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nexport function isLocalHost(\n hostname: string = window.location.hostname\n): boolean {\n return (\n [\"localhost\", \"127.0.0.1\", \"\", \"::1\", \"::\"].includes(hostname) ||\n hostname.startsWith(\"192.168.\") ||\n hostname.startsWith(\"10.0.\") ||\n hostname.endsWith(\".local\")\n )\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\n/**\n * @returns Timestamp in miliseconds\n */\nexport const getTimestamp = (): number =>\n // @ts-ignore\n typeof performance !== \"undefined\" ? performance.now() : new Date().getTime()\n\nexport function formatMilliseconds(ms: number): string {\n return ms > 999 ? (ms / 1000).toFixed(1) + \"s\" : ms.toFixed(2) + \"ms\"\n}\n\nexport function parseDate(\n ...dateCandidates: (string | Date)[]\n): Date | undefined {\n for (let dateCandidate of dateCandidates) {\n if (dateCandidate instanceof Date) {\n return dateCandidate\n }\n if (typeof dateCandidate === \"string\") {\n let date = null\n if (dateCandidate.includes(\":\")) {\n try {\n date = new Date(dateCandidate)\n } catch (err) {}\n }\n if (!(date instanceof Date)) {\n let m = /(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d)/.exec(dateCandidate)\n if (m) {\n date = new Date(+m[1], +m[2] - 1, +m[3], 12, 0)\n }\n }\n if (date instanceof Date) {\n return date\n }\n }\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { randomUint8Array } from \"./crypto\"\nimport { useBase } from \"./data/basex\"\nimport { getTimestamp } from \"./time\"\n\nconst { encode: encode62, decode: decode62 } = useBase(62)\nconst { encode: encode32 } = useBase(32)\n\n// function randomDigit(base = 32) {\n// if (_crypto && _crypto['getRandomValues']) {\n// let rands = new Uint8Array(1)\n// _crypto['getRandomValues'](rands)\n// return (rands[0] % base).toString(base)\n// }\n// return ((Math.random() * base) | 0).toString(base)\n// }\n\nexport function uuidBytes(): Uint8Array {\n return randomUint8Array(16)\n}\n\nexport function uuid(): string {\n return encode62(uuidBytes(), 22)\n}\n\nexport function uuidB32(): string {\n return encode32(uuidBytes(), 26)\n}\n\nlet _unameCounters: Record<string, number> = {}\n\nexport function uname(name: string = \"id\"): string {\n if (_unameCounters[name] == null) {\n _unameCounters[name] = 0\n }\n return `${name}-${_unameCounters[name]++}`\n}\n\nlet _qid = 0\n\nexport function qid(): string {\n return `id-${_qid++}`\n}\n\n// https://stackoverflow.com/a/2117523/140927\nconst pattern = \"10000000-1000-4000-8000-100000000000\" // String([1e7] + -1e3 + -4e3 + -8e3 + -1e11)\n\nexport const uuidv4 = () =>\n pattern.replace(/[018]/g, (c: any) =>\n (c ^ (randomUint8Array(1)[0] & (15 >> (c / 4)))).toString(16)\n )\n\n// https://github.com/segmentio/ksuid\n// https://pkg.go.dev/github.com/rsms/go-uuid\n\n/**\n * Sortable unique ID\n * Inspired by https://github.com/rsms/go-uuid\n *\n * Bytes 0-5: Current time in miliseconds from 2021-06-01T00:00:00Z\n * Bytes 6-15: Random\n */\n\n// 1622505600000 // new Date('2021-06-01T00:00:00Z').getTime()\nconst ReferenceDateInMS = 1600000000000\n\n// 6 bytes will stay valid until end of time: new Date(1622505600000 + 0xffffffffffff) === Date Sun Jan 01 10941 06:31:50 GMT+0100 (Central European Standard Time)\n\nfunction longToByteArray(long: number) {\n var byteArray = new Uint8Array([0, 0, 0, 0, 0, 0])\n const bytes = byteArray.length - 1\n for (var index = 0; index < byteArray.length; index++) {\n var byte = long & 0xff\n byteArray[bytes - index] = byte\n long = (long - byte) / 256\n }\n return byteArray\n}\n\n// function byteArrayToLong(byteArray: number[]): number {\n// var value = 0\n// for (var i = byteArray.length - 1; i >= 0; i--) {\n// value = value * 256 + byteArray[i]\n// }\n// return value\n// }\n\nexport function suidBytes(): Uint8Array {\n const ms = getTimestamp() - ReferenceDateInMS\n return new Uint8Array([...longToByteArray(ms), ...randomUint8Array(10)])\n}\n\nexport function suid(): string {\n return encode62(suidBytes(), 22)\n}\n\nexport function suidDate(id: string): Date {\n return suidBytesDate(decode62(id, 16))\n}\n\nexport function suidBytesDate(id: Uint8Array): Date {\n return new Date(\n ReferenceDateInMS +\n id.slice(0, 6).reduce((acc, byte) => {\n return acc * 256 + byte\n }, 0)\n )\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { Disposable, DisposerFunction } from \"../disposer\"\nimport { getGlobalContext } from \"../global\"\nimport { Logger } from \"../log\"\nimport { promisify } from \"../promise\"\n\nconst log = Logger(\"zeed:emitter\")\n\nexport type EmitterHandler = (...objs: any[]) => void\nexport type EmitterAllHandler<T = string> = (key: T, ...objs: any[]) => void\n\n// For magic see https://www.npmjs.com/package/tiny-typed-emitter / License MIT\n// https://stackoverflow.com/a/61609010/140927\n// https://basarat.gitbook.io/typescript/main-1/typed-event\n// https://github.com/andywer/typed-emitter#extending-an-emitter\n\n// TODO: Allow symbols? https://github.com/sindresorhus/emittery\n\nexport declare type ListenerSignature<L> = {\n [E in keyof L]: (...args: any[]) => any\n}\n\nexport declare type DefaultListener = {\n [k: string]: (...args: any[]) => any\n}\n\nexport class Emitter<L extends ListenerSignature<L> = DefaultListener>\n implements Disposable\n{\n subscribers: any = {}\n subscribersOnAny: any[] = []\n\n call: L = new Proxy<L>({} as any, {\n get:\n (target: any, name: any) =>\n (...args: any): any =>\n this.emit(name, ...args),\n })\n\n public async emit<U extends keyof L>(\n event: U,\n ...args: Parameters<L[U]>\n ): Promise<boolean> {\n let ok = false\n try {\n let subscribers = (this.subscribers[event] || []) as EmitterHandler[]\n // log.debug(\"emit\", this?.constructor?.name, event, ...args, subscribers)\n\n this.subscribersOnAny.forEach((fn) => fn(event, ...args))\n\n if (subscribers.length > 0) {\n let all = subscribers.map((fn) => {\n try {\n return promisify(fn(...args))\n } catch (err) {\n log.warn(\"emit warning:\", err)\n }\n })\n ok = true\n await Promise.all(all)\n }\n } catch (err) {\n log.error(\"emit exception\", err)\n }\n return ok\n }\n\n public onAny(fn: EmitterHandler) {\n this.subscribersOnAny.push(fn)\n }\n\n public on<U extends keyof L>(event: U, listener: L[U]): DisposerFunction {\n let subscribers = (this.subscribers[event] || []) as EmitterHandler[]\n subscribers.push(listener)\n this.subscribers[event] = subscribers\n return () => {\n this.off(event, listener)\n }\n }\n\n public onCall(handlers: Partial<L>) {\n for (const [name, handler] of Object.entries(handlers)) {\n this.on(name as any, handler as any)\n }\n }\n\n public once<U extends keyof L>(event: U, listener: L[U]): DisposerFunction {\n const onceListener = async (...args: any[]) => {\n this.off(event, onceListener as any)\n return await promisify(listener(...args))\n }\n this.on(event, onceListener as any)\n return () => {\n this.off(event, listener)\n }\n }\n\n public off<U extends keyof L>(event: U, listener: L[U]): this {\n // log(\"off\", key)\n this.subscribers[event] = (this.subscribers[event] || []).filter(\n (f: any) => listener && f !== listener\n )\n return this\n }\n\n public removeAllListeners(event?: keyof L): this {\n this.subscribers = {}\n return this\n }\n\n dispose() {\n this.subscribers = {}\n this.subscribersOnAny = []\n }\n}\n\ndeclare global {\n interface ZeedGlobalContext {\n emitter?: Emitter\n }\n\n interface ZeedGlobalEmitter {}\n}\n\n/** Global emitter that will listen even across modules */\nexport function getGlobalEmitter(): Emitter<ZeedGlobalEmitter> {\n let emitter = getGlobalContext().emitter\n if (!emitter) {\n emitter = new Emitter()\n getGlobalContext().emitter = emitter\n }\n return emitter as any\n}\n\n// This can be used as a global messaging port to connect loose\n// parts of your app\nexport const messages = new Emitter()\n\n// For debugging\n\ninterface LazyEvent {\n key: string\n obj: any\n}\n\nexport function lazyListener(\n emitter: any,\n listenerKey?: string\n): (key?: string, skipUnmatched?: boolean) => Promise<any> {\n const name = Math.round(Math.random() * 100)\n\n var events: LazyEvent[] = []\n var lazyResolve: (() => void) | undefined\n\n const incoming = (key: string, obj: any) => {\n let ev = { key, obj }\n // debug(name, \" lazy push\", ev)\n events.push(ev)\n lazyResolve && lazyResolve()\n }\n\n if (listenerKey) {\n if (emitter.on) {\n emitter.on(listenerKey, (obj: any) => {\n incoming(listenerKey, obj)\n })\n } else if (emitter.addEventListener) {\n emitter.addEventListener(listenerKey, (obj: any) => {\n incoming(listenerKey, obj)\n })\n } else {\n log.error(name, \"Cannot listen to key\")\n }\n } else {\n if (emitter.onAny) {\n emitter.onAny((key: string, obj: any) => {\n incoming(key, obj)\n })\n } else {\n log.error(name, \"cannot listen to all for\", emitter)\n }\n }\n\n let on = (key?: string, skipUnmatched: boolean = true): Promise<any> => {\n return new Promise((resolve, reject) => {\n if (!key) {\n key = listenerKey\n if (!key) {\n if (events.length) {\n // no key specified? just take the first one!\n key = events[0].key\n }\n }\n }\n // debug(name, \"lazy resolve on2\", key, skipUnmatched, events)\n lazyResolve = () => {\n // debug(name, \"lazy resolve\", key, listenerKey, events)\n while (events.length > 0) {\n let ev = <LazyEvent>events.shift()\n // debug(name, \" lazy analyze\", ev)\n if (ev.key === key) {\n lazyResolve = undefined\n resolve(ev.obj)\n } else {\n if (skipUnmatched) {\n log.warn(name, `Unhandled event ${key} with value: ${ev.obj}`)\n continue\n }\n reject(`Expected ${key}, but found ${ev.key} with value=${ev.obj}`)\n log.error(name, `Unhandled event ${key} with value: ${ev.obj}`)\n }\n break\n }\n }\n lazyResolve()\n })\n }\n\n return on\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\n// import { Logger } from \"../log\"\nimport { uuid } from \"../uuid\"\nimport { Emitter } from \"./emitter\"\n\n// const log = Logger(\"zeed:channel\")\n\n/** See http://developer.mozilla.org/en-US/docs/Web/API/MessageEvent */\nexport interface ChannelMessageEvent {\n data: any\n origin?: string\n lastEventId?: string\n}\n\n/**\n * Inspired by\n * http://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel\n * https://deno.com/deploy/docs/runtime-broadcast-channel\n * */\nexport abstract class Channel extends Emitter<{\n message(event: ChannelMessageEvent): void\n messageerror(event: ChannelMessageEvent): void // optional\n connect(): void // optional\n disconnect(): void // optional\n close(): void\n}> {\n id: string = uuid()\n abstract isConnected?: boolean\n abstract postMessage(data: any): void\n close() {}\n}\n\n/** Very basic channel demonstrating local communication */\nexport class LocalChannel extends Channel {\n isConnected = true\n\n other?: LocalChannel\n\n postMessage(data: any) {\n this.other?.emit(\"message\", {\n data, // : cloneObject(data),\n origin: \"local\",\n lastEventId: uuid(),\n })\n }\n}\n\nexport function fakeWorkerPair(): [LocalChannel, LocalChannel] {\n let w1 = new LocalChannel()\n let w2 = new LocalChannel()\n\n w1.other = w2\n w2.other = w1\n\n return [w1, w2]\n}\n","import { encrypt, decrypt } from \"../crypto\"\nimport { jsonToUint8Array, Uint8ArrayToJson } from \"../data/bin\"\n\nexport interface Encoder {\n encode(data: any): Promise<Uint8Array>\n decode(data: Uint8Array): Promise<any>\n}\n\nexport class JsonEncoder implements Encoder {\n async encode(data: any): Promise<Uint8Array> {\n return jsonToUint8Array(data)\n }\n\n async decode(data: Uint8Array): Promise<any> {\n return Uint8ArrayToJson(data)\n }\n}\n\nexport class CryptoEncoder implements Encoder {\n key: CryptoKey\n\n constructor(key: CryptoKey) {\n this.key = key\n }\n\n async encode(data: any): Promise<Uint8Array> {\n const plain = jsonToUint8Array(data)\n return await encrypt(plain, this.key)\n }\n\n async decode(data: Uint8Array): Promise<any> {\n const plain = await decrypt(data, this.key)\n return Uint8ArrayToJson(plain)\n }\n}\n","import { valueToString } from \"../data/convert\"\nimport { Logger } from \"../log\"\nimport { tryTimeout, isPromise } from \"../promise\"\nimport { Json } from \"../types\"\nimport { uname, uuid } from \"../uuid\"\nimport { Channel } from \"./channel\"\nimport { Encoder, JsonEncoder } from \"./encoder\"\n\nexport type MessageAction = {\n name: string\n id: string\n args?: Json[]\n}\n\nexport type MessageResult = {\n id: string\n result?: Json\n error?: { stack?: string; name: string; message: string }\n}\n\nexport type Message = MessageAction | MessageResult\n\nexport type MessagesOptions = {\n timeout?: number\n}\n\nexport type MessagesDefaultMethods<L> = {\n dispose(): void\n connect?(channel: Channel): void\n options(opt: MessagesOptions): L\n}\n\nexport type MessagesMethods<L> = L & MessagesDefaultMethods<L>\n\n// export type MessageDefinitions = {\n// [key: string]: (...args: any) => Promise<any>\n// }\n\nexport type MessageDefinitions = Record<any, (...args: any) => Promise<any>>\n\nexport type MessageHub = {\n dispose(): void\n connect: (newChannel: Channel) => void\n listen<L extends MessageDefinitions>(newHandlers: L): void\n send<L extends MessageDefinitions>(): MessagesMethods<L>\n}\n\n// The async proxy, waiting for a response\nexport const createPromiseProxy = <P extends object>(\n fn: (name: string, args: any[], opt: any) => Promise<unknown>,\n opt: MessagesOptions,\n predefinedMethods: any = {}\n): P =>\n new Proxy<P>(predefinedMethods, {\n get: (target: any, name: any) => {\n if (name in target) return target[name]\n return (...args: any): any => fn(name, args, opt)\n },\n })\n\nexport function useMessageHub(\n opt: {\n name?: string\n channel?: Channel\n encoder?: Encoder\n retryAfter?: number\n ignoreUnhandled?: boolean\n debug?: boolean\n } = {}\n): MessageHub {\n let {\n name = uname(\"hub\"),\n encoder = new JsonEncoder(),\n retryAfter = 1000,\n ignoreUnhandled = true,\n } = opt\n\n const log = Logger(name)\n\n let handlers = {}\n let channel: Channel | undefined\n let queue: Message[] = []\n let queueRetryTimer: any\n let waitingForResponse: Record<string, [Function, Function]> = {}\n\n const dispose = () => {\n clearTimeout(queueRetryTimer)\n }\n\n const postNext = async () => {\n clearTimeout(queueRetryTimer)\n if (channel) {\n if (channel.isConnected) {\n while (queue.length) {\n let message = queue[0]\n try {\n channel.postMessage(await encoder.encode(message))\n queue.shift() // remove from queue when done\n } catch (err) {\n log.warn(\"postMessage\", err)\n break\n }\n }\n }\n if (queue.length > 0 && retryAfter > 0) {\n queueRetryTimer = setTimeout(postNext, retryAfter)\n }\n }\n }\n\n const postMessage = async (message: Message) => {\n log(\"enqueue postMessage\", message)\n queue.push(message)\n await postNext()\n }\n\n const connect = async (newChannel: Channel) => {\n channel = newChannel\n channel.on(\"connect\", postNext)\n channel.on(\"message\", async (msg: any) => {\n log(\"onmessage\", typeof msg)\n const { name, args, id, result, error } = await encoder.decode(msg.data)\n\n // Incoming new message\n if (name) {\n log(`name ${name} id ${id}`)\n try {\n // @ts-ignore\n if (handlers[name] == null) {\n throw new Error(`handler for ${name} was not found`)\n }\n // @ts-ignore\n let result = handlers[name](...args)\n if (isPromise(result)) result = await result\n log(`result ${result}`)\n if (id) {\n postMessage({ id, result })\n }\n } catch (error) {\n let err =\n error instanceof Error ? error : new Error(valueToString(error))\n log.warn(\"execution error\", err.name)\n postMessage({\n id,\n error: {\n message: err.message,\n stack: err.stack,\n name: err.name,\n },\n })\n }\n }\n\n // Incoming new response\n else if (id) {\n log(`response for id=${id}: result=${result}, error=${error}`)\n if (waitingForResponse[id] == null) {\n if (result === undefined) {\n log(`skip response for ${id}`)\n } else {\n log.warn(`no response hook for ${id}`)\n }\n } else {\n const [resolve, reject] = waitingForResponse[id]\n if (resolve && reject) {\n delete waitingForResponse[id]\n if (error) {\n let err = new Error(error.message)\n err.stack = error.stack\n err.name = error.name\n log.warn(\"reject\", err.name)\n reject(err)\n } else {\n log(\"resolve\", result)\n resolve(result)\n }\n }\n }\n }\n\n // Don't know what to do with it\n else if (!ignoreUnhandled) {\n log.warn(\"Unhandled message\", msg)\n }\n })\n\n postNext()\n }\n\n const fetchMessage = async (\n name: string,\n args: any[],\n opt: MessagesOptions = {}\n ): Promise<unknown> => {\n const { timeout = 5000 } = opt\n const id = uuid()\n postMessage({\n name,\n args,\n id,\n })\n return tryTimeout(\n new Promise(\n (resolve, reject) => (waitingForResponse[id] = [resolve, reject])\n ),\n timeout\n )\n }\n\n if (opt.channel) {\n connect(opt.channel)\n }\n\n return {\n dispose,\n connect,\n listen<L extends object>(newHandlers: L) {\n Object.assign(handlers, newHandlers)\n },\n send<L extends object>() {\n // The regular proxy without responding, just send\n return createPromiseProxy<L>(fetchMessage, {}, {\n options(perCallopt: MessagesOptions) {\n return createPromiseProxy<L>(fetchMessage, { ...perCallopt })\n },\n } as MessagesDefaultMethods<L>) as MessagesMethods<L>\n },\n }\n}\n","import { Logger } from \"../log\"\nimport { uname } from \"../uuid\"\nimport { Channel } from \"./channel\"\nimport { DefaultListener, Emitter, ListenerSignature } from \"./emitter\"\nimport { Encoder, JsonEncoder } from \"./encoder\"\n\ninterface PubSubConfig {\n channel: Channel\n encoder?: Encoder\n name?: string\n debug?: boolean\n}\n\nexport class PubSub<\n L extends ListenerSignature<L> = DefaultListener\n> extends Emitter<L> {\n name: string\n channel: Channel\n encoder: Encoder\n log: any\n debug: boolean\n\n get shortId() {\n return this.name.substr(0, 6)\n }\n\n constructor(opt: PubSubConfig) {\n super()\n\n let { name, encoder = new JsonEncoder(), channel, debug = false } = opt\n\n this.channel = channel\n this.encoder = encoder\n this.debug = debug\n\n this.name = name ?? this.channel.id ?? uname(\"pubsub\")\n this.log = Logger(`${this.shortId}`)\n\n if (this.debug) {\n this.channel.on(\"connect\", () => {\n this.log(\"channel connected\")\n })\n this.channel.on(\"disconnect\", () => {\n this.log(\"channel disconnected\")\n })\n }\n\n this.channel.on(\"message\", async ({ data }) => {\n let info = await this.encoder.decode(data)\n if (this.debug)\n this.log(`channel message, event=${info?.event}, info=`, info)\n else this.log(`channel message, event=${info?.event}`)\n if (info) {\n const { event, args } = info\n await this.emitSuper(event, ...args)\n }\n })\n }\n\n private async emitSuper<U extends keyof L>(\n event: U,\n ...args: Parameters<L[U]>\n ): Promise<boolean> {\n return await super.emit(event, ...args)\n }\n\n async emit<U extends keyof L>(\n event: U,\n ...args: Parameters<L[U]>\n ): Promise<boolean> {\n try {\n if (this.debug) this.log(`emit(${event})`, event)\n else this.log(`emit(${event})`, args.length)\n if (!this.channel.isConnected) {\n this.log.warn(\"channel not connected\")\n return false\n }\n const data = await this.encoder.encode({ event, args })\n this.channel.postMessage(data)\n return true\n } catch (err) {\n this.log.warn(`emit(${event})`, err)\n }\n return false\n }\n\n publish = this.emit\n subscribe = this.on\n}\n\nexport function usePubSub<L extends ListenerSignature<L> = DefaultListener>(\n opt: PubSubConfig\n) {\n return new PubSub<L>(opt)\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nexport type Mutex = (fn: () => void, elseFn?: () => void) => boolean\n\nexport function createMutex(): Mutex {\n let token = true\n return (fn, elseFn) => {\n let executed = false\n if (token) {\n token = false\n try {\n fn()\n executed = true\n } finally {\n token = true\n }\n } else if (elseFn !== undefined) {\n elseFn()\n }\n return executed\n }\n}\n\n// export type Lock = ({lock: () => Promise<void>, unlock: () => void})\n\n// export function createLock() {\n// let lockCtr = []\n// return {\n// lock() {\n\n// },\n// unlock() {\n\n// }\n// }\n// }\n","import { Json } from \"./types\"\nimport { Logger } from \"./log\"\nimport { encodeQuery } from \"./data/url\"\n\nconst log = Logger(\"network\")\n\nconst defaultOptions = {\n cache: \"no-cache\",\n redirect: \"follow\",\n}\n\n// Source https://developer.mozilla.org/de/docs/Web/HTTP/Methods\nexport type httpMethod =\n | \"GET\"\n | \"POST\"\n | \"PUT\"\n | \"DELETE\"\n | \"HEAD\"\n | \"CONNECT\"\n | \"OPTIONS\"\n | \"TRACE\"\n | \"PATCH\"\n\nexport async function fetchBasic(\n url: string,\n fetchOptions: any = {},\n fetchFn: (input: RequestInfo, init?: RequestInit) => Promise<Response> = fetch\n): Promise<Response | undefined> {\n try {\n // if (fetchOptions.headers != null && !(fetchOptions.headers instanceof Headers)) {\n // fetchOptions.headers = new Headers(fetchOptions.headers)\n // }\n // log.log('fetch', url, fetchOptions)\n const response = await fetchFn(url, fetchOptions)\n\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status\n if (response.status < 400) {\n return response\n }\n try {\n log.warn(\n `Fetch of ${url} with ${fetchOptions} returned status=${response.status}`\n )\n log.warn(`Response: ${await response.text()}`)\n } catch (err) {\n log.error(\"Exception:\", err)\n }\n } catch (err) {\n log.error(\"fetchBasic\", err)\n }\n}\n\nexport async function fetchJson<T = Json>(\n url: string,\n opts: any = {},\n fetchFn: (input: RequestInfo, init?: RequestInit) => Promise<Response> = fetch\n): Promise<T | undefined> {\n try {\n let res = await fetchBasic(\n url,\n {\n method: \"GET\",\n ...defaultOptions,\n headers: {},\n ...opts,\n },\n fetchFn\n )\n if (res) {\n return await res.json()\n }\n } catch (err) {\n log.error(\"fetchJSON error:\", err)\n }\n}\n\nexport function fetchOptionsFormURLEncoded(\n data: Object,\n method: httpMethod = \"POST\"\n) {\n return {\n method,\n ...defaultOptions,\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded; charset=utf-8\",\n },\n body: encodeQuery(data),\n }\n}\n\nexport function fetchOptionsJson(data: Object, method: httpMethod = \"POST\") {\n return {\n method,\n ...defaultOptions,\n headers: {\n \"Content-Type\": \"application/json; charset=utf-8\",\n Accept: \"application/json\",\n },\n body: JSON.stringify(data),\n }\n}\n\nexport async function fetchText(\n url: string,\n opts: any = {},\n fetchFn: (input: RequestInfo, init?: RequestInit) => Promise<Response> = fetch\n): Promise<string | undefined> {\n try {\n let res = await fetchBasic(\n url,\n {\n method: \"GET\",\n ...defaultOptions,\n headers: {},\n ...opts,\n },\n fetchFn\n )\n if (res) {\n return await res.text()\n }\n } catch (err) {\n log.error(\"fetchHTML error:\", err)\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nexport function getWindow(): any | undefined {\n // @ts-ignore\n if (typeof window !== \"undefined\") return window\n}\n\nexport function getNavigator(): any | undefined {\n // @ts-ignore\n if (typeof navigator !== \"undefined\") return navigator\n}\n\nexport function getGlobal(): any {\n return getWindow() ??\n // @ts-ignore\n typeof WorkerGlobalScope !== \"undefined\"\n ? // @ts-ignore\n self\n : typeof global !== \"undefined\"\n ? global\n : Function(\"return this;\")()\n}\n\nconst _navigator = getNavigator()\nconst _window = getWindow()\n\nexport function detect(\n info = {\n ios: false,\n macos: false,\n windows: false,\n beaker: false,\n electron: false,\n wkwebview: false,\n pwa: false,\n pwaInstalled: false,\n browser: false,\n node: false,\n worker: false,\n jest: false,\n macosNative: false,\n iosNative: false,\n appleNative: false,\n touch: false,\n }\n) {\n info.ios = _navigator?.platform?.match(/(iPhone|iPod|iPad)/i) != null\n info.macos = !!_navigator?.platform?.startsWith(\"Mac\")\n info.windows = !!_navigator?.platform?.startsWith(\"Win\")\n\n // @ts-ignore\n info.beaker = _window?.[\"beaker\"] != null // https://github.com/beakerbrowser/beaker\n info.electron =\n (_navigator?.userAgent?.toLowerCase()?.indexOf(\" electron/\") || -1) > -1 &&\n !info.beaker\n // @ts-ignore\n info.wkwebview = _window?.webkit?.[\"messageHandlers\"] != null //Apple embedded\n\n info.pwa = _navigator?.serviceWorker != null\n\n info.pwaInstalled =\n // @ts-ignore\n _navigator?.standalone ||\n _window?.matchMedia?.(\"(display-mode: standalone)\")?.matches\n\n info.node =\n typeof process !== \"undefined\" && process?.release?.name === \"node\"\n info.browser = !info.electron && !info.wkwebview && !info.node\n\n // info.worker = typeof importScripts === 'function'\n // @ts-ignore\n info.worker =\n // @ts-ignore\n typeof WorkerGlobalScope !== \"undefined\" &&\n // @ts-ignore\n self instanceof WorkerGlobalScope\n // @ts-ignore\n info.jest = typeof jest !== \"undefined\"\n\n info.macosNative = info.wkwebview && info.macos\n info.iosNative = info.wkwebview && info.ios\n info.appleNative = info.wkwebview\n\n // https://github.com/viljamis/feature.js/blob/master/feature.js#L203\n // @ts-ignore\n info.touch =\n (_window && \"ontouchstart\" in _window) ||\n (_navigator?.maxTouchPoints || 0) > 1 ||\n // @ts-ignore\n (_navigator?.msPointerEnabled && _window?.MSGesture) ||\n // @ts-ignore\n (_window?.DocumentTouch && document instanceof DocumentTouch)\n\n return info\n}\n\n// https://stackoverflow.com/a/31090240/140927\n// export const isBrowser = new Function(\n// \"try {return this===window;}catch(e){ return false;}\"\n// )\n\n// export const isNode = new Function(\n// \"try {return this===global;}catch(e){return false;}\"\n// )\n\nexport const isBrowser = () =>\n typeof window !== \"undefined\" && globalThis === window\n\nexport const platform = detect()\n\n/**\n * Before closing the tab/window or quitting the node process\n * allow to do something important first\n */\nexport function useExitHandler(handler: () => void) {\n if (isBrowser()) {\n window.addEventListener(\"beforeunload\", handler)\n } else if (typeof process !== \"undefined\") {\n process.on(\"exit\", () => handler)\n }\n}\n","import { QueueTask } from \".\"\n\ninterface PoolConfig {\n maxParallel?: number\n}\n\ninterface PoolTask<T> {\n id: string\n priority: number\n task: QueueTask<T>\n running: boolean\n}\n\nexport function usePool<T = any>(config: PoolConfig = {}) {\n const { maxParallel = 3 } = config\n\n let currentParallel = 0\n let priority = 0\n let tasks: Record<string, PoolTask<T>> = {}\n\n function performNext() {\n if (currentParallel >= maxParallel) return\n let waitingTasks = Object.values(tasks).filter((t) => !t.running)\n if (waitingTasks.length > 0) {\n let taskInfo: PoolTask<T> | undefined\n for (let t of waitingTasks) {\n // fifo\n if (taskInfo == null || t.priority < taskInfo.priority) {\n taskInfo = t\n }\n }\n if (taskInfo) {\n taskInfo.running = true\n ++currentParallel\n taskInfo\n .task()\n .then((r) => {\n if (taskInfo?.id) delete tasks[taskInfo.id]\n --currentParallel\n performNext()\n })\n .catch((err) => {\n if (taskInfo?.id) delete tasks[taskInfo.id]\n --currentParallel\n performNext()\n })\n }\n }\n }\n\n function cancel(id: string) {\n let taskInfo = tasks[id]\n if (taskInfo && taskInfo.running !== true) {\n delete tasks[id]\n }\n }\n\n return {\n cancel,\n enqueue(id: string, task: QueueTask<T>) {\n if (tasks[id] == null) {\n tasks[id] = {\n id,\n task,\n priority: ++priority,\n running: false,\n }\n performNext()\n }\n return () => cancel(id)\n },\n }\n}\n\nexport type Pool = ReturnType<typeof usePool>\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\n// Can learn from here https://github.com/sindresorhus/p-queue\n\nimport { LoggerInterface, LogLevel } from \"../common/log-base\"\nimport { Logger } from \"../common/log\"\nimport { uname } from \"./uuid\"\n\nconst log = Logger(\"zeed:queue\")\n\ntype QueueTaskResolver = any\nexport type QueueTask<T = any> = () => Promise<T>\n\ninterface QueueTaskInfo {\n name: string\n task: QueueTask\n resolve: QueueTaskResolver\n}\n\n/** Guarentee serial execution of tasks. Able to wait, pause, resume and cancel all. */\nexport class SerialQueue {\n private queue: QueueTaskInfo[] = []\n\n private isPaused: boolean = false\n private waitToFinish: QueueTaskResolver[] = []\n\n private currentTask?: Promise<any>\n\n private log: LoggerInterface\n\n name: string\n\n constructor(opt: { name?: string; logLevel?: LogLevel } = {}) {\n const { name = uname(\"queue\"), logLevel } = opt\n\n this.name = name\n this.log = Logger(`zeed:queue:${name}`)\n this.log.level = logLevel ?? LogLevel.off\n }\n\n private async performNext() {\n this.log(`performNext, queue.length =`, this.queue.length)\n\n if (this.currentTask != null) {\n this.log(`performNext => skip while another task is running`)\n return\n }\n\n if (this.isPaused) {\n this.log(`performNext => skip while is paused`)\n return\n }\n\n while (this.currentTask == null && !this.isPaused) {\n let info = this.queue.shift()\n this.log(`performNext => ${info?.name}`)\n\n if (info == null) {\n break\n }\n\n const { name, task, resolve } = info\n this.currentTask = task()\n let result = undefined\n try {\n this.log.info(`start task ${name}`)\n result = await this.currentTask\n this.log(`finished task ${name} with result =`, result)\n } catch (err) {\n log.warn(\"Error performing task\", err)\n }\n\n resolve(result)\n this.currentTask = undefined\n }\n\n while (this.waitToFinish.length > 0) {\n this.waitToFinish.shift()()\n }\n }\n\n /** Enqueue task to be executed when all other tasks are done. Except `immediate = true`. */\n async enqueue<T>(\n task: QueueTask<T>,\n opt: { immediate?: boolean; name?: string } = {}\n ): Promise<T> {\n const { immediate = false, name = uname(this.name) } = opt\n if (immediate) {\n this.log.info(`immediate execution ${name}`)\n return await task()\n }\n this.log(`enqueue ${name}`)\n return new Promise((resolve) => {\n this.queue.push({\n name,\n task,\n resolve,\n })\n this.performNext()\n })\n }\n\n /** If a task is already performing, execute immediately. Otherwise enqueue as usual. */\n async enqueueReentrant<T>(\n task: QueueTask<T>,\n opt: { name?: string } = {}\n ): Promise<T> {\n return this.enqueue(task, {\n immediate: this.currentTask != null,\n name: opt.name,\n })\n }\n\n /** Remove all tasks from queue that are not yet executing. */\n async cancelAll(unblock = true) {\n this.log(`cancelAll`)\n let resolver = this.queue.map((task) => task.resolve)\n this.queue = []\n resolver.forEach((r) => r(undefined))\n await this.wait()\n }\n\n /** Pause execution after current task is finished. */\n async pause() {\n this.log(`pause`)\n this.isPaused = true\n await this.wait()\n }\n\n /** Resume paused queue. */\n resume() {\n this.log(`resume`)\n this.isPaused = false\n this.performNext()\n }\n\n /** Wait for all tasks to finish */\n async wait() {\n this.log(`wait`)\n if (\n this.currentTask == null &&\n (this.queue.length === 0 || this.isPaused)\n ) {\n return\n }\n return new Promise((resolve) => {\n this.waitToFinish.push(resolve)\n })\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { Json } from \"../types\"\nimport { Logger } from \"../log\"\nimport { ObjectStorage } from \"../types\"\nimport { cloneObject } from \"../data/utils\"\n\nconst log = Logger(\"zeed:memstorage\")\n\nexport interface MemStorageOptions {\n objectFromString?: (data: string) => any\n objectToString?: (data: any) => string\n}\n\nexport class MemStorage<T = Json> implements ObjectStorage<T> {\n private store: Record<string, T> = {}\n // private pretty: boolean = false\n // private objectFromString: (data: string) => any\n // private objectToString: (data: any) => string\n\n constructor(opt: MemStorageOptions = {}) {\n // this.objectToString =\n // opt.objectToString ??\n // ((data: any): string => {\n // return this.pretty\n // ? JSON.stringify(data, null, 2)\n // : JSON.stringify(data)\n // })\n // this.objectFromString =\n // opt.objectFromString ??\n // ((data: string) => {\n // try {\n // return JSON.parse(data)\n // } catch (err) {\n // log.warn(`MemStorage parse error '${err}' in`, data)\n // }\n // })\n }\n\n setItem(key: string, value: T): void {\n // const data = this.objectToString(value)\n this.store[key] = cloneObject(value)\n }\n\n getItem(key: string): T | undefined {\n if (this.store.hasOwnProperty(key)) {\n return cloneObject(this.store[key])\n }\n }\n\n removeItem(key: string): void {\n delete this.store[key]\n }\n\n clear(): void {\n this.store = {}\n }\n\n allKeys(): string[] {\n return Object.keys(this.store)\n }\n}\n","// General explaination https://css-tricks.com/debouncing-throttling-explained-examples/\n// From https://github.com/cowboy/jquery-throttle-debounce\n// And https://github.com/wuct/raf-throttle/blob/master/rafThrottle.js\n\nimport { Logger } from \"./log\"\n\nconst DEBUG = false\nconst log = DEBUG ? Logger(\"zeed:throttle\") : () => {}\n\ninterface ThrottleOptions {\n delay?: number\n trailing?: boolean\n leading?: boolean\n}\n\ntype ThrottleFunction = Function & { cancel: () => void; dispose: () => void }\n\ninterface DebounceOptions {\n delay?: number\n}\n\ntype DebounceFunction = ThrottleFunction\n\n/**\n * A special throttle implementation that tries to distribute execution\n * in an optimal way.\n *\n * For UI usage the function is executed on first occasion (`leading`).\n * If more calls follow it will again be executed at end (`trailing`).\n * If the next call is inside the timeframe, it is delayed until `trailing`.\n * This avoids timewise too close calls.\n * It is possible to `cancel` the timeout and to `flush` a call, e.g. if\n * leaving UI situation where a final call is required to write data or similar.\n */\nexport function throttle(\n callback: Function,\n opt: ThrottleOptions = {}\n): ThrottleFunction {\n const { delay = 100, trailing = true, leading = true } = opt\n\n let timeoutID: any = 0\n let checkpoint = 0\n let visited = 0\n\n let debugCheckpoint = Date.now()\n\n function clearExistingTimeout() {\n if (timeoutID) {\n clearTimeout(timeoutID)\n timeoutID = undefined\n }\n }\n\n function wrapper(this: any, ...arguments_: any[]) {\n const now = Date.now()\n let self = this\n let elapsed = now - checkpoint\n\n function debugElapsed() {\n const dnow = Date.now()\n return `total ${(dnow - debugCheckpoint).toFixed(1)}ms - elapsed ${(\n dnow - checkpoint\n ).toFixed(1)}ms - visited ${visited}x`\n }\n\n function exec() {\n visited = 0\n checkpoint = Date.now()\n callback.apply(self, arguments_)\n }\n\n // Make sure enough time has passed since last call\n if (elapsed > delay || !timeoutID) {\n DEBUG && log(\"elapsed\", debugElapsed())\n\n // Leading execute once immediately\n if (leading) {\n if (elapsed > delay) {\n DEBUG && log(\"🚀 leading\", debugElapsed())\n exec()\n } else {\n ++visited // at least trigger trailing this way\n }\n }\n\n const timeout = elapsed > delay ? delay : delay - elapsed\n log(`⏱ start timeout with ${timeout.toFixed(1)}ms}`, debugElapsed())\n\n // Prepare for next round\n clearExistingTimeout()\n checkpoint = now\n\n // Delay. We should not get here if timeout has not been reached before\n timeoutID = setTimeout(() => {\n DEBUG && log(\"⏱ reached timeout\", debugElapsed())\n timeoutID = 0\n // Only execute on trailing or when visited again, but do not twice if leading\n if (trailing && (!leading || visited > 0)) {\n DEBUG && log(\"🚀 trailing\", debugElapsed())\n exec()\n }\n }, timeout)\n } else {\n // Count visits\n ++visited\n DEBUG && log(\"visited\", debugElapsed())\n }\n }\n\n wrapper.cancel = clearExistingTimeout\n wrapper.dispose = clearExistingTimeout\n\n // wrapper.flush = () => throw 'todo'\n\n return wrapper\n}\n\n/**\n * Debounce fits best for filtering a large peak of events.\n * For UI event filtering throttle is probably a better choice.\n */\nexport function debounce(\n callback: Function,\n opt: DebounceOptions = {}\n): DebounceFunction {\n const { delay = 100 } = opt\n let timeoutID: any = 0\n\n function clearExistingTimeout() {\n if (timeoutID) {\n clearTimeout(timeoutID)\n timeoutID = 0\n }\n }\n\n function wrapper(this: any, ...arguments_: any[]) {\n let self = this\n clearExistingTimeout()\n timeoutID = setTimeout(() => {\n timeoutID = 0\n callback.apply(self, arguments_)\n }, delay)\n }\n\n wrapper.cancel = clearExistingTimeout\n wrapper.dispose = clearExistingTimeout\n return wrapper\n}\n","// https://nodejs.org/api/webcrypto.html\nimport nodeCrypto from \"crypto\"\n\nexport {}\n\ndeclare module NodeJS {\n interface Global {\n crypto: Crypto\n }\n}\n\ntry {\n if (\n nodeCrypto &&\n nodeCrypto.webcrypto &&\n typeof globalThis !== \"undefined\" &&\n typeof globalThis.crypto === \"undefined\"\n ) {\n // @ts-ignore\n globalThis.crypto = nodeCrypto.webcrypto\n }\n} catch (err) {\n console.warn(\"Failed to polyfill webcrypto\", err)\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\n// Adopted from https://github.com/motdotla/dotenv BSD-2\n\nimport { LogLevel } from \"../common/log-base\"\nimport { Logger } from \"../common/log\"\n\nimport fs from \"fs\"\nimport { resolve } from \"path\"\n\nconst log = Logger(\"zeed:env\")\n\nconst NEWLINE = \"\\n\"\nconst RE_INI_KEY_VAL = /^\\s*([\\w_.-]+)\\s*=\\s*(.*)?\\s*$/\nconst RE_NEWLINES = /\\\\n/g\nconst NEWLINES_MATCH = /\\n|\\r|\\r\\n/\n\ntype csvOptions = {\n /** @deprecated will probably be replaced by logLevel */\n debug?: boolean\n path?: string\n filename?: string\n encoding?: BufferEncoding\n prefix?: string\n env?: Record<string, string>\n}\n\n// Parses src into an Object\nfunction parse(src: string, options: csvOptions = {}) {\n let obj: Record<string, string> = {}\n\n // convert Buffers before splitting into lines and processing\n src\n .toString()\n .split(NEWLINES_MATCH)\n .forEach(function (line, idx) {\n // matching \"KEY' and 'VAL' in 'KEY=VAL'\n const keyValueArr = line.match(RE_INI_KEY_VAL)\n // matched?\n\n // log.debug(\"keyValueArr\", keyValueArr)\n\n if (keyValueArr != null) {\n const key = keyValueArr[1]\n // default undefined or missing values to empty string\n let val = keyValueArr[2] || \"\"\n const end = val.length - 1\n const isDoubleQuoted = val[0] === '\"' && val[end] === '\"'\n const isSingleQuoted = val[0] === \"'\" && val[end] === \"'\"\n\n // if single or double quoted, remove quotes\n if (isSingleQuoted || isDoubleQuoted) {\n val = val.substring(1, end)\n\n // if double quoted, expand newlines\n if (isDoubleQuoted) {\n val = val.replace(RE_NEWLINES, NEWLINE)\n }\n } else {\n // remove surrounding whitespace\n val = val.trim()\n }\n obj[key] = val\n } else {\n log.debug(\n `did not match key and value when parsing line ${idx + 1}: ${line}`\n )\n }\n })\n\n // log.debug(\"obj\", obj)\n return obj\n}\n\n/**\n * Return a path relative to the current working directory\n */\nexport function stringToPath(\n value?: string,\n defaultValue: string = \".\"\n): string {\n return resolve(process.cwd(), value ?? defaultValue)\n}\n\nexport function valueToPath(value?: any, defaultValue = \"\"): string {\n if (value == null) value = defaultValue\n return stringToPath(String(value).trim(), defaultValue)\n}\n\nexport const toPath = valueToPath\n\n// Populates process.env from .env file\nexport function setupEnv(options: csvOptions = {}) {\n const dotenvPath: string =\n options?.path ?? toPath(options?.filename ?? \".env\")\n const encoding: BufferEncoding = options?.encoding ?? \"utf8\"\n const debug = options?.debug || false\n\n if (debug !== true) log.level = LogLevel.off\n\n try {\n // specifying an encoding returns a string instead of a buffer\n const parsedEnv = fs.existsSync(dotenvPath)\n ? parse(fs.readFileSync(dotenvPath, { encoding }), { debug })\n : {}\n const parsedEnvLocal = fs.existsSync(dotenvPath + \".local\")\n ? parse(fs.readFileSync(dotenvPath + \".local\", { encoding }), { debug })\n : {}\n\n const parsed: Record<string, string> = Object.assign(\n {},\n parsedEnv,\n parsedEnvLocal\n )\n let env = options?.env ?? process.env\n\n Object.entries(parsed).forEach(([key, value]) => {\n if (typeof options?.prefix === \"string\") {\n key = options?.prefix + key\n }\n if (!Object.prototype.hasOwnProperty.call(env, key)) {\n if (value != null) {\n log.info(`set env.${key} = ${value}`)\n env[key] = value\n }\n } else {\n log.debug(`\"${key}\" is already defined and will not be overwritten`)\n }\n })\n return { parsed }\n } catch (e) {\n log.error(e)\n return { error: e }\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport {\n mkdirSync,\n readdirSync,\n readFileSync,\n rmSync,\n unlinkSync,\n writeFileSync,\n} from \"fs\"\nimport { dirname, resolve } from \"path\"\nimport { toValidFilename } from \"../common/data/path\"\nimport { cloneObject } from \"../common/data/utils\"\nimport { Logger } from \"../common/log\"\nimport { Json, ObjectStorage } from \"../common/types\"\n\nconst log = Logger(\"zeed:filestorage\")\n\nexport interface FileStorageOptions {\n pretty?: boolean\n path?: string\n extension?: string\n objectFromString?: (data: string) => any\n objectToString?: (data: any) => string\n keyToFilename?: (key: string) => string\n}\n\nexport class FileStorage<T = Json> implements ObjectStorage<T> {\n private store: Record<string, T | null> = {}\n private dirname: string\n private fileKeys?: string[] = undefined\n private pretty: boolean = false\n private extension: string\n private extensionLength: number\n private objectFromString: (data: string) => any\n private objectToString: (data: any) => string\n private keyToFilename: (key: string) => string\n\n constructor(opt: FileStorageOptions = {}) {\n this.dirname = resolve(process.cwd(), opt.path || \".fileStorage\")\n this.pretty = !!opt.pretty\n this.extension = opt.extension ?? \".json\"\n\n if (opt.extension && !this.extension.startsWith(\".\")) {\n this.extension = \".\" + this.extension\n }\n this.extensionLength = this.extension.length\n\n this.objectToString =\n opt.objectToString ??\n ((data: any): string => {\n return this.pretty\n ? JSON.stringify(data, null, 2)\n : JSON.stringify(data)\n })\n\n this.objectFromString =\n opt.objectFromString ??\n ((data: string) => {\n try {\n return JSON.parse(data)\n } catch (err) {\n log.warn(`fileStorage parse error '${err}' in`, data)\n }\n })\n\n this.keyToFilename = opt.keyToFilename ?? toValidFilename\n }\n\n setItem(key: string, value: T): void {\n this.store[key] = cloneObject(value)\n try {\n const data = this.objectToString(value)\n const path = this.getPath(key)\n mkdirSync(dirname(path), { recursive: true })\n writeFileSync(path, data, \"utf8\")\n } catch (err) {\n log.error(\"setItem error\", err)\n }\n }\n\n getPath(key: string): string {\n return resolve(this.dirname, this.keyToFilename(key) + this.extension)\n }\n\n getBuffer(key: string): Buffer {\n const path = this.getPath(key)\n return Buffer.from(readFileSync(path))\n }\n\n getItem(key: string): T | undefined {\n let value = this.store[key]\n\n // null is an indicator for not existing!\n if (value === null) return\n\n if (value != null) {\n return cloneObject(value) // this.objectFromString(value)\n }\n\n try {\n const path = this.getPath(key)\n const data = readFileSync(path, \"utf8\")\n if (data != null) {\n const value = this.objectFromString(data)\n this.store[key] = value\n return value\n }\n } catch (err) {\n log.warn(\"getItem error\", err)\n this.store[key] = null // do not retry next time\n }\n }\n\n removeItem(key: string): void {\n delete this.store[key]\n if (this.fileKeys != null) {\n const index: number = this.fileKeys.indexOf(key)\n if (index !== -1) {\n this.fileKeys.splice(index, 1)\n }\n }\n try {\n const path = this.getPath(key)\n unlinkSync(path)\n } catch (err) {}\n }\n\n clear(): void {\n this.fileKeys = []\n this.store = {}\n rmSync(this.dirname, { recursive: true, force: true })\n }\n\n allKeys(): string[] {\n if (this.fileKeys == null) {\n try {\n this.fileKeys =\n readdirSync(this.dirname, { withFileTypes: true })\n .filter(\n (item) =>\n !item.isDirectory() && item.name.endsWith(this.extension)\n )\n .map((item) => item.name.slice(0, -this.extensionLength)) || []\n } catch (err) {}\n }\n let keys = [...(this.fileKeys || [])]\n for (let key of Object.keys(this.store)) {\n if (!keys.includes(key)) {\n keys.push(key)\n }\n }\n keys.sort()\n return keys\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { createWriteStream, mkdirSync } from \"fs\"\nimport { dirname, resolve } from \"path\"\nimport { renderMessages } from \"../common/data/convert\"\nimport { LogHandlerOptions, LogLevel, LogMessage } from \"../common/log-base\"\nimport { useLevelFilter, useNamespaceFilter } from \"../common/log-filter\"\n\nlet namespaces: Record<string, any> = {}\n\nexport function LoggerFileHandler(path: string, opt: LogHandlerOptions = {}) {\n const { level = LogLevel.all, filter = \"*\" } = opt\n path = resolve(process.cwd(), path)\n mkdirSync(dirname(path), { recursive: true })\n var stream = createWriteStream(path, { flags: \"a\" })\n // stream.end()\n const matchesNamespace = useNamespaceFilter(filter)\n const matchesLevel = useLevelFilter(level)\n return (msg: LogMessage) => {\n if (!matchesLevel(msg.level)) return\n if (!matchesNamespace(msg.name)) return\n\n const time = new Date().toISOString()\n let name = msg.name || \"\"\n let ninfo = namespaces[name || \"\"]\n if (ninfo == null) {\n namespaces[name] = ninfo\n }\n\n let args: string[] = [\n `[${name || \"*\"}]`,\n renderMessages(msg.messages, { pretty: false }),\n ]\n\n function write(...args: string[]): void {\n stream.write(args.join(\"\\t\") + \"\\n\")\n }\n\n switch (msg.level) {\n case LogLevel.info:\n write(time, `I|* `, ...args)\n break\n case LogLevel.warn:\n write(time, `W|** `, ...args)\n break\n case LogLevel.error:\n write(time, `E|***`, ...args)\n break\n default:\n write(time, `D| `, ...args)\n break\n }\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport tty from \"tty\"\nimport { renderMessages } from \"../common/data/convert\"\nimport {\n LogHandler,\n LogHandlerOptions,\n LogLevel,\n LogMessage,\n} from \"../common/log-base\"\nimport { useLevelFilter, useNamespaceFilter } from \"../common/log-filter\"\nimport {\n getSourceLocation,\n getSourceLocationByPrecedingPattern,\n getStack,\n} from \"./log-util\"\nimport { formatMilliseconds, getTimestamp } from \"../common/time\"\n\nexport function isTTY(): boolean {\n try {\n return tty.isatty(process.stdout.fd)\n } catch (err) {}\n return false\n}\n\nconst colors = [6, 2, 3, 4, 5, 1]\n\nfunction selectColor(namespace: string) {\n let hash = 0\n for (let i = 0; i < namespace.length; i++) {\n hash = (hash << 5) - hash + namespace.charCodeAt(i)\n hash |= 0 // Convert to 32bit integer\n }\n return colors[Math.abs(hash) % colors.length]\n}\n\nlet namespaces: Record<string, any> = {}\n\nlet time = getTimestamp()\n\nconst useColors = tty.isatty(process.stderr.fd)\n\nfunction log(...args: any[]) {\n return process.stderr.write(renderMessages(args) + \"\\n\")\n}\n\n// export const BOLD = Symbol()\n// export const UNBOLD = Symbol()\n// export const BLUE = Symbol()\n// export const GREY = Symbol()\n// export const GREEN = Symbol()\n// export const RED = Symbol()\n// export const PURPLE = Symbol()\n// export const ORANGE = Symbol()\n// export const UNCOLOR = Symbol()\n\n// const _browserStyleMap = {\n// [BOLD]: pair.create(\"font-weight\", \"bold\"),\n// [UNBOLD]: pair.create(\"font-weight\", \"normal\"),\n// [BLUE]: pair.create(\"color\", \"blue\"),\n// [GREEN]: pair.create(\"color\", \"green\"),\n// [GREY]: pair.create(\"color\", \"grey\"),\n// [RED]: pair.create(\"color\", \"red\"),\n// [PURPLE]: pair.create(\"color\", \"purple\"),\n// [ORANGE]: pair.create(\"color\", \"orange\"), // not well supported in chrome when debugging node with inspector - TODO: deprecate\n// [UNCOLOR]: pair.create(\"color\", \"black\"),\n// }\n\nconst TTY_STYLE = {\n BOLD: \"\\u001b[1m\",\n UNBOLD: \"\\u001b[2m\",\n RED: \"\\u001b[31m\",\n GREEN: \"\\u001b[32m\",\n BLUE: \"\\u001b[34m\",\n PURPLE: \"\\u001b[35m\",\n GRAY: \"\\u001b[37m\",\n ORANGE: \"\\u001b[38;5;208m\",\n UNCOLOR: \"\\u001b[0m\",\n}\n\nenum COLOR {\n RED = 1,\n GREEN = 2,\n BLUE = 4,\n PURPLE = 5,\n GRAY = 7,\n ORANGE = 8,\n}\n\nconst colorEnd = \"\\u001B[0m\"\n\nexport function colorString(value: string, colorCode: number) {\n const colorStart =\n colorCode === COLOR.ORANGE\n ? TTY_STYLE.ORANGE\n : \"\\u001B[3\" + (colorCode < 8 ? colorCode : \"8;5;\" + colorCode) + \"m\"\n return `${colorStart}${value}${colorEnd}`\n}\n\nexport function colorStringList(\n list: Array<any>,\n style: string,\n bold: boolean = true\n) {\n return list.map((value) => {\n if (typeof value !== \"string\") return value\n let start = style\n let end = colorEnd\n if (bold) {\n start = `${TTY_STYLE.BOLD}${start}`\n end = `${end}${TTY_STYLE.BOLD}`\n }\n return `${start}${value}${end}`\n })\n}\n\nexport const loggerStackTraceDebug =\n \"loggerStackTraceDebug-7d38e5a9214b58d29734374cdb9521fd964d7485\"\n\nexport function LoggerNodeHandler(opt: LogHandlerOptions = {}): LogHandler {\n const {\n level = undefined,\n filter = undefined,\n colors = isTTY(),\n levelHelper = true,\n nameBrackets = true,\n padding = 0,\n fill = 0,\n stack = true,\n } = opt\n const matchesNamespace = useNamespaceFilter(filter)\n const matchesLevel = useLevelFilter(level)\n return (msg: LogMessage) => {\n if (!matchesLevel(msg.level)) return\n if (!matchesNamespace(msg.name)) return\n const timeNow = getTimestamp()\n let name = msg.name || \"\"\n let ninfo = namespaces[name || \"\"]\n if (ninfo == null) {\n ninfo = {\n color: selectColor(name),\n // time: timeNow\n }\n namespaces[name] = ninfo\n }\n const diff = formatMilliseconds(timeNow - time)\n\n let args: string[]\n\n let displayName = nameBrackets ? `[${name}]` : name\n\n if (padding > 0) {\n displayName = displayName.padStart(padding, \" \")\n }\n\n if (fill > 0) {\n displayName = displayName.padEnd(fill, \" \")\n }\n\n if (colors && useColors) {\n const c = ninfo.color\n args = [colorString(displayName, c) + ` | `] // nameBrackets ? [`%c[${name}]`] : [`%c${name}`]\n if (msg.level === LogLevel.warn) {\n args.push(...colorStringList(msg.messages, TTY_STYLE.ORANGE))\n } else if (msg.level === LogLevel.error) {\n args.push(...colorStringList(msg.messages, TTY_STYLE.RED))\n } else {\n args.push(...msg.messages)\n }\n args.push(colorString(`+${diff}`, c))\n } else {\n args = [displayName, ...msg.messages]\n args.push(`+${diff}`)\n }\n\n if (msg.messages?.[0] === loggerStackTraceDebug) {\n console.log(getStack())\n }\n\n if (stack) {\n let line: string = \"\"\n if (typeof stack === \"boolean\") {\n line = getSourceLocationByPrecedingPattern(\n [\"at Function.\", \"at null.log (\", \"at log (\"],\n true\n )\n if (!line) {\n line = getSourceLocation(0, true)\n }\n } else {\n const depth = typeof stack === \"number\" ? stack : 3\n line = getSourceLocation(depth, true)\n }\n if (line) {\n args.push(colorString(`(${line})`, COLOR.GRAY))\n }\n }\n switch (msg.level) {\n case LogLevel.info:\n if (levelHelper) args[0] = `I|* ` + args[0]\n log(...args)\n break\n case LogLevel.warn:\n if (levelHelper)\n args[0] =\n (colors && useColors\n ? colorString(`W|** `, COLOR.ORANGE)\n : `W|** `) + args[0]\n log(...args)\n break\n case LogLevel.error:\n if (levelHelper)\n args[0] =\n (colors && useColors\n ? colorString(`E|*** `, COLOR.RED)\n : `E|*** `) + args[0]\n log(...args)\n break\n default:\n if (levelHelper) args[0] = `D| ` + args[0]\n log(...args)\n break\n }\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { resolve } from \"path\"\n\nexport function getStackLlocationList(stack: string): any[] {\n if (typeof stack !== \"string\") return []\n // console.log(\"stack\", stack)\n return (\n stack\n ?.split(\"\\n\")\n ?.map((rawLine) => {\n let m = rawLine.match(/^\\s+at.*(\\((.*)\\)|file:\\/\\/(.*)$)/)\n if (m) {\n let line = m[3] || m[2]\n if (line.endsWith(\")\")) line = line.slice(0, -1)\n return line\n }\n })\n ?.filter((v) => v != null) || []\n )\n}\n\nconst cwd = resolve(process.cwd())\nconst home = process.env?.HOME ? resolve(process.env?.HOME) : \"\"\n// console.log(`cwd = ${cwd}, home = ${home}}`)\n\nfunction pathStripCwd(path: string) {\n // console.log(\">\", path)\n\n if (path.includes(\"/node_modules/\")) {\n return \"\"\n }\n\n const fileURL = \"file://\"\n if (path.startsWith(fileURL)) {\n return path.substr(fileURL.length)\n }\n\n if (cwd && path.startsWith(cwd)) {\n return path.substr(cwd.length + 1)\n }\n\n if (home && path.startsWith(home)) {\n path = \"~/\" + path.substr(home.length + 1)\n }\n\n return path\n}\n\nfunction extractFileInfo(stackLine: string): string {\n let m = stackLine.match(/^\\s*at.*(\\((.*)\\)|file:\\/\\/(.*)$)/)\n if (m) {\n let line = m[3] || m[2]\n if (line.endsWith(\")\")) line = line.slice(0, -1)\n return line\n }\n return \"\"\n}\n\n/**\n * Get the source code location of the caller\n * https://stackoverflow.com/a/47296370/140927\n *\n * @param level Number of levels to go down the stack trace\n * @param stripCwd Strip the current working directory, only reasonable for Node.js environment\n * @returns\n */\nexport function getSourceLocation(level = 2, stripCwd = true): string {\n let stack = new Error().stack || \"\"\n let line: string | undefined = getStackLlocationList(stack)?.[level]\n if (line && stripCwd) {\n line = pathStripCwd(line)\n }\n return line || \"\"\n}\n\nexport function getStack(): string {\n return new Error().stack || \"\"\n}\n\nexport function getSourceLocationByPrecedingPattern(\n patterns: string[],\n stripCwd = true\n) {\n let line = \"\"\n let stack = new Error().stack || \"\"\n if (typeof stack === \"string\") {\n const lines = stack.split(\"\\n\").map((l) => l.trim())\n // console.log(lines)\n const index = lines.findIndex((l) => patterns.some((p) => l.startsWith(p)))\n line = lines[index + 1]\n if (line) {\n line = extractFileInfo(line)\n }\n if (line && stripCwd) {\n line = pathStripCwd(line)\n }\n }\n return line\n}\n","import { Logger } from \"../common/log\"\nimport { toPath } from \"./env\"\nimport { LoggerFileHandler } from \"./log-file\"\nimport { LoggerNodeHandler } from \"./log-node\"\n\nfunction setupLogContextNode() {\n let handlers = [\n LoggerNodeHandler({\n padding: 32,\n nameBrackets: false,\n // levelHelper: false,\n }),\n ]\n\n let logFilePath = process.env.ZEED_LOG ?? process.env.LOG\n if (logFilePath) {\n handlers.unshift(LoggerFileHandler(toPath(logFilePath)))\n }\n\n Logger.setHandlers(handlers)\n}\n\nsetupLogContextNode()\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { Logger } from \"../common/log\"\n\nconst { error } = Logger(\"zeed:base64\")\n\nexport function urlBase64ToUint8Array(\n base64String: string\n): Uint8Array | undefined {\n try {\n let padding = \"=\".repeat((4 - (base64String.length % 4)) % 4)\n let base64 = (base64String + padding).replace(/-/g, \"+\").replace(/_/g, \"/\")\n\n let rawData = window.atob(base64)\n let outputArray = new Uint8Array(rawData.length)\n\n for (let i = 0; i < rawData.length; ++i) {\n outputArray[i] = rawData.charCodeAt(i)\n }\n return outputArray\n } catch (err) {\n error(err, base64String)\n }\n}\n","// MIT licensed\n// https://github.com/mazondo/gravatarjs/blob/master/gravatar.js\n// https://en.gravatar.com/site/implement/images/\n\nimport { Logger } from \"../common/log\"\n\nconst log = Logger(\"zeed:gravatar\")\n\nfunction gravatar(\n email: string,\n options: { size?: any; backup?: any; secure?: any; rating?: any }\n) {\n // using md5() from here: http://www.myersdaily.org/joseph/javascript/md5-text.html\n function md5cycle(e: any[], t: any[]) {\n var n = e[0],\n r = e[1],\n i = e[2],\n s = e[3]\n n = ff(n, r, i, s, t[0], 7, -680876936)\n s = ff(s, n, r, i, t[1], 12, -389564586)\n i = ff(i, s, n, r, t[2], 17, 606105819)\n r = ff(r, i, s, n, t[3], 22, -1044525330)\n n = ff(n, r, i, s, t[4], 7, -176418897)\n s = ff(s, n, r, i, t[5], 12, 1200080426)\n i = ff(i, s, n, r, t[6], 17, -1473231341)\n r = ff(r, i, s, n, t[7], 22, -45705983)\n n = ff(n, r, i, s, t[8], 7, 1770035416)\n s = ff(s, n, r, i, t[9], 12, -1958414417)\n i = ff(i, s, n, r, t[10], 17, -42063)\n r = ff(r, i, s, n, t[11], 22, -1990404162)\n n = ff(n, r, i, s, t[12], 7, 1804603682)\n s = ff(s, n, r, i, t[13], 12, -40341101)\n i = ff(i, s, n, r, t[14], 17, -1502002290)\n r = ff(r, i, s, n, t[15], 22, 1236535329)\n n = gg(n, r, i, s, t[1], 5, -165796510)\n s = gg(s, n, r, i, t[6], 9, -1069501632)\n i = gg(i, s, n, r, t[11], 14, 643717713)\n r = gg(r, i, s, n, t[0], 20, -373897302)\n n = gg(n, r, i, s, t[5], 5, -701558691)\n s = gg(s, n, r, i, t[10], 9, 38016083)\n i = gg(i, s, n, r, t[15], 14, -660478335)\n r = gg(r, i, s, n, t[4], 20, -405537848)\n n = gg(n, r, i, s, t[9], 5, 568446438)\n s = gg(s, n, r, i, t[14], 9, -1019803690)\n i = gg(i, s, n, r, t[3], 14, -187363961)\n r = gg(r, i, s, n, t[8], 20, 1163531501)\n n = gg(n, r, i, s, t[13], 5, -1444681467)\n s = gg(s, n, r, i, t[2], 9, -51403784)\n i = gg(i, s, n, r, t[7], 14, 1735328473)\n r = gg(r, i, s, n, t[12], 20, -1926607734)\n n = hh(n, r, i, s, t[5], 4, -378558)\n s = hh(s, n, r, i, t[8], 11, -2022574463)\n i = hh(i, s, n, r, t[11], 16, 1839030562)\n r = hh(r, i, s, n, t[14], 23, -35309556)\n n = hh(n, r, i, s, t[1], 4, -1530992060)\n s = hh(s, n, r, i, t[4], 11, 1272893353)\n i = hh(i, s, n, r, t[7], 16, -155497632)\n r = hh(r, i, s, n, t[10], 23, -1094730640)\n n = hh(n, r, i, s, t[13], 4, 681279174)\n s = hh(s, n, r, i, t[0], 11, -358537222)\n i = hh(i, s, n, r, t[3], 16, -722521979)\n r = hh(r, i, s, n, t[6], 23, 76029189)\n n = hh(n, r, i, s, t[9], 4, -640364487)\n s = hh(s, n, r, i, t[12], 11, -421815835)\n i = hh(i, s, n, r, t[15], 16, 530742520)\n r = hh(r, i, s, n, t[2], 23, -995338651)\n n = ii(n, r, i, s, t[0], 6, -198630844)\n s = ii(s, n, r, i, t[7], 10, 1126891415)\n i = ii(i, s, n, r, t[14], 15, -1416354905)\n r = ii(r, i, s, n, t[5], 21, -57434055)\n n = ii(n, r, i, s, t[12], 6, 1700485571)\n s = ii(s, n, r, i, t[3], 10, -1894986606)\n i = ii(i, s, n, r, t[10], 15, -1051523)\n r = ii(r, i, s, n, t[1], 21, -2054922799)\n n = ii(n, r, i, s, t[8], 6, 1873313359)\n s = ii(s, n, r, i, t[15], 10, -30611744)\n i = ii(i, s, n, r, t[6], 15, -1560198380)\n r = ii(r, i, s, n, t[13], 21, 1309151649)\n n = ii(n, r, i, s, t[4], 6, -145523070)\n s = ii(s, n, r, i, t[11], 10, -1120210379)\n i = ii(i, s, n, r, t[2], 15, 718787259)\n r = ii(r, i, s, n, t[9], 21, -343485551)\n e[0] = add32(n, e[0])\n e[1] = add32(r, e[1])\n e[2] = add32(i, e[2])\n e[3] = add32(s, e[3])\n }\n function cmn(e: number, t: number, n: any, r: any, i: number, s: any) {\n t = add32(add32(t, e), add32(r, s))\n return add32((t << i) | (t >>> (32 - i)), n)\n }\n function ff(\n e: any,\n t: number,\n n: number,\n r: number,\n i: any,\n s: number,\n o: number\n ) {\n return cmn((t & n) | (~t & r), e, t, i, s, o)\n }\n function gg(\n e: any,\n t: number,\n n: number,\n r: number,\n i: any,\n s: number,\n o: number\n ) {\n return cmn((t & r) | (n & ~r), e, t, i, s, o)\n }\n function hh(\n e: any,\n t: number,\n n: number,\n r: number,\n i: any,\n s: number,\n o: number\n ) {\n return cmn(t ^ n ^ r, e, t, i, s, o)\n }\n function ii(\n e: any,\n t: number,\n n: number,\n r: number,\n i: any,\n s: number,\n o: number\n ) {\n return cmn(n ^ (t | ~r), e, t, i, s, o)\n }\n function md51(e: string) {\n var t = e.length,\n n = [1732584193, -271733879, -1732584194, 271733878],\n r: number\n for (r = 64; r <= e.length; r += 64) {\n md5cycle(n, md5blk(e.substring(r - 64, r)))\n }\n e = e.substring(r - 64)\n var i = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n for (r = 0; r < e.length; r++) i[r >> 2] |= e.charCodeAt(r) << (r % 4 << 3)\n i[r >> 2] |= 128 << (r % 4 << 3)\n if (r > 55) {\n md5cycle(n, i)\n for (r = 0; r < 16; r++) i[r] = 0\n }\n i[14] = t * 8\n md5cycle(n, i)\n return n\n }\n function md5blk(e: string) {\n var t = [],\n n: number\n for (n = 0; n < 64; n += 4) {\n t[n >> 2] =\n e.charCodeAt(n) +\n (e.charCodeAt(n + 1) << 8) +\n (e.charCodeAt(n + 2) << 16) +\n (e.charCodeAt(n + 3) << 24)\n }\n return t\n }\n function rhex(e: number) {\n var t = \"\",\n n = 0\n for (; n < 4; n++)\n t += hex_chr[(e >> (n * 8 + 4)) & 15] + hex_chr[(e >> (n * 8)) & 15]\n return t\n }\n function hex(e: any[]) {\n for (var t = 0; t < e.length; t++) e[t] = rhex(e[t])\n return e.join(\"\")\n }\n function md5(e: string) {\n return hex(md51(e))\n }\n function add32(e: number, t: number) {\n return (e + t) & 4294967295\n }\n var hex_chr = \"0123456789abcdef\".split(\"\")\n //check to make sure you gave us something\n var options = options || {},\n base: string,\n params = []\n\n //set some defaults, just in case\n options = {\n size: options.size || \"50\",\n rating: options.rating || \"g\",\n secure: options.secure || location.protocol === \"https:\",\n backup: options.backup || \"\",\n }\n\n //setup the email address\n email = email.trim().toLowerCase()\n\n //determine which base to use\n base = options.secure\n ? \"https://secure.gravatar.com/avatar/\"\n : \"http://www.gravatar.com/avatar/\"\n\n //add the params\n if (options.rating) {\n params.push(\"r=\" + options.rating)\n }\n if (options.backup) {\n params.push(\"d=\" + encodeURIComponent(options.backup))\n }\n if (options.size) {\n params.push(\"s=\" + options.size)\n }\n\n //now throw it all together\n return base + md5(email) + \"?\" + params.join(\"&\")\n}\n\nexport function gravatarURLByEmail(\n email: string,\n defaultURL: string = \"\"\n): string {\n try {\n return gravatar(email, {\n size: 256,\n backup: \"monsterid\",\n // backup: \"https://holtwick.de/download/user.png\", // \"retro\",\n secure: true,\n })\n } catch (error) {\n log(\"Gravatar issue: Did not find an image for \" + email)\n return defaultURL\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { Json, ObjectStorage } from \"../common/types\"\nimport { Logger } from \"../common/log\"\n\nconst log = Logger(\"zeed:localstorage\")\n\nexport interface LocalStorageOptions {\n name: string\n objectFromString?: (data: string) => any\n objectToString?: (data: any) => string\n}\n\nexport class LocalStorage<T = Json> implements ObjectStorage<T> {\n private name: string\n private prefix: string\n private pretty: boolean = false\n private objectFromString: (data: string) => any\n private objectToString: (data: any) => string\n\n constructor(opt: LocalStorageOptions) {\n log.assert(opt.name, \"name required\")\n this.name = opt.name\n this.prefix = `${opt.name}$`\n this.objectToString =\n opt.objectToString ??\n ((data: any): string => {\n return this.pretty\n ? JSON.stringify(data, null, 2)\n : JSON.stringify(data)\n })\n\n this.objectFromString =\n opt.objectFromString ??\n ((data: string) => {\n try {\n return JSON.parse(data)\n } catch (err) {\n log.warn(`LocalStorage parse error '${err}' in`, data)\n }\n })\n }\n\n setItem(key: string, value: T): void {\n const data = this.objectToString(value)\n localStorage.setItem(`${this.prefix}${key}`, data)\n }\n\n getItem(key: string): T | undefined {\n let value = localStorage.getItem(`${this.prefix}${key}`)\n if (value != null) {\n return this.objectFromString(value)\n }\n }\n\n removeItem(key: string): void {\n localStorage.removeItem(`${this.prefix}${key}`)\n }\n\n clear(): void {\n Object.keys(localStorage)\n .filter((key) => key.startsWith(this.prefix))\n .forEach((key) => {\n localStorage.removeItem(key)\n })\n }\n\n allKeys(): string[] {\n const prefixLength = this.prefix.length\n return Object.keys(localStorage)\n .filter((key) => key.startsWith(this.prefix))\n .map((key) => key.substr(prefixLength))\n }\n}\n","// Taken from https://github.com/visionmedia/debug/blob/master/src/browser.js#L27\n\nconst colors = [\n \"#0000CC\",\n \"#0000FF\",\n \"#0033CC\",\n \"#0033FF\",\n \"#0066CC\",\n \"#0066FF\",\n \"#0099CC\",\n \"#0099FF\",\n \"#00CC00\",\n \"#00CC33\",\n \"#00CC66\",\n \"#00CC99\",\n \"#00CCCC\",\n \"#00CCFF\",\n \"#3300CC\",\n \"#3300FF\",\n \"#3333CC\",\n \"#3333FF\",\n \"#3366CC\",\n \"#3366FF\",\n \"#3399CC\",\n \"#3399FF\",\n \"#33CC00\",\n \"#33CC33\",\n \"#33CC66\",\n \"#33CC99\",\n \"#33CCCC\",\n \"#33CCFF\",\n \"#6600CC\",\n \"#6600FF\",\n \"#6633CC\",\n \"#6633FF\",\n \"#66CC00\",\n \"#66CC33\",\n \"#9900CC\",\n \"#9900FF\",\n \"#9933CC\",\n \"#9933FF\",\n \"#99CC00\",\n \"#99CC33\",\n \"#CC0000\",\n \"#CC0033\",\n \"#CC0066\",\n \"#CC0099\",\n \"#CC00CC\",\n \"#CC00FF\",\n \"#CC3300\",\n \"#CC3333\",\n \"#CC3366\",\n \"#CC3399\",\n \"#CC33CC\",\n \"#CC33FF\",\n \"#CC6600\",\n \"#CC6633\",\n \"#CC9900\",\n \"#CC9933\",\n \"#CCCC00\",\n \"#CCCC33\",\n \"#FF0000\",\n \"#FF0033\",\n \"#FF0066\",\n \"#FF0099\",\n \"#FF00CC\",\n \"#FF00FF\",\n \"#FF3300\",\n \"#FF3333\",\n \"#FF3366\",\n \"#FF3399\",\n \"#FF33CC\",\n \"#FF33FF\",\n \"#FF6600\",\n \"#FF6633\",\n \"#FF9900\",\n \"#FF9933\",\n \"#FFCC00\",\n \"#FFCC33\",\n]\n\nexport function supportsColors(): boolean {\n // NB: In an Electron preload script, document will be defined but not fully\n // initialized. Since we know we're in Chrome, we'll just detect this case\n // explicitly\n if (\n typeof window !== \"undefined\" &&\n window.process &&\n // @ts-ignore\n (window.process.type === \"renderer\" || window.process.__nwjs)\n ) {\n return true\n }\n\n // Internet Explorer and Edge do not support colors.\n if (\n typeof navigator !== \"undefined\" &&\n navigator.userAgent &&\n navigator.userAgent.toLowerCase().match(/(edge|trident)\\/(\\d+)/)\n ) {\n return false\n }\n\n // Is webkit? http://stackoverflow.com/a/16459606/376773\n // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632\n return (\n (typeof document !== \"undefined\" &&\n document.documentElement &&\n document.documentElement.style &&\n // @ts-ignore\n document.documentElement.style.WebkitAppearance) ||\n // Is firebug? http://stackoverflow.com/a/398120/376773\n (typeof window !== \"undefined\" &&\n window.console &&\n // @ts-ignore\n (window.console.firebug ||\n // @ts-ignore\n (window.console.exception && window.console.table))) ||\n // Is firefox >= v31?\n // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n (typeof navigator !== \"undefined\" &&\n navigator.userAgent &&\n navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/) &&\n parseInt(RegExp.$1, 10) >= 31) ||\n // Double check webkit in userAgent just in case we are in a worker\n (typeof navigator !== \"undefined\" &&\n navigator.userAgent &&\n navigator.userAgent.toLowerCase().match(/applewebkit\\/(\\d+)/))\n )\n}\n\nexport function selectColor(namespace: string) {\n let hash = 0\n for (let i = 0; i < namespace.length; i++) {\n hash = (hash << 5) - hash + namespace.charCodeAt(i)\n hash |= 0 // Convert to 32bit integer\n }\n return colors[Math.abs(hash) % colors.length]\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { deepEqual } from \"../common/data/deep\"\nimport {\n LoggerInterface,\n LogHandler,\n LogHandlerOptions,\n LogLevel,\n LogMessage,\n} from \"../common/log-base\"\nimport { useLevelFilter, useNamespaceFilter } from \"../common/log-filter\"\nimport { formatMilliseconds, getTimestamp } from \"../common/time\"\nimport { selectColor, supportsColors } from \"./log-colors\"\n\nconst styleFont = `font-family: \"JetBrains Mono\", Menlo; font-size: 11px;`\nconst styleDefault = `${styleFont}`\nconst styleBold = `font-weight: 600; ${styleFont}`\nconst useColors = supportsColors()\n\nlet namespaces: Record<string, any> = {}\n\nlet time = getTimestamp()\n\nexport function LoggerBrowserHandler(opt: LogHandlerOptions = {}): LogHandler {\n const {\n filter = undefined,\n level = undefined,\n colors = true,\n levelHelper = false,\n nameBrackets = true,\n padding = 16,\n } = opt\n const matchesNamespace = useNamespaceFilter(filter)\n const matchesLevel = useLevelFilter(level)\n return (msg: LogMessage) => {\n if (!matchesLevel(msg.level)) return\n if (!matchesNamespace(msg.name)) return\n\n const timeNow = getTimestamp()\n let name = msg.name || \"\"\n let ninfo = namespaces[name || \"\"]\n if (ninfo == null) {\n ninfo = {\n color: selectColor(name),\n // time: timeNow\n }\n namespaces[name] = ninfo\n }\n const diff = formatMilliseconds(timeNow - time)\n let args: string[]\n\n if (padding > 0) {\n name = name.padEnd(16, \" \")\n }\n\n if (colors && useColors) {\n args = [`%c${name}%c \\t%s %c+${diff}`]\n args.push(`color:${ninfo.color}; ${styleBold}`)\n args.push(styleDefault)\n args.push(msg.messages?.[0] ?? \"\")\n args.push(`color:${ninfo.color};`)\n args.push(...msg.messages.slice(1))\n } else {\n args = [name, ...msg.messages, `+${diff}`]\n }\n\n // function consoleArgs(args: any[] = []): any[] {\n // return [\n // args\n // .filter((a) => typeof a === \"string\")\n // .map((a) => String(a))\n // .join(\" \"),\n // ...styles,\n // ...args.filter((a) => typeof a !== \"string\"),\n // ]\n // }\n\n switch (msg.level) {\n case LogLevel.info:\n if (opt.levelHelper) args[0] = `I|* ` + args[0]\n console.info(...args)\n break\n case LogLevel.warn:\n if (opt.levelHelper) args[0] = `W|** ` + args[0]\n console.warn(...args)\n break\n case LogLevel.error:\n if (opt.levelHelper) args[0] = `E|*** ` + args[0]\n console.error(...args)\n break\n default:\n if (opt.levelHelper) args[0] = `D| ` + args[0]\n console.debug(...args)\n break\n }\n }\n}\n\nexport function LoggerBrowserSetupDebugFactory(opt: LogHandlerOptions = {}) {\n const filter = opt.filter ?? localStorage.zeed ?? localStorage.debug\n\n /// The trick is, that console called directly provides a reference to the source code.\n /// For the regular implementation this information is lost. But this approach has other\n /// drawbacks, therefore only use it in the Browser when actively debugging.\n return function LoggerBrowserDebugFactory(\n name: string = \"\"\n ): LoggerInterface {\n let log: LoggerInterface\n\n const matches = useNamespaceFilter(filter)\n\n if (matches(name)) {\n let fixedArgs = []\n if (useColors) {\n const color = selectColor(name)\n fixedArgs.push(`%c${name.padEnd(16, \" \")}%c \\t%s`)\n fixedArgs.push(`color:${color}; ${styleBold}`)\n fixedArgs.push(styleDefault)\n } else {\n fixedArgs.push(`[${name}] \\t%s`)\n }\n\n // @ts-ignore\n // console.previous = {\n // debug: console.debug,\n // info: console.info,\n // warn: console.warn,\n // error: console.error,\n // assert: console.assert,\n // }\n\n log = console.debug.bind(console, ...fixedArgs) as LoggerInterface\n log.debug = console.debug.bind(console, ...fixedArgs)\n log.info = console.info.bind(console, ...fixedArgs)\n log.warn = console.warn.bind(console, ...fixedArgs)\n log.error = console.error.bind(console, ...fixedArgs)\n\n log.assert = console.assert.bind(console)\n\n log.assertEqual = function (value: any, expected: any, ...args: any[]) {\n let equal = deepEqual(value, expected)\n if (!equal) {\n log.assert(\n equal,\n `Assert did fail. Expected ${expected} got ${value}`,\n expected,\n value,\n ...args\n )\n }\n }\n\n log.assertNotEqual = function (\n value: any,\n expected: any,\n ...args: any[]\n ) {\n let equal = deepEqual(value, expected)\n if (equal) {\n log.assert(\n equal,\n `Assert did fail. Expected ${expected} not to be equal with ${value}`,\n expected,\n value,\n ...args\n )\n }\n }\n } else {\n const noop = () => {}\n log = noop as LoggerInterface\n log.debug = noop\n log.info = noop\n log.warn = noop\n log.error = noop\n\n log.assert = noop\n log.assertEqual = noop\n log.assertNotEqual = noop\n }\n\n log.extend = (subName: string) => {\n return LoggerBrowserDebugFactory(name ? `${name}:${subName}` : subName)\n }\n\n return log\n }\n}\n\n/** @deprecated This output is default for initial use of Logger in browser environments. */\nexport function activateConsoleDebug(opt: LogHandlerOptions = {}) {\n console.info(\"activateConsoleDebug is activated by default in browsers\")\n // Logger.setHandlers([LoggerBrowserHandler(opt)]) // Fallback for previously registered Loggers\n // Logger.setFactory(LoggerBrowserSetupDebugFactory(opt))\n}\n\n// let klass = console\n// let debug = console.debug.bind(window.console, klass.toString() + \": \")\n\n// debug(\"test\")\n// console.debug(\"test2\")\n\n// let dd\n// if (Function.prototype.bind) {\n// dd = Function.prototype.bind.call(console.log, console)\n// } else {\n// dd = function () {\n// Function.prototype.apply.call(console.log, console, arguments)\n// }\n// }\n\n// dd(\"dd\")\n\n// let c = 1\n// Object.defineProperty(window, \"log2\", {\n// get: () => {\n// return console.log.bind(\n// window.console,\n// \"%c[log]%c %s\" + c++,\n// \"color:red\",\n// \"\"\n// )\n// },\n// })\n\n// // usage:\n// log2(\"Back to the future\")\n// log2(\"Back to the future\")\n\n// let plog = new Proxy(console.debug, {\n// apply: function (target, that, args) {\n// target.apply(that, args)\n// // base.apply(that, args);\n// },\n// })\n\n// let cons = console.debug\n// let plog = (...args) => {\n// cons.apply(window.console, [\"|\", ...args])\n// }\n\n// plog(\"xxx\")\n\n// function a() {\n// var err = new Error()\n// var caller_line = err.stack.split(\"\\n\")[2]\n// var index = caller_line.indexOf(\"at \")\n// var clean = caller_line.slice(index + 2, caller_line.length)\n// clean = clean.replace(/\\?t=\\d+/, \"\").replace(\"@fs/\", \"\")\n// console.log(clean)\n// console.log(\n// \"http://localhost:8080/Users/dirk/work/viidoo/lib/src/browser/log-browser.ts:188:1 log-browser.ts:291:10\"\n// )\n// }\n// function b() {\n// a()\n// }\n// b()\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { getTimestamp, formatMilliseconds } from \"../common/time\"\nimport {\n LogHandler,\n LogHandlerOptions,\n LogLevel,\n LogMessage,\n} from \"../common/log-base\"\nimport { selectColor, supportsColors } from \"./log-colors\"\nimport { useLevelFilter, useNamespaceFilter } from \"../common/log-filter\"\n\nlet namespaces: Record<string, any> = {}\n\nlet time = getTimestamp()\n\nconst useColors = supportsColors()\n\n/** @deprecated */\nexport function LoggerBrowserClassicHandler(\n level?: LogLevel,\n opt: LogHandlerOptions = {}\n): LogHandler {\n const { filter = undefined } = opt\n const matchesNamespace = useNamespaceFilter(filter)\n const matchesLevel = useLevelFilter(level)\n return (msg: LogMessage) => {\n if (!matchesLevel(msg.level)) return\n if (!matchesNamespace(msg.name)) return\n\n const timeNow = getTimestamp()\n let name = msg.name || \"\"\n let ninfo = namespaces[name || \"\"]\n if (ninfo == null) {\n ninfo = {\n color: selectColor(name),\n // time: timeNow\n }\n namespaces[name] = ninfo\n }\n\n const diff = formatMilliseconds(timeNow - time)\n\n let args: string[]\n if (opt.colors && useColors) {\n args = opt.nameBrackets ? [`%c[${name}]`] : [`%c${name}`]\n args.push(`color:${ninfo.color}`)\n args.push(...msg.messages)\n } else {\n args = [name, ...msg.messages]\n }\n args.push(`+${diff}`)\n switch (msg.level) {\n case LogLevel.info:\n if (opt.levelHelper) args[0] = `I|* ` + args[0]\n console.info(...args)\n break\n case LogLevel.warn:\n if (opt.levelHelper) args[0] = `W|** ` + args[0]\n console.warn(...args)\n break\n case LogLevel.error:\n if (opt.levelHelper) args[0] = `E|*** ` + args[0]\n console.error(...args)\n break\n default:\n if (opt.levelHelper) args[0] = `D| ` + args[0]\n console.debug(...args)\n break\n }\n }\n}\n","import { isBrowser } from \"../common/platform\"\nimport { Logger } from \"../common/log\"\nimport {\n LoggerBrowserHandler,\n LoggerBrowserSetupDebugFactory,\n} from \"./log-browser\"\n\nif (isBrowser()) {\n Logger.setHandlers([LoggerBrowserHandler()]) // Fallback for previously registered Loggers\n Logger.setFactory(LoggerBrowserSetupDebugFactory({}))\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.all.ts","../src/common/data/is.ts","../src/common/data/deep.ts","../src/common/log-filter.ts","../src/common/log-base.ts","../src/common/log-console.ts","../src/common/global.ts","../src/common/log.ts","../src/common/data/bin.ts","../src/common/crypto.ts","../src/common/csv.ts","../src/common/data/orderby.ts","../src/common/data/array.ts","../src/common/data/basex.ts","../src/common/data/camelcase.ts","../src/common/data/json.ts","../src/common/data/convert.ts","../src/common/data/currency.ts","../src/common/promise.ts","../src/common/data/day.ts","../src/common/data/html.ts","../src/common/data/math.ts","../src/common/data/path.ts","../src/common/data/regexp.ts","../src/common/data/sortable.ts","../src/common/data/url.ts","../src/common/data/utils.ts","../src/common/dispose-defer.ts","../src/common/localhost.ts","../src/common/time.ts","../src/common/uuid.ts","../src/common/msg/emitter.ts","../src/common/msg/channel.ts","../src/common/msg/encoder.ts","../src/common/msg/messages.ts","../src/common/msg/pubsub.ts","../src/common/mutex.ts","../src/common/network.ts","../src/common/platform.ts","../src/common/pool.ts","../src/common/queue.ts","../src/common/storage/memstorage.ts","../src/common/throttle-debounce.ts","../src/node/crypto.ts","../src/node/env.ts","../src/node/filestorage.ts","../src/node/log-file.ts","../src/node/log-node.ts","../src/node/log-util.ts","../src/node/log-context-node.ts","../src/browser/base64.ts","../src/browser/gravatar.ts","../src/browser/localstorage.ts","../src/browser/log-colors.ts","../src/browser/log-browser.ts","../src/browser/log-browser-classic.ts","../src/browser/log-context-browser.ts"],"sourcesContent":["// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nexport * from \"./common\"\nexport * from \"./node\"\nexport * from \"./browser\"\n","// https://github.com/sindresorhus/is/ MIT\n// https://github.com/sindresorhus/ts-extras\n// https://github.com/sindresorhus/type-fest\n// https://github.com/antfu/utils\n\nexport type Primitive =\n | null\n | undefined\n | string\n | number\n | boolean\n | symbol\n | bigint\n\nexport function isObject(obj: unknown): obj is object {\n return obj != null && typeof obj === \"object\"\n}\n\nexport function isPrimitive(obj: unknown): obj is Primitive {\n return Object(obj) !== obj\n}\n\nexport function isArray(obj: unknown): obj is Array<any> {\n return Array.isArray(obj)\n}\n\nexport function isRecord(obj: unknown): obj is Record<string, any> {\n return isObject(obj) && !isArray(obj)\n}\n\nexport function isString(obj: unknown): obj is string {\n return typeof obj === \"string\"\n}\n\nexport function isNumber(obj: unknown): obj is number {\n return typeof obj === \"number\"\n}\n\nexport function isInteger(obj: unknown): obj is number {\n return typeof obj === \"number\" && Number.isInteger(obj)\n}\n\nexport function isSafeInteger(obj: unknown): obj is number {\n return typeof obj === \"number\" && Number.isSafeInteger(obj)\n}\n\nexport function isBoolean(obj: unknown): obj is boolean {\n return typeof obj === \"boolean\"\n}\n\nexport function isNullOrUndefined(obj: unknown): obj is null | undefined {\n return obj == null\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { isObject, isPrimitive } from \"./is\"\n\n// // https://stackoverflow.com/a/40294058/140927\n// // Handles cyclic references\n// export function deepClonePrimitives(obj, hash = new WeakMap()) {\n//\n// // primitives\n// if (Object(obj) !== obj) {\n// // log('Primitive', obj)\n// return obj\n// }\n//\n// // cyclic reference\n// if (hash.has(obj)) {\n// return hash.get(obj)\n// }\n//\n// let result\n//\n// // primitives as objects like new String(), new Number()\n// if (\n// obj instanceof String ||\n// obj instanceof Number ||\n// obj instanceof BigInt ||\n// obj instanceof Boolean ||\n// obj instanceof Symbol\n// ) {\n// result = new obj.constructor(obj.valueOf())\n// // hash.set(obj, result)\n// return result\n// }\n//\n// // log('Obj', obj)\n//\n// if (obj instanceof Set) {\n// result = new Set(obj)\n// } else if (obj instanceof Map) {\n// result = new Map(Array.from(obj, ([key, val]) => [key, deepClonePrimitives(val, hash)]))\n// } else if (obj instanceof Date) {\n// result = new Date(obj)\n// } else if (obj instanceof RegExp) {\n// result = new RegExp(obj.source, obj.flags)\n// } else if (Array.isArray(obj)) {\n// result = Array.from(obj, val => deepClonePrimitives(val, hash))\n// } else if (obj.constructor) {\n// result = new obj.constructor()\n// log('bj object', result)\n// } else if (obj instanceof Function || typeof obj === 'function') {\n// log('Keep object', obj, Object.getPrototypeOf(obj))\n// result = obj\n// } else {\n// result = Object.create(null)\n// }\n//\n// hash.set(obj, result)\n//\n// return Object.assign(result, ...Object.keys(obj).map(key => ({\n// [key]: deepClonePrimitives(obj[key], hash),\n// })))\n// }\n\nexport function deepEqual(a: any, b: any, hash = new WeakSet()) {\n // if both x and y are null or undefined and exactly the same\n if (a === b) {\n return true\n }\n\n // Cyclic\n if (hash.has(b)) {\n // console.log('cyclic')\n return true\n }\n\n if (!isPrimitive(b)) {\n hash.add(b)\n }\n\n // if they are not strictly equal, they both need to be Objects\n if (!(a instanceof Object) || !(b instanceof Object)) {\n return false\n }\n\n // they must have the exact same prototype chain, the closest we can do is\n // test there constructor.\n if (a.constructor !== b.constructor) {\n return false\n }\n\n // Shortcut to avoid to many loops\n if (a.length !== b.length) {\n return false\n }\n\n for (let p in a) {\n // other properties were tested using x.constructor === y.constructor\n if (!a.hasOwnProperty(p)) {\n continue\n }\n\n // allows to compare x[ p ] and y[ p ] when set to undefined\n if (!b.hasOwnProperty(p)) {\n return false\n }\n\n let aa = a[p]\n let bb = b[p]\n\n // if they have the same strict value or identity then they are equal\n // if (aa === bb) {\n // console.log('eq', typeof bb)\n // if (bb != null) hash.set(bb, true)\n // continue\n // }\n //\n // // Numbers, Strings, Functions, Booleans must be strictly equal\n // if (typeof (aa) !== 'object') {\n // return false\n // }\n\n // Objects and Arrays must be tested recursively\n if (!deepEqual(aa, bb, hash)) {\n return false\n }\n }\n\n // allows x[ p ] to be set to undefined\n for (let p in b) {\n if (b.hasOwnProperty(p) && !a.hasOwnProperty(p)) {\n return false\n }\n }\n\n return true\n}\n\nexport function deepMerge(target: any, ...sources: any[]) {\n for (let source of sources) {\n if (!isObject(target)) {\n target = {}\n }\n\n if (source == null) continue\n\n Object.keys(source).forEach((key) => {\n const targetValue = target[key]\n const sourceValue = source[key]\n\n if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {\n target[key] = targetValue.concat(sourceValue)\n } else if (isObject(targetValue) && isObject(sourceValue)) {\n target[key] = deepMerge(Object.assign({}, targetValue), sourceValue)\n } else {\n target[key] = sourceValue\n }\n })\n }\n\n return target\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { LogLevel, LogLevelAlias } from \"./log-base\"\n\ninterface NamespaceFilter {\n (name: string): boolean\n accept: RegExp[]\n reject: RegExp[]\n filter: string\n}\n\nexport function getNamespaceFilterString(defaultNamespaceFilter: any): string {\n if (\n defaultNamespaceFilter === true ||\n defaultNamespaceFilter === \"true\" ||\n defaultNamespaceFilter === \"1\" ||\n (typeof defaultNamespaceFilter === \"number\" && defaultNamespaceFilter !== 0)\n ) {\n defaultNamespaceFilter = \"*\"\n } else if (\n defaultNamespaceFilter === false ||\n defaultNamespaceFilter === \"false\" ||\n defaultNamespaceFilter === 0 ||\n defaultNamespaceFilter === \"0\" ||\n defaultNamespaceFilter == null ||\n defaultNamespaceFilter === \"null\" ||\n defaultNamespaceFilter === \"undefined\"\n ) {\n defaultNamespaceFilter = \"\"\n } else {\n defaultNamespaceFilter = String(defaultNamespaceFilter)\n }\n return defaultNamespaceFilter\n}\n\nconst defaultNamespaceFilter: string = getNamespaceFilterString(\n typeof process !== \"undefined\"\n ? process.env.ZEED ?? process.env.DEBUG\n : typeof localStorage !== \"undefined\"\n ? localStorage.zeed ?? localStorage.debug\n : \"*\"\n)\n\n/**\n * Filter as described here https://github.com/visionmedia/debug#wildcards\n *\n * @param filter Namespace filter\n * @returns Function to check if filter applies\n */\nexport function useNamespaceFilter(\n filter: string = defaultNamespaceFilter\n): NamespaceFilter {\n let fn: any // (name: string) => boolean\n let reject = [] as RegExp[]\n let accept = [] as RegExp[]\n\n if (!filter) {\n fn = function (name: string) {\n return false\n }\n } else if (filter === \"*\") {\n fn = function (name: string) {\n return true\n }\n } else {\n let i\n const split = filter.split(/[\\s,]+/)\n const len = split.length\n for (i = 0; i < len; i++) {\n if (!split[i]) {\n // ignore empty strings\n continue\n }\n let template = split[i].replace(/\\*/g, \".*?\")\n if (template[0] === \"-\") {\n reject.push(new RegExp(\"^\" + template.substr(1) + \"$\"))\n } else {\n accept.push(new RegExp(\"^\" + template + \"$\"))\n }\n }\n\n fn = function (name: string) {\n if (reject.length === 0 && accept.length === 0) {\n return true\n }\n let i, len\n for (i = 0, len = reject.length; i < len; i++) {\n if (reject[i].test(name)) {\n return false\n }\n }\n for (i = 0, len = accept.length; i < len; i++) {\n if (accept[i].test(name)) {\n return true\n }\n }\n return false\n }\n }\n fn.accept = accept\n fn.reject = reject\n fn.filter = filter\n return fn as NamespaceFilter\n}\n\nconst defaultLevelFilter: any =\n typeof process !== \"undefined\"\n ? process.env.ZEED_LEVEL ?? process.env.LEVEL ?? process.env.DEBUG_LEVEL\n : typeof localStorage !== \"undefined\"\n ? localStorage.zeed_level ?? localStorage.level ?? localStorage.debug_level\n : undefined\n\nexport function useLevelFilter(\n filter: string | number = defaultLevelFilter\n): (level: LogLevel) => boolean {\n let filterLevel: LogLevel = LogLevel.all\n if (typeof filter === \"string\") {\n const l = LogLevelAlias[filter.toLocaleLowerCase().trim()]\n if (l != null) filterLevel = l\n } else if (typeof filter === \"number\") {\n filterLevel = filter as number\n }\n return (level) => level >= filterLevel\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { deepEqual } from \"./data/deep\"\nimport { LoggerConsoleHandler } from \"./log-console\"\nimport { useNamespaceFilter } from \"./log-filter\"\n\nexport enum LogLevel {\n all = -1,\n debug = 0,\n info,\n warn,\n error,\n fatal,\n off = Infinity,\n}\n\nexport const LogLevelAlias: Record<string, LogLevel> = {\n \"*\": LogLevel.all,\n a: LogLevel.all,\n all: LogLevel.all,\n d: LogLevel.debug,\n dbg: LogLevel.debug,\n debug: LogLevel.debug,\n i: LogLevel.info,\n inf: LogLevel.info,\n info: LogLevel.info,\n w: LogLevel.warn,\n warn: LogLevel.warn,\n warning: LogLevel.warn,\n e: LogLevel.error,\n err: LogLevel.error,\n error: LogLevel.error,\n fatal: LogLevel.fatal,\n off: LogLevel.off,\n \"-\": LogLevel.off,\n}\n\nexport interface LogMessage {\n level: LogLevel\n name: string\n messages: any[]\n line?: number\n file?: string\n timestamp?: number\n}\n\nexport type LogHandler = (msg: LogMessage) => void\n\nexport interface LoggerInterface {\n (...messages: any[]): void\n\n /** @deprecated use .level = LogLevel.off or LogLevel.all */\n active: boolean\n\n level: LogLevel\n\n debug(...messages: any[]): void\n\n info(...messages: any[]): void\n\n warn(...messages: any[]): void\n\n error(...messages: any[]): void\n\n assert(cond: any, ...messages: any[]): void\n\n /** @deprecated use .assert */\n assertEqual(value: any, expected: any, ...args: any[]): void\n\n /** @deprecated use .assert */\n assertNotEqual(value: any, expected: any, ...args: any[]): void\n\n extend(prefix: string): LoggerInterface\n\n factory?: LoggerContextInterface\n}\n\nexport interface LoggerContextInterface {\n (name?: string): LoggerInterface\n registerHandler(handler: LogHandler): void\n setFilter(namespaces: string): void\n setHandlers(handlers?: (LogHandler | undefined | null)[]): void\n setLock(lock: boolean): void\n setLogLevel(level?: LogLevel): void\n setFactory(factory: (name?: string) => LoggerInterface): void\n}\n\nexport interface LogHandlerOptions {\n level?: LogLevel\n filter?: string\n colors?: boolean\n levelHelper?: boolean\n nameBrackets?: boolean\n padding?: number\n fill?: number\n stack?: boolean | number\n}\n\nexport function LoggerContext(prefix: string = \"\"): LoggerContextInterface {\n let logHandlers: LogHandler[] = [LoggerConsoleHandler()]\n let logAssertLevel: LogLevel = LogLevel.warn\n let logCheckNamespace = (name: string) => true\n let logLock = false\n let logFactory = LoggerBaseFactory\n\n function LoggerBaseFactory(name: string = \"\"): LoggerInterface {\n log.extend = function (prefix: string): LoggerInterface {\n return logFactory(name ? `${name}:${prefix}` : prefix)\n }\n\n const emit = (msg: LogMessage) => {\n if (log.active === true) {\n if (msg.level >= Logger.level && msg.level >= log.level) {\n if (logCheckNamespace(name)) {\n for (let handler of logHandlers) {\n if (handler) handler(msg)\n }\n }\n }\n }\n }\n\n function log(...messages: any[]) {\n emit({\n name,\n messages,\n level: LogLevel.debug,\n })\n }\n\n log.active = true\n log.level = LogLevel.all\n\n log.debug = function (...messages: any[]) {\n emit({\n name,\n messages,\n level: LogLevel.debug,\n })\n }\n\n log.info = function (...messages: any[]) {\n emit({\n name,\n messages,\n level: LogLevel.info,\n })\n }\n\n log.warn = function (...messages: any[]) {\n emit({\n name,\n messages,\n level: LogLevel.warn,\n })\n }\n\n log.error = function (...messages: any[]) {\n emit({\n name,\n messages,\n level: LogLevel.error,\n })\n }\n\n // fatal(...args: any[]) {\n // console.error(...args)\n // },\n\n log.assert = function (cond: any, ...messages: any[]) {\n if (!cond) {\n if (typeof console !== undefined) {\n if (console.assert) {\n // https://developer.mozilla.org/de/docs/Web/API/Console/assert\n console.assert(cond, ...messages)\n } else {\n console.error(`Assert did fail with: ${cond}`, ...messages)\n }\n }\n emit({\n name,\n messages: messages || [`Assert did fail with: ${cond}`],\n level: logAssertLevel,\n })\n // try {\n // if (typeof expect !== undefined) {\n // expect(cond).toBeTruthy()\n // }\n // } catch (err) {\n // methods.warn(...args)\n // }\n }\n }\n\n log.assertEqual = function (value: any, expected: any, ...args: any[]) {\n let equal = deepEqual(value, expected)\n if (!equal) {\n log.assert(\n equal,\n `Assert did fail. Expected ${expected} got ${value}`,\n expected,\n value,\n ...args\n )\n // } else {\n // methods.debug(`Passed equal`)\n }\n }\n\n log.assertNotEqual = function (value: any, expected: any, ...args: any[]) {\n let equal = deepEqual(value, expected)\n if (equal) {\n log.assert(\n equal,\n `Assert did fail. Expected ${expected} not to be equal with ${value}`,\n expected,\n value,\n ...args\n )\n // } else {\n // methods.debug(`Passed not equal check`)\n }\n }\n\n return log\n }\n\n function Logger(name: string = \"\"): LoggerInterface {\n return logFactory(name)\n }\n\n Logger.registerHandler = function (handler: LogHandler) {\n logHandlers.push(handler)\n }\n\n Logger.setFilter = function (namespaces: string) {\n logCheckNamespace = useNamespaceFilter(namespaces)\n }\n\n Logger.setLock = (lock: boolean = true) => (logLock = lock)\n\n Logger.setHandlers = function (handlers: LogHandler[] = []) {\n if (logFactory !== LoggerBaseFactory) {\n logFactory = LoggerBaseFactory\n }\n if (logLock) return\n logHandlers = [...handlers].filter((h) => typeof h === \"function\")\n }\n\n Logger.level = LogLevel.all\n\n /** @deprecated */\n Logger.setLogLevel = function (level: LogLevel = LogLevel.all) {\n if (logLock) return\n Logger.level = level\n }\n\n Logger.setFactory = function (\n factory: (name?: string) => LoggerInterface\n ): void {\n if (logLock) return\n logFactory = factory\n }\n\n return Logger\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { LogHandler, LogHandlerOptions, LogLevel, LogMessage } from \"./log-base\"\nimport { useLevelFilter, useNamespaceFilter } from \"./log-filter\"\n\n/**\n * Very basic logger. Please take a look at the browser and node\n * optimized loggers. This one is just the absolute fallback option.\n *\n * @param level Log level\n * @returns Logger\n */\nexport function LoggerConsoleHandler(opt: LogHandlerOptions = {}): LogHandler {\n const {\n level = undefined,\n filter = undefined,\n colors = true,\n levelHelper = false,\n nameBrackets = true,\n padding = 16,\n } = opt\n const matchesNamespace = useNamespaceFilter(filter)\n const matchesLevel = useLevelFilter(level)\n return (msg: LogMessage) => {\n if (!matchesLevel(msg.level)) return\n if (!matchesNamespace(msg.name)) return\n let name = msg.name ? `[${msg.name}]` : \"\"\n switch (msg.level) {\n case LogLevel.info:\n console.info(`I|* ${name}`, ...msg.messages)\n break\n case LogLevel.warn:\n console.warn(`W|** ${name}`, ...msg.messages)\n break\n case LogLevel.error:\n console.error(`E|*** ${name}`, ...msg.messages)\n break\n default:\n console.debug(`D| ${name}`, ...msg.messages)\n break\n }\n }\n}\n","// Global context across build systems etc.\n\ndeclare global {\n interface ZeedGlobalContext {}\n}\n\ninterface ZeedGlobalIntegration {\n _zeedGlobal?: ZeedGlobalContext\n}\n\nfunction _global(): ZeedGlobalIntegration {\n if (typeof self !== \"undefined\") return self as ZeedGlobalIntegration\n if (typeof window !== \"undefined\") return window as ZeedGlobalIntegration\n if (typeof global !== \"undefined\") return global as ZeedGlobalIntegration\n if (typeof globalThis !== \"undefined\")\n return globalThis as ZeedGlobalIntegration\n throw new Error(\"unable to locate global object\")\n}\n\nexport function getGlobalContext(): ZeedGlobalContext {\n let gcontext = _global()\n if (gcontext._zeedGlobal == null) {\n gcontext._zeedGlobal = {}\n }\n return gcontext._zeedGlobal\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { LoggerConsoleHandler } from \"./log-console\"\nimport { getGlobalContext } from \"./global\"\nimport { LoggerContext, LoggerContextInterface } from \"./log-base\"\n\n// Global logger to guarantee all submodules use the same logger instance\n\nlet globalLogger: LoggerContextInterface\n\ndeclare global {\n interface ZeedGlobalContext {\n logger?: any // Should be LoggerContextInterface, but avoid compiler issues this way\n }\n}\n\nfunction getLoggerContext() {\n let logger = LoggerContext()\n logger.setHandlers([LoggerConsoleHandler()])\n return logger\n}\n\ntry {\n let _global = getGlobalContext()\n if (_global != null) {\n if (_global?.logger == null) {\n globalLogger = getLoggerContext()\n _global.logger = globalLogger\n } else {\n globalLogger = _global.logger\n }\n } else {\n globalLogger = getLoggerContext()\n }\n} catch (e) {\n globalLogger = getLoggerContext()\n}\n\n// /** @deprecated Use `Logger` instead, it is global as well */\n// export const GlobalLogger = globalLogger\n\nexport const Logger = globalLogger\n","import { Logger } from \"../log\"\n\nconst log = Logger(\"bin\")\n\nexport type BinInput = Uint8Array | ArrayBuffer | string | number[]\n\n// if (typeof TextEncoder !== \"undefined\") {\n\nlet _textEncoder: TextEncoder | undefined\nexport function stringToUInt8Array(text: string): Uint8Array {\n if (typeof TextEncoder === \"undefined\") return new Uint8Array()\n const textEncoder = _textEncoder ?? (_textEncoder = new TextEncoder())\n return textEncoder.encode(text.normalize(\"NFC\"))\n}\n\nlet _textDecoder: TextDecoder | undefined\nexport function Uint8ArrayToString(bin: Uint8Array): string {\n if (typeof TextDecoder === \"undefined\") return \"\"\n const textDecoder =\n _textDecoder ??\n (_textDecoder = new TextDecoder(\"utf-8\", { ignoreBOM: true }))\n return textDecoder.decode(bin).normalize(\"NFC\")\n}\n\nexport function toUint8Array(data: BinInput): Uint8Array {\n if (data instanceof ArrayBuffer) return new Uint8Array(data)\n if (typeof data === \"string\") return stringToUInt8Array(data)\n if (data.length) return new Uint8Array(data)\n // @ts-ignore\n return data\n}\n\nexport function toHex(bin: BinInput): string {\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(toUint8Array(bin)).toString(\"hex\")\n }\n const h = \"0123456789abcdef\"\n let s = \"\"\n for (const v of [...toUint8Array(bin)]) {\n s += h[v >> 4] + h[v & 15]\n }\n return s\n}\n\nexport function toBase64(bin: BinInput): string {\n const bytes = toUint8Array(bin)\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(bytes).toString(\"base64\")\n }\n let s = \"\"\n for (let i = 0; i < bytes.byteLength; i++) {\n s += String.fromCharCode(bytes[i])\n }\n return btoa(s)\n}\n\nexport function toBase64Url(bin: BinInput): string {\n const bytes = toUint8Array(bin)\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(bytes).toString(\"base64url\")\n }\n let s = \"\"\n for (let i = 0; i < bytes.byteLength; i++) {\n s += String.fromCharCode(bytes[i])\n }\n return btoa(s).replace(/\\+/g, \"-\").replace(/\\//g, \"_\")\n}\n\n/** Compare contents of binary arrays */\nexport function equalBinary(\n a: ArrayBuffer | Uint8Array,\n b: ArrayBuffer | Uint8Array\n): boolean {\n if (a.byteLength !== b.byteLength) return false\n const aa = toUint8Array(a)\n const bb = toUint8Array(b)\n for (let i = 0; i < aa.length; i++) {\n if (aa[i] !== bb[i]) {\n return false\n }\n }\n return true\n}\n\nexport function jsonToUint8Array(json: any): Uint8Array {\n try {\n return stringToUInt8Array(JSON.stringify(json))\n } catch (err) {\n log.warn(\"jsonToUint8Array\", json)\n throw err\n }\n}\n\nexport function Uint8ArrayToJson<T = any>(data: Uint8Array): T {\n try {\n return JSON.parse(Uint8ArrayToString(data))\n } catch (err) {\n log.warn(\"Uint8ArrayToJson\", data)\n throw err\n }\n}\n","import { BinInput, equalBinary, toUint8Array } from \"./data/bin\"\n\n/* \n\n// Web Crypto polyfill for node 15+:\n// https://nodejs.org/api/webcrypto.html\n\nimport { webcrypto } from \"crypto\"\n\nif (globalThis.crypto == null) {\n globalThis.crypto = webcrypto\n}\n*/\n\n// todo: should fallback to node crypto\nexport function randomUint8Array(length: number = 16): Uint8Array {\n let randomBytes = new Uint8Array(length)\n if (typeof crypto !== \"undefined\" && crypto.getRandomValues) {\n crypto.getRandomValues(randomBytes)\n } else {\n for (let i = 0; i < length; i++) {\n // Math.random: \"...range 0 to less than 1 (inclusive of 0, but not 1)\"\n // 0.9... * 0xff < 255 therefore * 0x100\n randomBytes[i] = Math.floor(Math.random() * 0x100) // 0...255\n }\n }\n return randomBytes\n}\n\nconst DEFAULT_HASH_ALG = \"SHA-256\"\nconst DEFAULT_CRYPTO_ALG = \"AES-GCM\"\nconst DEFAULT_DERIVE_ALG = \"PBKDF2\"\n\nexport async function digest(\n message: BinInput,\n algorithm: AlgorithmIdentifier = DEFAULT_HASH_ALG\n): Promise<ArrayBuffer> {\n return await crypto.subtle.digest(algorithm, toUint8Array(message))\n}\n\nexport async function deriveKeyPbkdf2(\n secret: BinInput,\n opt: {\n iterations?: number\n salt?: BinInput\n } = {}\n): Promise<CryptoKey> {\n const secretBuffer = toUint8Array(secret)\n const keyMaterial = await crypto.subtle.importKey(\n \"raw\",\n secretBuffer,\n DEFAULT_DERIVE_ALG,\n false,\n [\"deriveKey\"]\n )\n return await crypto.subtle.deriveKey(\n {\n name: DEFAULT_DERIVE_ALG,\n salt: opt.salt ? toUint8Array(opt.salt) : new Uint8Array(0),\n iterations: opt.iterations ?? 100000,\n hash: DEFAULT_HASH_ALG,\n },\n keyMaterial,\n {\n name: DEFAULT_CRYPTO_ALG,\n length: 256,\n },\n true,\n [\"encrypt\", \"decrypt\"]\n )\n}\n\nconst MAGIC_ID = new Uint8Array([1, 1])\n\nexport async function encrypt(\n data: Uint8Array,\n key: CryptoKey\n): Promise<Uint8Array> {\n const iv = randomUint8Array(12)\n const cipher = await crypto.subtle.encrypt(\n { name: DEFAULT_CRYPTO_ALG, iv },\n key,\n data\n )\n const binCypher = new Uint8Array(cipher)\n const bufferLength = MAGIC_ID.length + iv.length + binCypher.length\n const buffer = new Uint8Array(bufferLength)\n let pos = 0\n buffer.set(MAGIC_ID, pos)\n pos += MAGIC_ID.length\n buffer.set(iv, pos)\n pos += iv.length\n buffer.set(binCypher, pos)\n return buffer\n}\n\nexport async function decrypt(\n data: Uint8Array,\n key: CryptoKey\n): Promise<Uint8Array> {\n let magic = data.subarray(0, 2)\n if (!equalBinary(magic, MAGIC_ID)) {\n return Promise.reject(`Unknown magic ${magic}`)\n }\n let iv = data.subarray(2, 2 + 12)\n let cipher = data.subarray(2 + 12, data.length)\n const plain = await crypto.subtle.decrypt(\n { name: DEFAULT_CRYPTO_ALG, iv },\n key,\n cipher\n )\n return new Uint8Array(plain)\n}\n","/*\n csv-express\n Forked and modified by John J Czaplewski <jczaplew@gmail.com>\n Copyright 2011 Seiya Konno <nulltask@gmail.com>\n MIT Licensed\n\n https://github.com/jczaplew/csv-express/blob/master/lib/csv-express.js\n */\n\n// Configurable settings\nconst separator = \",\"\nconst preventCast = false\nconst ignoreNullOrUndefined = true\n\n// Stricter parseFloat to support hexadecimal strings from\n// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/parseFloat#A_stricter_parse_function\nfunction filterFloat(value: string) {\n if (/^([-+])?([0-9]+(\\.[0-9]+)?|Infinity)$/.test(value)) {\n return Number(value)\n }\n return NaN\n}\n\nfunction escape(field: any) {\n if (ignoreNullOrUndefined && field == undefined) {\n return \"\"\n }\n if (preventCast) {\n return '=\"' + String(field).replace(/\"/g, '\"\"') + '\"'\n }\n if (!isNaN(filterFloat(field)) && isFinite(field)) {\n return parseFloat(field)\n }\n return '\"' + String(field).replace(/\"/g, '\"\"') + '\"'\n}\n\nexport function csv(data: any[], headerRow: string[]): string {\n let body = \"\"\n\n // Append the header row to the response if requested\n if (headerRow) {\n body = headerRow.join(separator) + \"\\r\\n\"\n }\n\n // Convert the data to a CSV-like structure\n for (let i = 0; i < data.length; i++) {\n body += data[i].map(escape).join(separator) + \"\\r\\n\"\n }\n\n return body\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nexport function parseOrderby(value: string = \"\"): {\n field: string\n orderby: string\n asc: boolean\n desc: boolean\n} {\n let [field = \"\", orderby = \"asc\"] = value.split(\" \")\n orderby = orderby.toLowerCase()\n return {\n field,\n orderby,\n asc: orderby !== \"desc\",\n desc: orderby === \"desc\",\n }\n}\n\nexport function composeOrderby(field: string, asc: boolean = true): string {\n return `${field} ${asc ? \"asc\" : \"desc\"}`\n}\n\n// Classic compare function with direction flag\nexport function cmp(a: any, b: any, asc: boolean = true): number {\n const aa = a || 0\n const bb = b || 0\n return aa > bb ? (asc ? 1 : -1) : aa < bb ? (asc ? -1 : 1) : 0\n}\n\nexport function sortedOrderby<T>(values: T[], ...orderby: string[]): T[] {\n if (orderby.length > 0) {\n let orderByList = orderby.map(parseOrderby)\n // let { field, asc } = parseOrderby(orderby)\n //if (field != null && typeof field === \"string\") {\n // let bigger = asc ? 1 : -1\n // let smaller = asc ? -1 : 1\n let sortValues = Array.from(values)\n sortValues.sort((a: any, b: any): number => {\n for (let { field, asc } of orderByList) {\n const result = cmp(a[field], b[field], asc)\n if (result !== 0) return result\n }\n return 0\n // const aa = a[field] || 0\n // const bb = b[field] || 0\n // return aa > bb ? bigger : aa < bb ? smaller : 0\n })\n return sortValues\n }\n return values\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { NestedArray } from \"../types\"\nimport { cmp } from \"./orderby\"\n\nexport function arrayUnique<T>(x: T[]): T[] {\n return x.filter((n: any, index: any) => x.indexOf(n) === index)\n}\n\nexport function arrayMinus<T>(x: T[], y: T[]): T[] {\n return arrayUnique(x.filter((n: any) => !y.includes(n)))\n}\n\nexport function arrayUnion<T>(...a: T[][]): T[] {\n return arrayUnique(a.reduce((acc: T[] = [], value) => acc.concat(value), []))\n}\n\n/** `[1,[2,3]]` becomes `[1,2,3]` */\nexport function arrayFlatten<T>(...list: NestedArray<T>[]): T[] {\n return list.flat(Infinity)\n}\n\nexport function arrayIntersection<T>(x: T[], y: T[]): T[] {\n return arrayUnique<T>(x).filter((n: any) => y.includes(n))\n}\n\nexport function arraySymmetricDifference<T>(x: T[], y: T[]): T[] {\n return arrayMinus(arrayUnion(x, y), arrayIntersection(x, y))\n // return arrayUnique(x.filter(n => !y.includes(n)).concat(y.filter(n => !x.includes(n))))\n}\n\n// export function arrayApply<T>(fn: any, a: T[]): T[] {\n// return a.reduce(fn, [])\n// }\n\nexport function arrayRemoveElement<T>(arr: T[], el: T): T[] {\n if (arr && Array.isArray(arr)) {\n let index\n while ((index = arr.indexOf(el)) !== -1) {\n // log(\"arrayRemoveElement remove\", index, el)\n arr.splice(index, 1)\n }\n // log(\"arrayRemoveElement result\", arr)\n return arr\n }\n // log(\"arrayRemoveElement no array\", arr, el)\n return []\n}\n\n/** Only have it once in the set */\nexport function arraySetElement<T>(arr: T[], el: T): T[] {\n if (!arr.includes(el)) arr.push(el)\n return arr\n}\n\n// via https://stackoverflow.com/a/49587869 and Erwin\nexport function arrayFilterInPlace<T>(array: T[], fn: (el: T) => boolean): T[] {\n array.splice(0, array.length, ...array.filter(fn))\n return array\n}\n\n// via https://stackoverflow.com/a/49587869 and Erwin\nexport function arrayToggleInPlace<T>(array: T[], el: T): T[] {\n const index = array.findIndex((e) => e === el)\n if (index >= 0) array.splice(index, 1)\n else array.push(el)\n return array\n}\n\nexport function arrayEmptyInPlace<T>(array: T[]): T[] {\n array.splice(0, array.length)\n return array\n}\n\nexport function arraySorted<T>(\n arr: Iterable<T> | ArrayLike<T>,\n cond: ((a: T, b: T) => number) | undefined = cmp\n): T[] {\n return Array.from(arr).sort(cond)\n}\n\nexport function arraySortedNumbers(arr: number[]): number[] {\n return arraySorted(arr, (l: number, r: number) => l - r)\n}\n\nexport function arrayIsEqual<T>(array1: T[], array2: T[]): boolean {\n return (\n array1.length === array2.length &&\n array1.every((value, index) => value === array2[index])\n )\n}\n\nexport function arrayShuffleInPlace<T>(array: T[]): T[] {\n array.sort(() => (Math.random() > 0.5 ? 1 : -1))\n\n // Alternative https://github.com/sindresorhus/array-shuffle/blob/main/index.js#L8\n // for (let index = array.length - 1; index > 0; index--) {\n // \tconst newIndex = Math.floor(Math.random() * (index + 1));\n // \t[array[index], array[newIndex]] = [array[newIndex], array[index]];\n // }\n\n return array\n}\n\nexport function arrayShuffle<T>(array: T[]): T[] {\n return arrayShuffleInPlace(Array.from(array))\n}\n\n/** Randomly shuffle the order of the array's elements. Force to have a different order if array has more than one element. */\nexport function arrayShuffleForce<T>(array: T[]): T[] {\n while (array.length > 1) {\n const copy = Array.from(array)\n arrayShuffleInPlace(copy)\n if (!arrayIsEqual(array, copy)) return copy\n }\n return array\n}\n\nexport function arrayRandomElement<T>(array: T[]): T {\n return array[Math.floor(Math.random() * array.length)]\n}\n\nexport function arrayMax<T>(...array: NestedArray<T>[]): T {\n // @ts-ignore\n return arrayFlatten(array).reduce(\n (acc, value) => (acc != null ? (value > acc ? value : acc) : value),\n undefined\n )\n}\n\nexport function arrayMin<T>(...array: NestedArray<T>[]): T {\n // @ts-ignore\n return arrayFlatten(array).reduce(\n (acc, value) => (acc != null ? (value < acc ? value : acc) : value),\n undefined\n )\n}\n\nexport function createArray<T>(\n size: number = 0,\n item?: T | ((index: number) => T)\n): T[] {\n if (size <= 0) return []\n let arr = new Array(size)\n for (let i = 0; i < size; i++) {\n arr[i] = item instanceof Function ? item(i) : item\n }\n return arr\n}\n","// Originial code at https://github.com/cryptocoinjs/base-x/blob/master/ts_src/index.ts\n//\n// base-x encoding / decoding\n// Copyright (c) 2018 base-x contributors\n// Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp)\n// Distributed under the MIT software license, see the accompanying\n// file LICENSE or http://www.opensource.org/licenses/mit-license.php.\n\n// \"Fast base encoding / decoding of any given alphabet using bitcoin style leading zero compression.\"\n// \"WARNING: This module is NOT RFC3548 compliant, it cannot be used for base16 (hex), base32, or base64 encoding in a standards compliant manner.\"\n\nimport { BinInput, toUint8Array } from \"./bin\"\nimport { Logger } from \"../log\"\n\nconst log = Logger(\"zeed:basex\")\n\nconst alphabets = {\n \"2\": \"01\",\n \"8\": \"01234567\",\n \"11\": \"0123456789a\",\n \"16\": \"0123456789abcdef\",\n \"32\": \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\",\n \"32-rfc\": \"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567\", // https://datatracker.ietf.org/doc/html/rfc4648#section-6\n \"32-hex\": \"0123456789ABCDEFGHIJKLMNOPQRSTUV\", // https://datatracker.ietf.org/doc/html/rfc4648#section-7\n \"32-zbase\": \"ybndrfg8ejkmcpqxot1uwisza345h769\", // https://en.wikipedia.org/wiki/Base32#z-base-32\n \"36\": \"0123456789abcdefghijklmnopqrstuvwxyz\",\n \"58\": \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\",\n // \"62\": \"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\", // The sort order is not kept!\n \"62\": \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\",\n \"64\": \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\",\n \"64-url\": \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\", // https://datatracker.ietf.org/doc/html/rfc4648#section-5\n \"66\": \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.!~\",\n \"85\": \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~\", // https://datatracker.ietf.org/doc/html/rfc1924#section-4.2\n}\n\nexport function useBase(alphaOrBase: string | number) {\n let ALPHABET: string\n if (typeof alphaOrBase === \"string\") {\n ALPHABET = alphaOrBase\n } else {\n // @ts-ignore\n ALPHABET = alphabets[alphaOrBase.toString()]\n if (ALPHABET == null) throw new Error(`Unknown base ${alphaOrBase}`)\n }\n\n if (ALPHABET.length >= 255) throw new TypeError(\"Alphabet too long\")\n\n const BASE_MAP = new Uint8Array(256)\n for (let j = 0; j < BASE_MAP.length; j++) {\n BASE_MAP[j] = 255\n }\n\n for (let i = 0; i < ALPHABET.length; i++) {\n const x = ALPHABET.charAt(i)\n const xc = x.charCodeAt(0)\n\n if (BASE_MAP[xc] !== 255) throw new TypeError(x + \" is ambiguous\")\n BASE_MAP[xc] = i\n }\n\n const BASE = ALPHABET.length\n const LEADER = ALPHABET.charAt(0)\n const FACTOR = Math.log(BASE) / Math.log(256) // log(BASE) / log(256), rounded up\n const iFACTOR = Math.log(256) / Math.log(BASE) // log(256) / log(BASE), rounded up\n\n function encode(source: BinInput, padToLength: number = -1): string {\n let data = toUint8Array(source)\n if (data.byteLength === 0) return \"\"\n\n // Skip & count leading zeroes.\n let length = 0\n let pbegin = 0\n const pend = data.byteLength\n\n while (pbegin !== pend && data[pbegin] === 0) pbegin++\n\n // Allocate enough space in big-endian base58 representation.\n const size = ((pend - pbegin) * iFACTOR + 1) >>> 0\n const dataEncoded = new Uint8Array(size)\n\n // Process the bytes.\n while (pbegin !== pend) {\n let carry = data[pbegin]\n\n // Apply \"dataEncoded = dataEncoded * 256 + ch\".\n let i = 0\n for (\n let it1 = size - 1;\n (carry !== 0 || i < length) && it1 !== -1;\n it1--, i++\n ) {\n carry += (256 * dataEncoded[it1]) >>> 0\n dataEncoded[it1] = carry % BASE >>> 0\n carry = (carry / BASE) >>> 0\n }\n\n if (carry !== 0) {\n log.warn(\"Non-zero carry\", data, padToLength, i, size)\n throw new Error(\"Non-zero carry\")\n }\n\n length = i\n pbegin++\n }\n\n let it2 = size - length\n\n // Skip leading zeroes\n while (it2 !== size && dataEncoded[it2] === 0) {\n it2++\n }\n\n // Translate the result into a string.\n let str = \"\"\n for (; it2 < size; ++it2) str += ALPHABET.charAt(dataEncoded[it2])\n\n if (padToLength > 0) {\n // const pad = Math.ceil(source.length * iFACTOR)\n return str.padStart(padToLength, LEADER)\n }\n return str\n }\n\n function decode(source: string, padToLength: number = -1): Uint8Array {\n if (typeof source !== \"string\") throw new TypeError(\"Expected String\")\n if (source.length === 0) return new Uint8Array()\n\n // Normalize\n source = source.replace(/\\s+/gi, \"\")\n\n let psz = 0\n let length = 0\n\n while (source[psz] === LEADER) {\n psz++\n }\n\n // Allocate enough space in big-endian base256 representation.\n const size = ((source.length - psz) * FACTOR + 1) >>> 0 // log(58) / log(256), rounded up.\n const dataDecoded = new Uint8Array(size)\n\n // Process the characters.\n while (source[psz]) {\n let carry = BASE_MAP[source.charCodeAt(psz)]\n\n // Invalid character\n if (carry === 255)\n throw new Error(`Unsupported character \"${source[psz]}\"`)\n\n let i = 0\n for (\n let it3 = size - 1;\n (carry !== 0 || i < length) && it3 !== -1;\n it3--, i++\n ) {\n carry += (BASE * dataDecoded[it3]) >>> 0\n dataDecoded[it3] = carry % 256 >>> 0\n carry = (carry / 256) >>> 0\n }\n\n if (carry !== 0) throw new Error(\"Non-zero carry\")\n length = i\n psz++\n }\n\n // Skip leading zeroes\n let it4 = size - length\n while (it4 !== size && dataDecoded[it4] === 0) {\n it4++\n }\n\n if (padToLength > 0) {\n return new Uint8Array([\n ...new Uint8Array(padToLength - dataDecoded.length + it4),\n ...dataDecoded.slice(it4),\n ])\n }\n\n return dataDecoded.slice(it4)\n }\n\n return {\n encode,\n decode,\n }\n}\n\n// Shortcuts\n\nexport const { encode: encodeBase16, decode: decodeBase16 } = useBase(16)\nexport const { encode: encodeBase32, decode: decodeBase32 } = useBase(32)\nexport const { encode: encodeBase58, decode: decodeBase58 } = useBase(58)\nexport const { encode: encodeBase62, decode: decodeBase62 } = useBase(62)\nexport const { encode: encodeBase64, decode: decodeBase64 } = useBase(62)\n","/*\nhttps://matthiashager.com/converting-snake-case-to-camel-case-object-keys-with-javascript\n\ncamelCase\nsnake_case\nkebab-case\nPascalCase // I won't be using this here, but it's only one small step further if you want to use it\n*/\n\nexport const toCamelCase = (s: string) => {\n // if only capital letters, convert to lower case\n if (s.length > 0) {\n if (/^[A-Z0-9_\\-\\ ]*$/g.test(s)) {\n s = s.toLowerCase()\n }\n s = s\n // strip trailing non chars\n .replace(/^[-_\\ ]+/gi, \"\")\n .replace(/[-_\\ ]+$/gi, \"\")\n // strip separators and upper case first char\n .replace(/[-_\\ ]+([a-z0-9])/gi, ($0, $1) => $1.toUpperCase())\n // lower case first char\n s = s[0].toLowerCase() + s.substring(1)\n }\n return s\n}\n\nexport function toCapitalize(s: string) {\n return s.charAt(0).toUpperCase() + s.toLowerCase().slice(1)\n}\n\nexport function toCapitalizeWords(s: string) {\n return s.replace(/\\w\\S*/g, toCapitalize)\n}\n\n// export function camelize(str: string) {\n// return str\n// .replace(/(?:^\\w|[A-Z]|\\b\\w)/g, (word: string, index: number) =>\n// index === 0 ? word.toLowerCase() : word.toUpperCase()\n// )\n// .replace(/\\s+/g, \"\")\n// }\n\nexport function fromCamelCase(str: string, separator: string = \"-\") {\n separator = typeof separator === \"undefined\" ? \"_\" : separator\n return str\n .replace(/([a-z\\d])([A-Z])/g, \"$1\" + separator + \"$2\")\n .replace(/([A-Z]+)([A-Z][a-z\\d]+)/g, \"$1\" + separator + \"$2\")\n .toLowerCase()\n}\n","// From https://github.com/moll/json-stringify-safe License ISC\n\ntype EntryProcessor = (key: string, value: any) => any\n\nfunction serializer(replacer: EntryProcessor, cycleReplacer?: EntryProcessor) {\n var stack: any[] = [],\n keys: string[] = []\n\n if (cycleReplacer == null)\n cycleReplacer = function (key, value) {\n if (stack[0] === value) return \"[Circular ~]\"\n return (\n \"[Circular ~.\" + keys.slice(0, stack.indexOf(value)).join(\".\") + \"]\"\n )\n }\n\n return function (this: EntryProcessor, key: string, value: any): any {\n if (stack.length > 0) {\n var thisPos = stack.indexOf(this)\n ~thisPos ? stack.splice(thisPos + 1) : stack.push(this)\n ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key)\n if (~stack.indexOf(value)) value = cycleReplacer?.call(this, key, value)\n } else stack.push(value)\n\n return replacer == null ? value : replacer.call(this, key, value)\n }\n}\n\n/**\n * Similar to JSON.stringify but can handle circular references\n */\nexport function jsonStringify(\n obj: any,\n replacer?: EntryProcessor | null,\n spaces?: string | number | null,\n cycleReplacer?: EntryProcessor\n): string {\n // @ts-ignore\n return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces)\n}\n\n//\n\n// From https://github.com/unjs/destr MIT\n// https://github.com/fastify/secure-json-parse\n// https://github.com/hapijs/bourne\nconst suspectProtoRx =\n /\"(?:_|\\\\u005[Ff])(?:_|\\\\u005[Ff])(?:p|\\\\u0070)(?:r|\\\\u0072)(?:o|\\\\u006[Ff])(?:t|\\\\u0074)(?:o|\\\\u006[Ff])(?:_|\\\\u005[Ff])(?:_|\\\\u005[Ff])\"\\s*:/\nconst suspectConstructorRx =\n /\"(?:c|\\\\u0063)(?:o|\\\\u006[Ff])(?:n|\\\\u006[Ee])(?:s|\\\\u0073)(?:t|\\\\u0074)(?:r|\\\\u0072)(?:u|\\\\u0075)(?:c|\\\\u0063)(?:t|\\\\u0074)(?:o|\\\\u006[Ff])(?:r|\\\\u0072)\"\\s*:/\n\nconst JsonSigRx = /^[\"{[]|^-?[0-9][0-9.]{0,14}$/\n\nfunction jsonParseTransform(key: string, value: any): any {\n if (key === \"__proto__\" || key === \"constructor\") {\n return\n }\n return value\n}\n\nexport default function jsonParse(val: string): any {\n if (typeof val !== \"string\") {\n return val\n }\n\n const _lval = val.toLowerCase()\n if (_lval === \"true\") {\n return true\n }\n if (_lval === \"false\") {\n return false\n }\n if (_lval === \"null\") {\n return null\n }\n if (_lval === \"nan\") {\n return NaN\n }\n if (_lval === \"infinity\") {\n return Infinity\n }\n if (_lval === \"undefined\") {\n return undefined\n }\n\n if (!JsonSigRx.test(val)) {\n return val\n }\n\n try {\n if (suspectProtoRx.test(val) || suspectConstructorRx.test(val)) {\n return JSON.parse(val, jsonParseTransform)\n }\n return JSON.parse(val)\n } catch (_e) {\n return val\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nconst TRUE_VALUES_LIST = [\"1\", \"true\", \"yes\", \"y\", \"on\"]\n\nexport function stringToBoolean(value?: string, defaultValue = false): boolean {\n if (value == null || typeof value !== \"string\") return defaultValue\n return TRUE_VALUES_LIST.includes(String(value).trim().toLowerCase())\n}\n\nexport function stringToInteger(value?: string, defaultValue = 0): number {\n if (value == null || typeof value !== \"string\") return defaultValue\n return parseInt(value.trim(), 10) ?? defaultValue\n}\n\nexport function stringToFloat(value?: string, defaultValue = 0.0): number {\n if (value == null || typeof value !== \"string\") return defaultValue\n return parseFloat(value.trim()) ?? defaultValue\n}\n\nexport function valueToBoolean(value?: any, defaultValue = false): boolean {\n if (value == null) return defaultValue\n if (typeof value === \"boolean\") return value\n if (typeof value === \"number\") return value !== 0\n return TRUE_VALUES_LIST.includes(String(value).trim().toLowerCase())\n}\n\nexport function valueToInteger(value?: any, defaultValue = 0): number {\n if (value == null) return defaultValue\n if (typeof value === \"boolean\") return value ? 1 : 0\n if (typeof value === \"number\") return Math.floor(value)\n return parseInt(String(value).trim(), 10) ?? defaultValue\n}\n\nexport function valueToFloat(value?: any, defaultValue = 0.0): number {\n if (value == null) return defaultValue\n if (typeof value === \"boolean\") return value ? 1 : 0\n if (typeof value === \"number\") return Math.floor(value)\n return parseFloat(String(value).trim()) ?? defaultValue\n}\n\nexport function valueToString(value?: any, defaultValue = \"\"): string {\n if (value == null) return defaultValue\n // if (value == \"\") return defaultValue // ???\n return String(value) ?? defaultValue\n}\n\n// todo: toDate, toTimestamp, toData(value, base=64)\n\n// export function mapToObject<T>(map: Map<string, T>): { [key: string]: T } {\n// return Object.fromEntries(map)\n// }\n\n// export function objectToMap<T>(obj: { [key: string]: T }): Map<string, T> {\n// return new Map(Object.entries(obj))\n// }\n\n// Shortcuts\n\nexport const toFloat = valueToFloat\nexport const toInt = valueToInteger\nexport const toString = valueToString\nexport const toBool = valueToBoolean\n\n// Strings\n\nimport { jsonStringify } from \"./json\"\n\nexport type RenderMessagesOptions = {\n trace?: boolean // = true\n pretty?: boolean // = true\n}\n\nexport function formatMessages(\n messages: any[],\n opt: RenderMessagesOptions = {}\n): any[] {\n const { trace = true, pretty = true } = opt\n return messages.map((obj) => {\n if (obj && typeof obj === \"object\") {\n if (obj instanceof Error) {\n if (!trace) {\n return `${obj.name || \"Error\"}: ${obj.message}`\n }\n return `${obj.name || \"Error\"}: ${obj.message}\\n${obj.stack}`\n }\n return pretty ? jsonStringify(obj, null, 2) : jsonStringify(obj)\n }\n return String(obj)\n })\n}\n\nexport function renderMessages(\n messages: any[],\n opt: RenderMessagesOptions = {}\n): string {\n return formatMessages(messages, opt).join(\" \")\n}\n\n//\n\n// Awesome trick from https://stackoverflow.com/a/5396742/140927\nexport function fixBrokenUth8String(brokenString: string): string {\n try {\n return decodeURIComponent(escape(brokenString))\n } catch (e) {\n // log.debug(\"fixString failed for\", s)\n }\n return brokenString\n}\n","// Original taken from https://github.com/scurker/currency.js\n// @ts-nocheck\n\nimport { arrayFlatten } from \"./array\"\n\nexport type CurrencyInput = number | string | Currency\n\ntype CurrencyFormat = (currency?: Currency, opts?: CurrencyOptions) => string\n\ninterface CurrencyOptions {\n symbol?: string\n separator?: string\n decimal?: string\n errorOnInvalid?: boolean\n precision?: number\n increment?: number\n useVedic?: boolean\n pattern?: string\n negativePattern?: string\n format?: CurrencyFormat\n fromCents?: boolean\n groups?: RegExp\n}\n\nconst defaults = {\n symbol: \"$\",\n separator: \",\",\n decimal: \".\",\n errorOnInvalid: false,\n precision: 2,\n pattern: \"!#\",\n negativePattern: \"-!#\",\n format,\n fromCents: false,\n}\n\nconst round = (v: number) => Math.round(v)\nconst pow = (p: number) => Math.pow(10, p)\nconst rounding = (value: number, increment: number) =>\n round(value / increment) * increment\n\nconst groupRegex = /(\\d)(?=(\\d{3})+\\b)/g\nconst vedicRegex = /(\\d)(?=(\\d\\d)+\\d\\b)/g\n\nexport function currency(\n value: CurrencyInput,\n opts: CurrencyOptions = {}\n): Currency {\n return new Currency(value, opts)\n}\n\n/**\n * Immuteable currency representation\n */\nexport class Currency {\n public readonly intValue: number\n public readonly value: number\n private readonly _settings: CurrencyOptions\n private readonly _precision: number\n\n constructor(value: CurrencyInput, opts: CurrencyOptions = {}) {\n let settings = Object.assign({}, defaults, opts)\n let precision = pow(settings.precision ?? 2)\n let v = parse(value, settings)\n\n this.intValue = v\n this.value = v / precision\n\n // Set default incremental value\n settings.increment = settings.increment || 1 / precision\n\n // Support vedic numbering systems\n // see: https://en.wikipedia.org/wiki/Indian_numbering_system\n if (settings.useVedic) {\n settings.groups = vedicRegex\n } else {\n settings.groups = groupRegex\n }\n\n // Intended for internal usage only - subject to change\n this._settings = settings\n this._precision = precision\n }\n\n add(number: CurrencyInput): Currency {\n let { intValue, _settings, _precision } = this\n return currency(\n (intValue += parse(number, _settings)) /\n (_settings.fromCents ? 1 : _precision),\n _settings\n )\n }\n\n subtract(number: CurrencyInput): Currency {\n let { intValue, _settings, _precision } = this\n return currency(\n (intValue -= parse(number, _settings)) /\n (_settings.fromCents ? 1 : _precision),\n _settings\n )\n }\n\n multiply(number: CurrencyInput): Currency {\n // todo\n let { intValue, _settings, _precision } = this\n return currency(\n (intValue *= number) / (_settings.fromCents ? 1 : pow(_precision)),\n _settings\n )\n }\n\n divide(number: CurrencyInput): Currency {\n let { intValue, _settings } = this\n return currency((intValue /= parse(number, _settings, false)), _settings)\n }\n\n distribute(count: number): number[] {\n let { intValue, _precision, _settings } = this,\n distribution = [],\n split = Math[intValue >= 0 ? \"floor\" : \"ceil\"](intValue / count),\n pennies = Math.abs(intValue - split * count),\n precision = _settings.fromCents ? 1 : _precision\n\n for (; count !== 0; count--) {\n let item = currency(split / precision, _settings)\n\n // Add any left over pennies\n pennies-- > 0 &&\n (item = item[intValue >= 0 ? \"add\" : \"subtract\"](1 / precision))\n\n distribution.push(item)\n }\n\n return distribution as any\n }\n\n dollars(): number {\n return ~~this.value\n }\n\n cents(): number {\n let { intValue, _precision } = this\n return ~~(intValue % _precision)\n }\n\n format(options: CurrencyOptions | Function) {\n let { _settings } = this\n if (typeof options === \"function\") {\n return options(this, _settings)\n }\n return _settings.format(this, Object.assign({}, _settings, options))\n }\n\n toString(): string {\n let { intValue, _precision, _settings } = this\n return rounding(intValue / _precision, _settings.increment).toFixed(\n _settings.precision\n )\n }\n\n toJSON(): number {\n return this.value\n }\n\n static zero = new Currency(0)\n static one = new Currency(1)\n\n static sum(...array: (CurrencyInput | CurrencyInput[])[]): Currency {\n return arrayFlatten(array).reduce(\n (acc, value) => currency(acc).add(value),\n this.zero\n )\n }\n\n static avg(...array: (CurrencyInput | CurrencyInput[])[]): Currency {\n let arr = arrayFlatten(array)\n return arr\n .reduce((acc, value) => currency(acc).add(value), this.zero)\n .divide(arr.length)\n }\n}\n\nfunction parse(\n value: CurrencyInput,\n opts: CurrencyOptions,\n useRounding = true\n): number {\n let v: any = 0,\n { decimal, errorOnInvalid, precision: decimals, fromCents } = opts,\n precision = pow(decimals),\n isNumber = typeof value === \"number\"\n\n if (value instanceof Currency && fromCents) {\n return value.intValue\n }\n\n if (isNumber || value instanceof Currency) {\n v = value instanceof Currency ? value.value : value\n } else if (typeof value === \"string\") {\n let regex = new RegExp(\"[^-\\\\d\" + decimal + \"]\", \"g\"),\n decimalString = new RegExp(\"\\\\\" + decimal, \"g\")\n v = value\n .replace(/\\((.*)\\)/, \"-$1\") // allow negative e.g. (1.99)\n .replace(regex, \"\") // replace any non numeric values\n .replace(decimalString, \".\") // convert any decimal values\n v = v || 0\n } else {\n if (errorOnInvalid) {\n throw Error(\"Invalid Input\")\n }\n v = 0\n }\n\n if (!fromCents) {\n v *= precision // scale number to integer value\n v = v.toFixed(4) // Handle additional decimal for proper rounding.\n }\n\n return useRounding ? round(v) : v\n}\n\nfunction format(currency: Currency, settings: CurrencyOptions): string {\n let { pattern, negativePattern, symbol, separator, decimal, groups } =\n settings,\n split = (\"\" + currency).replace(/^-/, \"\").split(\".\"),\n dollars = split[0],\n cents = split[1]\n\n return (currency.value >= 0 ? pattern : negativePattern)\n .replace(\"!\", symbol)\n .replace(\n \"#\",\n dollars.replace(groups, \"$1\" + separator) + (cents ? decimal + cents : \"\")\n )\n}\n\n// todo: percent calculations\n\n// From https://v2.dinerojs.com/docs/api/formatting/to-unit MIT\n\nexport type RoundingMode = (value: number) => number\n\nexport const isHalf = (value: number) => Math.abs(value) % 1 === 0.5\nexport const isEven = (value: number) => value % 2 === 0\n\nexport const roundUp: RoundingMode = (value) => Math.ceil(value)\nexport const roundDown: RoundingMode = (value) => Math.floor(value)\nexport const roundHalfUp: RoundingMode = (value) => Math.round(value)\n\n/**\n * Round a number with half values to nearest odd integer.\n */\nexport const roundHalfOdd: RoundingMode = (value) => {\n const rounded = Math.round(value)\n if (!isHalf(value)) {\n return rounded\n }\n return isEven(rounded) ? rounded - 1 : rounded\n}\n\n/**\n * Round a number with half values to nearest integer farthest from zero.\n */\nexport const roundHalfAwayFromZero: RoundingMode = (value) => {\n return isHalf(value)\n ? Math.sign(value) * Math.ceil(Math.abs(value))\n : Math.round(value)\n}\n\n/**\n * Round a number with half values down.\n */\nexport const roundHalfDown: RoundingMode = (value) =>\n isHalf(value) ? Math.floor(value) : Math.round(value)\n\n/**\n * Round a number with half values to nearest even integer.\n * https://wiki.c2.com/?BankersRounding\n */\nexport const roundHalfEven: RoundingMode = (value) => {\n const rounded = Math.round(value)\n if (!isHalf(value)) {\n return rounded\n }\n return isEven(rounded) ? rounded : rounded - 1\n}\n\n/**\n * Round a number with half values to nearest integer closest to zero.\n */\nexport const roundHalfTowardsZero: RoundingMode = (value) =>\n isHalf(value)\n ? Math.sign(value) * Math.floor(Math.abs(value))\n : Math.round(value)\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { Logger } from \"./log\"\n\nconst { warn } = Logger(\"zeed:promise\")\n\n/** Sleep for `milliSeconds`. Example 1s: `await sleep(1000)` */\nexport async function sleep(milliSeconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, milliSeconds))\n}\n\nexport async function immediate(): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, 0))\n}\n\nexport const timeoutReached = Symbol(\"timeout\")\n\ntype Unwrap<T> = T extends Promise<infer U>\n ? U\n : T extends (...args: any) => Promise<infer U>\n ? U\n : T extends (...args: any) => infer U\n ? U\n : T\n\nexport async function timeout<T>(\n promise: Promise<T>,\n milliSeconds: number,\n timeoutValue = timeoutReached\n): Promise<T | typeof timeoutValue> {\n return new Promise(async (resolve, reject) => {\n let done = false\n\n const timeout = setTimeout(() => {\n done = true\n resolve(timeoutValue)\n }, milliSeconds)\n\n try {\n let result = await promise\n clearTimeout(timeout)\n if (!done) resolve(result)\n } catch (err) {\n clearTimeout(timeout)\n if (!done) reject(err)\n }\n })\n}\n\nexport const timoutError = new Error(\"Timeout reached\")\n\nexport function isTimeout(value: any): boolean {\n return value === timeoutReached || value === timoutError\n}\n\nexport async function tryTimeout<T>(\n promise: Promise<T>,\n milliSeconds: number\n): Promise<T | undefined> {\n if (milliSeconds <= 0) {\n return await promise\n }\n return new Promise(async (resolve, reject) => {\n let done = false\n\n const timeout = setTimeout(() => {\n done = true\n reject(timoutError)\n }, milliSeconds)\n\n try {\n let result = await promise\n clearTimeout(timeout)\n if (!done) resolve(result)\n } catch (err) {\n clearTimeout(timeout)\n if (!done) reject(err)\n }\n })\n}\n\n/** Wait for `event` on `obj` to emit. Resolve with result or reject on `timeout` */\nexport function waitOn(\n obj: any,\n event: string,\n timeoutMS: number = 1000\n): Promise<any> {\n return new Promise((resolve, reject) => {\n let fn = (value: any) => {\n if (timer) {\n clearTimeout(timer)\n done()\n resolve(value)\n }\n }\n\n let done = () => {\n timer = null\n if (obj.off) {\n obj.off(event, fn)\n } else if (obj.removeEventListener) {\n obj.removeEventListener(event, fn)\n } else {\n warn(\"No remove listener method found for\", obj, event)\n }\n }\n\n let timer: any = setTimeout(() => {\n done()\n reject(new Error(`Did not response in time`))\n }, timeoutMS)\n\n if (obj.on) {\n obj.on(event, fn)\n } else if (obj.addEventListener) {\n obj.addEventListener(event, fn)\n } else {\n warn(\"No listener method found for\", obj)\n }\n })\n}\n\nexport function isPromise<T>(value: Promise<T> | T): value is Promise<T> {\n return Boolean(\n value &&\n (value instanceof Promise ||\n // @ts-ignore\n typeof value.then === \"function\")\n )\n}\n\n/** This is exactly what Prose.resolve(x) is supposed to be: return a Promise no matter what type x is */\nexport function promisify<T>(value: Promise<T> | T): Promise<T> {\n return Promise.resolve(value)\n // return isPromise(value) ? value : Promise.resolve(value)\n}\n\n// // https://github.com/unjs/items-promise\n\n// /**\n// * Run tasks one by one by calling fn(task, previous) in a promise chain.\n// * Return value is of type Promise<*> which resolves to the last fn result.\n// */\n// export async function serial(tasks: any, fn: any) {\n// return tasks.reduce(\n// (promise: Promise<any>, task: any) =>\n// promise.then((previous) => fn(task, previous)),\n// Promise.resolve(null)\n// )\n// }\n\n// /**\n// * Run all tasks in parallel by calling fn(tasks) and await using Promise.all.\n// * Return value is of type Promise<*[]> which resolves to results of all fns in an array.\n// */\n// export async function parallel(tasks: any[], fn: any): Promise<any[]> {\n// return Promise.all(tasks.map((task) => fn(task)))\n// }\n","import { isPromise } from \"../promise\"\n\nexport const DAY_MS = 1000 * 60 * 60 * 24\n\nexport type DayInput = number | string | Date | Day\n\nexport class Day {\n days: number\n\n constructor(days?: DayInput) {\n if (typeof days === \"number\") {\n this.days = days\n return\n }\n\n if (days != null) {\n days = Day.from(days)?.days\n }\n\n if (days == null) {\n const date = new Date()\n this.days =\n date.getFullYear() * 10000 +\n (date.getMonth() + 1) * 100 +\n date.getDate()\n } else {\n this.days = days\n }\n }\n\n static fromNumber(n: number): Day {\n return new Day(n)\n }\n\n static fromString(dateString: string): Day | undefined {\n return new Day(+dateString.replace(/[^0-9]/g, \"\"))\n }\n\n static fromDate(date: Date, gmt: boolean = false): Day {\n return (\n gmt\n ? Day.fromString(date.toISOString().substr(0, 10))\n : new Day(\n date.getFullYear() * 10000 +\n (date.getMonth() + 1) * 100 +\n date.getDate()\n )\n ) as Day\n }\n\n static fromDateGMT(date: Date): Day {\n return Day.fromDate(date, true)\n }\n\n static from(value: DayInput, gmt: boolean = false): Day | undefined {\n if (typeof value === \"number\") {\n return new Day(value)\n } else if (typeof value === \"string\") {\n return Day.fromString(value)\n } else if (value instanceof Date) {\n return Day.fromDate(value, gmt)\n } else if (value instanceof Day) {\n return value\n }\n }\n\n toNumber(): number {\n return this.days\n }\n\n // Transformer\n\n /** Just for future extensions */\n toJson() {\n return this.days\n }\n\n toString(sep: string = \"-\") {\n let baseString = String(this.days)\n return (\n baseString.slice(0, 4) +\n sep +\n baseString.slice(4, 6) +\n sep +\n baseString.slice(6, 8)\n )\n }\n\n toDate(gmt: boolean = false): Date {\n return gmt\n ? new Date(`${this.toString()}T00:00:00.000Z`)\n : new Date(\n this.days / 10000, // year\n ((this.days / 100) % 100) - 1, // month\n this.days % 100 // day\n )\n }\n\n toDateGMT() {\n return this.toDate(true)\n }\n\n // Calculations\n\n dayOffset(offset: number): Day {\n // Important! Don't use local time here due to summer/winter time days can\n // be longer or shorter!\n return Day.fromDateGMT(\n new Date(this.toDateGMT().getTime() + offset * DAY_MS)\n )\n }\n\n daysUntil(otherDay: DayInput): number {\n return Math.round(\n (new Day(otherDay)?.toDateGMT().getTime() - this.toDateGMT().getTime()) /\n DAY_MS\n )\n }\n\n // Shortcuts\n\n yesterday() {\n return this.dayOffset(-1)\n }\n\n tomorrow() {\n return this.dayOffset(+1)\n }\n}\n\nexport async function forEachDay(\n from: DayInput,\n to: DayInput,\n handler: (date: Day) => Promise<void> | void\n) {\n let start = Day.from(from)\n let end = Day.from(to)\n while (start && end && start?.days <= end?.days) {\n let result = handler(start)\n if (isPromise(result)) {\n await result\n }\n start = start.dayOffset(+1)\n }\n}\n\nexport function today(): Day {\n return new Day()\n}\n\nexport function day(days?: DayInput): Day {\n return new Day(days)\n}\n","export const escapeHTML = (s: string): string =>\n s\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/'/g, \"'\")\n .replace(/\"/g, \""\")\n\nexport const unescapeHTML = (s: string): string =>\n s\n .replace(/</gi, \"<\")\n .replace(/>/gi, \">\")\n .replace(/"/gi, '\"')\n .replace(/'/gi, \"'\")\n .replace(/&/gi, \"&\")\n","export function randomBoolean(bias = 0.25): boolean {\n return Math.random() < bias\n}\n\n/** max is not included, min is included */\nexport function randomInt(max = 100, min = 0): number {\n return min + Math.floor(Math.random() * (max - min))\n}\n\nexport function randomFloat(max = 100, min = 0): number {\n return min + Math.random() * (max - min)\n}\n\nexport function between(min: number, value: number, max: number): number {\n return Math.max(min, Math.min(max, value))\n}\n\n// export const clamp = (n: number, min: number, max: number) => Math.min(max, Math.max(min, n))\n","// https://github.com/sindresorhus/filenamify/blob/main/filenamify.js\n\nconst MAX_FILENAME_LENGTH = 100\n\nconst reControlChars = /[\\u0000-\\u001F\\u0080-\\u009F]/g // eslint-disable-line no-control-regex\nconst reRelativePath = /^\\.+/\nconst reTrailingPeriods = /\\.+$/\n\nfunction filenameReservedRegex() {\n return /[<>:\"/\\\\|?*\\u0000-\\u001F]/g\n}\n\nfunction windowsReservedNameRegex() {\n return /^(con|prn|aux|nul|com\\d|lpt\\d)$/i\n}\n\nexport function toValidFilename(string: string) {\n if (typeof string !== \"string\") {\n throw new TypeError(\"Expected a string\")\n }\n\n const replacement = \"_\"\n\n if (\n filenameReservedRegex().test(replacement) &&\n reControlChars.test(replacement)\n ) {\n throw new Error(\n \"Replacement string cannot contain reserved filename characters\"\n )\n }\n\n string = string\n .replace(filenameReservedRegex(), replacement)\n .replace(reControlChars, replacement)\n .replace(reRelativePath, replacement)\n .replace(reTrailingPeriods, \"\")\n\n string = windowsReservedNameRegex().test(string)\n ? string + replacement\n : string\n\n return string.slice(0, MAX_FILENAME_LENGTH)\n}\n","const rxEscape = /[\\\\\\-\\[\\]\\/{}()*+?.^$|]/g // Finds: \\ - [ ] / { } ( ) * + ? . ^ $ |\n\nexport function escapeRegExp(value: RegExp | string): string {\n if (!value) return \"\"\n if (value instanceof RegExp) {\n return value.source\n }\n return value.replace(rxEscape, \"\\\\$&\")\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\n// Get a sort_weight suitable for adding to top of list\n// Original idea https://holtwick.de/en/blog/smart-table-reordering\n\nexport interface SortableItem {\n sort_weight: number\n}\n\nexport function startSortWeight(items: SortableItem[]): number {\n return (\n items.reduce((acc, item) => Math.min(acc, item.sort_weight || 0), 0) -\n 1 -\n Math.random()\n )\n}\n\n// Get a sort_weight suitable for adding to end of list\nexport function endSortWeight(items: SortableItem[]): number {\n return (\n items.reduce((acc, item) => Math.max(acc, item.sort_weight || 0), 0) +\n 1 +\n Math.random()\n )\n}\n\n// The real magic\nexport function moveSortWeight(\n newIndex: number,\n oldIndex: number,\n items: SortableItem[]\n): number {\n let count = items.length\n\n const moveLower = newIndex < oldIndex\n if (count <= 0 || newIndex >= count - 1) {\n return endSortWeight(items)\n }\n if (newIndex <= 0) {\n return startSortWeight(items)\n }\n\n // Make sure they are sorted\n items = sortedItems([...items])\n\n const step = moveLower ? -1 : 0\n const lower = items[newIndex + step].sort_weight || 0\n const upper = items[newIndex + step + 1].sort_weight || 0\n const distance = upper - lower\n if (distance === 0) {\n // Ugly list with no presets, make the best guess\n if (moveLower) {\n return startSortWeight(items)\n }\n return endSortWeight(items)\n }\n const middle = lower + distance / 2\n const fuzzy = distance * 0.01 * (Math.random() - 0.5) // 1% fuzziness to avoid conflicts\n return middle + fuzzy\n}\n\nexport function sortedItems<T extends SortableItem>(items: T[]): T[] {\n items.sort((a, b) => (a.sort_weight || 0) - (b.sort_weight || 0))\n return items\n}\n","// https://mathiasbynens.be/demo/url-regex\n// https://gist.github.com/dperini/729294\n\nimport { escapeHTML } from \"./html\"\n\nconst findURL =\n /((?:(?:(?:https?|ftp):)?\\/\\/)(?:\\S+(?::\\S*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z0-9\\u00a1-\\uffff][a-z0-9\\u00a1-\\uffff_-]{0,62})?[a-z0-9\\u00a1-\\uffff]\\.)+(?:[a-z\\u00a1-\\uffff]{2,}\\.?))(?::\\d{2,5})?(?:[/?#]\\S*)?)/gim\n\nexport function linkifyPlainText(text: string): string {\n return text\n .split(findURL)\n .map((part, i) => {\n const escapedPart = escapeHTML(part)\n return i % 2\n ? `<a target=\"_blank\" href=\"${escapedPart}\">${toHumanReadableUrl(\n escapedPart\n )}</a>`\n : escapedPart\n })\n .join(\"\")\n}\n\nexport function toHumanReadableUrl(url: string): string {\n return url.replace(/^https?:\\/\\/(www\\.)?/, \"\").replace(/\\/$/, \"\")\n}\n\n//\n\nexport function encodeQuery(data: Record<string, any>) {\n let pairs = []\n for (let [key, value] of Object.entries(data)) {\n if (value != null) {\n if (!Array.isArray(value)) {\n value = [value]\n }\n for (let v of value) {\n if (v != null) {\n pairs.push(\n encodeURIComponent(key) +\n \"=\" +\n encodeURIComponent(v.toString() || \"\")\n )\n }\n }\n }\n }\n return pairs.join(\"&\")\n}\n\nexport function parseQuery(queryString: string) {\n let query: any = {}\n let pairs = (\n queryString[0] === \"?\" ? queryString.substr(1) : queryString\n ).split(\"&\")\n for (let i = 0; i < pairs.length; i++) {\n let pair = pairs[i].split(\"=\")\n let key = decodeURIComponent(pair[0])\n let value = decodeURIComponent(pair[1] || \"\")\n if (query[key] != null) {\n if (!Array.isArray(query[key])) {\n query[key] = [query[key]]\n }\n query[key].push(value)\n } else {\n query[key] = value\n }\n }\n return query\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { Json } from \"../types\"\n\nexport function size(obj: any) {\n if (obj != null) {\n if (obj.size != null) {\n return obj.size\n }\n if (obj.length != null) {\n return obj.length\n }\n return Object.keys(obj).length\n }\n return 0\n}\n\nexport function last<T>(array?: T[]): T | undefined {\n return array != null && array.length > 0 ? array[array.length - 1] : undefined\n}\n\n// True for [], {}, \"\", Map(), Set() and all primitives\nexport function empty(value: any): boolean {\n try {\n if (value != null) {\n if (Array.isArray(value)) {\n return value.length <= 0\n } else if (typeof value === \"string\") {\n return value.length <= 0\n } else if (value?.size != null) {\n return value.size <= 0\n } else {\n return Object.keys(value).length <= 0\n }\n }\n } catch (err) {\n console.error(\"Failed to check if empty for\", value, err)\n }\n return true\n}\n\n// Also see common/data/deep.ts\nexport function cloneObject<T>(obj: T): T {\n // Primitives are immutable anyway\n if (Object(obj) !== obj) return obj\n\n // Rude but very efficient way to clone\n return JSON.parse(JSON.stringify(obj))\n}\n\n// Also see common/data/deep.ts\nexport function cloneJsonObject<T = Json>(obj: T): T {\n // Primitives are immutable anyway\n if (Object(obj) !== obj) return obj\n\n // Rude but very efficient way to clone\n return JSON.parse(JSON.stringify(obj))\n}\n\n// export function cloneStructuredObject<T>(obj: T): T {\n// // Primitives are immutable anyway\n// if (Object(obj) !== obj) return obj\n\n// // https://developer.mozilla.org/en-US/docs/Web/API/structuredClone\n// // @ts-ignore\n// return typeof structuredClone !== \"undefined\"\n// ? // @ts-ignore\n// structuredClone(obj)\n// : // Rude but very efficient way to clone\n// JSON.parse(JSON.stringify(obj))\n// }\n","import { arrayFilterInPlace } from \"./data/array\"\nimport { promisify, isPromise } from \"./promise\"\n\n// https://blog.hediet.de/post/the_disposable_pattern_in_typescript\n\nexport type DisposerFunction = () => any | Promise<any>\n\nexport type Disposer =\n | DisposerFunction\n | {\n dispose?: Function | Promise<unknown>\n cleanup?: Function | Promise<unknown> // deprecated, but used often in my old code\n }\n\nexport interface Disposable {\n dispose(): void | Promise<void>\n}\n\n/** Different kinds of implementations have grown, this should unify them */\nasync function callDisposer(disposable: Disposer): Promise<void> {\n if (typeof disposable === \"function\") {\n await promisify(disposable())\n } else if (isPromise(disposable)) {\n await disposable\n } else if (typeof disposable.dispose === \"function\") {\n await promisify(disposable.dispose())\n } else if (isPromise(disposable.dispose)) {\n await disposable.dispose\n } else if (typeof disposable.cleanup === \"function\") {\n await promisify(disposable.cleanup())\n } else if (isPromise(disposable.cleanup)) {\n await disposable.cleanup\n }\n}\n\n// export function disposeFn()\n\nexport function useDispose() {\n let tracked: Disposer[] = []\n\n const untrack = async (disposable: Disposer) => {\n if (tracked.includes(disposable)) {\n arrayFilterInPlace(tracked, (el) => el !== disposable)\n await callDisposer(disposable)\n }\n }\n\n const dispose = async () => {\n while (tracked.length > 0) {\n await untrack(tracked[0]) // LIFO\n }\n }\n\n const track = (obj: Disposer): DisposerFunction => {\n tracked.unshift(obj) // LIFO\n return () => untrack(obj)\n }\n\n return Object.assign(dispose, {\n track,\n add: track, // ?\n untrack, // ?\n dispose,\n exec: dispose, // ?\n getSize() {\n return tracked.length\n },\n })\n}\n\nexport type UseDispose = ReturnType<typeof useDispose>\n\n/** @deprecated use `useDispose` instead */\nexport const useDisposer = useDispose\n\nexport function useDefer(\n config: {\n mode?: \"lifo\" | \"fifo\"\n } = {}\n) {\n const { mode = \"fifo\" } = config\n let steps: Disposer[] = []\n\n /**\n * Excutes all steps. If all steps are not Promises, they are executed immediately,\n * otherwise a Promise is returned\n */\n const exec = async (expectSync: boolean = false) => {\n while (steps.length > 0) {\n let step = steps[0]\n arrayFilterInPlace(steps, (el) => el !== step)\n if (typeof step === \"function\") {\n let result = step()\n if (isPromise(result)) {\n if (expectSync)\n throw new Error(\n `Expected sync only function, but found async: ${step}`\n )\n await result\n }\n } else if (isPromise(step)) {\n if (expectSync)\n throw new Error(\n `Expected sync only function, but found async: ${step}`\n )\n await step\n } else {\n throw new Error(`Unhandled disposable: ${step}`)\n }\n }\n }\n\n const add = (obj: Disposer) => {\n if (mode === \"lifo\") {\n steps.unshift(obj)\n } else {\n steps.push(obj)\n }\n }\n\n return Object.assign(exec, {\n add,\n exec,\n getSize() {\n return steps.length\n },\n })\n}\n\nexport type UseDefer = ReturnType<typeof useDefer>\n\nexport function useTimeout(\n fn: Function,\n timeout: number = 0\n): DisposerFunction {\n let timeoutHandle: any = setTimeout(fn, timeout)\n return () => {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle)\n timeoutHandle = undefined\n }\n }\n}\n\nexport function useInterval(fn: Function, interval: number): DisposerFunction {\n let intervalHandle: any = setInterval(fn, interval)\n return () => {\n if (intervalHandle) {\n clearInterval(intervalHandle)\n intervalHandle = undefined\n }\n }\n}\n\nexport function useEventListener(\n emitter: any,\n eventName: string,\n fn: (ev?: any) => void,\n ...args: any[]\n): DisposerFunction {\n if (emitter == null) return () => {}\n\n if (emitter.on) {\n emitter.on(eventName, fn, ...args)\n } else if (emitter.addEventListener) {\n emitter.addEventListener(eventName, fn, ...args)\n }\n\n return () => {\n if (emitter.off) {\n emitter.off(eventName, fn, ...args)\n } else if (emitter.removeEventListener) {\n emitter.removeEventListener(eventName, fn, ...args)\n }\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nexport function isLocalHost(\n hostname: string = window.location.hostname\n): boolean {\n return (\n [\"localhost\", \"127.0.0.1\", \"\", \"::1\", \"::\"].includes(hostname) ||\n hostname.startsWith(\"192.168.\") ||\n hostname.startsWith(\"10.0.\") ||\n hostname.endsWith(\".local\")\n )\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\n/**\n * @returns Timestamp in miliseconds\n */\nexport const getTimestamp = (): number =>\n // @ts-ignore\n typeof performance !== \"undefined\" ? performance.now() : new Date().getTime()\n\nexport function formatMilliseconds(ms: number): string {\n return ms > 999 ? (ms / 1000).toFixed(1) + \"s\" : ms.toFixed(2) + \"ms\"\n}\n\nexport function parseDate(\n ...dateCandidates: (string | Date)[]\n): Date | undefined {\n for (let dateCandidate of dateCandidates) {\n if (dateCandidate instanceof Date) {\n return dateCandidate\n }\n if (typeof dateCandidate === \"string\") {\n let date = null\n if (dateCandidate.includes(\":\")) {\n try {\n date = new Date(dateCandidate)\n } catch (err) {}\n }\n if (!(date instanceof Date)) {\n let m = /(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d)/.exec(dateCandidate)\n if (m) {\n date = new Date(+m[1], +m[2] - 1, +m[3], 12, 0)\n }\n }\n if (date instanceof Date) {\n return date\n }\n }\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { randomUint8Array } from \"./crypto\"\nimport { useBase } from \"./data/basex\"\nimport { getTimestamp } from \"./time\"\n\nconst { encode: encode62, decode: decode62 } = useBase(62)\nconst { encode: encode32 } = useBase(32)\n\n// function randomDigit(base = 32) {\n// if (_crypto && _crypto['getRandomValues']) {\n// let rands = new Uint8Array(1)\n// _crypto['getRandomValues'](rands)\n// return (rands[0] % base).toString(base)\n// }\n// return ((Math.random() * base) | 0).toString(base)\n// }\n\nexport function uuidBytes(): Uint8Array {\n return randomUint8Array(16)\n}\n\nexport const uuid32bit = () => new Uint32Array(randomUint8Array(4))[0]\n\nexport function uuid(): string {\n return encode62(uuidBytes(), 22)\n}\n\nexport function uuidB32(): string {\n return encode32(uuidBytes(), 26)\n}\n\nlet _unameCounters: Record<string, number> = {}\n\nexport function uname(name: string = \"id\"): string {\n if (_unameCounters[name] == null) {\n _unameCounters[name] = 0\n }\n return `${name}-${_unameCounters[name]++}`\n}\n\nlet _qid = 0\n\nexport function qid(): string {\n return `id-${_qid++}`\n}\n\n// https://stackoverflow.com/a/2117523/140927\nconst pattern = \"10000000-1000-4000-8000-100000000000\" // String([1e7] + -1e3 + -4e3 + -8e3 + -1e11)\n\nexport const uuidv4 = () =>\n pattern.replace(/[018]/g, (c: any) =>\n (c ^ (randomUint8Array(1)[0] & (15 >> (c / 4)))).toString(16)\n )\n\n// https://github.com/segmentio/ksuid\n// https://pkg.go.dev/github.com/rsms/go-uuid\n\n/**\n * Sortable unique ID\n * Inspired by https://github.com/rsms/go-uuid\n *\n * Bytes 0-5: Current time in miliseconds from 2021-06-01T00:00:00Z\n * Bytes 6-15: Random\n */\n\n// 1622505600000 // new Date('2021-06-01T00:00:00Z').getTime()\nconst ReferenceDateInMS = 1600000000000\n\n// 6 bytes will stay valid until end of time: new Date(1622505600000 + 0xffffffffffff) === Date Sun Jan 01 10941 06:31:50 GMT+0100 (Central European Standard Time)\n\nfunction longToByteArray(long: number) {\n var byteArray = new Uint8Array([0, 0, 0, 0, 0, 0])\n const bytes = byteArray.length - 1\n for (var index = 0; index < byteArray.length; index++) {\n var byte = long & 0xff\n byteArray[bytes - index] = byte\n long = (long - byte) / 256\n }\n return byteArray\n}\n\n// function byteArrayToLong(byteArray: number[]): number {\n// var value = 0\n// for (var i = byteArray.length - 1; i >= 0; i--) {\n// value = value * 256 + byteArray[i]\n// }\n// return value\n// }\n\nexport function suidBytes(): Uint8Array {\n const ms = getTimestamp() - ReferenceDateInMS\n return new Uint8Array([...longToByteArray(ms), ...randomUint8Array(10)])\n}\n\nexport function suid(): string {\n return encode62(suidBytes(), 22)\n}\n\nexport function suidDate(id: string): Date {\n return suidBytesDate(decode62(id, 16))\n}\n\nexport function suidBytesDate(id: Uint8Array): Date {\n return new Date(\n ReferenceDateInMS +\n id.slice(0, 6).reduce((acc, byte) => {\n return acc * 256 + byte\n }, 0)\n )\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { Disposable, DisposerFunction } from \"../dispose-defer\"\nimport { getGlobalContext } from \"../global\"\nimport { Logger } from \"../log\"\nimport { promisify } from \"../promise\"\n\nconst log = Logger(\"zeed:emitter\")\n\nexport type EmitterHandler = (...objs: any[]) => void\nexport type EmitterAllHandler<T = string> = (key: T, ...objs: any[]) => void\n\n// For magic see https://www.npmjs.com/package/tiny-typed-emitter / License MIT\n// https://stackoverflow.com/a/61609010/140927\n// https://basarat.gitbook.io/typescript/main-1/typed-event\n// https://github.com/andywer/typed-emitter#extending-an-emitter\n\n// TODO: Allow symbols? https://github.com/sindresorhus/emittery\n\nexport declare type ListenerSignature<L> = {\n [E in keyof L]: (...args: any[]) => any\n}\n\nexport declare type DefaultListener = {\n [k: string]: (...args: any[]) => any\n}\n\nexport class Emitter<L extends ListenerSignature<L> = DefaultListener>\n implements Disposable\n{\n subscribers: any = {}\n subscribersOnAny: any[] = []\n\n call: L = new Proxy<L>({} as any, {\n get:\n (target: any, name: any) =>\n (...args: any): any =>\n this.emit(name, ...args),\n })\n\n public async emit<U extends keyof L>(\n event: U,\n ...args: Parameters<L[U]>\n ): Promise<boolean> {\n let ok = false\n try {\n let subscribers = (this.subscribers[event] || []) as EmitterHandler[]\n // log.debug(\"emit\", this?.constructor?.name, event, ...args, subscribers)\n\n this.subscribersOnAny.forEach((fn) => fn(event, ...args))\n\n if (subscribers.length > 0) {\n let all = subscribers.map((fn) => {\n try {\n return promisify(fn(...args))\n } catch (err) {\n log.warn(\"emit warning:\", err)\n }\n })\n ok = true\n await Promise.all(all)\n }\n } catch (err) {\n log.error(\"emit exception\", err)\n }\n return ok\n }\n\n public onAny(fn: EmitterHandler) {\n this.subscribersOnAny.push(fn)\n }\n\n public on<U extends keyof L>(event: U, listener: L[U]): DisposerFunction {\n let subscribers = (this.subscribers[event] || []) as EmitterHandler[]\n subscribers.push(listener)\n this.subscribers[event] = subscribers\n return () => {\n this.off(event, listener)\n }\n }\n\n public onCall(handlers: Partial<L>) {\n for (const [name, handler] of Object.entries(handlers)) {\n this.on(name as any, handler as any)\n }\n }\n\n public once<U extends keyof L>(event: U, listener: L[U]): DisposerFunction {\n const onceListener = async (...args: any[]) => {\n this.off(event, onceListener as any)\n return await promisify(listener(...args))\n }\n this.on(event, onceListener as any)\n return () => {\n this.off(event, listener)\n }\n }\n\n public off<U extends keyof L>(event: U, listener: L[U]): this {\n // log(\"off\", key)\n this.subscribers[event] = (this.subscribers[event] || []).filter(\n (f: any) => listener && f !== listener\n )\n return this\n }\n\n public removeAllListeners(event?: keyof L): this {\n this.subscribers = {}\n return this\n }\n\n dispose() {\n this.subscribers = {}\n this.subscribersOnAny = []\n }\n}\n\ndeclare global {\n interface ZeedGlobalContext {\n emitter?: Emitter\n }\n\n interface ZeedGlobalEmitter {}\n}\n\n/** Global emitter that will listen even across modules */\nexport function getGlobalEmitter(): Emitter<ZeedGlobalEmitter> {\n let emitter = getGlobalContext().emitter\n if (!emitter) {\n emitter = new Emitter()\n getGlobalContext().emitter = emitter\n }\n return emitter as any\n}\n\n// This can be used as a global messaging port to connect loose\n// parts of your app\nexport const messages = new Emitter()\n\n// For debugging\n\ninterface LazyEvent {\n key: string\n obj: any\n}\n\nexport function lazyListener(\n emitter: any,\n listenerKey?: string\n): (key?: string, skipUnmatched?: boolean) => Promise<any> {\n const name = Math.round(Math.random() * 100)\n\n var events: LazyEvent[] = []\n var lazyResolve: (() => void) | undefined\n\n const incoming = (key: string, obj: any) => {\n let ev = { key, obj }\n // debug(name, \" lazy push\", ev)\n events.push(ev)\n lazyResolve && lazyResolve()\n }\n\n if (listenerKey) {\n if (emitter.on) {\n emitter.on(listenerKey, (obj: any) => {\n incoming(listenerKey, obj)\n })\n } else if (emitter.addEventListener) {\n emitter.addEventListener(listenerKey, (obj: any) => {\n incoming(listenerKey, obj)\n })\n } else {\n log.error(name, \"Cannot listen to key\")\n }\n } else {\n if (emitter.onAny) {\n emitter.onAny((key: string, obj: any) => {\n incoming(key, obj)\n })\n } else {\n log.error(name, \"cannot listen to all for\", emitter)\n }\n }\n\n let on = (key?: string, skipUnmatched: boolean = true): Promise<any> => {\n return new Promise((resolve, reject) => {\n if (!key) {\n key = listenerKey\n if (!key) {\n if (events.length) {\n // no key specified? just take the first one!\n key = events[0].key\n }\n }\n }\n // debug(name, \"lazy resolve on2\", key, skipUnmatched, events)\n lazyResolve = () => {\n // debug(name, \"lazy resolve\", key, listenerKey, events)\n while (events.length > 0) {\n let ev = <LazyEvent>events.shift()\n // debug(name, \" lazy analyze\", ev)\n if (ev.key === key) {\n lazyResolve = undefined\n resolve(ev.obj)\n } else {\n if (skipUnmatched) {\n log.warn(name, `Unhandled event ${key} with value: ${ev.obj}`)\n continue\n }\n reject(`Expected ${key}, but found ${ev.key} with value=${ev.obj}`)\n log.error(name, `Unhandled event ${key} with value: ${ev.obj}`)\n }\n break\n }\n }\n lazyResolve()\n })\n }\n\n return on\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\n// import { Logger } from \"../log\"\nimport { uuid } from \"../uuid\"\nimport { Emitter } from \"./emitter\"\n\n// const log = Logger(\"zeed:channel\")\n\n/** See http://developer.mozilla.org/en-US/docs/Web/API/MessageEvent */\nexport interface ChannelMessageEvent {\n data: any\n origin?: string\n lastEventId?: string\n}\n\n/**\n * Inspired by\n * http://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel\n * https://deno.com/deploy/docs/runtime-broadcast-channel\n * */\nexport abstract class Channel extends Emitter<{\n message(event: ChannelMessageEvent): void\n messageerror(event: ChannelMessageEvent): void // optional\n connect(): void // optional\n disconnect(): void // optional\n close(): void\n}> {\n id: string = uuid()\n abstract isConnected?: boolean\n abstract postMessage(data: any): void\n close() {}\n}\n\n/** Very basic channel demonstrating local communication */\nexport class LocalChannel extends Channel {\n isConnected = true\n\n other?: LocalChannel\n\n postMessage(data: any) {\n this.other?.emit(\"message\", {\n data, // : cloneObject(data),\n origin: \"local\",\n lastEventId: uuid(),\n })\n }\n}\n\nexport function fakeWorkerPair(): [LocalChannel, LocalChannel] {\n let w1 = new LocalChannel()\n let w2 = new LocalChannel()\n\n w1.other = w2\n w2.other = w1\n\n return [w1, w2]\n}\n","import { encrypt, decrypt } from \"../crypto\"\nimport { jsonToUint8Array, Uint8ArrayToJson } from \"../data/bin\"\n\nexport interface Encoder {\n encode(data: any): Promise<Uint8Array>\n decode(data: Uint8Array): Promise<any>\n}\n\nexport class JsonEncoder implements Encoder {\n async encode(data: any): Promise<Uint8Array> {\n return jsonToUint8Array(data)\n }\n\n async decode(data: Uint8Array): Promise<any> {\n return Uint8ArrayToJson(data)\n }\n}\n\nexport class CryptoEncoder implements Encoder {\n key: CryptoKey\n\n constructor(key: CryptoKey) {\n this.key = key\n }\n\n async encode(data: any): Promise<Uint8Array> {\n const plain = jsonToUint8Array(data)\n return await encrypt(plain, this.key)\n }\n\n async decode(data: Uint8Array): Promise<any> {\n const plain = await decrypt(data, this.key)\n return Uint8ArrayToJson(plain)\n }\n}\n","import { valueToString } from \"../data/convert\"\nimport { Logger } from \"../log\"\nimport { tryTimeout, isPromise } from \"../promise\"\nimport { Json } from \"../types\"\nimport { uname, uuid } from \"../uuid\"\nimport { Channel } from \"./channel\"\nimport { Encoder, JsonEncoder } from \"./encoder\"\n\nexport type MessageAction = {\n name: string\n id: string\n args?: Json[]\n}\n\nexport type MessageResult = {\n id: string\n result?: Json\n error?: { stack?: string; name: string; message: string }\n}\n\nexport type Message = MessageAction | MessageResult\n\nexport type MessagesOptions = {\n timeout?: number\n}\n\nexport type MessagesDefaultMethods<L> = {\n dispose(): void\n connect?(channel: Channel): void\n options(opt: MessagesOptions): L\n}\n\nexport type MessagesMethods<L> = L & MessagesDefaultMethods<L>\n\n// export type MessageDefinitions = {\n// [key: string]: (...args: any) => Promise<any>\n// }\n\nexport type MessageDefinitions = Record<any, (...args: any) => Promise<any>>\n\nexport type MessageHub = {\n dispose(): void\n connect: (newChannel: Channel) => void\n listen<L extends MessageDefinitions>(newHandlers: L): void\n send<L extends MessageDefinitions>(): MessagesMethods<L>\n}\n\n// The async proxy, waiting for a response\nexport const createPromiseProxy = <P extends object>(\n fn: (name: string, args: any[], opt: any) => Promise<unknown>,\n opt: MessagesOptions,\n predefinedMethods: any = {}\n): P =>\n new Proxy<P>(predefinedMethods, {\n get: (target: any, name: any) => {\n if (name in target) return target[name]\n return (...args: any): any => fn(name, args, opt)\n },\n })\n\nexport function useMessageHub(\n opt: {\n name?: string\n channel?: Channel\n encoder?: Encoder\n retryAfter?: number\n ignoreUnhandled?: boolean\n debug?: boolean\n } = {}\n): MessageHub {\n let {\n name = uname(\"hub\"),\n encoder = new JsonEncoder(),\n retryAfter = 1000,\n ignoreUnhandled = true,\n } = opt\n\n const log = Logger(name)\n\n let handlers = {}\n let channel: Channel | undefined\n let queue: Message[] = []\n let queueRetryTimer: any\n let waitingForResponse: Record<string, [Function, Function]> = {}\n\n const dispose = () => {\n clearTimeout(queueRetryTimer)\n }\n\n const postNext = async () => {\n clearTimeout(queueRetryTimer)\n if (channel) {\n if (channel.isConnected) {\n while (queue.length) {\n let message = queue[0]\n try {\n channel.postMessage(await encoder.encode(message))\n queue.shift() // remove from queue when done\n } catch (err) {\n log.warn(\"postMessage\", err)\n break\n }\n }\n }\n if (queue.length > 0 && retryAfter > 0) {\n queueRetryTimer = setTimeout(postNext, retryAfter)\n }\n }\n }\n\n const postMessage = async (message: Message) => {\n log(\"enqueue postMessage\", message)\n queue.push(message)\n await postNext()\n }\n\n const connect = async (newChannel: Channel) => {\n channel = newChannel\n channel.on(\"connect\", postNext)\n channel.on(\"message\", async (msg: any) => {\n log(\"onmessage\", typeof msg)\n const { name, args, id, result, error } = await encoder.decode(msg.data)\n\n // Incoming new message\n if (name) {\n log(`name ${name} id ${id}`)\n try {\n // @ts-ignore\n if (handlers[name] == null) {\n throw new Error(`handler for ${name} was not found`)\n }\n // @ts-ignore\n let result = handlers[name](...args)\n if (isPromise(result)) result = await result\n log(`result ${result}`)\n if (id) {\n postMessage({ id, result })\n }\n } catch (error) {\n let err =\n error instanceof Error ? error : new Error(valueToString(error))\n log.warn(\"execution error\", err.name)\n postMessage({\n id,\n error: {\n message: err.message,\n stack: err.stack,\n name: err.name,\n },\n })\n }\n }\n\n // Incoming new response\n else if (id) {\n log(`response for id=${id}: result=${result}, error=${error}`)\n if (waitingForResponse[id] == null) {\n if (result === undefined) {\n log(`skip response for ${id}`)\n } else {\n log.warn(`no response hook for ${id}`)\n }\n } else {\n const [resolve, reject] = waitingForResponse[id]\n if (resolve && reject) {\n delete waitingForResponse[id]\n if (error) {\n let err = new Error(error.message)\n err.stack = error.stack\n err.name = error.name\n log.warn(\"reject\", err.name)\n reject(err)\n } else {\n log(\"resolve\", result)\n resolve(result)\n }\n }\n }\n }\n\n // Don't know what to do with it\n else if (!ignoreUnhandled) {\n log.warn(\"Unhandled message\", msg)\n }\n })\n\n postNext()\n }\n\n const fetchMessage = async (\n name: string,\n args: any[],\n opt: MessagesOptions = {}\n ): Promise<unknown> => {\n const { timeout = 5000 } = opt\n const id = uuid()\n postMessage({\n name,\n args,\n id,\n })\n return tryTimeout(\n new Promise(\n (resolve, reject) => (waitingForResponse[id] = [resolve, reject])\n ),\n timeout\n )\n }\n\n if (opt.channel) {\n connect(opt.channel)\n }\n\n return {\n dispose,\n connect,\n listen<L extends object>(newHandlers: L) {\n Object.assign(handlers, newHandlers)\n },\n send<L extends object>() {\n // The regular proxy without responding, just send\n return createPromiseProxy<L>(fetchMessage, {}, {\n options(perCallopt: MessagesOptions) {\n return createPromiseProxy<L>(fetchMessage, { ...perCallopt })\n },\n } as MessagesDefaultMethods<L>) as MessagesMethods<L>\n },\n }\n}\n","import { Logger } from \"../log\"\nimport { uname } from \"../uuid\"\nimport { Channel } from \"./channel\"\nimport { DefaultListener, Emitter, ListenerSignature } from \"./emitter\"\nimport { Encoder, JsonEncoder } from \"./encoder\"\n\ninterface PubSubConfig {\n channel: Channel\n encoder?: Encoder\n name?: string\n debug?: boolean\n}\n\nexport class PubSub<\n L extends ListenerSignature<L> = DefaultListener\n> extends Emitter<L> {\n name: string\n channel: Channel\n encoder: Encoder\n log: any\n debug: boolean\n\n get shortId() {\n return this.name.substr(0, 6)\n }\n\n constructor(opt: PubSubConfig) {\n super()\n\n let { name, encoder = new JsonEncoder(), channel, debug = false } = opt\n\n this.channel = channel\n this.encoder = encoder\n this.debug = debug\n\n this.name = name ?? this.channel.id ?? uname(\"pubsub\")\n this.log = Logger(`${this.shortId}`)\n\n if (this.debug) {\n this.channel.on(\"connect\", () => {\n this.log(\"channel connected\")\n })\n this.channel.on(\"disconnect\", () => {\n this.log(\"channel disconnected\")\n })\n }\n\n this.channel.on(\"message\", async ({ data }) => {\n let info = await this.encoder.decode(data)\n if (this.debug)\n this.log(`channel message, event=${info?.event}, info=`, info)\n else this.log(`channel message, event=${info?.event}`)\n if (info) {\n const { event, args } = info\n await this.emitSuper(event, ...args)\n }\n })\n }\n\n private async emitSuper<U extends keyof L>(\n event: U,\n ...args: Parameters<L[U]>\n ): Promise<boolean> {\n return await super.emit(event, ...args)\n }\n\n async emit<U extends keyof L>(\n event: U,\n ...args: Parameters<L[U]>\n ): Promise<boolean> {\n try {\n if (this.debug) this.log(`emit(${event})`, event)\n else this.log(`emit(${event})`, args.length)\n if (!this.channel.isConnected) {\n this.log.warn(\"channel not connected\")\n return false\n }\n const data = await this.encoder.encode({ event, args })\n this.channel.postMessage(data)\n return true\n } catch (err) {\n this.log.warn(`emit(${event})`, err)\n }\n return false\n }\n\n publish = this.emit\n subscribe = this.on\n}\n\nexport function usePubSub<L extends ListenerSignature<L> = DefaultListener>(\n opt: PubSubConfig\n) {\n return new PubSub<L>(opt)\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { isPromise } from \"./promise\"\n\nexport type Mutex = (fn: Function, elseFn?: Function) => boolean\nexport type AsyncMutex = (fn: Function, elseFn?: Function) => Promise<boolean>\n\nexport function useMutex(): Mutex {\n let token = true\n return (fn, elseFn) => {\n let executed = false\n if (token) {\n token = false\n try {\n fn()\n executed = true\n } finally {\n token = true\n }\n } else if (elseFn !== undefined) {\n elseFn()\n }\n return executed\n }\n}\n\nexport function useAsyncMutex(): AsyncMutex {\n let token = true\n return async (fn, elseFn) => {\n let executed = false\n if (token) {\n token = false\n try {\n let result = fn()\n if (isPromise(result)) await result\n executed = true\n } finally {\n token = true\n }\n } else if (elseFn !== undefined) {\n let result = elseFn()\n if (isPromise(result)) await result\n }\n return executed\n }\n}\n\n// export type Lock = ({lock: () => Promise<void>, unlock: () => void})\n\n// export function createLock() {\n// let lockCtr = []\n// return {\n// lock() {\n\n// },\n// unlock() {\n\n// }\n// }\n// }\n","import { Json } from \"./types\"\nimport { Logger } from \"./log\"\nimport { encodeQuery } from \"./data/url\"\n\nconst log = Logger(\"network\")\n\nconst defaultOptions = {\n cache: \"no-cache\",\n redirect: \"follow\",\n}\n\n// Source https://developer.mozilla.org/de/docs/Web/HTTP/Methods\nexport type httpMethod =\n | \"GET\"\n | \"POST\"\n | \"PUT\"\n | \"DELETE\"\n | \"HEAD\"\n | \"CONNECT\"\n | \"OPTIONS\"\n | \"TRACE\"\n | \"PATCH\"\n\nexport async function fetchBasic(\n url: string,\n fetchOptions: any = {},\n fetchFn: (input: RequestInfo, init?: RequestInit) => Promise<Response> = fetch\n): Promise<Response | undefined> {\n try {\n // if (fetchOptions.headers != null && !(fetchOptions.headers instanceof Headers)) {\n // fetchOptions.headers = new Headers(fetchOptions.headers)\n // }\n // log.log('fetch', url, fetchOptions)\n const response = await fetchFn(url, fetchOptions)\n\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status\n if (response.status < 400) {\n return response\n }\n try {\n log.warn(\n `Fetch of ${url} with ${fetchOptions} returned status=${response.status}`\n )\n log.warn(`Response: ${await response.text()}`)\n } catch (err) {\n log.error(\"Exception:\", err)\n }\n } catch (err) {\n log.error(\"fetchBasic\", err)\n }\n}\n\nexport async function fetchJson<T = Json>(\n url: string,\n opts: any = {},\n fetchFn: (input: RequestInfo, init?: RequestInit) => Promise<Response> = fetch\n): Promise<T | undefined> {\n try {\n let res = await fetchBasic(\n url,\n {\n method: \"GET\",\n ...defaultOptions,\n headers: {},\n ...opts,\n },\n fetchFn\n )\n if (res) {\n return await res.json()\n }\n } catch (err) {\n log.error(\"fetchJSON error:\", err)\n }\n}\n\nexport function fetchOptionsFormURLEncoded(\n data: Object,\n method: httpMethod = \"POST\"\n) {\n return {\n method,\n ...defaultOptions,\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded; charset=utf-8\",\n },\n body: encodeQuery(data),\n }\n}\n\nexport function fetchOptionsJson(data: Object, method: httpMethod = \"POST\") {\n return {\n method,\n ...defaultOptions,\n headers: {\n \"Content-Type\": \"application/json; charset=utf-8\",\n Accept: \"application/json\",\n },\n body: JSON.stringify(data),\n }\n}\n\nexport async function fetchText(\n url: string,\n opts: any = {},\n fetchFn: (input: RequestInfo, init?: RequestInit) => Promise<Response> = fetch\n): Promise<string | undefined> {\n try {\n let res = await fetchBasic(\n url,\n {\n method: \"GET\",\n ...defaultOptions,\n headers: {},\n ...opts,\n },\n fetchFn\n )\n if (res) {\n return await res.text()\n }\n } catch (err) {\n log.error(\"fetchHTML error:\", err)\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nexport function getWindow(): any | undefined {\n // @ts-ignore\n if (typeof window !== \"undefined\") return window\n}\n\nexport function getNavigator(): any | undefined {\n // @ts-ignore\n if (typeof navigator !== \"undefined\") return navigator\n}\n\nexport function getGlobal(): any {\n return getWindow() ??\n // @ts-ignore\n typeof WorkerGlobalScope !== \"undefined\"\n ? // @ts-ignore\n self\n : typeof global !== \"undefined\"\n ? global\n : Function(\"return this;\")()\n}\n\nconst _navigator = getNavigator()\nconst _window = getWindow()\n\nexport function detect(\n info = {\n ios: false,\n macos: false,\n windows: false,\n beaker: false,\n electron: false,\n wkwebview: false,\n pwa: false,\n pwaInstalled: false,\n browser: false,\n node: false,\n worker: false,\n jest: false,\n macosNative: false,\n iosNative: false,\n appleNative: false,\n touch: false,\n }\n) {\n info.ios = _navigator?.platform?.match(/(iPhone|iPod|iPad)/i) != null\n info.macos = !!_navigator?.platform?.startsWith(\"Mac\")\n info.windows = !!_navigator?.platform?.startsWith(\"Win\")\n\n // @ts-ignore\n info.beaker = _window?.[\"beaker\"] != null // https://github.com/beakerbrowser/beaker\n info.electron =\n (_navigator?.userAgent?.toLowerCase()?.indexOf(\" electron/\") || -1) > -1 &&\n !info.beaker\n // @ts-ignore\n info.wkwebview = _window?.webkit?.[\"messageHandlers\"] != null //Apple embedded\n\n info.pwa = _navigator?.serviceWorker != null\n\n info.pwaInstalled =\n // @ts-ignore\n _navigator?.standalone ||\n _window?.matchMedia?.(\"(display-mode: standalone)\")?.matches\n\n info.node =\n typeof process !== \"undefined\" && process?.release?.name === \"node\"\n info.browser = !info.electron && !info.wkwebview && !info.node\n\n // info.worker = typeof importScripts === 'function'\n // @ts-ignore\n info.worker =\n // @ts-ignore\n typeof WorkerGlobalScope !== \"undefined\" &&\n // @ts-ignore\n self instanceof WorkerGlobalScope\n // @ts-ignore\n info.jest = typeof jest !== \"undefined\"\n\n info.macosNative = info.wkwebview && info.macos\n info.iosNative = info.wkwebview && info.ios\n info.appleNative = info.wkwebview\n\n // https://github.com/viljamis/feature.js/blob/master/feature.js#L203\n // @ts-ignore\n info.touch =\n (_window && \"ontouchstart\" in _window) ||\n (_navigator?.maxTouchPoints || 0) > 1 ||\n // @ts-ignore\n (_navigator?.msPointerEnabled && _window?.MSGesture) ||\n // @ts-ignore\n (_window?.DocumentTouch && document instanceof DocumentTouch)\n\n return info\n}\n\n// https://stackoverflow.com/a/31090240/140927\n// export const isBrowser = new Function(\n// \"try {return this===window;}catch(e){ return false;}\"\n// )\n\n// export const isNode = new Function(\n// \"try {return this===global;}catch(e){return false;}\"\n// )\n\nexport const isBrowser = () =>\n typeof window !== \"undefined\" && globalThis === window\n\nexport const platform = detect()\n\n/**\n * Before closing the tab/window or quitting the node process\n * allow to do something important first\n */\nexport function useExitHandler(handler: () => void) {\n if (isBrowser()) {\n window.addEventListener(\"beforeunload\", handler)\n } else if (typeof process !== \"undefined\") {\n process.on(\"exit\", () => handler)\n }\n}\n","import { QueueTask } from \".\"\n\ninterface PoolConfig {\n maxParallel?: number\n}\n\ninterface PoolTask<T> {\n id: string\n priority: number\n task: QueueTask<T>\n running: boolean\n}\n\nexport function usePool<T = any>(config: PoolConfig = {}) {\n const { maxParallel = 3 } = config\n\n let currentParallel = 0\n let priority = 0\n let tasks: Record<string, PoolTask<T>> = {}\n\n function performNext() {\n if (currentParallel >= maxParallel) return\n let waitingTasks = Object.values(tasks).filter((t) => !t.running)\n if (waitingTasks.length > 0) {\n let taskInfo: PoolTask<T> | undefined\n for (let t of waitingTasks) {\n // fifo\n if (taskInfo == null || t.priority < taskInfo.priority) {\n taskInfo = t\n }\n }\n if (taskInfo) {\n taskInfo.running = true\n ++currentParallel\n taskInfo\n .task()\n .then((r) => {\n if (taskInfo?.id) delete tasks[taskInfo.id]\n --currentParallel\n performNext()\n })\n .catch((err) => {\n if (taskInfo?.id) delete tasks[taskInfo.id]\n --currentParallel\n performNext()\n })\n }\n }\n }\n\n function cancel(id: string) {\n let taskInfo = tasks[id]\n if (taskInfo && taskInfo.running !== true) {\n delete tasks[id]\n }\n }\n\n return {\n cancel,\n enqueue(id: string, task: QueueTask<T>) {\n if (tasks[id] == null) {\n tasks[id] = {\n id,\n task,\n priority: ++priority,\n running: false,\n }\n performNext()\n }\n return () => cancel(id)\n },\n }\n}\n\nexport type Pool = ReturnType<typeof usePool>\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\n// Can learn from here https://github.com/sindresorhus/p-queue\n\nimport { LoggerInterface, LogLevel } from \"../common/log-base\"\nimport { Logger } from \"../common/log\"\nimport { uname } from \"./uuid\"\n\nconst log = Logger(\"zeed:queue\")\n\ntype QueueTaskResolver = any\nexport type QueueTask<T = any> = () => Promise<T>\n\ninterface QueueTaskInfo {\n name: string\n task: QueueTask\n resolve: QueueTaskResolver\n}\n\n/** Guarentee serial execution of tasks. Able to wait, pause, resume and cancel all. */\nexport class SerialQueue {\n private queue: QueueTaskInfo[] = []\n\n private isPaused: boolean = false\n private waitToFinish: QueueTaskResolver[] = []\n\n private currentTask?: Promise<any>\n\n private log: LoggerInterface\n\n name: string\n\n constructor(opt: { name?: string; logLevel?: LogLevel } = {}) {\n const { name = uname(\"queue\"), logLevel } = opt\n\n this.name = name\n this.log = Logger(`zeed:queue:${name}`)\n this.log.level = logLevel ?? LogLevel.off\n }\n\n private async performNext() {\n this.log(`performNext, queue.length =`, this.queue.length)\n\n if (this.currentTask != null) {\n this.log(`performNext => skip while another task is running`)\n return\n }\n\n if (this.isPaused) {\n this.log(`performNext => skip while is paused`)\n return\n }\n\n while (this.currentTask == null && !this.isPaused) {\n let info = this.queue.shift()\n this.log(`performNext => ${info?.name}`)\n\n if (info == null) {\n break\n }\n\n const { name, task, resolve } = info\n this.currentTask = task()\n let result = undefined\n try {\n this.log.info(`start task ${name}`)\n result = await this.currentTask\n this.log(`finished task ${name} with result =`, result)\n } catch (err) {\n log.warn(\"Error performing task\", err)\n }\n\n resolve(result)\n this.currentTask = undefined\n }\n\n while (this.waitToFinish.length > 0) {\n this.waitToFinish.shift()()\n }\n }\n\n /** Enqueue task to be executed when all other tasks are done. Except `immediate = true`. */\n async enqueue<T>(\n task: QueueTask<T>,\n opt: { immediate?: boolean; name?: string } = {}\n ): Promise<T> {\n const { immediate = false, name = uname(this.name) } = opt\n if (immediate) {\n this.log.info(`immediate execution ${name}`)\n return await task()\n }\n this.log(`enqueue ${name}`)\n return new Promise((resolve) => {\n this.queue.push({\n name,\n task,\n resolve,\n })\n this.performNext()\n })\n }\n\n /** If a task is already performing, execute immediately. Otherwise enqueue as usual. */\n async enqueueReentrant<T>(\n task: QueueTask<T>,\n opt: { name?: string } = {}\n ): Promise<T> {\n return this.enqueue(task, {\n immediate: this.currentTask != null,\n name: opt.name,\n })\n }\n\n /** Remove all tasks from queue that are not yet executing. */\n async cancelAll(unblock = true) {\n this.log(`cancelAll`)\n let resolver = this.queue.map((task) => task.resolve)\n this.queue = []\n resolver.forEach((r) => r(undefined))\n await this.wait()\n }\n\n /** Pause execution after current task is finished. */\n async pause() {\n this.log(`pause`)\n this.isPaused = true\n await this.wait()\n }\n\n /** Resume paused queue. */\n resume() {\n this.log(`resume`)\n this.isPaused = false\n this.performNext()\n }\n\n /** Wait for all tasks to finish */\n async wait() {\n this.log(`wait`)\n if (\n this.currentTask == null &&\n (this.queue.length === 0 || this.isPaused)\n ) {\n return\n }\n return new Promise((resolve) => {\n this.waitToFinish.push(resolve)\n })\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { Json } from \"../types\"\nimport { Logger } from \"../log\"\nimport { ObjectStorage } from \"../types\"\nimport { cloneObject } from \"../data/utils\"\n\nconst log = Logger(\"zeed:memstorage\")\n\nexport interface MemStorageOptions {\n objectFromString?: (data: string) => any\n objectToString?: (data: any) => string\n}\n\nexport class MemStorage<T = Json> implements ObjectStorage<T> {\n private store: Record<string, T> = {}\n // private pretty: boolean = false\n // private objectFromString: (data: string) => any\n // private objectToString: (data: any) => string\n\n constructor(opt: MemStorageOptions = {}) {\n // this.objectToString =\n // opt.objectToString ??\n // ((data: any): string => {\n // return this.pretty\n // ? JSON.stringify(data, null, 2)\n // : JSON.stringify(data)\n // })\n // this.objectFromString =\n // opt.objectFromString ??\n // ((data: string) => {\n // try {\n // return JSON.parse(data)\n // } catch (err) {\n // log.warn(`MemStorage parse error '${err}' in`, data)\n // }\n // })\n }\n\n setItem(key: string, value: T): void {\n // const data = this.objectToString(value)\n this.store[key] = cloneObject(value)\n }\n\n getItem(key: string): T | undefined {\n if (this.store.hasOwnProperty(key)) {\n return cloneObject(this.store[key])\n }\n }\n\n removeItem(key: string): void {\n delete this.store[key]\n }\n\n clear(): void {\n this.store = {}\n }\n\n allKeys(): string[] {\n return Object.keys(this.store)\n }\n}\n","// General explaination https://css-tricks.com/debouncing-throttling-explained-examples/\n// From https://github.com/cowboy/jquery-throttle-debounce\n// And https://github.com/wuct/raf-throttle/blob/master/rafThrottle.js\n\nimport { Logger } from \"./log\"\n\nconst DEBUG = false\nconst log = DEBUG ? Logger(\"zeed:throttle\") : () => {}\n\ninterface ThrottleOptions {\n delay?: number\n trailing?: boolean\n leading?: boolean\n}\n\ntype ThrottleFunction = Function & { cancel: () => void; dispose: () => void }\n\ninterface DebounceOptions {\n delay?: number\n}\n\ntype DebounceFunction = ThrottleFunction\n\n/**\n * A special throttle implementation that tries to distribute execution\n * in an optimal way.\n *\n * For UI usage the function is executed on first occasion (`leading`).\n * If more calls follow it will again be executed at end (`trailing`).\n * If the next call is inside the timeframe, it is delayed until `trailing`.\n * This avoids timewise too close calls.\n * It is possible to `cancel` the timeout and to `flush` a call, e.g. if\n * leaving UI situation where a final call is required to write data or similar.\n */\nexport function throttle(\n callback: Function,\n opt: ThrottleOptions = {}\n): ThrottleFunction {\n const { delay = 100, trailing = true, leading = true } = opt\n\n let timeoutID: any = 0\n let checkpoint = 0\n let visited = 0\n\n let debugCheckpoint = Date.now()\n\n function clearExistingTimeout() {\n if (timeoutID) {\n clearTimeout(timeoutID)\n timeoutID = undefined\n }\n }\n\n function wrapper(this: any, ...arguments_: any[]) {\n const now = Date.now()\n let self = this\n let elapsed = now - checkpoint\n\n function debugElapsed() {\n const dnow = Date.now()\n return `total ${(dnow - debugCheckpoint).toFixed(1)}ms - elapsed ${(\n dnow - checkpoint\n ).toFixed(1)}ms - visited ${visited}x`\n }\n\n function exec() {\n visited = 0\n checkpoint = Date.now()\n callback.apply(self, arguments_)\n }\n\n // Make sure enough time has passed since last call\n if (elapsed > delay || !timeoutID) {\n DEBUG && log(\"elapsed\", debugElapsed())\n\n // Leading execute once immediately\n if (leading) {\n if (elapsed > delay) {\n DEBUG && log(\"🚀 leading\", debugElapsed())\n exec()\n } else {\n ++visited // at least trigger trailing this way\n }\n }\n\n const timeout = elapsed > delay ? delay : delay - elapsed\n log(`⏱ start timeout with ${timeout.toFixed(1)}ms}`, debugElapsed())\n\n // Prepare for next round\n clearExistingTimeout()\n checkpoint = now\n\n // Delay. We should not get here if timeout has not been reached before\n timeoutID = setTimeout(() => {\n DEBUG && log(\"⏱ reached timeout\", debugElapsed())\n timeoutID = 0\n // Only execute on trailing or when visited again, but do not twice if leading\n if (trailing && (!leading || visited > 0)) {\n DEBUG && log(\"🚀 trailing\", debugElapsed())\n exec()\n }\n }, timeout)\n } else {\n // Count visits\n ++visited\n DEBUG && log(\"visited\", debugElapsed())\n }\n }\n\n wrapper.cancel = clearExistingTimeout\n wrapper.dispose = clearExistingTimeout\n\n // wrapper.flush = () => throw 'todo'\n\n return wrapper\n}\n\n/**\n * Debounce fits best for filtering a large peak of events.\n * For UI event filtering throttle is probably a better choice.\n */\nexport function debounce(\n callback: Function,\n opt: DebounceOptions = {}\n): DebounceFunction {\n const { delay = 100 } = opt\n let timeoutID: any = 0\n\n function clearExistingTimeout() {\n if (timeoutID) {\n clearTimeout(timeoutID)\n timeoutID = 0\n }\n }\n\n function wrapper(this: any, ...arguments_: any[]) {\n let self = this\n clearExistingTimeout()\n timeoutID = setTimeout(() => {\n timeoutID = 0\n callback.apply(self, arguments_)\n }, delay)\n }\n\n wrapper.cancel = clearExistingTimeout\n wrapper.dispose = clearExistingTimeout\n return wrapper\n}\n","// https://nodejs.org/api/webcrypto.html\nimport nodeCrypto from \"crypto\"\n\nexport {}\n\ndeclare module NodeJS {\n interface Global {\n crypto: Crypto\n }\n}\n\ntry {\n if (\n nodeCrypto &&\n nodeCrypto.webcrypto &&\n typeof globalThis !== \"undefined\" &&\n typeof globalThis.crypto === \"undefined\"\n ) {\n // @ts-ignore\n globalThis.crypto = nodeCrypto.webcrypto\n }\n} catch (err) {\n console.warn(\"Failed to polyfill webcrypto\", err)\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\n// Adopted from https://github.com/motdotla/dotenv BSD-2\n\nimport { LogLevel } from \"../common/log-base\"\nimport { Logger } from \"../common/log\"\n\nimport fs from \"fs\"\nimport { resolve } from \"path\"\n\nconst log = Logger(\"zeed:env\")\n\nconst NEWLINE = \"\\n\"\nconst RE_INI_KEY_VAL = /^\\s*([\\w_.-]+)\\s*=\\s*(.*)?\\s*$/\nconst RE_NEWLINES = /\\\\n/g\nconst NEWLINES_MATCH = /\\n|\\r|\\r\\n/\n\ntype csvOptions = {\n /** @deprecated will probably be replaced by logLevel */\n debug?: boolean\n path?: string\n filename?: string\n encoding?: BufferEncoding\n prefix?: string\n env?: Record<string, string>\n}\n\n// Parses src into an Object\nfunction parse(src: string, options: csvOptions = {}) {\n let obj: Record<string, string> = {}\n\n // convert Buffers before splitting into lines and processing\n src\n .toString()\n .split(NEWLINES_MATCH)\n .forEach(function (line, idx) {\n // matching \"KEY' and 'VAL' in 'KEY=VAL'\n const keyValueArr = line.match(RE_INI_KEY_VAL)\n // matched?\n\n // log.debug(\"keyValueArr\", keyValueArr)\n\n if (keyValueArr != null) {\n const key = keyValueArr[1]\n // default undefined or missing values to empty string\n let val = keyValueArr[2] || \"\"\n const end = val.length - 1\n const isDoubleQuoted = val[0] === '\"' && val[end] === '\"'\n const isSingleQuoted = val[0] === \"'\" && val[end] === \"'\"\n\n // if single or double quoted, remove quotes\n if (isSingleQuoted || isDoubleQuoted) {\n val = val.substring(1, end)\n\n // if double quoted, expand newlines\n if (isDoubleQuoted) {\n val = val.replace(RE_NEWLINES, NEWLINE)\n }\n } else {\n // remove surrounding whitespace\n val = val.trim()\n }\n obj[key] = val\n } else {\n log.debug(\n `did not match key and value when parsing line ${idx + 1}: ${line}`\n )\n }\n })\n\n // log.debug(\"obj\", obj)\n return obj\n}\n\n/**\n * Return a path relative to the current working directory\n */\nexport function stringToPath(\n value?: string,\n defaultValue: string = \".\"\n): string {\n return resolve(process.cwd(), value ?? defaultValue)\n}\n\nexport function valueToPath(value?: any, defaultValue = \"\"): string {\n if (value == null) value = defaultValue\n return stringToPath(String(value).trim(), defaultValue)\n}\n\nexport const toPath = valueToPath\n\n// Populates process.env from .env file\nexport function setupEnv(options: csvOptions = {}) {\n const dotenvPath: string =\n options?.path ?? toPath(options?.filename ?? \".env\")\n const encoding: BufferEncoding = options?.encoding ?? \"utf8\"\n const debug = options?.debug || false\n\n if (debug !== true) log.level = LogLevel.off\n\n try {\n // specifying an encoding returns a string instead of a buffer\n const parsedEnv = fs.existsSync(dotenvPath)\n ? parse(fs.readFileSync(dotenvPath, { encoding }), { debug })\n : {}\n const parsedEnvLocal = fs.existsSync(dotenvPath + \".local\")\n ? parse(fs.readFileSync(dotenvPath + \".local\", { encoding }), { debug })\n : {}\n\n const parsed: Record<string, string> = Object.assign(\n {},\n parsedEnv,\n parsedEnvLocal\n )\n let env = options?.env ?? process.env\n\n Object.entries(parsed).forEach(([key, value]) => {\n if (typeof options?.prefix === \"string\") {\n key = options?.prefix + key\n }\n if (!Object.prototype.hasOwnProperty.call(env, key)) {\n if (value != null) {\n log.info(`set env.${key} = ${value}`)\n env[key] = value\n }\n } else {\n log.debug(`\"${key}\" is already defined and will not be overwritten`)\n }\n })\n return { parsed }\n } catch (e) {\n log.error(e)\n return { error: e }\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport {\n mkdirSync,\n readdirSync,\n readFileSync,\n rmSync,\n unlinkSync,\n writeFileSync,\n} from \"fs\"\nimport { dirname, resolve } from \"path\"\nimport { toValidFilename } from \"../common/data/path\"\nimport { cloneObject } from \"../common/data/utils\"\nimport { Logger } from \"../common/log\"\nimport { Json, ObjectStorage } from \"../common/types\"\n\nconst log = Logger(\"zeed:filestorage\")\n\nexport interface FileStorageOptions {\n pretty?: boolean\n path?: string\n extension?: string\n objectFromString?: (data: string) => any\n objectToString?: (data: any) => string\n keyToFilename?: (key: string) => string\n}\n\nexport class FileStorage<T = Json> implements ObjectStorage<T> {\n private store: Record<string, T | null> = {}\n private dirname: string\n private fileKeys?: string[] = undefined\n private pretty: boolean = false\n private extension: string\n private extensionLength: number\n private objectFromString: (data: string) => any\n private objectToString: (data: any) => string\n private keyToFilename: (key: string) => string\n\n constructor(opt: FileStorageOptions = {}) {\n this.dirname = resolve(process.cwd(), opt.path || \".fileStorage\")\n this.pretty = !!opt.pretty\n this.extension = opt.extension ?? \".json\"\n\n if (opt.extension && !this.extension.startsWith(\".\")) {\n this.extension = \".\" + this.extension\n }\n this.extensionLength = this.extension.length\n\n this.objectToString =\n opt.objectToString ??\n ((data: any): string => {\n return this.pretty\n ? JSON.stringify(data, null, 2)\n : JSON.stringify(data)\n })\n\n this.objectFromString =\n opt.objectFromString ??\n ((data: string) => {\n try {\n return JSON.parse(data)\n } catch (err) {\n log.warn(`fileStorage parse error '${err}' in`, data)\n }\n })\n\n this.keyToFilename = opt.keyToFilename ?? toValidFilename\n }\n\n setItem(key: string, value: T): void {\n this.store[key] = cloneObject(value)\n try {\n const data = this.objectToString(value)\n const path = this.getPath(key)\n mkdirSync(dirname(path), { recursive: true })\n writeFileSync(path, data, \"utf8\")\n } catch (err) {\n log.error(\"setItem error\", err)\n }\n }\n\n getPath(key: string): string {\n return resolve(this.dirname, this.keyToFilename(key) + this.extension)\n }\n\n getBuffer(key: string): Buffer {\n const path = this.getPath(key)\n return Buffer.from(readFileSync(path))\n }\n\n getItem(key: string): T | undefined {\n let value = this.store[key]\n\n // null is an indicator for not existing!\n if (value === null) return\n\n if (value != null) {\n return cloneObject(value) // this.objectFromString(value)\n }\n\n try {\n const path = this.getPath(key)\n const data = readFileSync(path, \"utf8\")\n if (data != null) {\n const value = this.objectFromString(data)\n this.store[key] = value\n return value\n }\n } catch (err) {\n log.warn(\"getItem error\", err)\n this.store[key] = null // do not retry next time\n }\n }\n\n removeItem(key: string): void {\n delete this.store[key]\n if (this.fileKeys != null) {\n const index: number = this.fileKeys.indexOf(key)\n if (index !== -1) {\n this.fileKeys.splice(index, 1)\n }\n }\n try {\n const path = this.getPath(key)\n unlinkSync(path)\n } catch (err) {}\n }\n\n clear(): void {\n this.fileKeys = []\n this.store = {}\n rmSync(this.dirname, { recursive: true, force: true })\n }\n\n allKeys(): string[] {\n if (this.fileKeys == null) {\n try {\n this.fileKeys =\n readdirSync(this.dirname, { withFileTypes: true })\n .filter(\n (item) =>\n !item.isDirectory() && item.name.endsWith(this.extension)\n )\n .map((item) => item.name.slice(0, -this.extensionLength)) || []\n } catch (err) {}\n }\n let keys = [...(this.fileKeys || [])]\n for (let key of Object.keys(this.store)) {\n if (!keys.includes(key)) {\n keys.push(key)\n }\n }\n keys.sort()\n return keys\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { createWriteStream, mkdirSync } from \"fs\"\nimport { dirname, resolve } from \"path\"\nimport { renderMessages } from \"../common/data/convert\"\nimport { LogHandlerOptions, LogLevel, LogMessage } from \"../common/log-base\"\nimport { useLevelFilter, useNamespaceFilter } from \"../common/log-filter\"\n\nlet namespaces: Record<string, any> = {}\n\nexport function LoggerFileHandler(path: string, opt: LogHandlerOptions = {}) {\n const { level = LogLevel.all, filter = \"*\" } = opt\n path = resolve(process.cwd(), path)\n mkdirSync(dirname(path), { recursive: true })\n var stream = createWriteStream(path, { flags: \"a\" })\n // stream.end()\n const matchesNamespace = useNamespaceFilter(filter)\n const matchesLevel = useLevelFilter(level)\n return (msg: LogMessage) => {\n if (!matchesLevel(msg.level)) return\n if (!matchesNamespace(msg.name)) return\n\n const time = new Date().toISOString()\n let name = msg.name || \"\"\n let ninfo = namespaces[name || \"\"]\n if (ninfo == null) {\n namespaces[name] = ninfo\n }\n\n let args: string[] = [\n `[${name || \"*\"}]`,\n renderMessages(msg.messages, { pretty: false }),\n ]\n\n function write(...args: string[]): void {\n stream.write(args.join(\"\\t\") + \"\\n\")\n }\n\n switch (msg.level) {\n case LogLevel.info:\n write(time, `I|* `, ...args)\n break\n case LogLevel.warn:\n write(time, `W|** `, ...args)\n break\n case LogLevel.error:\n write(time, `E|***`, ...args)\n break\n default:\n write(time, `D| `, ...args)\n break\n }\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport tty from \"tty\"\nimport { renderMessages } from \"../common/data/convert\"\nimport {\n LogHandler,\n LogHandlerOptions,\n LogLevel,\n LogMessage,\n} from \"../common/log-base\"\nimport { useLevelFilter, useNamespaceFilter } from \"../common/log-filter\"\nimport {\n getSourceLocation,\n getSourceLocationByPrecedingPattern,\n getStack,\n} from \"./log-util\"\nimport { formatMilliseconds, getTimestamp } from \"../common/time\"\n\nexport function isTTY(): boolean {\n try {\n return tty.isatty(process.stdout.fd)\n } catch (err) {}\n return false\n}\n\nconst colors = [6, 2, 3, 4, 5, 1]\n\nfunction selectColor(namespace: string) {\n let hash = 0\n for (let i = 0; i < namespace.length; i++) {\n hash = (hash << 5) - hash + namespace.charCodeAt(i)\n hash |= 0 // Convert to 32bit integer\n }\n return colors[Math.abs(hash) % colors.length]\n}\n\nlet namespaces: Record<string, any> = {}\n\nlet time = getTimestamp()\n\nconst useColors = tty.isatty(process.stderr.fd)\n\nfunction log(...args: any[]) {\n return process.stderr.write(renderMessages(args) + \"\\n\")\n}\n\n// export const BOLD = Symbol()\n// export const UNBOLD = Symbol()\n// export const BLUE = Symbol()\n// export const GREY = Symbol()\n// export const GREEN = Symbol()\n// export const RED = Symbol()\n// export const PURPLE = Symbol()\n// export const ORANGE = Symbol()\n// export const UNCOLOR = Symbol()\n\n// const _browserStyleMap = {\n// [BOLD]: pair.create(\"font-weight\", \"bold\"),\n// [UNBOLD]: pair.create(\"font-weight\", \"normal\"),\n// [BLUE]: pair.create(\"color\", \"blue\"),\n// [GREEN]: pair.create(\"color\", \"green\"),\n// [GREY]: pair.create(\"color\", \"grey\"),\n// [RED]: pair.create(\"color\", \"red\"),\n// [PURPLE]: pair.create(\"color\", \"purple\"),\n// [ORANGE]: pair.create(\"color\", \"orange\"), // not well supported in chrome when debugging node with inspector - TODO: deprecate\n// [UNCOLOR]: pair.create(\"color\", \"black\"),\n// }\n\nconst TTY_STYLE = {\n BOLD: \"\\u001b[1m\",\n UNBOLD: \"\\u001b[2m\",\n RED: \"\\u001b[31m\",\n GREEN: \"\\u001b[32m\",\n BLUE: \"\\u001b[34m\",\n PURPLE: \"\\u001b[35m\",\n GRAY: \"\\u001b[37m\",\n ORANGE: \"\\u001b[38;5;208m\",\n UNCOLOR: \"\\u001b[0m\",\n}\n\nenum COLOR {\n RED = 1,\n GREEN = 2,\n BLUE = 4,\n PURPLE = 5,\n GRAY = 7,\n ORANGE = 8,\n}\n\nconst colorEnd = \"\\u001B[0m\"\n\nexport function colorString(value: string, colorCode: number) {\n const colorStart =\n colorCode === COLOR.ORANGE\n ? TTY_STYLE.ORANGE\n : \"\\u001B[3\" + (colorCode < 8 ? colorCode : \"8;5;\" + colorCode) + \"m\"\n return `${colorStart}${value}${colorEnd}`\n}\n\nexport function colorStringList(\n list: Array<any>,\n style: string,\n bold: boolean = true\n) {\n return list.map((value) => {\n if (typeof value !== \"string\") return value\n let start = style\n let end = colorEnd\n if (bold) {\n start = `${TTY_STYLE.BOLD}${start}`\n end = `${end}${TTY_STYLE.BOLD}`\n }\n return `${start}${value}${end}`\n })\n}\n\nexport const loggerStackTraceDebug =\n \"loggerStackTraceDebug-7d38e5a9214b58d29734374cdb9521fd964d7485\"\n\nexport function LoggerNodeHandler(opt: LogHandlerOptions = {}): LogHandler {\n const {\n level = undefined,\n filter = undefined,\n colors = isTTY(),\n levelHelper = true,\n nameBrackets = true,\n padding = 0,\n fill = 0,\n stack = true,\n } = opt\n const matchesNamespace = useNamespaceFilter(filter)\n const matchesLevel = useLevelFilter(level)\n return (msg: LogMessage) => {\n if (!matchesLevel(msg.level)) return\n if (!matchesNamespace(msg.name)) return\n const timeNow = getTimestamp()\n let name = msg.name || \"\"\n let ninfo = namespaces[name || \"\"]\n if (ninfo == null) {\n ninfo = {\n color: selectColor(name),\n // time: timeNow\n }\n namespaces[name] = ninfo\n }\n const diff = formatMilliseconds(timeNow - time)\n\n let args: string[]\n\n let displayName = nameBrackets ? `[${name}]` : name\n\n if (padding > 0) {\n displayName = displayName.padStart(padding, \" \")\n }\n\n if (fill > 0) {\n displayName = displayName.padEnd(fill, \" \")\n }\n\n if (colors && useColors) {\n const c = ninfo.color\n args = [colorString(displayName, c) + ` | `] // nameBrackets ? [`%c[${name}]`] : [`%c${name}`]\n if (msg.level === LogLevel.warn) {\n args.push(...colorStringList(msg.messages, TTY_STYLE.ORANGE))\n } else if (msg.level === LogLevel.error) {\n args.push(...colorStringList(msg.messages, TTY_STYLE.RED))\n } else {\n args.push(...msg.messages)\n }\n args.push(colorString(`+${diff}`, c))\n } else {\n args = [displayName, ...msg.messages]\n args.push(`+${diff}`)\n }\n\n if (msg.messages?.[0] === loggerStackTraceDebug) {\n console.log(getStack())\n }\n\n if (stack) {\n let line: string = \"\"\n if (typeof stack === \"boolean\") {\n line = getSourceLocationByPrecedingPattern(\n [\"at Function.\", \"at null.log (\", \"at log (\"],\n true\n )\n if (!line) {\n line = getSourceLocation(0, true)\n }\n } else {\n const depth = typeof stack === \"number\" ? stack : 3\n line = getSourceLocation(depth, true)\n }\n if (line) {\n args.push(colorString(`(${line})`, COLOR.GRAY))\n }\n }\n switch (msg.level) {\n case LogLevel.info:\n if (levelHelper) args[0] = `I|* ` + args[0]\n log(...args)\n break\n case LogLevel.warn:\n if (levelHelper)\n args[0] =\n (colors && useColors\n ? colorString(`W|** `, COLOR.ORANGE)\n : `W|** `) + args[0]\n log(...args)\n break\n case LogLevel.error:\n if (levelHelper)\n args[0] =\n (colors && useColors\n ? colorString(`E|*** `, COLOR.RED)\n : `E|*** `) + args[0]\n log(...args)\n break\n default:\n if (levelHelper) args[0] = `D| ` + args[0]\n log(...args)\n break\n }\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { resolve } from \"path\"\n\nexport function getStackLlocationList(stack: string): any[] {\n if (typeof stack !== \"string\") return []\n // console.log(\"stack\", stack)\n return (\n stack\n ?.split(\"\\n\")\n ?.map((rawLine) => {\n let m = rawLine.match(/^\\s+at.*(\\((.*)\\)|file:\\/\\/(.*)$)/)\n if (m) {\n let line = m[3] || m[2]\n if (line.endsWith(\")\")) line = line.slice(0, -1)\n return line\n }\n })\n ?.filter((v) => v != null) || []\n )\n}\n\nconst cwd = resolve(process.cwd())\nconst home = process.env?.HOME ? resolve(process.env?.HOME) : \"\"\n// console.log(`cwd = ${cwd}, home = ${home}}`)\n\nfunction pathStripCwd(path: string) {\n // console.log(\">\", path)\n\n if (path.includes(\"/node_modules/\")) {\n return \"\"\n }\n\n const fileURL = \"file://\"\n if (path.startsWith(fileURL)) {\n return path.substr(fileURL.length)\n }\n\n if (cwd && path.startsWith(cwd)) {\n return path.substr(cwd.length + 1)\n }\n\n if (home && path.startsWith(home)) {\n path = \"~/\" + path.substr(home.length + 1)\n }\n\n return path\n}\n\nfunction extractFileInfo(stackLine: string): string {\n let m = stackLine.match(/^\\s*at.*(\\((.*)\\)|file:\\/\\/(.*)$)/)\n if (m) {\n let line = m[3] || m[2]\n if (line.endsWith(\")\")) line = line.slice(0, -1)\n return line\n }\n return \"\"\n}\n\n/**\n * Get the source code location of the caller\n * https://stackoverflow.com/a/47296370/140927\n *\n * @param level Number of levels to go down the stack trace\n * @param stripCwd Strip the current working directory, only reasonable for Node.js environment\n * @returns\n */\nexport function getSourceLocation(level = 2, stripCwd = true): string {\n let stack = new Error().stack || \"\"\n let line: string | undefined = getStackLlocationList(stack)?.[level]\n if (line && stripCwd) {\n line = pathStripCwd(line)\n }\n return line || \"\"\n}\n\nexport function getStack(): string {\n return new Error().stack || \"\"\n}\n\nexport function getSourceLocationByPrecedingPattern(\n patterns: string[],\n stripCwd = true\n) {\n let line = \"\"\n let stack = new Error().stack || \"\"\n if (typeof stack === \"string\") {\n const lines = stack.split(\"\\n\").map((l) => l.trim())\n // console.log(lines)\n const index = lines.findIndex((l) => patterns.some((p) => l.startsWith(p)))\n line = lines[index + 1]\n if (line) {\n line = extractFileInfo(line)\n }\n if (line && stripCwd) {\n line = pathStripCwd(line)\n }\n }\n return line\n}\n","import { Logger } from \"../common/log\"\nimport { toPath } from \"./env\"\nimport { LoggerFileHandler } from \"./log-file\"\nimport { LoggerNodeHandler } from \"./log-node\"\n\nfunction setupLogContextNode() {\n let handlers = [\n LoggerNodeHandler({\n padding: 32,\n nameBrackets: false,\n // levelHelper: false,\n }),\n ]\n\n let logFilePath = process.env.ZEED_LOG ?? process.env.LOG\n if (logFilePath) {\n handlers.unshift(LoggerFileHandler(toPath(logFilePath)))\n }\n\n Logger.setHandlers(handlers)\n}\n\nsetupLogContextNode()\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { Logger } from \"../common/log\"\n\nconst { error } = Logger(\"zeed:base64\")\n\nexport function urlBase64ToUint8Array(\n base64String: string\n): Uint8Array | undefined {\n try {\n let padding = \"=\".repeat((4 - (base64String.length % 4)) % 4)\n let base64 = (base64String + padding).replace(/-/g, \"+\").replace(/_/g, \"/\")\n\n let rawData = window.atob(base64)\n let outputArray = new Uint8Array(rawData.length)\n\n for (let i = 0; i < rawData.length; ++i) {\n outputArray[i] = rawData.charCodeAt(i)\n }\n return outputArray\n } catch (err) {\n error(err, base64String)\n }\n}\n","// MIT licensed\n// https://github.com/mazondo/gravatarjs/blob/master/gravatar.js\n// https://en.gravatar.com/site/implement/images/\n\nimport { Logger } from \"../common/log\"\n\nconst log = Logger(\"zeed:gravatar\")\n\nfunction gravatar(\n email: string,\n options: { size?: any; backup?: any; secure?: any; rating?: any }\n) {\n // using md5() from here: http://www.myersdaily.org/joseph/javascript/md5-text.html\n function md5cycle(e: any[], t: any[]) {\n var n = e[0],\n r = e[1],\n i = e[2],\n s = e[3]\n n = ff(n, r, i, s, t[0], 7, -680876936)\n s = ff(s, n, r, i, t[1], 12, -389564586)\n i = ff(i, s, n, r, t[2], 17, 606105819)\n r = ff(r, i, s, n, t[3], 22, -1044525330)\n n = ff(n, r, i, s, t[4], 7, -176418897)\n s = ff(s, n, r, i, t[5], 12, 1200080426)\n i = ff(i, s, n, r, t[6], 17, -1473231341)\n r = ff(r, i, s, n, t[7], 22, -45705983)\n n = ff(n, r, i, s, t[8], 7, 1770035416)\n s = ff(s, n, r, i, t[9], 12, -1958414417)\n i = ff(i, s, n, r, t[10], 17, -42063)\n r = ff(r, i, s, n, t[11], 22, -1990404162)\n n = ff(n, r, i, s, t[12], 7, 1804603682)\n s = ff(s, n, r, i, t[13], 12, -40341101)\n i = ff(i, s, n, r, t[14], 17, -1502002290)\n r = ff(r, i, s, n, t[15], 22, 1236535329)\n n = gg(n, r, i, s, t[1], 5, -165796510)\n s = gg(s, n, r, i, t[6], 9, -1069501632)\n i = gg(i, s, n, r, t[11], 14, 643717713)\n r = gg(r, i, s, n, t[0], 20, -373897302)\n n = gg(n, r, i, s, t[5], 5, -701558691)\n s = gg(s, n, r, i, t[10], 9, 38016083)\n i = gg(i, s, n, r, t[15], 14, -660478335)\n r = gg(r, i, s, n, t[4], 20, -405537848)\n n = gg(n, r, i, s, t[9], 5, 568446438)\n s = gg(s, n, r, i, t[14], 9, -1019803690)\n i = gg(i, s, n, r, t[3], 14, -187363961)\n r = gg(r, i, s, n, t[8], 20, 1163531501)\n n = gg(n, r, i, s, t[13], 5, -1444681467)\n s = gg(s, n, r, i, t[2], 9, -51403784)\n i = gg(i, s, n, r, t[7], 14, 1735328473)\n r = gg(r, i, s, n, t[12], 20, -1926607734)\n n = hh(n, r, i, s, t[5], 4, -378558)\n s = hh(s, n, r, i, t[8], 11, -2022574463)\n i = hh(i, s, n, r, t[11], 16, 1839030562)\n r = hh(r, i, s, n, t[14], 23, -35309556)\n n = hh(n, r, i, s, t[1], 4, -1530992060)\n s = hh(s, n, r, i, t[4], 11, 1272893353)\n i = hh(i, s, n, r, t[7], 16, -155497632)\n r = hh(r, i, s, n, t[10], 23, -1094730640)\n n = hh(n, r, i, s, t[13], 4, 681279174)\n s = hh(s, n, r, i, t[0], 11, -358537222)\n i = hh(i, s, n, r, t[3], 16, -722521979)\n r = hh(r, i, s, n, t[6], 23, 76029189)\n n = hh(n, r, i, s, t[9], 4, -640364487)\n s = hh(s, n, r, i, t[12], 11, -421815835)\n i = hh(i, s, n, r, t[15], 16, 530742520)\n r = hh(r, i, s, n, t[2], 23, -995338651)\n n = ii(n, r, i, s, t[0], 6, -198630844)\n s = ii(s, n, r, i, t[7], 10, 1126891415)\n i = ii(i, s, n, r, t[14], 15, -1416354905)\n r = ii(r, i, s, n, t[5], 21, -57434055)\n n = ii(n, r, i, s, t[12], 6, 1700485571)\n s = ii(s, n, r, i, t[3], 10, -1894986606)\n i = ii(i, s, n, r, t[10], 15, -1051523)\n r = ii(r, i, s, n, t[1], 21, -2054922799)\n n = ii(n, r, i, s, t[8], 6, 1873313359)\n s = ii(s, n, r, i, t[15], 10, -30611744)\n i = ii(i, s, n, r, t[6], 15, -1560198380)\n r = ii(r, i, s, n, t[13], 21, 1309151649)\n n = ii(n, r, i, s, t[4], 6, -145523070)\n s = ii(s, n, r, i, t[11], 10, -1120210379)\n i = ii(i, s, n, r, t[2], 15, 718787259)\n r = ii(r, i, s, n, t[9], 21, -343485551)\n e[0] = add32(n, e[0])\n e[1] = add32(r, e[1])\n e[2] = add32(i, e[2])\n e[3] = add32(s, e[3])\n }\n function cmn(e: number, t: number, n: any, r: any, i: number, s: any) {\n t = add32(add32(t, e), add32(r, s))\n return add32((t << i) | (t >>> (32 - i)), n)\n }\n function ff(\n e: any,\n t: number,\n n: number,\n r: number,\n i: any,\n s: number,\n o: number\n ) {\n return cmn((t & n) | (~t & r), e, t, i, s, o)\n }\n function gg(\n e: any,\n t: number,\n n: number,\n r: number,\n i: any,\n s: number,\n o: number\n ) {\n return cmn((t & r) | (n & ~r), e, t, i, s, o)\n }\n function hh(\n e: any,\n t: number,\n n: number,\n r: number,\n i: any,\n s: number,\n o: number\n ) {\n return cmn(t ^ n ^ r, e, t, i, s, o)\n }\n function ii(\n e: any,\n t: number,\n n: number,\n r: number,\n i: any,\n s: number,\n o: number\n ) {\n return cmn(n ^ (t | ~r), e, t, i, s, o)\n }\n function md51(e: string) {\n var t = e.length,\n n = [1732584193, -271733879, -1732584194, 271733878],\n r: number\n for (r = 64; r <= e.length; r += 64) {\n md5cycle(n, md5blk(e.substring(r - 64, r)))\n }\n e = e.substring(r - 64)\n var i = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n for (r = 0; r < e.length; r++) i[r >> 2] |= e.charCodeAt(r) << (r % 4 << 3)\n i[r >> 2] |= 128 << (r % 4 << 3)\n if (r > 55) {\n md5cycle(n, i)\n for (r = 0; r < 16; r++) i[r] = 0\n }\n i[14] = t * 8\n md5cycle(n, i)\n return n\n }\n function md5blk(e: string) {\n var t = [],\n n: number\n for (n = 0; n < 64; n += 4) {\n t[n >> 2] =\n e.charCodeAt(n) +\n (e.charCodeAt(n + 1) << 8) +\n (e.charCodeAt(n + 2) << 16) +\n (e.charCodeAt(n + 3) << 24)\n }\n return t\n }\n function rhex(e: number) {\n var t = \"\",\n n = 0\n for (; n < 4; n++)\n t += hex_chr[(e >> (n * 8 + 4)) & 15] + hex_chr[(e >> (n * 8)) & 15]\n return t\n }\n function hex(e: any[]) {\n for (var t = 0; t < e.length; t++) e[t] = rhex(e[t])\n return e.join(\"\")\n }\n function md5(e: string) {\n return hex(md51(e))\n }\n function add32(e: number, t: number) {\n return (e + t) & 4294967295\n }\n var hex_chr = \"0123456789abcdef\".split(\"\")\n //check to make sure you gave us something\n var options = options || {},\n base: string,\n params = []\n\n //set some defaults, just in case\n options = {\n size: options.size || \"50\",\n rating: options.rating || \"g\",\n secure: options.secure || location.protocol === \"https:\",\n backup: options.backup || \"\",\n }\n\n //setup the email address\n email = email.trim().toLowerCase()\n\n //determine which base to use\n base = options.secure\n ? \"https://secure.gravatar.com/avatar/\"\n : \"http://www.gravatar.com/avatar/\"\n\n //add the params\n if (options.rating) {\n params.push(\"r=\" + options.rating)\n }\n if (options.backup) {\n params.push(\"d=\" + encodeURIComponent(options.backup))\n }\n if (options.size) {\n params.push(\"s=\" + options.size)\n }\n\n //now throw it all together\n return base + md5(email) + \"?\" + params.join(\"&\")\n}\n\nexport function gravatarURLByEmail(\n email: string,\n defaultURL: string = \"\"\n): string {\n try {\n return gravatar(email, {\n size: 256,\n backup: \"monsterid\",\n // backup: \"https://holtwick.de/download/user.png\", // \"retro\",\n secure: true,\n })\n } catch (error) {\n log(\"Gravatar issue: Did not find an image for \" + email)\n return defaultURL\n }\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { Json, ObjectStorage } from \"../common/types\"\nimport { Logger } from \"../common/log\"\n\nconst log = Logger(\"zeed:localstorage\")\n\nexport interface LocalStorageOptions {\n name: string\n objectFromString?: (data: string) => any\n objectToString?: (data: any) => string\n}\n\nexport class LocalStorage<T = Json> implements ObjectStorage<T> {\n private name: string\n private prefix: string\n private pretty: boolean = false\n private objectFromString: (data: string) => any\n private objectToString: (data: any) => string\n\n constructor(opt: LocalStorageOptions) {\n log.assert(opt.name, \"name required\")\n this.name = opt.name\n this.prefix = `${opt.name}$`\n this.objectToString =\n opt.objectToString ??\n ((data: any): string => {\n return this.pretty\n ? JSON.stringify(data, null, 2)\n : JSON.stringify(data)\n })\n\n this.objectFromString =\n opt.objectFromString ??\n ((data: string) => {\n try {\n return JSON.parse(data)\n } catch (err) {\n log.warn(`LocalStorage parse error '${err}' in`, data)\n }\n })\n }\n\n setItem(key: string, value: T): void {\n const data = this.objectToString(value)\n localStorage.setItem(`${this.prefix}${key}`, data)\n }\n\n getItem(key: string): T | undefined {\n let value = localStorage.getItem(`${this.prefix}${key}`)\n if (value != null) {\n return this.objectFromString(value)\n }\n }\n\n removeItem(key: string): void {\n localStorage.removeItem(`${this.prefix}${key}`)\n }\n\n clear(): void {\n Object.keys(localStorage)\n .filter((key) => key.startsWith(this.prefix))\n .forEach((key) => {\n localStorage.removeItem(key)\n })\n }\n\n allKeys(): string[] {\n const prefixLength = this.prefix.length\n return Object.keys(localStorage)\n .filter((key) => key.startsWith(this.prefix))\n .map((key) => key.substr(prefixLength))\n }\n}\n","// Taken from https://github.com/visionmedia/debug/blob/master/src/browser.js#L27\n\nconst colors = [\n \"#0000CC\",\n \"#0000FF\",\n \"#0033CC\",\n \"#0033FF\",\n \"#0066CC\",\n \"#0066FF\",\n \"#0099CC\",\n \"#0099FF\",\n \"#00CC00\",\n \"#00CC33\",\n \"#00CC66\",\n \"#00CC99\",\n \"#00CCCC\",\n \"#00CCFF\",\n \"#3300CC\",\n \"#3300FF\",\n \"#3333CC\",\n \"#3333FF\",\n \"#3366CC\",\n \"#3366FF\",\n \"#3399CC\",\n \"#3399FF\",\n \"#33CC00\",\n \"#33CC33\",\n \"#33CC66\",\n \"#33CC99\",\n \"#33CCCC\",\n \"#33CCFF\",\n \"#6600CC\",\n \"#6600FF\",\n \"#6633CC\",\n \"#6633FF\",\n \"#66CC00\",\n \"#66CC33\",\n \"#9900CC\",\n \"#9900FF\",\n \"#9933CC\",\n \"#9933FF\",\n \"#99CC00\",\n \"#99CC33\",\n \"#CC0000\",\n \"#CC0033\",\n \"#CC0066\",\n \"#CC0099\",\n \"#CC00CC\",\n \"#CC00FF\",\n \"#CC3300\",\n \"#CC3333\",\n \"#CC3366\",\n \"#CC3399\",\n \"#CC33CC\",\n \"#CC33FF\",\n \"#CC6600\",\n \"#CC6633\",\n \"#CC9900\",\n \"#CC9933\",\n \"#CCCC00\",\n \"#CCCC33\",\n \"#FF0000\",\n \"#FF0033\",\n \"#FF0066\",\n \"#FF0099\",\n \"#FF00CC\",\n \"#FF00FF\",\n \"#FF3300\",\n \"#FF3333\",\n \"#FF3366\",\n \"#FF3399\",\n \"#FF33CC\",\n \"#FF33FF\",\n \"#FF6600\",\n \"#FF6633\",\n \"#FF9900\",\n \"#FF9933\",\n \"#FFCC00\",\n \"#FFCC33\",\n]\n\nexport function supportsColors(): boolean {\n // NB: In an Electron preload script, document will be defined but not fully\n // initialized. Since we know we're in Chrome, we'll just detect this case\n // explicitly\n if (\n typeof window !== \"undefined\" &&\n window.process &&\n // @ts-ignore\n (window.process.type === \"renderer\" || window.process.__nwjs)\n ) {\n return true\n }\n\n // Internet Explorer and Edge do not support colors.\n if (\n typeof navigator !== \"undefined\" &&\n navigator.userAgent &&\n navigator.userAgent.toLowerCase().match(/(edge|trident)\\/(\\d+)/)\n ) {\n return false\n }\n\n // Is webkit? http://stackoverflow.com/a/16459606/376773\n // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632\n return (\n (typeof document !== \"undefined\" &&\n document.documentElement &&\n document.documentElement.style &&\n // @ts-ignore\n document.documentElement.style.WebkitAppearance) ||\n // Is firebug? http://stackoverflow.com/a/398120/376773\n (typeof window !== \"undefined\" &&\n window.console &&\n // @ts-ignore\n (window.console.firebug ||\n // @ts-ignore\n (window.console.exception && window.console.table))) ||\n // Is firefox >= v31?\n // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n (typeof navigator !== \"undefined\" &&\n navigator.userAgent &&\n navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/) &&\n parseInt(RegExp.$1, 10) >= 31) ||\n // Double check webkit in userAgent just in case we are in a worker\n (typeof navigator !== \"undefined\" &&\n navigator.userAgent &&\n navigator.userAgent.toLowerCase().match(/applewebkit\\/(\\d+)/))\n )\n}\n\nexport function selectColor(namespace: string) {\n let hash = 0\n for (let i = 0; i < namespace.length; i++) {\n hash = (hash << 5) - hash + namespace.charCodeAt(i)\n hash |= 0 // Convert to 32bit integer\n }\n return colors[Math.abs(hash) % colors.length]\n}\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { deepEqual } from \"../common/data/deep\"\nimport {\n LoggerInterface,\n LogHandler,\n LogHandlerOptions,\n LogLevel,\n LogMessage,\n} from \"../common/log-base\"\nimport { useLevelFilter, useNamespaceFilter } from \"../common/log-filter\"\nimport { formatMilliseconds, getTimestamp } from \"../common/time\"\nimport { selectColor, supportsColors } from \"./log-colors\"\n\nconst styleFont = `font-family: \"JetBrains Mono\", Menlo; font-size: 11px;`\nconst styleDefault = `${styleFont}`\nconst styleBold = `font-weight: 600; ${styleFont}`\nconst useColors = supportsColors()\n\nlet namespaces: Record<string, any> = {}\n\nlet time = getTimestamp()\n\nexport function LoggerBrowserHandler(opt: LogHandlerOptions = {}): LogHandler {\n const {\n filter = undefined,\n level = undefined,\n colors = true,\n levelHelper = false,\n nameBrackets = true,\n padding = 16,\n } = opt\n const matchesNamespace = useNamespaceFilter(filter)\n const matchesLevel = useLevelFilter(level)\n return (msg: LogMessage) => {\n if (!matchesLevel(msg.level)) return\n if (!matchesNamespace(msg.name)) return\n\n const timeNow = getTimestamp()\n let name = msg.name || \"\"\n let ninfo = namespaces[name || \"\"]\n if (ninfo == null) {\n ninfo = {\n color: selectColor(name),\n // time: timeNow\n }\n namespaces[name] = ninfo\n }\n const diff = formatMilliseconds(timeNow - time)\n let args: string[]\n\n if (padding > 0) {\n name = name.padEnd(16, \" \")\n }\n\n if (colors && useColors) {\n args = [`%c${name}%c \\t%s %c+${diff}`]\n args.push(`color:${ninfo.color}; ${styleBold}`)\n args.push(styleDefault)\n args.push(msg.messages?.[0] ?? \"\")\n args.push(`color:${ninfo.color};`)\n args.push(...msg.messages.slice(1))\n } else {\n args = [name, ...msg.messages, `+${diff}`]\n }\n\n // function consoleArgs(args: any[] = []): any[] {\n // return [\n // args\n // .filter((a) => typeof a === \"string\")\n // .map((a) => String(a))\n // .join(\" \"),\n // ...styles,\n // ...args.filter((a) => typeof a !== \"string\"),\n // ]\n // }\n\n switch (msg.level) {\n case LogLevel.info:\n if (opt.levelHelper) args[0] = `I|* ` + args[0]\n console.info(...args)\n break\n case LogLevel.warn:\n if (opt.levelHelper) args[0] = `W|** ` + args[0]\n console.warn(...args)\n break\n case LogLevel.error:\n if (opt.levelHelper) args[0] = `E|*** ` + args[0]\n console.error(...args)\n break\n default:\n if (opt.levelHelper) args[0] = `D| ` + args[0]\n console.debug(...args)\n break\n }\n }\n}\n\nexport function LoggerBrowserSetupDebugFactory(opt: LogHandlerOptions = {}) {\n const filter = opt.filter ?? localStorage.zeed ?? localStorage.debug\n\n /// The trick is, that console called directly provides a reference to the source code.\n /// For the regular implementation this information is lost. But this approach has other\n /// drawbacks, therefore only use it in the Browser when actively debugging.\n return function LoggerBrowserDebugFactory(\n name: string = \"\"\n ): LoggerInterface {\n let log: LoggerInterface\n\n const matches = useNamespaceFilter(filter)\n\n if (matches(name)) {\n let fixedArgs = []\n if (useColors) {\n const color = selectColor(name)\n fixedArgs.push(`%c${name.padEnd(16, \" \")}%c \\t%s`)\n fixedArgs.push(`color:${color}; ${styleBold}`)\n fixedArgs.push(styleDefault)\n } else {\n fixedArgs.push(`[${name}] \\t%s`)\n }\n\n // @ts-ignore\n // console.previous = {\n // debug: console.debug,\n // info: console.info,\n // warn: console.warn,\n // error: console.error,\n // assert: console.assert,\n // }\n\n log = console.debug.bind(console, ...fixedArgs) as LoggerInterface\n log.debug = console.debug.bind(console, ...fixedArgs)\n log.info = console.info.bind(console, ...fixedArgs)\n log.warn = console.warn.bind(console, ...fixedArgs)\n log.error = console.error.bind(console, ...fixedArgs)\n\n log.assert = console.assert.bind(console)\n\n log.assertEqual = function (value: any, expected: any, ...args: any[]) {\n let equal = deepEqual(value, expected)\n if (!equal) {\n log.assert(\n equal,\n `Assert did fail. Expected ${expected} got ${value}`,\n expected,\n value,\n ...args\n )\n }\n }\n\n log.assertNotEqual = function (\n value: any,\n expected: any,\n ...args: any[]\n ) {\n let equal = deepEqual(value, expected)\n if (equal) {\n log.assert(\n equal,\n `Assert did fail. Expected ${expected} not to be equal with ${value}`,\n expected,\n value,\n ...args\n )\n }\n }\n } else {\n const noop = () => {}\n log = noop as LoggerInterface\n log.debug = noop\n log.info = noop\n log.warn = noop\n log.error = noop\n\n log.assert = noop\n log.assertEqual = noop\n log.assertNotEqual = noop\n }\n\n log.extend = (subName: string) => {\n return LoggerBrowserDebugFactory(name ? `${name}:${subName}` : subName)\n }\n\n return log\n }\n}\n\n/** @deprecated This output is default for initial use of Logger in browser environments. */\nexport function activateConsoleDebug(opt: LogHandlerOptions = {}) {\n console.info(\"activateConsoleDebug is activated by default in browsers\")\n // Logger.setHandlers([LoggerBrowserHandler(opt)]) // Fallback for previously registered Loggers\n // Logger.setFactory(LoggerBrowserSetupDebugFactory(opt))\n}\n\n// let klass = console\n// let debug = console.debug.bind(window.console, klass.toString() + \": \")\n\n// debug(\"test\")\n// console.debug(\"test2\")\n\n// let dd\n// if (Function.prototype.bind) {\n// dd = Function.prototype.bind.call(console.log, console)\n// } else {\n// dd = function () {\n// Function.prototype.apply.call(console.log, console, arguments)\n// }\n// }\n\n// dd(\"dd\")\n\n// let c = 1\n// Object.defineProperty(window, \"log2\", {\n// get: () => {\n// return console.log.bind(\n// window.console,\n// \"%c[log]%c %s\" + c++,\n// \"color:red\",\n// \"\"\n// )\n// },\n// })\n\n// // usage:\n// log2(\"Back to the future\")\n// log2(\"Back to the future\")\n\n// let plog = new Proxy(console.debug, {\n// apply: function (target, that, args) {\n// target.apply(that, args)\n// // base.apply(that, args);\n// },\n// })\n\n// let cons = console.debug\n// let plog = (...args) => {\n// cons.apply(window.console, [\"|\", ...args])\n// }\n\n// plog(\"xxx\")\n\n// function a() {\n// var err = new Error()\n// var caller_line = err.stack.split(\"\\n\")[2]\n// var index = caller_line.indexOf(\"at \")\n// var clean = caller_line.slice(index + 2, caller_line.length)\n// clean = clean.replace(/\\?t=\\d+/, \"\").replace(\"@fs/\", \"\")\n// console.log(clean)\n// console.log(\n// \"http://localhost:8080/Users/dirk/work/viidoo/lib/src/browser/log-browser.ts:188:1 log-browser.ts:291:10\"\n// )\n// }\n// function b() {\n// a()\n// }\n// b()\n","// (C)opyright 2021-07-15 Dirk Holtwick, holtwick.it. All rights reserved.\n\nimport { getTimestamp, formatMilliseconds } from \"../common/time\"\nimport {\n LogHandler,\n LogHandlerOptions,\n LogLevel,\n LogMessage,\n} from \"../common/log-base\"\nimport { selectColor, supportsColors } from \"./log-colors\"\nimport { useLevelFilter, useNamespaceFilter } from \"../common/log-filter\"\n\nlet namespaces: Record<string, any> = {}\n\nlet time = getTimestamp()\n\nconst useColors = supportsColors()\n\n/** @deprecated */\nexport function LoggerBrowserClassicHandler(\n level?: LogLevel,\n opt: LogHandlerOptions = {}\n): LogHandler {\n const { filter = undefined } = opt\n const matchesNamespace = useNamespaceFilter(filter)\n const matchesLevel = useLevelFilter(level)\n return (msg: LogMessage) => {\n if (!matchesLevel(msg.level)) return\n if (!matchesNamespace(msg.name)) return\n\n const timeNow = getTimestamp()\n let name = msg.name || \"\"\n let ninfo = namespaces[name || \"\"]\n if (ninfo == null) {\n ninfo = {\n color: selectColor(name),\n // time: timeNow\n }\n namespaces[name] = ninfo\n }\n\n const diff = formatMilliseconds(timeNow - time)\n\n let args: string[]\n if (opt.colors && useColors) {\n args = opt.nameBrackets ? [`%c[${name}]`] : [`%c${name}`]\n args.push(`color:${ninfo.color}`)\n args.push(...msg.messages)\n } else {\n args = [name, ...msg.messages]\n }\n args.push(`+${diff}`)\n switch (msg.level) {\n case LogLevel.info:\n if (opt.levelHelper) args[0] = `I|* ` + args[0]\n console.info(...args)\n break\n case LogLevel.warn:\n if (opt.levelHelper) args[0] = `W|** ` + args[0]\n console.warn(...args)\n break\n case LogLevel.error:\n if (opt.levelHelper) args[0] = `E|*** ` + args[0]\n console.error(...args)\n break\n default:\n if (opt.levelHelper) args[0] = `D| ` + args[0]\n console.debug(...args)\n break\n }\n }\n}\n","import { isBrowser } from \"../common/platform\"\nimport { Logger } from \"../common/log\"\nimport {\n LoggerBrowserHandler,\n LoggerBrowserSetupDebugFactory,\n} from \"./log-browser\"\n\nif (isBrowser()) {\n Logger.setHandlers([LoggerBrowserHandler()]) // Fallback for previously registered Loggers\n Logger.setFactory(LoggerBrowserSetupDebugFactory({}))\n}\n"],"mappings":"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","names":[]}
|