/**
* Logger for debugging and calculation output
* @module logger
* @requires module:arial
*/
import * as arial from './arial.js';
const colors = {
black: "#2F2F2F",
brightBlack: "#5A6374",
white: "#D3D7CF",
brightWhite: "#ffffff",
red: "#DC322F",
brightRed: "#EF2929",
yellow: "#C4A000",
brightYellow: "#FCE94F",
green: "#4E9A06",
brightGreen: "#8AE234",
cyan: "#06989A",
brightCyan: "#34E2E2",
blue: "#3465A4",
brightBlue: "#729FCF",
purple: "#A626A4",
brightPurple: "#C577DD",
}
/**
* Status of logger, determines if console wrapper functions are executed
*/
export let enabled = false;
/**
* Status of debugging, exported to allow modules to pre-fill their own test values
*/
export let debugEnabled = false;
/**
* Enables logging
*/
export function enable() {
enabled = true;
black(' Logging enabled ');
}
/**
* Enables debugger
*/
export function presetValues() {
debugEnabled = true;
gray(' Debug mode, values pre-filled ');
}
/**
* Wrapper for console.log, dependent on whether logging has been enabled.
* @param {String|Object|Array} msg Message to log to console
* @param {String} title Title for message
* @returns {undefined}
*/
export function log(msg = '', title = '') {
if (!enabled) return;
if ( (typeof msg === 'object' || Array.isArray(msg) ) && title !== '' ) {
console.log(`==========${title}==========`);
console.log(msg);
} else {
console.log(title === '' ? msg : `==${title}== ${msg}`);
}
}
/**
* Wrapper for console.log when using multiple arguments or colors
* Used when behavior of the log() function is not desired.
* @param {} msg
* @returns {undefined}
*/
export function logArgs(...msg) {
if ( !enabled ) return;
console.log(...msg);
}
export function blue(msg) {
if ( !enabled ) return;
console.log(`%c ${msg} `, `background: ${colors.blue};color: ${colors.brightWhite}`);
}
export function red(msg) {
if ( !enabled ) return;
console.log(`%c ${msg} `, `background: ${colors.red};color: ${colors.brightWhite}`);
}
export function yellow(msg) {
if ( !enabled ) return;
console.log(`%c ${msg} `, `background: ${colors.brightYellow};color: ${colors.black}`);
}
export function cyan(msg) {
if ( !enabled ) return;
console.log(`%c ${msg} `, `background: ${colors.cyan};color: ${colors.brightWhite}`);
}
export function purple(msg) {
if ( !enabled ) return;
console.log(`%c ${msg} `, `background: ${colors.purple};color: ${colors.brightWhite}`);
}
export function green(msg) {
if ( !enabled ) return;
console.log(`%c ${msg} `, `background: ${colors.green};color: ${colors.brightWhite}`);
}
export function black(msg) {
if ( !enabled ) return;
console.log(`%c ${msg} `, `background: ${colors.black};color: ${colors.brightWhite}`);
}
export function gray(msg) {
if ( !enabled ) return;
console.log(`%c ${msg} `, `background: ${colors.brightBlack};color: ${colors.brightWhite}`);
}
export function blueGroup(msg) {
if ( !enabled ) return;
console.group(`%c ${msg} `, `background: ${colors.blue};color: ${colors.brightWhite}`);
}
export function redGroup(msg) {
if ( !enabled ) return;
console.group(`%c ${msg} `, `background: ${colors.red};color: ${colors.brightWhite}`);
}
export function yellowGroup(msg) {
if ( !enabled ) return;
console.group(`%c ${msg} `, `background: ${colors.brightYellow};color: ${colors.black}`);
}
export function cyanGroup(msg) {
if ( !enabled ) return;
console.group(`%c ${msg} `, `background: ${colors.cyan};color: ${colors.brightWhite}`);
}
export function purpleGroup(msg) {
if ( !enabled ) return;
console.group(`%c ${msg} `, `background: ${colors.purple};color: ${colors.brightWhite}`);
}
export function greenGroup(msg) {
if ( !enabled ) return;
console.group(`%c ${msg} `, `background: ${colors.green};color: ${colors.brightWhite}`);
}
export function blackGroup(msg) {
if ( !enabled ) return;
console.group(`%c ${msg} `, `background: ${colors.black};color: ${colors.brightWhite}`);
}
export function grayGroup(msg) {
if ( !enabled ) return;
console.group(`%c ${msg} `, `background: ${colors.brightBlack};color: ${colors.brightWhite}`);
}
export function blueGroupCollapsed(msg) {
if ( !enabled ) return;
console.groupCollapsed(`%c ${msg} `, `background: ${colors.blue};color: ${colors.brightWhite}`);
}
export function redGroupCollapsed(msg) {
if ( !enabled ) return;
console.groupCollapsed(`%c ${msg} `, `background: ${colors.red};color: ${colors.brightWhite}`);
}
export function yellowGroupCollapsed(msg) {
if ( !enabled ) return;
console.groupCollapsed(`%c ${msg} `, `background: ${colors.brightYellow};color: ${colors.black}`);
}
export function cyanGroupCollapsed(msg) {
if ( !enabled ) return;
console.groupCollapsed(`%c ${msg} `, `background: ${colors.cyan};color: ${colors.brightWhite}`);
}
export function purpleGroupCollapsed(msg) {
if ( !enabled ) return;
console.groupCollapsed(`%c ${msg} `, `background: ${colors.purple};color: ${colors.brightWhite}`);
}
export function greenGroupCollapsed(msg) {
if ( !enabled ) return;
console.groupCollapsed(`%c ${msg} `, `background: ${colors.green};color: ${colors.brightWhite}`);
}
export function blackGroupCollapsed(msg) {
if ( !enabled ) return;
console.groupCollapsed(`%c ${msg} `, `background: ${colors.black};color: ${colors.brightWhite}`);
}
export function grayGroupCollapsed(msg) {
if ( !enabled ) return;
console.groupCollapsed(`%c ${msg} `, `background: ${colors.brightBlack};color: ${colors.brightWhite}`);
}
export function blueText(msg) {
if ( !enabled ) return;
console.log(`%c${msg}`, `color: ${colors.blue}`);
}
export function redText(msg) {
if ( !enabled ) return;
console.log(`%c${msg}`, `color: ${colors.red}`);
}
export function yellowText(msg) {
if ( !enabled ) return;
console.log(`%c${msg}`, `color: ${colors.yellow}`);
}
export function cyanText(msg) {
if ( !enabled ) return;
console.log(`%c${msg}`, `color: ${colors.cyan}`);
}
export function purpleText(msg) {
if ( !enabled ) return;
console.log(`%c${msg}`, `color: ${colors.purple}`);
}
export function greenText(msg) {
if ( !enabled ) return;
console.log(`%c${msg}`, `color: ${colors.green}`);
}
export function grayText(msg) {
if ( !enabled ) return;
console.log(`%c${msg}`, `color: ${colors.brightBlack}`);
}
/**
* Wrapper for console.error, dependent on whether logging has been enabled
* @param {String} msg Error message to log to console
* @param {String} title Title for error message
* @returns {undefined}
*/
export function error(msg = '', title = '') {
if (!enabled) return;
console.error(title === '' ? msg : `[${title}] ${msg}`);
}
/**
* Wrapper for console.warn, dependent on whether logging has been enabled
* @param {String} msg Warning message to log to console
* @param {String} title Title for warning message
* @returns {undefined}
*/
export function warn(msg = '', title = '') {
if (!enabled) return;
console.warn(title === '' ? msg : `[${title}] ${msg}`);
}
/**
* Wrapper for console.group, dependent on whether logging has been enabled
* @param {String} msg Message to log to console
* @returns {undefined}
*/
export function group(msg = "") {
if (!enabled) return;
console.group(msg);
}
/**
* Wrapper for console.groupCollapsed, dependent on whether logging has been enabled
* @param {String} msg Message to log to console
* @returns {undefined}
*/
export function groupCollapsed(msg = "") {
if (!enabled) return;
console.groupCollapsed(msg);
}
/**
* Wrapper for console.groupEnd, dependent on whether logging has been enabled
* @returns {undefined}
*/
export function groupEnd() {
if (!enabled) return;
console.groupEnd();
}
/**
* Shortcut to start a group with the name of a function and its arguments
* @example LOG.beginFunction('myFunctionName', arguments);
*
* @param {String} functionName - Name of the function, to serve as the group caption
* @param {Any[]} [args] - The function's arguments object
* @returns {undefined}
*/
export function beginFunction(functionName, args){
if (!enabled) return;
console.groupCollapsed(`%c ${functionName} `, `color:${colors.brightYellow};background:${colors.blue}` );
if ( args ) {
console.group('%c Input ', `background: ${colors.brightBlue};color:${colors.brightWhite}`);
for ( let i = 0; i < args.length; i++ ) {
log(JSON.parse(JSON.stringify(args[i])));
}
groupEnd();
}
}
/**
* Use when exiting a function due to missing or invalid input(s)
*
* @param {Any} [res] Result of the function
* @returns {undefined}
*/
export function exitFunction(res){
if (!enabled) return;
console.log('%c Required value(s) are missing or invalid ', `background: ${colors.red};color: ${colors.brightYellow}`);
if ( res ) {
console.group('%c Result ', `background: ${colors.brightBlue};color:${colors.brightWhite}`);
log(JSON.parse(JSON.stringify(res)));
groupEnd();
}
groupEnd();
}
/**
* Shortcut for LOG.log({result: res});LOG.groupEnd()
* @param {Any} res result of function
*/
export function endResult(res){
if (!enabled) return;
console.group('%c Result ', `background: ${colors.brightBlue};color:${colors.brightWhite}`);
if ( res ) log(JSON.parse(JSON.stringify(res)));
groupEnd();
console.log('%c ', `background: ${colors.blue}`);
groupEnd();
}
/**
* Log an object to the console as a deep copy
* @param {any} obj
*/
export function deep(obj){
if ( !enabled ) return;
console.log(JSON.parse(JSON.stringify(obj)));
}
//TODO: document outputTape function
export function outputTape(parent, title = "") {
let titleHtml = "";
title = title.toUpperCase();
const divider = arial.underline(title, "=");
if ( title !== "" ) {
titleHtml = `${title}<br>${divider}`;
}
let txt = "";
const items = [];
parent.forEach(child => {
if ( !( child[1] instanceof Array ) ) {
items.push(child);
} else {
if ( child[0] instanceof Array ) {
txt += `<br>`;
txt += printArray(child);
} else {
txt += `<br><u>${child[0]}</u><br>`;
txt += printArray(child[1]);
}
}
});
return `${titleHtml}${printArray(items)}${txt}`;
}
/**
* Takes an array of [label, value] arrays and converts to text/html with breaks
* after each line, padded with nonbreaking spaces so values will be aligned.
* Labels with an empty string as their value will not be included.
*
* @example
* printArray([
* ['Actual Body Weight', '70 kg'],
* ['Height', '180 cm'],
* ]);
*
* // resulting HTML will appear like this (in Arial):
* Actual Body Weight: 70 kg
* Height: 180 cm
*
* @param {String[][]} arr Array of any length, each member must be an array of 2 strings
* @returns {String}
*/
function printArray(arr) {
let labels = [];
const values = [];
let txt = "";
arr.forEach(el => {
if ( el[1] !== "" ) {
labels.push(`${el[0]}:`);
values.push(el[1]);
}
});
labels = arial.padArray(labels);
for ( let i = 0; i < labels.length; i++ ) {
txt += `${labels[i] + values[i] }<br>`;
}
return txt;
}