{"version":3,"sources":["jsdelivr-header.js","/npm/mcode-log@0.8.0/index.js"],"names":[],"mappings":"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","file":"/npm/mcode-log@0.8.0/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/mcode-log@0.8.0/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","// #region  F I L E\n// <copyright file=\"mcode-log/index.js\" company=\"MicroCODE Incorporated\">Copyright © 2022-2024 MicroCODE, Inc. Troy, MI</copyright><author>Timothy J. McGuire</author>\n// #region  M O D U L E\n// #region  D O C U M E N T A T I O N\n/**\n *      Project:  MicroCODE MERN Applications\n *      Customer: Internal + MIT xPRO Course\n *      @module   'mcode-log.js'\n *      @memberof mcode\n *      @created  January 2022-2024\n *      @author   Timothy McGuire, MicroCODE, Inc.\n *      @description >\n *      MicroCODE Shared App Logging Library\n *\n *      LICENSE:\n *      --------\n *      MIT License: MicroCODE.mcode-log\n *\n *      Copyright (c) 2022-2024 Timothy McGuire, MicroCODE, Inc.\n *\n *      Permission is hereby granted, free of charge, to any person obtaining a copy\n *      of this software and associated documentation files (the \"Software\"), to deal\n *      in the Software without restriction, including without limitation the rights\n *      to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n *      copies of the Software, and to permit persons to whom the Software is\n *      furnished to do so, subject to the following conditions:\n *\n *      The above copyright notice and this permission notice shall be included in all\n *      copies or substantial portions of the Software.\n *\n *      THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n *      IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n *      FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n *      AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n *      LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n *      OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n *      SOFTWARE.\n *\n *\n *      DESCRIPTION:\n *      ------------\n *      This module implements the MicroCODE's Common JavaScript functions for logging and debugging.\n *\n *\n *      REFERENCES:\n *      -----------\n *      1. MIT xPRO Course: Professional Certificate in Coding: Full Stack Development with MERN\n *\n *      2. List of ANSI Color Escape Sequences\n *         https://stackoverflow.com/questions/4842424/list-of-ansi-color-escape-sequences\n *\n *      3. Showing Line Numbers in console.log from Node.js\n *         https://stackoverflow.com/questions/45395369/how-to-get-console-log-line-numbers-shown-in-nodejs\n *\n *\n *\n *\n *      MODIFICATIONS:\n *      --------------\n *      Date:         By-Group:   Rev:    Description:\n *\n *      27-Jan-2022   TJM-MCODE  {0001}   New module for common reusable Javascript logging functions.\n *      05-Mar-2022   TJM-MCODE  {0002}   Documentation updates.\n *      04-May-0222   TJM-MCODE  {0003}   Corrected 'month' in timeStamp.\n *      03-Oct-2022   TJM-MCODE  {0004}   Added 'log()' to simplify console logging of app events.\n *      03-Oct-2022   TJM-MCODE  {0005}   Added use of 'vt' for colorizing Console Log entries.\n *      16-Oct-2022   TJM-MCODE  {0006}   Added 'success' as a severity.\n *      30-Oct-2023   TJM-MCODE  {0007}   Updated to TypeScript, reversed to pure JavaScript in Jan 2024.\n *      03-Dec-2023   TJM-MCODE  {0008}   Don't log 'debug' messages in staging or production mode.\n *      21-Jan-2024   TJM-MCODE  {0009}   Converted to a single ES6 Module (ESM) for use in both\n *                                        Frontend/Client and Backend/Server as a NodeJS package.\n *      01-Feb-2024   TJM-MCODE  {0010}   Changed to the Universal Module Definition (UMD) pattern to support AMD,\n *                                        CommonJS/Node.js, and browser global in our exported module.\n *      02-Mar-2024   TJM-MCODE  {0011}   Added 'logobj()', 'expobj()', 'isFunction()', 'hexify()', 'octify()', and 'colorizeLines()'\n *                                        all in the pursuit of a more complete and consistent logging and debugging experience,\n *                                        in both the Console, NPM, and the Browser's DevTools.\n *      06-Jul-2024   TJM-MCODE  {0012}   0.4.00 - moved all 'data' functions into sub-package 'mcode-data'.\n *      22-Aug-2024   TJM-MCODE  {0013}   0.4.04 - corrected 'colorizeLines()' to carry on embedded colors to following lines.\n *      22-Aug-2024   TJM-MCODE  {0014}   0.4.05 - corrected 'logify()' to accept all legal JSON Key names.\n *      19-Feb-2025   TJM-MCODE  {0015}   0.5.08 - updated 'resx()' to support returning non-db entity results,\n *                                                 to carry this common response code into our HTMX UI responses.\n *      21-Feb-2025   TJM-MCODE  {0016}   0.5.09 - optimized many functions, standardized on '' strings instead of a mix\n *                                                 of \"\" and '', now \"\" only used when embedded ' are needed.\n *                                               - fixed an issues in 'logify*()' with string arrays where element had embedded \".\n *      08-Mar-2025   TJM-MCODE  {0017}   0.5.10 - updated resx() handle HTTP Status 204 properly with '.end()'.\n *      16-Mar-2025   TJM-MCODE  {0018}   0.6.07 - Passing MODULE_NAME is now optional and the logging functions\n *                                                 all log complete source path and line # of the caller automatically.\n *      17-Apr-2025   TJM-MCODE  {0019}   0.6.08 - added 'logifyObject()' to handle all objects, including arrays and JSON.\n *      18-Apr-2025   TJM-MCODE  {0020}   0.6.09 - add support for passing 'data' thru 'resx()' to support HTML responses for\n *                                                 HTMX UI swaps, specifically to support an 'app-banner',\n *                                                 added 'fatal' severity to align with app-banner.\n *      24-Apr-2025   TJM-MCODE  {0021}   0.6.09 - added support for UUID 'Event Id' as optional data to be logged for traceability.\n *      03-Oct-2025   TJM-MCODE  {0022}   0.7.00 - added support for HTML output thru the use of a new 'ht' table used in\n *                                                 combination with the existing 'vt' table.\n *      16-Oct-2025   TJM-MCODE  {0023}   0.7.04 - fixed logify() to stop inserting blank line before and between JSON objects.\n *                                                 Also fixed logObj() to always use logifyObject(), even for simple arrays to\n *                                                 correct a unique indentation issue.\n *      19-Oct-2025   TJM-MCODE  {0024}   0.7.05 - fixed 'getFrom()' to work properly in non-NodeJS environments by checking for 'process.versions.node'.\n *\n *\n *\n *\n * NOTE: This module follow's MicroCODE's JavaScript Style Guide and Template JS file, see:\n *\n *       o  https://github.com/MicroCODEIncorporated/JavaScriptSG\n *       o  https://github.com/MicroCODEIncorporated/TemplatesJS\n *\n * ...be sure to check out the CTRL-SHIFT+K, +L, +J keybaord shortcuts in Visual Studio Code\n *    for taking advance of the #regions in this file and our templates.\n *\n *\n */\n// #endregion\n\n// #region  I M P O R T S\n\nconst _data = require('mcode-data');\n\nconst isNode = typeof process !== 'undefined' && process.versions?.node;\nconst path = isNode ? require('path') : null;\nconst packageJson = require('./package.json');\n\n// #endregion\n\n// #region  T Y P E S\n\n// #endregion\n\n// #region  I N T E R F A C E S\n\n// #endregion\n\n// #region  C O N S T A N T S, F U N C T I O N S – P U B L I C\n\n// MicroCODE: define this module's name for our 'mcode-log' package\nconst MODULE_NAME = 'mcode-log.js';\nconst WEEKDAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\nconst MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n\nconst theme = process.env.THEME || 'dark'; // default to dark mode\nconst mode = process.env.NODE_ENV || 'development'; // default to development mode\n\n/**\n * @namespace mcode\n * @desc mcode namespace containing functions and constants.\n */\nconst mcode = {\n\n    /**\n     * @const vt\n     * @memberof mcode\n     * @desc Colors constants for changing Console appearance ala DEC's VT52 + VT100 + VT220.\n     * @example\n        ANSI Color Escape Sequence\n\n        \\x1b[***m  -- where '***' is a series of command codes separated by semi-colons (;).\n\n        Code\tEffect -- notes\n        ------------------------------------------------------------------------------\n        0\t    Reset / Normal -- all attributes off\n        1\t    Bold -- increased intensity\n        2\t    Faint -- decreased intensity - not widely supported\n        3\t    Italic -- not widely supported, sometimes treated as inverse\n        4\t    Underline\n        5\t    Slow Blink -- less than 150 per minute\n        6\t    Rapid Blink -- MS-DOS ANSI.SYS; 150+ per minute; not widely supported\n        7\t    Reverse video -- swap foreground and background colors\n        8\t    Conceal -- not widely supported.\n        9\t    Crossed-out -- characters legible, but marked for deletion. Not widely supported\n        10\t    Primary font (default)\n        11–19\tAlternate font -- select alternate font n-10\n        20\t    Fraktur -- hardly ever supported\n        21\t    Bold off or Double Underline -- bold off not widely supported; double underline hardly ever supported\n        22\t    Normal color or intensity -- neither bold nor faint\n        23\t    Not italic, not Fraktur\n        24\t    Underline roundOff -- not singly or doubly underlined\n        25\t    Blink off\n        27\t    Inverse off\n        28\t    Reveal\tconceal off\n        29\t    Not crossed out\n        30–37\tSet foreground color -- see color table below\n        38\t    Set foreground color -- next arguments are 5;<n> or 2;<r>;<g>;<b>, see below\n        39\t    Default foreground color -- implementation defined (according to standard)\n        40–47   Set background color -- see color table below\n        48\t    Set background color -- next arguments are 5;<n> or 2;<r>;<g>;<b>, see below\n        49\t    Default background color -- implementation defined (according to standard)\n        51\t    Framed\n        52\t    Encircled\n        53\t    Overlined\n        54\t    Not framed or encircled\n        55\t    Not overlined\n        60\t    ideogram underline -- hardly ever supported\n        61\t    ideogram double underline -- hardly ever supported\n        62\t    ideogram overline -- hardly ever supported\n        63\t    ideogram double overline -- hardly ever supported\n        64\t    ideogram stress marking\thardly ever supported\n        65\t    ideogram attributes off\treset the effects of all of 60-64\n        90–97\tSet bright foreground color\taixterm (not in standard)\n        100–107\tSet bright background color\taixterm (not in standard)\n     *\n     */\n    vt:\n    {\n        notice: \"This is a test string for logifying 'mcode' as an object during testing.\",\n\n        // common effects, predefined ANSI escape sequences\n        reset: '\\x1b[0m',\n        bold: '\\x1b[1m',\n        bright: '\\x1b[1m',\n        dim: '\\x1b[2m',\n        faint: '\\x1b[2m',\n        italic: '\\x1b[3m',\n        underscore: '\\x1b[4m',\n        underline: '\\x1b[4m',\n        blink: '\\x1b[5m',\n        blink_slow: '\\x1b[5m',\n        blink_fast: '\\x1b[6m',\n        reverse: '\\x1b[7m',\n        hidden: '\\x1b[8m',\n        conceal: '\\x1b[8m',\n        strikethru: '\\x1b[9m',\n        crossed_out: '\\x1b[9m',\n\n        // foreground colors\n        fg: {\n            black: '\\x1b[30m',\n            red: '\\x1b[31m',\n            green: '\\x1b[32m',\n            yellow: '\\x1b[33m',\n            blue: '\\x1b[34m',\n            magenta: '\\x1b[35m',\n            cyan: '\\x1b[36m',\n            white: '\\x1b[37m',\n        },\n\n        // background colors\n        bg: {\n            black: '\\x1b[40m',\n            red: '\\x1b[41m',\n            green: '\\x1b[42m',\n            yellow: '\\x1b[43m',\n            blue: '\\x1b[44m',\n            magenta: '\\x1b[45m',\n            cyan: '\\x1b[46m',\n            white: '\\x1b[47m',\n        },\n\n        // colors for event severity:   dark        light\n        gray: (theme === 'dark') ? '\\x1b[90m' : '\\x1b[30m',  // gray\n        errr: (theme === 'dark') ? '\\x1b[91m' : '\\x1b[31m',  // red\n        good: (theme === 'dark') ? '\\x1b[92m' : '\\x1b[32m',  // green\n        warn: (theme === 'dark') ? '\\x1b[93m' : '\\x1b[33m',  // yellow\n        cold: (theme === 'dark') ? '\\x1b[94m' : '\\x1b[34m',  // blue\n        dead: (theme === 'dark') ? '\\x1b[95m' : '\\x1b[35m',  // magenta\n        code: (theme === 'dark') ? '\\x1b[96m' : '\\x1b[36m',  // cyan\n        info: (theme === 'dark') ? '\\x1b[97m' : '\\x1b[37m',  // white\n        dbug: (theme === 'dark') ? '\\x1b[38;2;255;140;0m' : '\\x1b[38;5;208m',  // orange\n\n        // custom JSON colors -- see 'logify()' for use\n        punc: '\\x1b[96m\\x1b[1m',  // string value - CYAN, BOLD\n        key: '\\x1b[97m',  // key name - WHITE\n        string: '\\x1b[96m',  // string value - CYAN\n        integer: '\\x1b[94m',  // integer value - BLUE\n        real: '\\x1b[92m',  // floating point value - GREEN\n        bigint: '\\x1b[95m',  // bigint value - MAGENTA\n        true: '\\x1b[92m',  // boolean true - BRIGHT GREEN (LIME)\n        false: '\\x1b[91m',  // boolean false - RED\n        null: '\\x1b[90m',  // null value - GRAY\n        value: '\\x1b[93m',  // fallback for other values - YELLOW\n        nl: '\\n'  // newline\n    },\n\n    /**\n     * @const ht\n     * @memberof mcode\n     * @desc HTML inline style constants for generating HTML with colorized appearance similar to the VT ANSI colors.\n     * @example\n        Supported HTML equivalents for ANSI Color Escape Sequence\n\n        Code\t    Effect -- notes\n        ------------------------------------------------------------------------------\n        reset       end span\n        bold        font-weight: 600\n        bright      font-weight: 600\n        dim         opacity: 0.6\n        faint       opacity: 0.6\n        italic      font-style: italic\n        underscore  text-decoration: underline\n        underline   text-decoration: underline\n        blink       animation: blink 1s infinite\n\n        blink_slow  animation: blink 2s infinite\n        blink_fast  animation: blink 0.5s infinite\n        reverse     filter: invert(1)\n        hidden      visibility: hidden\n        conceal     visibility: hidden\n        strikethru  text-decoration: line-through\n        crossed_out text-decoration: line-through\n     */\n    ht:\n    {\n        notice: \"This is a test string for HTML-ifying 'mcode' as an object during testing.\",\n\n        // common effects, HTML inline styles\n        reset: '</span>',\n        bold: '<span style=\"font-weight: 600;\">',\n        bright: '<span style=\"font-weight: 600;\">',\n        dim: '<span style=\"opacity: 0.6;\">',\n        faint: '<span style=\"opacity: 0.6;\">',\n        italic: '<span style=\"font-style: italic;\">',\n        underscore: '<span style=\"text-decoration: underline;\">',\n        underline: '<span style=\"text-decoration: underline;\">',\n        blink: '<span style=\"animation: blink 1s infinite;\">',\n        blink_slow: '<span style=\"animation: blink 2s infinite;\">',\n        blink_fast: '<span style=\"animation: blink 0.5s infinite;\">',\n        reverse: '<span style=\"filter: invert(1);\">',\n        hidden: '<span style=\"visibility: hidden;\">',\n        conceal: '<span style=\"visibility: hidden;\">',\n        strikethru: '<span style=\"text-decoration: line-through;\">',\n        crossed_out: '<span style=\"text-decoration: line-through;\">',\n\n        // foreground colors\n        fg: {\n            black: '<span style=\"color: black;\">',\n            red: '<span style=\"color: red;\">',\n            green: '<span style=\"color: green;\">',\n            yellow: '<span style=\"color: yellow;\">',\n            blue: '<span style=\"color: blue;\">',\n            magenta: '<span style=\"color: magenta;\">',\n            cyan: '<span style=\"color: cyan;\">',\n            white: '<span style=\"color: white;\">',\n        },\n\n        // background colors\n        bg: {\n            black: '<span style=\"background-color: black;\">',\n            red: '<span style=\"background-color: red;\">',\n            green: '<span style=\"background-color: green;\">',\n            yellow: '<span style=\"background-color: yellow;\">',\n            blue: '<span style=\"background-color: blue;\">',\n            magenta: '<span style=\"background-color: magenta;\">',\n            cyan: '<span style=\"background-color: cyan;\">',\n            white: '<span style=\"background-color: white;\">',\n        },\n\n        // colors for event severity:            dark                                 light     themes\n        gray: (theme === 'dark') ? '<span style=\"color: #999999;\">' : '<span style=\"color: #333333;\">',  // gray\n        errr: (theme === 'dark') ? '<span style=\"color: #ff6b6b;\">' : '<span style=\"color: #d32f2f;\">',  // red\n        good: (theme === 'dark') ? '<span style=\"color: #51cf66;\">' : '<span style=\"color: #388e3c;\">',  // green\n        warn: (theme === 'dark') ? '<span style=\"color: #efff3b;\">' : '<span style=\"color: #cbc800;\">',  // yellow\n        cold: (theme === 'dark') ? '<span style=\"color: #339af0;\">' : '<span style=\"color: #1976d2;\">',  // blue\n        dead: (theme === 'dark') ? '<span style=\"color: #e599f7;\">' : '<span style=\"color: #7b1fa2;\">',  // magenta\n        code: (theme === 'dark') ? '<span style=\"color: #3bc9db;\">' : '<span style=\"color: #0097a7;\">',  // cyan\n        info: (theme === 'dark') ? '<span style=\"color: #f8f9fa;\">' : '<span style=\"color: #212529;\">',  // white/black\n        dbug: (theme === 'dark') ? '<span style=\"color: #f2c200;\">' : '<span style=\"color: #f57c00;\">',  // orange\n\n        // custom JSON colors -- see 'logifyHtml()' for use\n        punc: '<span style=\"font-weight: 500; color: #00ffff;\">',  // punctuation - CYAN, BOLD\n        key: '<span style=\"font-weight: 300; color: #f8f9fa;\">',  // key name - WHITE\n        string: '<span style=\"font-weight: 500; color: #00cccc;\">',  // string value - CYAN, DARKER\n        integer: '<span style=\"font-weight: 600; color: #8bd6ffff;\">',  // integer value - BLUE\n        real: '<span style=\"font-weight: 600; color: #a0ff86;\">',  // floating point value - GREEN\n        bigint: '<span style=\"font-weight: 600; color: #cf86ff;\">',  // bigint value - MAGENTA\n        true: '<span style=\"font-weight: 600; color: #00ff00;\">',  // boolean true - LIME\n        false: '<span style=\"font-weight: 600; color: #ff0000;\">',  // boolean false - RED\n        null: '<span style=\"font-weight: 600; color: #7c7c7c;\">',  // null value - GRAY\n        value: '<span style=\"font-weight: 600; color: #ffbf00;\">',  // fallback for other values - ORANGE\n        nl: '<br/>'  // newline\n    },\n\n    /**\n     * @func resolveSeverity\n     * @memberof mcode\n     * @desc Resolves a severity level to its corresponding text, icon, color, and prefix.\n     * This is used throughout to ensure consistency in the logged output.\n     * @api public\n     * @param {string} severity The severity level to resolve.\n     * @param {object} vx [Optional] the color video effects to use, defaults to 'mcode.vt'.\n     * @returns {object} An object containing the resolved text, icon, color, and prefix.\n     */\n    resolveSeverity: function (severity, vx = mcode.vt)\n    {\n        const normalized = (severity ?? '').toString().toLowerCase();\n        const severityMap = [\n            {keys: ['i', 'inf', 'info'], text: 'info', icon: '📣', colorKey: 'info', prefix: 'i'},\n            {keys: ['w', 'wrn', 'warn', 'warning'], text: 'warn', icon: '⚠️', colorKey: 'warn', prefix: '!'},\n            {keys: ['e', 'err', 'error'], text: 'error', icon: '⛔', colorKey: 'errr', prefix: 'x'},\n            {keys: ['x', 'exp', 'crash', 'fatal', 'exception'], text: 'exception', icon: '💀', colorKey: 'dead', prefix: '*'},\n            {keys: ['s', 'ack', 'done', 'success'], text: 'success', icon: '✅', colorKey: 'good', prefix: '✓'},\n            {keys: ['d', 'dbg', 'dbug', 'debug'], text: 'debug', icon: '🎃', colorKey: 'dbug', prefix: 'µ'}\n        ];\n\n        const entry = severityMap.find((item) => item.keys.includes(normalized))\n            || {text: 'undefined', icon: '❓', colorKey: 'punc', prefix: '?'};\n\n        const colorValue = `${vx.reset}${vx[entry.colorKey] ?? vx.punc}`;\n\n        return {\n            text: entry.text,\n            icon: entry.icon,\n            color: colorValue,\n            prefix: entry.prefix\n        };\n    },\n\n    /**\n     * @func extractEntity\n     * @memberof mcode\n     * @api private\n     * @desc Extracts, capitalizes, and returns the ENTITY name of a source module,\n     * by MicroCODE's convention this is APP of app.controller.js, USER of user.view.js, etc.\n     * @param {string} relativePath location of the source code module.\n     * @returns Just the first part--before 1st '.'--of the source file.\n     */\n    extractEntity: function (relativePath)\n    {\n        // Extract the file name (last part of the path)\n        const parts = relativePath.split(/[\\\\/]/); // Split on both forward and backslashes\n        const fileName = parts.pop(); // Get last element (file name)\n\n        // Extract the part before the first dot (.), return ready for message header as [ENTITY]\n        return fileName.split('.')[0].toUpperCase();\n    },\n\n    /**\n     * @func getFrom\n     * @memberof mcode\n     * @api private\n     * @desc Helper function for log() to determine module and line of caller.\n     * @param {string} source the module name from the mcode.log() call as a default (optional).\n     * @returns (2) strings: 'appModule' and 'module:line' of mcode.log() caller.\n     */\n    getFrom: function (source)\n    {\n        let appModule = 'APP';\n        let moduleLine = 'UNKNOWN';\n\n        if (typeof source !== 'string' || source.trim() === '') return [appModule, moduleLine];\n\n        // Get <app-base-dir> (3 levels up from <baseDir>/node_modules/mcode-log)\n        const baseDir = isNode ? path.resolve(__dirname, '../../..') : '';\n        appModule = source.split(/[\\.,:;!?\\s]+/)[0].toUpperCase();\n\n        // ƒ Convert absolute file path to relative to baseDir for NODE environment\n        const toRelative = (filePath) =>\n        {\n            if (!filePath) return source;\n            if (!isNode || filePath.startsWith('node:')) return filePath;\n\n            return path.relative(baseDir, filePath);\n        };\n\n        if (typeof Error.prepareStackTrace !== 'function')\n        {\n            // Fallback for non-V8 engines -- crawl a string stack trace\n            const stack = new Error().stack.split('\\n');\n\n            for (let i = 2; i < stack.length; i++)\n            {\n                if (!stack[i].includes('index.js'))\n                {\n                    const match = stack[i].match(/\\(([^)]+):(\\d+):\\d+\\)/);\n                    if (match)\n                    {\n                        // convert to relative path to keep short but informative\n                        const filePath = match[1];\n                        const lineNumber = match[2];\n                        let relativePath = (filePath.includes('node:'))\n                            ? filePath\n                            : toRelative(filePath);\n                        moduleLine = `${relativePath}:${lineNumber}`;\n                        appModule = this.extractEntity(relativePath);\n                    }\n                }\n            }\n        }\n        else\n        {\n            // V8 Engine, use structured stack trace for speed, save the original handler (string generator)\n            const prepareStackTrace = Error.prepareStackTrace;\n\n            try\n            {\n                // Override to return structured stack trace\n                Error.prepareStackTrace = (_, stack) => stack;\n                const stack = new Error().stack;\n\n                if (stack && stack.length > 2)\n                {\n                    const caller = stack.find((s) => !s.getFileName().includes('index.js'));\n\n                    if (caller)\n                    {\n                        // convert to relative path to keep short but informative\n                        const filePath = caller.getFileName();\n                        const lineNumber = caller.getLineNumber();\n                        let relativePath = (filePath.includes('node:'))\n                            ? filePath\n                            : toRelative(filePath);\n                        moduleLine = `${relativePath}:${lineNumber}`;\n                        appModule = this.extractEntity(relativePath);\n                    }\n                }\n            }\n            finally\n            {\n                // ensure restoration no matter what\n                Error.prepareStackTrace = prepareStackTrace;\n            }\n        }\n\n        return [appModule, moduleLine];\n    },\n\n    /**\n     * @func log/logHtml\n     * @memberof mcode\n     * @desc Logs App Events to the Console in a standardized format.\n     * @api public\n     * @param {object} message pre-formatted message to be logged.\n     * @param {string} source where the message orginated.\n     * @param {string} severity Event.Severity: 'info', 'warn', 'error', 'exception', and 'success'.\n     * @param {string} error [Optional] error message from another source.\n     * @param {string} event_id [Optional] a UUID to uniquely tie this logged event back into an error display in the UI.\n     * @param {object} vx [Optional] the color video effects to use, defaults to 'mcode.vt' for Console, 'mcode.ht' for HTML.\n     * @returns {string} '{severity}: {message}' for display in UI.\n     *\n     * @example\n     *      mcode.log('This is a test message.', 'myModule', 'info');\n     *      mcode.log('object', object, 'myModule);\n     */\n    logHtml: function (message = '<no message>', source = '<unknown>.js', severity = 'debug', error = null, event_id = null)\n    {\n        return mcode.log(message, source, severity, error, event_id, mcode.ht);\n    },\n    log: function (message = '<no message>', source = '<unknown>.js', severity = 'debug', error = null, event_id = null, vx = mcode.vt)\n    {\n        let logText = [];  // build the response as an array for speed\n        let status = `${severity}: ${message}`;\n        let logifiedMessage = '';\n\n        // support mcode.log(object) directly -- {0023}\n        if (_data.isObject(message)) return mcode.logobj('', message, source, severity, event_id, vx);\n\n        // support mcode.log('This object is bad', object) directly -- {0023}\n        if (_data.isObject(source))\n        {\n            // If event_id looks like a source string (not a UUID), use it as source\n            const evtIsSrc = (typeof event_id === 'string' && !event_id.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i));\n            const src = evtIsSrc ? event_id : '<unknown>.js';\n            const evt = !evtIsSrc ? event_id : null;\n            return mcode.logobj(message, source, src, severity, evt, vx);\n        }\n\n        // do not log 'debug' messages in production mode - {0008}\n        if ((severity === 'debug') && (mode === 'production')) return status;\n\n        // flatten the message object to strings for logging...\n        if (_data.isArray(message))\n        {\n            logifiedMessage = `${vx.nl}` + mcode.logify(mcode.logifyObject(message, vx), vx);\n        }\n        else if (_data.isJson(message))\n        {\n            logifiedMessage = `${vx.nl}` + mcode.logify(mcode.logifyObject(message, vx), vx);\n        }\n        else if (_data.isFunction(message))\n        {\n            logifiedMessage = `${vx.nl}` + `${message}`;\n        }\n        else\n        {\n            logifiedMessage = message;\n        }\n        const [appModule, moduleLine] = this.getFrom(source);\n\n        const {text: sevText, icon: sevIcon, color: sevColor, prefix: sevPrefix} = mcode.resolveSeverity(severity, vx);\n\n        logText.push(`${vx.reset}${vx.dim}++${vx.nl}${vx.reset}${vx.dim}`);\n        logText.push(`${vx.reset}${vx.dim} ${sevPrefix} ｢mcode｣: ${sevColor}${sevIcon} [${appModule}] '${mcode.colorizeLines(logifiedMessage, sevColor, vx)}'`);\n        logText.push(`${vx.nl}`);\n\n        let logifiedError = false;\n        if (error)\n        {\n            if (_data.isObject(error))\n            {\n                logifiedError = mcode.logify(mcode.logifyObject(error, vx), vx);\n            }\n            else if (_data.isJson(error))\n            {\n                logifiedError = mcode.logify(mcode.logifyObject(error, vx), vx);\n            }\n            else\n            {\n                logifiedError = error;\n            }\n            status += ` ERROR: ${mcode.simplify(logifiedError)}`;\n        }\n\n        if (logifiedError)\n        {\n            logifiedError = mcode.colorizeLines(logifiedError, sevColor, vx);\n\n            logText.push(`${vx.reset}${vx.dim}     error: ${vx.reset}${sevColor}${logifiedError}${vx.nl}`);\n        }\n        if (event_id)\n        {\n            const uuidInfo = _data.uuidDecode(event_id);  // see mcode.data package\n\n            logText.push(`${vx.reset}${vx.dim}     event: ${vx.reset}${sevColor}${event_id}${vx.reset}`);\n            logText.push(`${vx.reset}${vx.dim}    node: ${vx.reset}${sevColor}${uuidInfo?.macid}${vx.reset}${vx.nl}`);  // aligned to 'time:'\n        }\n        logText.push(`${vx.reset}${vx.dim}      time: ${vx.reset}${mcode.timeStamp()}`);\n        logText.push(`${vx.reset}${vx.dim}      from: ${vx.reset}${moduleLine}`);\n        logText.push(`${vx.reset}${vx.dim}  severity: ${vx.reset}${sevColor}${sevText}${vx.reset}${vx.nl}`);\n        logText.push(`${vx.reset}${vx.dim}--${vx.reset}`);\n\n        // Output to console or return HTML based on vx parameter\n        const output = logText.join('');\n\n        if (vx === mcode.ht)\n        {\n            // Wrap HTML output in div with severity color\n            const codeColor = sevColor.match(/color:\\s*([^;\"]*)/)?.[1] || '#3bc9db';\n            return `<div style=\"color: ${codeColor};\">${output}</div>`;\n        }\n        else\n        {\n            // Set severity color for VT output\n            console.log(`${sevColor}${output}${vx.reset}`);\n            return status;  // for caller to use as needed\n        }\n    },\n\n    /**\n     * @func logobj/logobjHtml\n     * @memberof mcode\n     * @desc Logs a labeled Object to the Console in a standardized format.\n     * @api public\n     * @param {string} objName the name of the Object and/or a message to precede it in the log.\n     * @param {object} obj javaScript Object to log.\n     * @param {string} source where the Object orginated.\n     * @param {string} event_id [Optional] a UUID to uniquely tie this logged event back into an error display in the UI.\n     * @param {object} vx [Optional] the color video effects to use, defaults to 'mcode.vt' for Console, 'mcode.ht' for HTML.\n     * @returns {string} '{objName}: {obj}' for display in UI.\n     *\n     * @example\n     *            mcode.logobj('myObject', myObject, 'myModule');\n     *            mcode.obj('myObject', myObject, 'myModule');\n     */\n    logobjHtml: function (objName, obj, source = '<undefined>.js', severity = 'info', event_id = null)\n    {\n        return mcode.logobj(objName, obj, source, severity, event_id, mcode.ht);\n    },\n    logobj: function (objName, obj, source = '<undefined>.js', severity = 'info', event_id = null, vx = mcode.vt)\n    {\n        let logText = [];  // build the response as an array for speed\n        let logifiedMessage = '';\n        const [appModule, moduleLine] = this.getFrom(source);\n        const {text: sevText, icon: sevIcon, color: sevColor, prefix: sevPrefix} = mcode.resolveSeverity(severity, vx);\n\n        const logObjName = (typeof objName === 'string' && objName.trim() !== '') ? `${sevColor}${objName}:${vx.reset}${vx.nl}` : '';\n\n        // 'Logifiy' all objects passed to this function...\n        if (_data.isArray(obj))\n        {\n            logifiedMessage = `${sevColor}{array}${vx.reset}${vx.nl}${vx.nl}${logObjName}` + mcode.logify(mcode.logifyObject(obj, vx), vx);\n        }\n        else if (_data.isObject(obj))\n        {\n            logifiedMessage = `${sevColor}{${(typeof obj)}}${vx.reset}${vx.nl}${vx.nl}${logObjName}` + mcode.logify(mcode.logifyObject(obj, vx), vx);\n        }\n        else if (_data.isJson(obj))\n        {\n            logifiedMessage = `${sevColor}{json}${vx.reset}${vx.nl}${vx.nl}${logObjName}` + mcode.logify(mcode.logifyObject(obj, vx), vx);\n        }\n        else\n        {\n            logifiedMessage = `${sevColor}{${(typeof obj)}}${vx.reset}${vx.nl}${vx.nl}${logObjName}` + obj;\n        }\n\n        // Apply severity color to the entire message\n        logifiedMessage = mcode.colorizeLines(logifiedMessage, sevColor, vx);\n\n        logText.push(`${vx.reset}${vx.dim}++${vx.nl}`);\n        logText.push(`${vx.reset}${vx.dim} ${sevPrefix} ｢mcode｣: ${sevColor}${sevIcon} [${appModule}] '${logifiedMessage}'${vx.nl}`);\n\n        if (event_id)\n        {\n            const uuidInfo = _data.uuidDecode(event_id);  // see mcode.data package\n\n            logText.push(`${vx.reset}${vx.dim}     event: ${vx.reset}${sevColor}${event_id}${vx.reset}`);\n            logText.push(`${vx.reset}${vx.dim}    node: ${vx.reset}${sevColor}${uuidInfo?.macid}${vx.reset}${vx.nl}`);  // aligned to 'time:'\n        }\n        logText.push(`${vx.reset}${vx.dim}      time: ${vx.reset}${mcode.timeStamp()}`);\n        logText.push(`${vx.reset}${vx.dim}      from: ${vx.reset}${moduleLine}`);\n        logText.push(`${vx.reset}${vx.dim}  severity: ${vx.reset}${sevColor}${sevText}${vx.reset}${vx.nl}`);\n        logText.push(`${vx.reset}${vx.dim}--${vx.reset}`);\n\n        // Output to console or return HTML based on vx parameter\n        const output = logText.join('');\n\n        if (vx === mcode.ht)\n        {\n            // Wrap HTML output in div with severity color using !important to override nested spans\n            const codeColor = sevColor.match(/color:\\s*([^;\"]*)/)?.[1] || '#3bc9db';\n            return `<div style=\"color: ${codeColor} !important;\">${output}</div>`;\n        }\n        else\n        {\n            // Set severity color for VT output\n            console.log(`${sevColor}${output}${vx.reset}`);\n        }\n    },\n\n    // convenient abbreviations of all the logged severities...\n    info: function (message, source, event_id) {mcode.log(message, source, 'info', null, event_id);},\n    warn: function (message, source, event_id) {mcode.log(message, source, 'warn', null, event_id);},\n    crash: function (message, source, event_id) {mcode.log(message, source, 'exception', null, event_id);},\n    fatal: function (message, source, event_id) {mcode.log(message, source, 'exception', null, event_id);},\n    done: function (message, source, event_id) {mcode.log(message, source, 'success', null, event_id);},\n    debug: function (message, source, event_id) {mcode.log(message, source, 'debug', null, event_id);},\n    success: function (message, source, event_id) {mcode.log(message, source, 'success', null, event_id);},\n\n    // error() takes an optional 'error' parameter for logging underlying error information\n    error: function (message, source, error, event_id) {mcode.log(message, source, 'error', error, event_id);},\n\n    /**\n     * @func ready\n     * @memberof mcode\n     * @desc Logs a message to the Console when the module is loaded to show version.\n     */\n    ready: function ()\n    {\n        this.log(`MicroCODE ${MODULE_NAME} v${packageJson.version} is loaded, mode: ${mode}, theme: ${theme}.`, MODULE_NAME, 'success');\n    },\n\n    /**\n     * @func exp/expHtml\n     * @memberof mcode\n     * @desc logs an exception to the Console in a standardized format and a stack dump.\n     * @api public\n     * @param {object} message pre-formatted message to be logged.\n     * @param {string} source where the message orginated.\n     * @param {string} exception the underlying exception object/trace that was caught.\n     * @param {string} exptrace the underlying exception object/trace that was caught... if 'source' is an object to log.\n     * @param {string} event_id [Optional] a UUID to uniquely tie this logged event back into an error display in the UI.\n     * @returns {string} 'message: {message} - exception: {exception}' for display in UI.\n     */\n    expHtml: function (message = '<no message>', source = '<unknown>.js', exception = {}, exptrace = {}, event_id = null)\n    {\n        return mcode.exp(message, source, exception, exptrace, event_id, mcode.ht);\n    },\n    exp: function (message = '<no message>', source = '<unknown>.js', exception = {}, exptrace = {}, event_id = null, vx = mcode.vt)\n    {\n        let logText = [];  // build the response as an array for speed\n        let logifiedMessage = '';\n        let logifiedException = '';\n        let isExpObject = false;\n\n        // support mcode.log(object) directly -- {0023}\n        if (_data.isObject(message)) return mcode.expobj('', message, source, exception, event_id, vx);\n\n        // if an exception object has been passed without source, shift parameters...\n        if (!_data.isString(source))\n        {\n            exception = source;\n            source = '<unknown>.js';\n        }\n\n        if (_data.isJson(message))\n        {\n            logifiedMessage = `${vx.nl}` + mcode.logify(mcode.logifyObject(message));\n        }\n        else\n        {\n            logifiedMessage = message;\n        }\n\n        // flatten the exception object to strings for logging...\n        if (_data.isObject(exception))\n        {\n            isExpObject = true;\n\n            if (exception.stack)\n            {\n                // colorized the passed the stack trace...\n                logifiedException = mcode.colorizeLines(exception.stack, vx.gray);\n            }\n            else\n            {\n                // treat as an Object, not a stack trace and show in default colors...\n                logifiedException = `${vx.reset}` + mcode.colorizeLines(mcode.logify(mcode.logifyObject(exception), vx), vx.punc);\n            }\n        }\n        else if (_data.isJson(exception))\n        {\n            // treat as JSON, not a stack trace and show in default colors...\n            logifiedException = `${vx.reset}` + mcode.colorizeLines(mcode.logify(mcode.logifyObject(exception), vx), vx.punc);\n        }\n        else\n        {\n            // treat as a string, not a stack trace or object and show in gray...\n            logifiedException = `${vx.reset}${vx.gray}` + exception;\n            logifiedException = mcode.colorizeLines(logifiedException, vx.gray);\n        }\n\n        const [appModule, moduleLine] = this.getFrom(source);\n\n        let sevColor = vx.reset;\n        sevColor += vx.dead;\n\n        // created a simplified exception message for the log entry...\n        const loggedException = ' exception: ' + mcode.colorizeLines(mcode.simplify(logifiedException), vx.dead);\n\n        // if 'loggedException' contains a stack trace, log it as an 'exception w/stack'\n        if (loggedException.includes('Error:') && loggedException.includes('at '))\n        {\n            isExpObject = true;\n        }\n\n        if (isExpObject)\n        {\n            logText.push(`${vx.reset}${vx.dim}++${vx.nl}`);\n            logText.push(`${vx.reset}${vx.dim} * ｢mcode｣: ${sevColor}💀 [${appModule}] '${logifiedMessage}'${vx.nl}`);\n            logText.push(`${vx.reset}${vx.dim}${sevColor} exception:${vx.nl}`);\n            logText.push(logifiedException + `${vx.nl}`);\n            if (event_id)\n            {\n                const uuidInfo = _data.uuidDecode(event_id);  // see mcode.data package\n\n                logText.push(`${vx.reset}${vx.dim}     event: ${vx.reset}${sevColor}${event_id}${vx.reset}`);\n                logText.push(`${vx.reset}${vx.dim}    node: ${vx.reset}${sevColor}${uuidInfo?.macid}${vx.reset}${vx.nl}`);  // aligned to 'time:'\n            }\n            logText.push(`${vx.reset}${vx.dim}      time: ${vx.reset}${mcode.timeStamp()}`);\n            logText.push(`${vx.reset}${vx.dim}      from: ${vx.reset}${moduleLine}`);\n            logText.push(`${vx.reset}${vx.dim}  severity: ${sevColor}exception w/stack${vx.reset}${vx.nl}`);\n            logText.push(`${vx.reset}${vx.dim}--${vx.reset}`);\n\n            const output = logText.join('');\n            if (vx === mcode.ht)\n            {\n                const codeColor = vx.punc.match(/color:\\s*([^;\"]*)/)?.[1] || '#3bc9db';\n                return `<div style=\"color: ${codeColor};\">${output}</div>`;\n            }\n            else\n            {\n                console.log(output);\n                return `${message} ${exception}`;  // for caller to return\n            }\n        }\n        else\n        {\n            logText.push(`${vx.reset}${vx.dim}++${vx.nl}`);\n            logText.push(`${vx.reset}${vx.dim} * ｢mcode｣: ${sevColor}💀 [${appModule}] '${logifiedMessage}'${vx.nl}`);\n            logText.push(`${vx.reset}${vx.dim}${sevColor}${loggedException}${vx.gray}${vx.nl}`);\n            logText.push(mcode.colorizeLines(`call stack: ${new Error().stack}${vx.nl}`, vx.gray));\n            if (event_id)\n            {\n                const uuidInfo = _data.uuidDecode(event_id);  // see mcode.data package\n\n                logText.push(`${vx.reset}${vx.dim}     event: ${vx.reset}${sevColor}${event_id}${vx.reset}`);\n                logText.push(`${vx.reset}${vx.dim}    node: ${vx.reset}${sevColor}${uuidInfo?.macid}${vx.reset}${vx.nl}`);  // aligned to 'time:'\n            }\n            logText.push(`${vx.reset}${vx.dim}      time: ${vx.reset}${mcode.timeStamp()}`);\n            logText.push(`${vx.reset}${vx.dim}      from: ${vx.reset}${moduleLine}`);\n            logText.push(`${vx.reset}${vx.dim}  severity: ${sevColor}exception w/trace${vx.reset}${vx.nl}`);\n            logText.push(`${vx.reset}${vx.dim}--${vx.reset}`);\n\n            const output = logText.join('');\n            if (vx === mcode.ht)\n            {\n                const codeColor = vx.punc.match(/color:\\s*([^;\"]*)/)?.[1] || '#3bc9db';\n                return `<div style=\"color: ${codeColor};\">${output}</div>`;\n            }\n            else\n            {\n                console.log(output);\n                return `${message} ${exception}`;  // for caller to return\n            }\n        }\n    },\n\n    /**\n     * @func expobj/expobjHtml\n     * @memberof mcode\n     * @desc Logs a labeled Object to the Console in a standardized format, with an associated exception and stack dump.\n     * @api public\n     * @param {string} objName the name of the Object and/or a message to precede it in the log.\n     * @param {object} obj javaScript Object to log.\n     * @param {string} source where the Object orginated.\n     * @param {string} exception the underlying exception message that was caught.\n     * @param {string} event_id [Optional] a UUID to uniquely tie this logged event back into an error display in the UI.\n     * @param {object} vx [Optional] the color video effects to use, defaults to 'mcode.vt' for Console, 'mcode.ht' for HTML.\n     * @returns {string} 'message: {message} - exception: {exception}' for display in UI.\n     *\n     * @example\n     *            mcode.expobj('myObject', myObject, 'myModule', err);  // from within a 'catch (err)' block\n     */\n    expobjHtml: function (objName = '<no name>', obj = {}, source = '<unknown>.js', exception = {}, event_id = null)\n    {\n        return mcode.expobj(objName, obj, source, exception, event_id, mcode.ht);\n    },\n    expobj: function (objName = '<no name>', obj = {}, source = '<unknown>.js', exception = {}, event_id = null, vx = mcode.vt)\n    {\n        let logText = [];  // build the response as an array for speed\n        let logifiedMessage = '';\n        let logifiedException = '';\n        const logObjName = (typeof objName === 'string' && objName.trim() !== '') ? `${objName}:${vx.nl}` : '';\n\n        let isExpObject = false;\n\n        // flatten the message object to strings for logging...\n        if (_data.isArray(obj))\n        {\n            logifiedMessage = `{array}${vx.nl}${vx.nl}${vx.punc}${logObjName}` + mcode.logify(mcode.logifyObject(obj), vx);\n        }\n        else if (_data.isObject(obj))\n        {\n            logifiedMessage = `{${(typeof obj)}}${vx.nl}${vx.nl}${vx.punc}${logObjName}` + mcode.logify(mcode.logifyObject(obj), vx);\n        }\n        else if (_data.isJson(obj))\n        {\n            logifiedMessage = `{json}${vx.nl}${vx.nl}${vx.punc}${logObjName}` + mcode.logify(mcode.logifyObject(obj), vx);\n        }\n        else\n        {\n            logifiedMessage = `{${(typeof obj)}}${vx.nl}${vx.nl}${vx.punc}${logObjName}` + obj;\n        }\n\n        // flatten the exception object to strings for logging...\n        if (_data.isObject(exception))\n        {\n            isExpObject = true;\n\n            if (exception.stack)\n            {\n                // colorized the passed the stack trace...\n                logifiedException = mcode.colorizeLines(exception.stack, vx.gray);\n            }\n            else\n            {\n                logifiedException = `${vx.reset}` + mcode.colorizeLines(mcode.logify(mcode.logifyObject(exception), vx), vx.punc);\n            }\n        }\n        else if (_data.isJson(exception))\n        {\n            logifiedException = mcode.colorizeLines(mcode.logify(mcode.logifyObject(exception), vx), vx.punc);\n        }\n        else\n        {\n            logifiedException = mcode.colorizeLines(exception, vx.gray);\n        }\n\n        const [appModule, moduleLine] = this.getFrom(source);\n\n        let sevColor = vx.reset;\n        sevColor += vx.dead;\n\n        // created a simplified exception message for the log entry...\n        const loggedException = 'exception: ' + mcode.simplify(logifiedException);\n\n        // if 'loggedException' contains a stack trace, log it as an 'exception w/stack'\n        if (loggedException.includes('Error:') && loggedException.includes('at '))\n        {\n            isExpObject = true;\n            source = `${sevColor}exception${vx.reset}`;\n        }\n\n        if (isExpObject)\n        {\n            logText.push(`${vx.reset}${vx.dim}++${vx.nl}`);\n            logText.push(`${vx.reset}${vx.dim} * ｢mcode｣: ${sevColor}💀 [${appModule}] '${logifiedMessage}'${vx.nl}`);\n            logText.push(`${vx.reset}${vx.dim}${sevColor}exception:${vx.nl}`);\n            logText.push(`${vx.reset}` + logifiedException + `${vx.nl}`);\n            if (event_id)\n            {\n                const uuidInfo = _data.uuidDecode(event_id);  // see mcode.data package\n\n                logText.push(`${vx.reset}${vx.dim}     event: ${vx.reset}${sevColor}${event_id}${vx.reset}`);\n                logText.push(`${vx.reset}${vx.dim}    node: ${vx.reset}${sevColor}${uuidInfo?.macid}${vx.reset}${vx.nl}`);  // aligned to 'time:'\n            }\n            logText.push(`${vx.reset}${vx.dim}      time: ${vx.reset}${mcode.timeStamp()}`);\n            logText.push(`${vx.reset}${vx.dim}      from: ${vx.reset}${moduleLine}`);\n            logText.push(`${vx.reset}${vx.dim}  severity: ${sevColor}exception w/stack${vx.reset}${vx.nl}`);\n            logText.push(`${vx.reset}${vx.dim}--${vx.reset}`);\n\n            const output = logText.join('');\n            if (vx === mcode.ht)\n            {\n                const codeColor = vx.punc.match(/color:\\s*([^;\"]*)/)?.[1] || '#3bc9db';\n                return `<div style=\"color: ${codeColor};\">${output}</div>`;\n            }\n            else\n            {\n                console.log(output);\n                return `Object: ${objName} ${exception}`;  // for caller to return\n            }\n        }\n        else\n        {\n            logText.push(`${vx.reset}${vx.dim}++${vx.nl}`);\n            logText.push(`${vx.reset}${vx.dim} * ｢mcode｣: ${sevColor}💀 [${appModule}] '${logifiedMessage}'${vx.nl}`);\n            logText.push(`${vx.reset}${vx.dim}${sevColor}${loggedException}${vx.gray}${vx.nl}`);\n            logText.push(mcode.colorizeLines(`call stack: ${new Error().stack}${vx.nl}`, vx.gray));\n            if (event_id)\n            {\n                const uuidInfo = _data.uuidDecode(event_id);  // see mcode.data package\n\n                logText.push(`${vx.reset}${vx.dim}     event: ${vx.reset}${sevColor}${event_id}${vx.reset}`);\n                logText.push(`${vx.reset}${vx.dim}    node: ${vx.reset}${sevColor}${uuidInfo?.macid}${vx.reset}${vx.nl}`);  // aligned to 'time:'\n            }\n            logText.push(`${vx.reset}${vx.dim}      time: ${vx.reset}${mcode.timeStamp()}`);\n            logText.push(`${vx.reset}${vx.dim}      from: ${vx.reset}${moduleLine}`);\n            logText.push(`${vx.reset}${vx.dim}  severity: ${sevColor}exception w/trace${vx.reset}${vx.nl}`);\n            logText.push(`${vx.reset}${vx.dim}--${vx.reset}`);\n\n            const output = logText.join('');\n            if (vx === mcode.ht)\n            {\n                const codeColor = vx.punc.match(/color:\\s*([^;\"]*)/)?.[1] || '#3bc9db';\n                return `<div style=\"color: ${codeColor};\">${output}</div>`;\n            }\n            else\n            {\n                console.log(output);\n                return `Object: ${objName} ${exception}`;  // for caller to return\n            }\n        }\n    },\n\n    /**\n     * @typedef {object} resxData\n     * @property {number} status - HTTP Status Code\n     * @property {string} message - Message to log to console / file\n     * @property {string} data - Response data to be send to Frontend/Client/Browser - optionally a HTML component\n     * @property {string} entity - [optional] The DB Entity name associated with this Response/Event\n     * @property {string} endpoint - [optional] The API Endpoint name associated with this Response/Event\n     * @property {string} error - [optional] Any error message associated with this response/event\n     * @property {UUID} _id - [optional] The DB Record UUID associated with this Response/Event\n     * @property {UUID} event_id - [optional] A unique Event UUID for traceability from UI to LOG.\n     */\n\n    /**\n     * @func resx\n     * @memberof mcode\n     * @desc 'res' extension - logs an http response and returns the response result.\n     * @api public\n     * @param {object} res the response object.\n     * @param {string} action the action that was being performed.\n     * @param {object} resxData the response: datatype = 'resxData'.\n     * @param {string} source where the message orginated.\n     * @returns {object} the response object.\n     */\n    resx: function (res = {}, action = 'none', resxData = {}, source = '<unknown>.js>')\n    {\n        // example   DB Entity: READ [200] OK,  Entity: 'user' _id: nnnn-nnnn-nnnn-nnnn  or  Array: (n)\n        // example HTML Result: READ [200] OK,  Endpoint: 'account.settings'\n        const _id = resxData?._id || resxData.data?._id || resxData.data?.id || '<_id?>';\n        const count_id = _data.isArray(resxData.data) ? `Array: (${resxData.data.length})` : (_id != '') ? `_id: ${_id}` : ``;\n        const event_id = resxData?.event_id || null;\n\n        const entity = resxData?.entity;\n        const endpoint = resxData?.endpoint || `<endpoint?>`;\n        const caller = (entity) ? `Entity: ${entity} ${count_id}` : `Endpoint: ${endpoint}`;\n        const status = resxData?.status || 0;\n        const message = `${action.toUpperCase()} ${_data.httpStatus(status)},  ${caller}`;\n\n        // status to severity: 100s = 'info', 200s = 'success', etc.\n        const severity = _data.httpSeverity(status);\n\n        if (_data.isHtml(resxData?.data))\n        {\n            if (severity === 'fatal')\n            {\n                // show exception that caused this in the response...\n                this.exp(message, source, resxData?.error?.message, resxData?.error?.stack, event_id);\n            }\n            else\n            {\n                // all severities other than 'fatal' exception are logged\n                // with color and icons based on 'severity'\n                this.log(message, source, severity, resxData?.error?.message, event_id);\n            }\n\n            // send HTML directly to the Frontend (HTMX Support)\n            return res.status(resxData.status).send(resxData.data);\n        }\n        else\n        {\n            if (resxData.error)\n            {\n                // returning an error in the response...\n                this.exp(message, source, resxData.error, null, event_id);\n                return res.status(resxData.status).send({message: message, error: resxData.error});\n            }\n            if (resxData.data)\n            {\n                if (entity)\n                {\n                    // returning Entity data in the response...\n                    this.log(message, source, severity, null, event_id);\n                    return res.status(resxData.status).send({message: message, data: resxData.data});\n                }\n                else\n                {\n                    // returning a direct Endpoint *result*, like HTML/HTMX - {0015}\n                    this.log(message, source, severity, null, event_id);\n                    return res.status(resxData.status).send(resxData.data);\n                }\n            }\n\n            // log the response...\n            this.log(message, source, severity, null, event_id);\n\n            // handle 'No Content' (204) response - {0017}\n            if (resxData.status === 204)\n            {\n                return res.status(204).end();  // to end request without a body and prevent client retry\n            }\n\n            // all other responses...\n            return res.status(resxData.status).send({message: message});\n        }\n    },\n\n    /**\n     * @func trace\n     * @memberof mcode\n     * @desc logs 'function call' showing call patterns to the Console in a standardized format.\n     * @api public\n     * @param {object} message pre-formatted message to be logged.\n     * @param {string} source where the message orginated.\n     * @param {string} event_id [Optional] a UUID to uniquely tie this logged event back into an error display in the UI.\n     * @param {object} vx [Optional] the color video effects to use, defaults to 'mcode.vt' for Console, 'mcode.ht' for HTML.\n     * @returns nothing.\n     */\n    traceHtml: function (message = '<no message>', source = '<unknown>.js', event_id = null)\n    {\n        return mcode.trace(message, source, event_id, mcode.ht);\n    },\n    trace: function (message = '<no message>', source = '<unknown>.js', event_id = null, vx = mcode.vt)\n    {\n        let logText = [];  // build the response as an array for speed\n        let logifiedMessage = '';\n\n        // flatten the message object to strings for logging...\n        if (_data.isArray(message))\n        {\n            logifiedMessage = `${vx.nl}` + mcode.logify(mcode.logifyObject(message), vx);\n        }\n        else if (_data.isObject(message))\n        {\n            logifiedMessage = `${vx.nl}` + mcode.logify(mcode.logifyObject(message), vx);\n        }\n        else if (_data.isJson(message))\n        {\n            logifiedMessage = `${vx.nl}` + mcode.logify(mcode.logifyObject(message), vx);\n        }\n        else\n        {\n            logifiedMessage = message;\n        }\n\n        const [appModule, moduleLine] = this.getFrom(source);\n\n        let sevColor = vx.reset + vx.punc;\n\n        // Function calls are always logged as 'Info'\n        logText.push(`${vx.reset}${vx.dim}++${vx.nl}`);\n        logText.push(`${vx.reset}${vx.dim} µ ｢mcode｣: ${sevColor}🔍 [${appModule}] '${logifiedMessage}'${vx.reset}${vx.gray}${vx.nl}`);\n        logText.push(mcode.colorizeLines(`call stack: ${new Error().stack}${vx.nl}`, vx.gray));\n        if (event_id)\n        {\n            const uuidInfo = _data.uuidDecode(event_id);  // see mcode.data package\n\n            logText.push(`${vx.reset}${vx.dim}     event: ${vx.reset}${sevColor}${event_id}${vx.reset}`);\n            logText.push(`${vx.reset}${vx.dim}    node: ${vx.reset}${sevColor}${uuidInfo?.macid}${vx.reset}${vx.nl}`);  // aligned to 'time:'\n        }\n        logText.push(`${vx.reset}${vx.dim}      time: ${vx.reset}${mcode.timeStamp()}`);\n        logText.push(`${vx.reset}${vx.dim}      from: ${vx.reset}${moduleLine}`);\n        logText.push(`${vx.reset}${vx.dim}  severity: ${sevColor}trace${vx.reset}${vx.nl}`);\n        logText.push(`${vx.reset}${vx.dim}--${vx.reset}`);\n\n        const output = logText.join('');\n        if (vx === mcode.ht)\n        {\n            const codeColor = vx.punc.match(/color:\\s*([^;\"]*)/)?.[1] || '#3bc9db';\n            return `<div style=\"color: ${codeColor};\">${output}</div>`;\n        }\n        else\n        {\n            console.log(output);\n        }\n    },\n\n    /**\n     * @func simplify\n     * @memberof mcode\n     * @desc Strips a string of BRACES, BRACKETS, QUOTES, etc.\n     * @api public\n     * @param {object} object the string to be simplified to data\n     * @returns {string} the simplified text\n     */\n    simplify: function (object)\n    {\n        if (_data.isUndefined(object))\n        {\n            return 'undefined';\n        }\n\n        // flatten the message object to strings for logging...\n        if (_data.isObject(object))\n        {\n            // do not use JSON.stringify(object, null, 4)\n            // --it's output is horrible, produce our own here in 'simplify()'\n            object = JSON.stringify(object);\n        }\n\n        let simplifiedText = '';\n        let inValue = false;\n        let inEscape = false;\n        let c = ' ';\n        let clast = ' ';\n\n        for (let i = 0; i < object.length; i++)\n        {\n            clast = c;\n            c = object[i];\n\n            // detect VT52,100,200 escape sequence\n            if (c === '\\x1b')\n            {\n                inEscape = true;\n                continue;\n            }\n            // skip entire escape sequence\n            if (inEscape)\n            {\n                if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')))\n                {\n                    inEscape = false;\n                }\n                continue;\n            }\n            switch (c)\n            {\n                case '{':\n                case '}':\n                case '[':\n                case ']':\n                    inValue = false;\n                    c = ' ';\n                    break;\n                case '\"':\n                    c = ' ';\n                    break;\n                case ':':\n                    simplifiedText += c;\n                    if (!inValue)\n                    {\n                        simplifiedText += ' ';\n                        c = ' ';\n                    }\n                    inValue = true;\n                    break;\n                case ',':\n                    simplifiedText += c;\n                    simplifiedText += ' ';\n                    c = ' ';\n                    inValue = false;\n                    break;\n                case '\\n':\n                case '\\t':\n                    c = ' ';\n                    break;  // strip newlines and tabs\n                case ' ':\n                    if (clast != ' ')\n                    {\n                        simplifiedText += c;\n                    }\n                    break;\n                default:\n                    simplifiedText += c;\n                    break;\n            }\n        }\n\n        return simplifiedText;\n    },\n\n    /**\n     * @func simplifyObject\n     * @memberof mcode\n     * @desc Strips an object of BRACES, BRACKETS, QUOTES, etc.\n     * @api public\n     * @param {object} objectToSimplify the object to be formatted for the event log\n     * @returns {string} the simplified object\n     */\n    simplifyObject: function (objectToSimplify)\n    {\n        // do not use JSON.stringify(object, null, 4) -- it's output is horrible, use our own\n        return mcode.simplify(JSON.stringify(objectToSimplify));\n    },\n\n    /**\n     * @func logify/logifyHtml\n     * @memberof mcode\n     * @desc Formats a string of BRACES, BRACKETS, QUOTES, for display in the EVENT LOG.\n     * No formatting occurs until the opening brace '{' of the JSON Data. VT Escape sequences are stripped.\n     * @api public\n     * @param {string} textToLogify the string to be formatted for the event log\n     * @returns {string} the logified text\n     */\n    logifyHtml: function (textToLogify)\n    {\n        return mcode.logify(textToLogify, mcode.ht);\n    },\n    logify: function (textToLogify, vx = mcode.vt)\n    {\n        let inJson = false;  // start formatting when we hit the first '{' or '['\n        let inValue = false;  // handle 'true, false, null, or number' as-is\n        let inString = false;  // handle \"quoted strings\" as-is\n        let inLiteral = false;  // take internal text as-is\n        let inKey = false;  // track when we're processing a key name\n        let expectingValue = false;  // track when we just processed a colon and expect a value\n        let contextStack = [];  // stack to track nested object/array contexts\n\n        let logText = [];  // build the response as an array for speed\n        let tabStop = 0;  // indent level for formatting\n        let lineEmpty = true;  // controls indent() output\n\n        // ƒ to remove surrounding \" \" from key names only.\n        let keyPairs = (jsonString) =>\n        {\n            // loop backward through the string, building a new copy, remove \" \" from key names\n            let newString = '';\n            let inKey = false;\n            let inKeyName = false;\n            let inString = false;\n            let c = '';\n\n            for (let i = jsonString.length - 1; i >= 0; i--)\n            {\n                c = jsonString[i];\n\n                if (inString)\n                {\n                    if (c === '\"')\n                    {\n                        inString = false;\n                        newString = c + newString;\n                        continue;\n                    }\n                    newString = c + newString;\n                    continue;\n                }\n                if (inKeyName)\n                {\n                    if (c === '\"')\n                    {\n                        inKeyName = false;\n                        inKey = false;\n                        continue;\n                    }\n                    else\n                    {\n                        newString = c + newString;\n                        continue;\n                    }\n                }\n                if (inKey)\n                {\n                    if (c === '\"')\n                    {\n                        inKeyName = true;\n                        continue;\n                    }\n                    else\n                    {\n                        newString = c + newString;\n                        continue;\n                    }\n                }\n                if (c === '\"')\n                {\n                    newString = c + newString;\n                    inString = true;\n                    continue;\n                }\n                if (c === ':')\n                {\n                    inKey = true;\n                }\n                newString = c + newString;\n            }\n\n            return newString;\n        };\n\n        // ƒ to indent the JSON\n        let indent = () =>\n        {\n            let newline = '';\n            if (!lineEmpty)\n            {\n                newline += `${vx.nl}` + `${vx.reset}`;\n                for (let index = 0; index < tabStop; index++)\n                {\n                    newline += '    ';  // 4-space tab-stop\n                }\n                lineEmpty = true;\n            }\n            return newline;\n        };\n\n        // ƒ to check for legal value name characters\n        let isKeyChar = (c) =>\n        {\n            const code = c.charCodeAt(0);\n            return (c !== '\"') && (c !== ':') && (code >= 32 && code <= 126);\n        };\n\n        // ƒ to check for alpha-numeric characters\n        let isValueChar = (c) =>\n        {\n            return (c === '-') || (c === '_') || (c === ' ') || (c === '$') || (c === '.') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9');\n        };\n\n        // ƒ to get the appropriate color for a value based on its content\n        let getValueColor = (valueText) =>\n        {\n            const trimmed = valueText.trim();\n\n            // Check for boolean values\n            if (trimmed === 'true') return vx.true;\n            if (trimmed === 'false') return vx.false;\n\n            // Check for null\n            if (trimmed === 'null') return vx.null;\n\n            // Check for BigInt first (ends with 'n') - must come before integer check\n            if (/^\\d+n$/.test(trimmed))\n            {\n                // BigInt (ends with 'n')\n                return vx.bigint;\n            }\n\n            // Check for numbers\n            if (/^-?\\d+$/.test(trimmed))\n            {\n                // Integer\n                return vx.integer;\n            }\n            if (/^-?\\d*\\.\\d+([eE][+-]?\\d+)?$/.test(trimmed))\n            {\n                // Float/real number\n                return vx.real;\n            }\n\n            // Fallback to generic value color\n            return vx.value;\n        };\n\n        // S T A R T   P R O C E S S I N G   T H E   J S O N   S T R I N G\n        textToLogify = keyPairs(textToLogify);\n\n        let cc = '';  // 'cc' - current character, vs. 'c' - temporary character\n\n        for (let i = 0; i < textToLogify.length; i++)\n        {\n            cc = textToLogify[i];\n\n            if (textToLogify.substring(i, i + 2) === '\\\\\\\\')\n            {\n                // take backslash as-is\n                logText.push(cc);\n                logText.push(cc);\n                i++; // skip the next '\\'\n                continue;\n            }\n\n            if (!inString && textToLogify.substring(i, i + 2) === `\\${vt.nl}`)\n            {\n                logText.push(indent());\n                lineEmpty = false;\n                i++; // skip the 'n'\n                continue;\n            }\n\n            if (inLiteral)\n            {\n                logText.push(cc);\n                if (cc === '}')\n                {\n                    inLiteral = false;\n                }\n                continue;\n            }\n\n            if (textToLogify.substring(i, i + 2) === '${')\n            {\n                inLiteral = true;\n                logText.push(cc);\n                continue;\n            }\n\n            if (!inString && !inJson && (cc === '{' || cc === '['))\n            {\n                inJson = true;\n                --i;  // reprocess '{' or '[' as JSON\n                continue;\n            }\n\n            if (inKey)\n            {\n                if (!isKeyChar(cc))\n                {\n                    // End of key, add reset and continue\n                    logText.push(`${vx.reset}`);\n                    inKey = false;\n                    --i;  // reprocess the character that ended the key\n                }\n                else\n                {\n                    logText.push(cc);\n                }\n                continue;\n            }\n\n            if (inValue)\n            {\n                if (!isValueChar(cc))\n                {\n                    // We've reached the end of a value, find what we just collected and colorize it\n                    // Look back through logText to find the start of this value\n                    let valueStartIndex = logText.length;\n                    let collectedValue = '';\n\n                    // Scan backwards to find where the value started\n                    for (let j = logText.length - 1; j >= 0; j--)\n                    {\n                        const char = logText[j];\n                        if (char && char.length === 1 && isValueChar(char))\n                        {\n                            collectedValue = char + collectedValue;\n                            valueStartIndex = j;\n                        }\n                        else\n                        {\n                            break;\n                        }\n                    }\n\n                    if (collectedValue)\n                    {\n                        // Remove the collected characters from logText\n                        logText.splice(valueStartIndex);\n\n                        // Add the value with appropriate color\n                        const valueColor = getValueColor(collectedValue);\n                        logText.push(`${valueColor}${collectedValue}${vx.reset}`);\n                    }\n\n                    inValue = false;\n                    expectingValue = false;\n                    // Don't use --i, instead continue with current character processing\n                    // Fall through to process the current character normally\n                }\n                else\n                {\n                    logText.push(cc);\n                    continue;\n                }\n            }\n\n            if (inString)\n            {\n                if (cc === '\"')\n                {\n                    inString = false;\n                    cc = '\\\"' + `${vx.reset}`;\n                }\n                else if (cc === '\\n')\n                {\n                    // Handle newlines within strings by adding proper indentation\n                    logText.push(cc);\n                    // Add indentation for the next line within the string\n                    logText.push(`${vx.reset}`);\n                    for (let index = 0; index < tabStop; index++)\n                    {\n                        logText.push('    ');  // 4-space tab-stop to match key indentation\n                    }\n                    logText.push(`${vx.string}`);  // Restore string color after indentation\n                    continue;\n                }\n                logText.push(cc);\n                continue;\n            }\n\n            if (!inJson)\n            {\n                logText.push(cc);\n                lineEmpty = false;\n                continue;\n            }\n\n            switch (cc)\n            {\n                case '{':\n                    lineEmpty = true;  // prevent blank line before/between { JSON Objects }\n                    logText.push(indent() + `${vx.punc}{${vx.reset}`);\n                    lineEmpty = false;\n                    tabStop++;\n                    logText.push(indent());\n                    contextStack.push('object');  // push object context\n                    expectingValue = false;  // objects start with keys, not values\n                    break;\n                case '[':\n                    logText.push(indent() + `${vx.punc}[${vx.reset}`);\n                    lineEmpty = false;\n                    tabStop++;\n                    logText.push(indent());\n                    contextStack.push('array');   // push array context\n                    expectingValue = true;  // arrays contain values (an object being a value), not key-value pairs\n                    break;\n                case '}':\n                    tabStop--;\n                    logText.push(indent() + `${vx.punc}}${vx.reset}`);\n                    lineEmpty = false;\n                    inJson = tabStop > 0;\n                    contextStack.pop();  // pop object context\n                    // Reset expectingValue based on current context\n                    const currentContext = contextStack[contextStack.length - 1];\n                    expectingValue = currentContext === 'array';\n                    break;\n                case ']':\n                    tabStop--;\n                    logText.push(indent() + `${vx.punc}]${vx.reset}`);\n                    lineEmpty = false;\n                    contextStack.pop();  // pop array context\n                    // Reset expectingValue based on current context\n                    const currentContextAfterArray = contextStack[contextStack.length - 1];\n                    expectingValue = currentContextAfterArray === 'array';\n                    break;\n                case ',':\n                    logText.push(`${vx.reset}${vx.punc},${vx.reset}` + indent());\n                    lineEmpty = false;\n                    // In array context, we're still expecting values after a comma\n                    // In object context, we're expecting a key after a comma\n                    const currentCtx = contextStack[contextStack.length - 1];\n                    expectingValue = currentCtx === 'array';\n                    break;\n                case ':':\n                    logText.push(`${vx.punc}:${vx.reset} `);\n                    lineEmpty = false;\n                    expectingValue = true;\n                    break;\n                case '\"':\n                    logText.push(`${vx.string}`);\n                    logText.push('\\\"');\n                    lineEmpty = false;\n                    inString = true;\n                    break;\n                case ' ':\n                    lineEmpty = false;\n                    break;\n                default:\n                    if (isKeyChar(cc))\n                    {\n                        if (expectingValue)\n                        {\n                            inValue = true;  // true, false, null, or number\n                            // We'll collect the value and then colorize it appropriately\n                            logText.push(cc);\n                        }\n                        else\n                        {\n                            // This is a key name\n                            inKey = true;\n                            logText.push(`${vx.key}${cc}`);\n                        }\n                        lineEmpty = false;\n                    }\n                    break;\n            }\n        }\n\n        return logText.join('');\n    },\n\n    /**\n     * @func logifyObject\n     * @memberof mcode\n     * @desc Converts a JSON Object into loggable text, like JSON.stringify() but with more control.\n     * @api public\n     * @param {object} objectToLogify\n     * @param {object|array} vxOrParentObjects the color table (mcode.vt or mcode.ht) or parentObjects array for backward compatibility.\n     * @param {array} parentObjects internal parameter for circular reference detection.\n     * @returns {string} the logified object\n     */\n    logifyObject: function (objectToLogify, vxOrParentObjects = [''], parentObjects = null)\n    {\n        // Handle parameter overloading: determine if second parameter is vx or parentObjects\n        let vx = null;\n        let actualParentObjects = [''];\n\n        if (Array.isArray(vxOrParentObjects))\n        {\n            // Old signature: (objectToLogify, parentObjects)\n            actualParentObjects = vxOrParentObjects;\n        }\n        else\n        {\n            // New signature: (objectToLogify, vx, parentObjects)\n            vx = vxOrParentObjects;\n            actualParentObjects = parentObjects || [''];\n        }\n\n        // ƒ to check for and handle circular references\n        const isCyclic = (member) =>\n        {\n            if (actualParentObjects.includes(member))\n            {\n                return '\"<self-reference>\"';  // 'true'\n            }\n            return false;\n        };\n\n        // ƒ to handle non-object types\n        const handleNonObject = (value) =>\n        {\n            if (value === null)\n            {\n                return `null`;\n            }\n            if (typeof value === 'string')\n            {\n                // detect JSON objects that have been escaped and convert them back to JSON\n                if (value.startsWith(`{`) && value.endsWith(`}`))\n                {\n                    // convert to JSON representation\n                    return value.replaceAll('\\\\\"', '\"');\n                }\n                else\n                {\n                    // standardize text for enclosing \"s.\n                    return `\"${value.replaceAll(`\"`, `'`)}\"`;\n                }\n            }\n            if (typeof value === 'function')\n            {\n                return `\"ƒ ${value.name}\"`;\n            }\n            if (typeof value === 'symbol')\n            {\n                return '\"<symbol>\"';\n            }\n            if (typeof value === 'bigint')\n            {\n                return value.toString() + 'n';\n            }\n            if (typeof value === 'number')\n            {\n                return value.toString();\n            }\n            if (typeof value === 'boolean')\n            {\n                return value.toString();\n            }\n            if (typeof value === 'undefined')\n            {\n                return '\"<undefined>\"';\n            }\n\n            return '<unknown>';\n        };\n\n        // ƒ to detect Fetch API Headers, Request, and Response objects\n        const isFetchHeaders = (value) =>\n            typeof Headers === 'function' && value instanceof Headers;\n\n        // ƒ to convert Headers to simple object\n        const headersToObject = (headers) =>\n        {\n            if (!headers) return {};\n\n            const result = {};\n\n            if (typeof headers.forEach === 'function')\n            {\n                headers.forEach((headerValue, headerName) =>\n                {\n                    result[headerName] = headerValue;\n                });\n            }\n            else if (typeof headers.entries === 'function')\n            {\n                for (const [headerName, headerValue] of headers.entries())\n                {\n                    result[headerName] = headerValue;\n                }\n            }\n\n            return result;\n        };\n\n        // ƒ to detect Fetch API Response objects\n        const isFetchResponse = (value) =>\n            typeof Response === 'function' && value instanceof Response;\n\n        // ƒ to detect Fetch API Request objects\n        const isFetchRequest = (value) =>\n            typeof Request === 'function' && value instanceof Request;\n\n        // ƒ to convert Response to simple object\n        const summarizeResponse = (response) =>\n        {\n            return {\n                ok: response.ok,\n                status: response.status,\n                statusText: response.statusText,\n                redirected: response.redirected,\n                type: response.type,\n                url: response.url,\n                bodyUsed: response.bodyUsed,\n                headers: headersToObject(response.headers),\n                body: response.bodyUsed ? '<body consumed>' : '<body available via response.clone()>'\n            };\n        };\n\n        // ƒ to convert Request to simple object\n        const summarizeRequest = (request) =>\n        {\n            return {\n                method: request.method,\n                url: request.url,\n                cache: request.cache,\n                credentials: request.credentials,\n                integrity: request.integrity,\n                keepalive: request.keepalive,\n                mode: request.mode,\n                redirect: request.redirect,\n                referrer: request.referrer,\n                referrerPolicy: request.referrerPolicy,\n                bodyUsed: request.bodyUsed,\n                headers: headersToObject(request.headers)\n            };\n        };\n\n        // ƒ to recursively stringify an object\n        const recursiveStringify = (currentObject) =>\n        {\n            // Handle non-object types\n            if (typeof currentObject !== 'object' || currentObject === null)\n            {\n                return handleNonObject(currentObject);\n            }\n\n            if (_data.isTimeStamp(currentObject))\n            {\n                return `\"${this.timeStamp(now = currentObject, local = true)}\"`;\n            }\n\n            // special case for File objects which cannot be completely stringified\n            if (typeof File !== 'undefined' && currentObject instanceof File)\n            {\n                let file = currentObject;\n                const date = new Date(file.lastModified);\n\n                // change File to a simple object\n                currentObject = {\n                    name: file.name,\n                    size: file.size,\n                    date: date.toString()\n                };\n            }\n\n            if (isFetchHeaders(currentObject))\n            {\n                actualParentObjects.pop();\n\n                return recursiveStringify(headersToObject(currentObject));\n            }\n\n            if (isFetchResponse(currentObject))\n            {\n                actualParentObjects.pop();\n\n                return recursiveStringify(summarizeResponse(currentObject));\n            }\n\n            if (isFetchRequest(currentObject))\n            {\n                actualParentObjects.pop();\n\n                return recursiveStringify(summarizeRequest(currentObject));\n            }\n\n            // Detect and handle circular references\n            let cyclicCheck = isCyclic(currentObject);\n            if (cyclicCheck)\n            {\n                return cyclicCheck;\n            }\n\n            // Keep track of parent objects to detect circular references\n            actualParentObjects.push(currentObject);\n\n            let result;\n            if (Array.isArray(currentObject))\n            {\n                // ƒ to handle array members\n                result = currentObject.map((item) => recursiveStringify(item)).join(',');\n\n                actualParentObjects.pop();\n\n                return `[${result}]`;\n            }\n            else\n            {\n                // ƒ to handle object members\n                result = Object.keys(currentObject).map((key) =>\n                {\n                    let value = currentObject[key];\n\n                    // Skip functions, symbols, and undefined properties\n                    if (typeof value === 'function'\n                        || typeof value === 'symbol'\n                        || typeof value === 'undefined'\n                        || typeof value === 'null')\n                    {\n                        return `\"${key}\":${handleNonObject(value)}`;\n                    }\n\n                    return `\"${key}\":${recursiveStringify(value)}`;\n\n                }).filter(Boolean).join(',');\n\n                actualParentObjects.pop();\n\n                return `{${result}}`;\n            }\n        };\n\n        // stringify the object, recursively\n        return recursiveStringify(objectToLogify);\n    },\n\n    /**\n     * @func listifyObject\n     * @memberof mcode\n     * @desc Converts a JSON Object into a HTML or JSX List.\n     * @api public\n     * @param {Object} objectToListify the object to be converted to a HTML List.\n     * @param {string} outputType how to out the list: 'html' or 'jsx'.\n     * @returns {string} the HTML List code.\n     */\n    listifyObject: function (objectToListify, outputType = 'html')\n    {\n        let listifiedText = '';\n        let keyIndex = 0;\n\n        if (outputType === 'jsx')\n        {\n            listifiedText += '<ul className=\"list-group\">';\n\n            Object.entries(objectToListify).forEach(([key, value]) =>\n            {\n                // ƒ to convert array element to text, simplify for display, and add to LIST...\n                listifiedText += `<li className=\"list-group-item\" key=\"${keyIndex++}\">${key}: ${value}</li>`;\n            });\n\n            listifiedText += '</ul>';\n        }\n        else\n        {\n            Object.entries(objectToListify).forEach(([key, value]) =>\n            {\n                // ƒ to convert array element to text, simplify for display, and add to LIST...\n                listifiedText += `<li className=\"list-group-item\" key=\"${keyIndex++}\">${key}: ${value}</li>`;\n            });\n        }\n\n        return listifiedText;\n    },\n\n    /**\n     * @func listifyArray\n     * @memberof mcode\n     * @desc Converts an array of text items into a HTML or JSX List.\n     * @api public\n     * @param {Array<any>} arrayToListify the array to be converted to a HTML List.\n     * @param {string} outputType how to out the list: 'html' or 'jsx'.\n     * @returns {string} the HTML List code.\n     */\n    listifyArray: function (arrayToListify, outputType = 'html')\n    {\n        let listText = [];\n        let keyIndex = 0;\n\n        if (outputType === 'jsx')\n        {\n            listText.push(`<ul className=\"list-group\">`);\n\n            arrayToListify.forEach(element =>\n            {\n                // ƒ to convert array element to text, simplify for display, and add to LIST...\n                listText.push(`<li className=\"list-group-item\" key=\"${keyIndex++}\">${mcode.simplifyObject(element)}</li>`);\n            });\n\n            listText.push('</ul>');\n        }\n        else\n        {\n            arrayToListify.forEach(element =>\n            {\n                // ƒ to convert array element to text, simplify for display, and add to LIST...\n                listText.push(`<li className=\"list-group-item\" key=\"${keyIndex++}\">${mcode.simplifyObject(element)}</li>`);\n            });\n        }\n\n        return listText.join('');\n    },\n\n    /**\n     * @func colorizeLines\n     * @memberof mcode\n     * @desc Colorizes each line of a string using VT escape sequences or HTML inline styles.\n     * This is useful for log messages that span multiple lines and need to maintain color, the console\n     * does not do this automatically. HTML does this automatically so that mode just returns the input unchanged.\n     * @api public\n     * @param {string} inputLines the string to be colorized.\n     * @param {string} vtColor the VT escape sequence to use for colorizing the lines.\n     * @param {object} vx the color table (mcode.vt or mcode.ht) - optional, defaults to VT.\n     * @returns {string} the colorized string.\n     * @example\n     *          mcode.colorizeLines('Hello, World!${vx.nl}This is fun!', mcode.vt.red);  // returns: '\\u001b[31mHello, World!\\u001b[31mThis is fun!'\n     */\n    colorizeLines: function (inputLines, vtColor, vx = null)\n    {\n        // If vx is provided and it's the HTML table, return unchanged since HTML doesn't need line color carry-over\n        if (vx === mcode.ht) return inputLines;\n\n        // Default VT behavior\n        // Split the input string into lines\n        const lineArray = inputLines?.split(`${vx ? vx.nl : mcode.vt.nl}`);\n\n        let currentColor = vtColor;\n\n        // for each line in the array, find the last escape sequence and apply that color to\n        // all the lines that follow until a new escape sequence is found at the end of a line {0013}\n        for (let i = 0; i < lineArray?.length; i++)\n        {\n            // Apply the color to each line\n            lineArray[i] = `${currentColor}${lineArray[i]}`;\n\n            // pick up the last color in the line we just added...\n            currentColor = lineArray[i].match(/\\u001b\\[\\d+m/g)?.pop() || currentColor;\n        }\n\n        // Rejoin the colorized lines into a single string\n        return lineArray ? lineArray.join(`${vx ? vx.nl : mcode.vt.nl}`) : '';\n    },\n\n    /**\n     * @func timeStamp\n     * @memberof mcode\n     * @desc Generates a timestamp string: YYYY-MM-DD Day HH:MM:SS.mmm.\n     * @api public\n     * @param {boolean} local [Optional] determines whether or not local time is used, if not it returns use UTC.\n     * @returns {string} 'YYYY-MM-DD Day HH:MM:SS.mmm UTC|Local'.\n     */\n    timeStamp: function (now = new Date(), local = true)\n    {\n        // ƒ to make sure all fields are fixed length with leading zeros\n        const leadingZeros = (number, length) =>\n        {\n            let numberField = '' + number;\n            while (numberField.length < length)\n            {\n                numberField = '0' + numberField;\n            }\n            return numberField;\n        };\n\n        if (local)\n        {\n            let dayofweek = WEEKDAYS[now.getDay()];           // 3-letter day of week\n            let year = now.getFullYear();                     // 4-digit year\n            let month = MONTHS[now.getMonth()];               // 3-letter month of year\n            let day = leadingZeros(now.getDate(), 2);         // 2-digit day\n            let hours = leadingZeros(now.getHours(), 2);      // 2-digit hour\n            let minutes = leadingZeros(now.getMinutes(), 2);  // 2-digit minute\n            let seconds = leadingZeros(now.getSeconds(), 2);  // 2-digit second\n            let ms = leadingZeros(now.getMilliseconds(), 3);  // 3-digit millisecond\n\n            return `${year}-${month}-${day} ${dayofweek} ${hours}:${minutes}:${seconds}.${ms} Local`;\n        }\n        else\n        {\n            let dayofweek = WEEKDAYS[now.getUTCDay()];           // 3-letter day of week\n            let year = now.getUTCFullYear();                     // 4-digit year\n            let month = MONTHS[now.getUTCMonth()];               // 3-letter month of year\n            let day = leadingZeros(now.getUTCDate(), 2);         // 2-digit day\n            let hours = leadingZeros(now.getUTCHours(), 2);      // 2-digit hour\n            let minutes = leadingZeros(now.getUTCMinutes(), 2);  // 2-digit minute\n            let seconds = leadingZeros(now.getUTCSeconds(), 2);  // 2-digit second\n            let ms = leadingZeros(now.getUTCMilliseconds(), 3);  // 3-digit millisecond\n\n            return `${year}-${month}-${day} ${dayofweek} ${hours}:${minutes}:${seconds}.${ms} UTC`;\n        }\n    },\n\n    // #region  U T C / Z U L U   T I M E   U T I L I T I E S\n\n    /**\n     * @static\n     * @public\n     * @constant {object} TIME_FORMATS - Available time display formats\n     * @memberof mcode\n     */\n    TIME_FORMATS: Object.freeze({\n        MILITARY: 'military',\n        MERIDIAN: 'meridian',\n        UTC: 'utc'\n    }),\n\n    /**\n     * @static\n     * @public\n     * @method getCurrentZuluTime\n     * @memberof mcode\n     * @desc Gets the current time as UTC/Zulu timestamp in milliseconds.\n     * @returns {number} Current UTC time in milliseconds\n     */\n    getCurrentZuluTime: function ()\n    {\n        return Date.now(); // Date.now() already returns UTC milliseconds\n    },\n\n    /**\n     * @static\n     * @public\n     * @method parseZuluTime\n     * @memberof mcode\n     * @desc Parses UTC/Zulu timestamps ending with 'Z' into Date objects with validation.\n     * @param {string|number|Date} timestamp - The timestamp to parse (supports 'Z' time, ISO strings, milliseconds, or Date objects)\n     * @returns {Date|null} Parsed Date object or null if invalid\n     */\n    parseZuluTime: function (timestamp)\n    {\n        if (!timestamp) return null;\n        if (timestamp instanceof Date) return isNaN(timestamp.getTime()) ? null : new Date(timestamp.getTime());\n        if (typeof timestamp === 'number') return Number.isFinite(timestamp) ? new Date(timestamp) : null;\n        if (typeof timestamp === 'string')\n        {\n            // Handle ISO strings with 'Z' suffix or standard ISO format\n            try\n            {\n                const parsed = new Date(timestamp);\n                return isNaN(parsed.getTime()) ? null : parsed;\n            }\n            catch\n            {\n                return null;\n            }\n        }\n\n        return null;\n    },\n\n    /**\n     * @static\n     * @public\n     * @method formatMilitaryTime\n     * @memberof mcode\n     * @desc Formats a timestamp for display as local military time (24-hour format).\n     * @param {string|number|Date} timestamp - The timestamp to format\n     * @returns {string} Formatted time string in local military format (HH:MM:SS)\n     */\n    formatMilitaryTime: function (timestamp)\n    {\n        const date = this.parseZuluTime(timestamp);\n        if (!date) return '--:--:--';\n\n        return date.toLocaleTimeString('en-US', {\n            hour12: false,\n            hour: '2-digit',\n            minute: '2-digit',\n            second: '2-digit'\n        });\n    },\n\n    /**\n     * @static\n     * @public\n     * @method formatMeridianTime\n     * @memberof mcode\n     * @desc Formats a timestamp for display as local meridian time (12-hour format with AM/PM).\n     * @param {string|number|Date} timestamp - The timestamp to format\n     * @returns {string} Formatted time string in local meridian format\n     */\n    formatMeridianTime: function (timestamp)\n    {\n        const date = this.parseZuluTime(timestamp);\n        if (!date) return '--:--:-- --';\n\n        return date.toLocaleTimeString('en-US', {\n            hour12: true,\n            hour: 'numeric',\n            minute: '2-digit',\n            second: '2-digit'\n        });\n    },\n\n    /**\n     * @static\n     * @public\n     * @method formatUTCTime\n     * @memberof mcode\n     * @desc Formats a timestamp for display as UTC time.\n     * @param {string|number|Date} timestamp - The timestamp to format\n     * @returns {string} Formatted time string in UTC format (HH:MM:SS UTC)\n     */\n    formatUTCTime: function (timestamp)\n    {\n        const date = this.parseZuluTime(timestamp);\n        if (!date) return '--:--:-- UTC';\n\n        return date.toUTCString().split(' ')[4] + ' UTC'; // Extract just the time portion\n    },\n\n    /**\n     * @static\n     * @public\n     * @method formatTimeByMode\n     * @memberof mcode\n     * @desc Formats a timestamp according to the specified display mode.\n     * @param {string|number|Date} timestamp - The timestamp to format\n     * @param {string} displayMode - Display format from TIME_FORMATS\n     * @returns {string} Formatted time string\n     */\n    formatTimeByMode: function (timestamp, displayMode = this.TIME_FORMATS.MILITARY)\n    {\n        switch (displayMode)\n        {\n            case this.TIME_FORMATS.MERIDIAN:\n                return this.formatMeridianTime(timestamp);\n            case this.TIME_FORMATS.UTC:\n                return this.formatUTCTime(timestamp);\n            case this.TIME_FORMATS.MILITARY:\n            default:\n                return this.formatMilitaryTime(timestamp);\n        }\n    },\n\n    /**\n     * @static\n     * @public\n     * @method isTimestampInView\n     * @memberof mcode\n     * @desc Determines if a timestamp is LATE or EARLY compared to current UTC time and a time window.\n     * @param {string|number|Date} timestamp - The timestamp to check\n     * @param {number} windowMs - Time window in milliseconds for \"on-time\" timestamps\n     * @returns {string|null} 'LATE', 'EARLY', or null if on-time\n     */\n    isTimestampInView: function (timestamp, windowMs = 30000)\n    {\n        const thisTime = this.parseZuluTime(timestamp);\n        if (!thisTime) return 'INVALID';\n\n        const thisTimeMs = thisTime.getTime();\n        const currentZuluMs = this.getCurrentZuluTime();\n        const windowStart = currentZuluMs - windowMs;\n\n        if (thisTimeMs > currentZuluMs) return 'EARLY'; // timestamp is in the future\n        if (thisTimeMs < windowStart) return 'LATE'; // timestamp is older than time window\n\n        return 'VISIBLE'; // timestamp is within acceptable time window\n    },\n\n    // #endregion\n};\n\n// #endregion\n\n// #region  M E T H O D - E X P O R T S\n\n// Immediately Invoked Function Expression (IIFE) invoked on 'this' which\n// represents the global object (window in a browser, global in Node.js).\n// This IIFE returns the 'mcode' object to be assigned to the global object.\n// The Universal Module Definition (UMD) pattern supports Asynchronous Module Definition (AMD),\n// CommonJS / Node.js, and Browser 'global' usage. {0010}\n(\n    /**\n     * @function (IIFE)\n     * @description Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, and browser global\n     * @param {any} root the global object (window, self, global, etc.) being updated.\n     * @param {any} factory a function that returns the exports of the module. This function is invoked in\n     * the context of the global object when the module is loaded. The return value of this function is used\n     * as the exported value of the module when it's not being used with AMD or Node.js module systems.\n     * This function is where you define what your module exports.\n     */\n    function (root, factory)\n    {\n        if (typeof define === 'function' && define.amd)\n        {\n            // AMD. Register as an anonymous module.\n            define([], factory);\n        }\n        else if (typeof module === 'object' && module.exports)\n        {\n            // NODE. Does not work with strict CommonJS, but\n            // only CommonJS-like environments that support module.exports, like Node.\n            module.exports = factory();\n        }\n        else\n        {\n            // BROWSER. Window globals (root is 'window').\n            root.mcode = factory();\n        }\n\n    }(  // root: the global object (window, self, global, etc.)\n        (typeof self !== 'undefined') ? self : this,\n\n        // factory: a function that returns the exports of the module\n        function () {return mcode;})\n);\n\n// #endregion\n\n// #endregion\n// #endregion"]}