npm package: @haystacks/async
Description: A framework to build any number or any kind of native application or automation solution.
Author: Seth Hollingsead
Latest version: 0.3.0

# Haystacks-Async
A basic NodeJS platform that can be easily be used in your application as the command interface and execution environment written with ES6 syntax. The testHarness provides an example template application for how to use the platform, see instructions below on how to setup the environment locally or how to implement your own application using Haystacks. There is an example architecture with coding patterns you can follow to build out your own, cross platform (Windows, Mac & Linux) applications and enterprise scale business automation applications.

Please consider supporting:
https://www.buymeacoffee.com/iceversakah

# Purpose
The purpose of this repository is to provide a command-line utility, interface and design patterns to build any kind of command line application that you need or want. Special focus will be on automation, specifically testing automation. It's a general purpose automation development platform, but not to the exclusion of supporting the development of any other kind of command line application, such as an installer, a test data management system, a stock trading bot or network security scanning tool, data conversion tool or any other kind of application that can be run from a command line.

# Run Locally
Pre-requisites
Install NPM - NODE Package Manager (>= v16)
https://nodejs.org/en/download/
Install GIT or Git-for-Windows
https://git-scm.com/downloads 

Open your favorite CLI/Powershell/BASH/CMD tool.
Navigate to your favorite projects folder.
Enter the command:
```
  git clone https://github.com/SethEden/haystacks-async.git
```

Navigate into the haystacks folder.
Enter the command:
```
  npm install
  npm link
```

Navigate into the folder ./test/testHarness.
Enter the command:
```
  npm install
  npm link @haystacks/async
```

If you wish to run the plugins as well, follow these additional instructions:
Under your favorite projects folder, create a new folder called: haystacks-plugins
Navigate into this folder and enter the following commands to clone all three of the haystacks prototype test plugins.
```
  git clone https://github.com/SethEden/plugin-one.git
  git clone https://github.com/SethEden/plugin-two.git
  git clone https://github.com/SethEden/plugin-three.git
```

Navigate into each of these three folders and for each folder enter the following commands:
```
  npm install
  npm link @haystacks/async
```

Open the file in the path: ./test/testHarness/src/resources/plugins/plugins.json
Delete the contents of the plugins array so that it looks like this: "plugins": []
Then insert the path to your haystacks-plugins folder that you created in the step above like this:
```
  "path": "/home/myHomePath/haystacks-plugins/",
```

If you wish to NOT load or run plugins then follow this step:
Load the file in the path: ./test/testHarness/src/resources/configuration/application.system.json
Change the setting for: enablePluginLoader to false like so:
```
  "system.enablePluginLoader": false,
```

Then save the file.

Navigate in your command window/shell/CLI back to the haystacks root path.
You can run the command by starting from the development environment by using NPM.
Enter the command:
```
  npm test
```

This will launch the testHarness application from the development environment.

If you do enable the plugins flag, there are many plugins related commands that allow you to do many plugin related activities such as:
```
  listAllLoadedPlugins
  listAllPluginsInRegistry
  listAllPluginsInRegistryPath
  countPluginsInRegistry
  countPluginsInRegistryPath
  registerPlugin
  unregisterPlugin
  unregisterPlugins (A list of plugins)
  syncPluginRegistryWithPath
  listPluginsRegistryPath
  unregisterAllPlugins
  savePluginRegistryToDisk
  loadPlugin
  loadPlugins (A list of plugins to load)
  loadPluginsFromRegistry
  unloadPlugin
  unloadPlugins (A list of plugins to unload)
  unloadAllPlugins
```

# Useful stuff you can do
I will assume you are still running in the argumentDrivenInterface value="false" mode for this tutorial.
This mode can be enabled in the configuration file to enable processing of command-line arguments as input to drive actions processing without user interaction.
The argumentDriveInterface setting will not prevent you from entering command arguments and executing them when the application starts before entering into the main program loop.
The argumentDriveInterface will only disable the main program loop from going into an interactive command prompt loop. Rather with this setting set to true the application will exit after finishing the execution of your input argument as a command.

Once you enter the command:
```
  npm test
```

The application will display the application name, version number and application description:

```
> haystacks-async@0.2.0 test
> node ./test/testHarness/src/testHarness.js

BEGIN testHarness.application Function
.___________. _______     _______.___________. __    __       ___      .______      .__   __.  _______     _______.     _______.
|           ||   ____|   /       |           ||  |  |  |     /   \     |   _  \     |  \ |  | |   ____|   /       |    /       |
`---|  |----`|  |__     |   (----`---|  |----`|  |__|  |    /  ^  \    |  |_)  |    |   \|  | |  |__     |   (----`   |   (----`
    |  |     |   __|     \   \       |  |     |   __   |   /  /_\  \   |      /     |  . `  | |   __|     \   \        \   \
    |  |     |  |____.----)   |      |  |     |  |  |  |  /  _____  \  |  |\  \----.|  |\   | |  |____.----)   |   .----)   |
    |__|     |_______|_______/       |__|     |__|  |__| /__/     \__\ | _| `._____||__| \__| |_______|_______/    |_______/

0.0.1
A test harness application to test the haystacks framework.
BEGIN main program loop
BEGIN command parser
>
```

The application is now running and awaiting input via an interactive command prompt that will process commands entered in a program loop.
If you are not sure what you can do, you can type the command:
```
  ?
```

and press enter.
You should see a table of commands:
```
>?
┌───────────────────────────────────┬─────────────────────────────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│              (index)              │                Name                 │                                                          Description                                                          │
├───────────────────────────────────┼─────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│         commandSequencer          │         'commandSequencer'          │                         'Takes a sequence of commands/aliases and enqueues all to the command queue.'                         │
│             workflow              │             'workflow'              │                  'Loads the specified workflow, calls the command sequencer to get each commands enqueued.'                   │
│           businessRule            │           'businessRule'            │                               'Executes a user specified business rule and prints the results.'                               │
│         commandGenerator          │         'commandGenerator'          │                           'Generates and enqueues any number of command calls based on user input.'                           │
│       commandAliasGenerator       │       'commandAliasGenerator'       │                      'Generates command aliases given a command name and a list of word abbreviations.'                       │
│           convertColors           │           'convertColors'           │                         'Converts all the colors in the color library from hex values to RGB values.'                         │
│         saveConfiguration         │         'saveConfiguration'         │                                       'Saves all of the configuration data out to disk'                                       │
│    changeConfigurationSetting     │    'changeConfigurationSetting'     │                             'Command to change a configuration setting in an automated fashion.'                              │
│      listConfigurationThemes      │      'listConfigurationThemes'      │                                   'List all the themes currently installed in the system.'                                    │
│   changeDebugConfigurationTheme   │   'changeDebugConfigurationTheme'   │                                         'Changes the color theme of the debug logs.'                                          │
│        constantsGenerator         │        'constantsGenerator'         │                     'Determines the most optimized way to define a new constant in the constants system.'                     │
│      constantsGeneratorList       │      'constantsGeneratorList'       │                                'Generates optimized constants from an input list of strings.'                                 │
│    constantsPatternRecognizer     │    'constantsPatternRecognizer'     │                            'Finds common sub-string patterns in a coma separated list of strings.'                            │
│         evaluateConstant          │         'evaluateConstant'          │                              'Resolves a constant and prints the output of the constant value.'                               │
│           printDataHive           │           'printDataHive'           │ 'Prints the specified data hive (CommandWorkflows, CommandsAliases, Colors, Configuration, or root) in the D-data structure.' │
│      printDataHiveAttributes      │      'printDataHiveAttributes'      │             'Prints out all the specified attributes contained in a data set in the application data structure.'              │
│         clearDataStorage          │         'clearDataStorage'          │                       'Clears a sub-data hive or the entire Data Storage hive in the D-data structure.'                       │
│           changeSetting           │           'changeSetting'           │              'Changes a setting in the data structure, given the fully qualified path, property name and value.'              │
│         validateConstants         │         'validateConstants'         │                                'Validates all constants with a 2-phase verification process.'                                 │
│      validateCommandAliases       │      'validateCommandAliases'       │                                        'Validates all command aliases for duplicates.'                                        │
│         validateWorkflows         │         'validateWorkflows'         │                                           'Validates all workflows for duplicates.'                                           │
│         runAllValidations         │         'runAllValidations'         │           'Runs all validations together, constants validation, command alias validation and workflow validation.'            │
│       businessRulesMetrics        │       'businessRulesMetrics'        │                     'Computes statistics on business rule performance metrics and displays the results.'                      │
│          commandMetrics           │          'commandMetrics'           │                        'Computes statistics on command performance metrics and displays the results.'                         │
│       listAllLoadedPlugins        │       'listAllLoadedPlugins'        │                            'Prints out a list of all the plugins currently loaded by the system.'                             │
│     listAllPluginsInRegistry      │     'listAllPluginsInRegistry'      │                           'Prints out a list of all the plugins currently in the plugin registry.'                            │
│   listAllPluginsInRegistryPath    │   'listAllPluginsInRegistryPath'    │                                     'List all the plugins in the plugins registry path.'                                      │
│      countPluginsInRegistry       │      'countPluginsInRegistry'       │                              'Print out the number of plugins currently in the plugin registry.'                              │
│    countPluginsInRegistryPath     │    'countPluginsInRegistryPath'     │                        'Print out the number of plugins currently in the plugin registry folder path.'                        │
│          registerPlugin           │          'registerPlugin'           │                             'Add a plugin and its path to the plugin registry for auto-loading.'                              │
│         unregisterPlugin          │         'unregisterPlugin'          │                           'Remove a named plugin from the plugin registry to prevent auto-loading.'                           │
│         unregisterPlugins         │         'unregisterPlugins'         │                      'Remove a list of named plugins from the plugin registry to prevent auto-loading.'                       │
│    syncPluginRegistryWithPath     │    'syncPluginRegistryWithPath'     │                'Synchronize the plugin registry with the plugins listed in the plugins registry folder path.'                 │
│      listPluginsRegistryPath      │      'listPluginsRegistryPath'      │                                'Prints out the path for the plugins from the plugin registry.'                                │
│       unregisterAllPlugins        │       'unregisterAllPlugins'        │                   'Unregister all plugins from the plugin registry, clear the plugin registry of all data.'                   │
│     savePluginRegistryToDisk      │     'savePluginRegistryToDisk'      │                                   'Save or persist the plugin registry to the hard drive.'                                    │
│            loadPlugin             │            'loadPlugin'             │                                            'Load a plugin from a specified path.'                                             │
│            loadPlugins            │            'loadPlugins'            │                              'Load an array of plugins from a single path or an array of paths.'                              │
│      loadPluginsFromRegistry      │      'loadPluginsFromRegistry'      │                                     'Load all the plugins listed in the plugin registry.'                                     │
│           unloadPlugin            │           'unloadPlugin'            │                                                      'Unload a plugin.'                                                       │
│           unloadPlugins           │           'unloadPlugins'           │                                                  'Unload a list of plugins.'                                                  │
│         unloadAllPlugins          │         'unloadAllPlugins'          │                                                   'Unload all the plugins.'                                                   │
│            echoCommand            │            'echoCommand'            │                                        'Echos back whatever is input to the command.'                                         │
│               exit                │               'exit'                │                                              'Exit the application completely.'                                               │
│              version              │              'version'              │                                      'Displays the current version of the application.'                                       │
│               about               │               'about'               │                                   'Displays the about message for the current application.'                                   │
│               name                │               'name'                │                                'Displays a message with the name of the current application.'                                 │
│            clearScreen            │            'clearScreen'            │         'Clears the screen of any extra data by pushing lots of empty strings past the cache of the console system.'          │
│               help                │               'help'                │                                    'Displays all of the commands names and descriptions.'                                     │
│           workflowHelp            │           'workflowHelp'            │                                        'Displays all the workflows, names and values.'                                        │
│       printUserCommandsLog        │       'printUserCommandsLog'        │                      'Displays all the commands entered by the user since the start of the application.'                      │
│        printAllCommandsLog        │        'printAllCommandsLog'        │                    'Displays all the commands executed by the system since the start of the application.'                     │
│       clearUserCommandsLog        │       'clearUserCommandsLog'        │             'Wipes out the user command log, destroying all evidence of whatever commands the user has entered.'              │
│        clearAllCommandsLog        │        'clearAllCommandsLog'        │          'Wipes out the all commands log, destroying all evidence of whatever commands were executed by the system.'          │
│          applicationHelp          │          'applicationHelp'          │              'Displays all application commands and all plugin commands for plugins loaded by the application.'               │
│      applicationWorkflowHelp      │      'applicationWorkflowHelp'      │             'Displays all application workflows and all plugin workflows for plugins loaded by the application.'              │
│   validateApplicationConstants    │   'validateApplicationConstants'    │             'Validates all application constants and all plugin constants for plugins loaded by the application.'             │
│ validateApplicationCommandAliases │ 'validateApplicationCommandAliases' │       'Validates all application command aliases and all plugin command aliases for plugins loaded by the application.'       │
│   validateApplicationWorkflows    │   'validateApplicationWorkflows'    │             'Validates all application workflows and all plugin workflows for plugins loaded by the application.'             │
│     allApplicationValidations     │     'allApplicationValidations'     │           'Validates all application validations and all plugin validations for plugins loaded by the application.'           │
│         customEchoCommand         │         'customEchoCommand'         │                    'A client defined custom Echo command that echos back the input plus something extra.'                     │
│             bossPanic             │             'bossPanic'             │                          'Print a bunch of text on the screen so it looks like the computer is busy'                          │
│            placeHolder            │            'placeHolder'            │                                   'Description of the command, this is just a placeHolder.'                                   │
│             command01             │             'command01'             │                                                      'Client Command 1'                                                       │
│             command02             │             'command02'             │                                                      'Client Command 2'                                                       │
│             command03             │             'command03'             │                                                      'Client Command 3'                                                       │
│             command04             │             'command04'             │                                                      'Client Command 4'                                                       │
│             command05             │             'command05'             │                                                      'Client Command 5'                                                       │
│             command06             │             'command06'             │                                                      'Client Command 6'                                                       │
│             command07             │             'command07'             │                                                      'Client Command 7'                                                       │
│             command08             │             'command08'             │                                                      'Client Command 8'                                                       │
│             command09             │             'command09'             │                                                      'Client Command 9'                                                       │
│             command10             │             'command10'             │                                                      'Client Command 10'                                                      │
│        pluginOneCommand01         │        'pluginOneCommand01'         │                                        'The first demo command as part of pluginOne.'                                         │
│        pluginOneCommand02         │        'pluginOneCommand02'         │                                        'The second demo command as part of pluginOne.'                                        │
│       pluginThreeCommand01        │       'pluginThreeCommand01'        │                                       'The first demo command as part of pluginThree.'                                        │
│       pluginThreeCommand02        │       'pluginThreeCommand02'        │                                       'The second demo command as part of pluginThree.'                                       │
│        pluginTwoCommand01         │        'pluginTwoCommand01'         │                                        'The first demo command as part of pluginTwo.'                                         │
│        pluginTwoCommand02         │        'pluginTwoCommand02'         │                                        'The second demo command as part of pluginTwo.'                                        │
└───────────────────────────────────┴─────────────────────────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
>
```

NOTE: The above command table listing shows what it would look like if all three of the prototype plugins are also loaded: plugin-one, plugin-two, plugin-three.
If the "enablePluginLoader" setting is disabled these plugins will not load and all commands and workflows relating to these plugins will not be present.

One thing you can do is type:
```
  workflow?
```

and press enter.
This will display a list of all the workflows the application supports: (Abbreviated because the list is very long!)
```
>workflow?
┌─────────┬───────────────────────────────────────────────────────────────────────────────┐
│ (index) │                                    Values                                     │
├─────────┼───────────────────────────────────────────────────────────────────────────────┤
│    0    │                          'doesArrayContainCharacter'                          │
│    1    │                          'removeCharacterFromArray'                           │
│    2    │                           'replaceCharacterAtIndex'                           │
│    3    │                            'characterArrayParsing'                            │
│    4    │                          'doesArrayContainFilename'                           │
│    5    │                          'getFileAndPathListForPath'                          │
│    6    │                              'pathArrayParsing'                               │
│    7    │                        'convertCamelCaseStringToArray'                        │
│    8    │                        'convertArrayToCamelCaseString'                        │
│    9    │                 'doesArrayContainLowerCaseConsolidatedString'                 │
│   10    │                              'wordArrayParsing'                               │
│   11    │              'randomlyGenerateMixedCaseLetterOrSpecialCharacter'              │
...
...
│  1104   │                    'allBusinessRulesArrayParsingWorkflows'                    │
│  1105   │                   'allBusinessRulesStringParsingWorkflows'                    │
│  1106   │                          'allBusinessRulesWorkflows'                          │
│  1107   │                             'allSystemWorkflows'                              │
│  1108   │                             'disableAllDebugging'                             │
│  1109   │                                  'workflow1'                                  │
│  1110   │                                  'workflow2'                                  │
│  1111   │                             'bossPanicWorkflow1'                              │
│  1112   │                             'bossPanicWorkflow2'                              │
│  1113   │                             'bossPanicWorkflow3'                              │
│  1114   │                             'bossPanicWorkflow4'                              │
│  1115   │                             'bossPanicWorkflow5'                              │
│  1116   │                             'bossPanicWorkflow6'                              │
│  1117   │                              'mostPopularNumber'                              │
│  1118   │                             'isAlmostPalindrome'                              │
│  1119   │                              'threePointAverage'                              │
│  1120   │                                'arrayCounter'                                 │
│  1121   │                           'allClientBusinessRules'                            │
│  1122   │                     'allClientAndFrameworkBusinessRules'                      │
│  1123   │                              'DefaultThemeDemo'                               │
│  1124   │                             'SkywalkerThemeDemo'                              │
│  1125   │                               'VaderThemeDemo'                                │
│  1126   │                               'MatrixThemeDemo'                               │
│  1127   │                                'TronThemeDemo'                                │
│  1128   │                                'DemoAllThemes'                                │
│  1129   │                            'TestCommandSequence1'                             │
│  1130   │                            'TestCommandSequence2'                             │
│  1131   │                            'TestCommandSequence3'                             │
│  1132   │                            'TestCommandSequence4'                             │
│  1133   │                            'TestCommandSequence5'                             │
│  1134   │                           'TestCommandSequenceALL'                            │
│  1135   │                          'clientStringParsingEnable'                          │
│  1136   │                         'clientStringParsingDisable'                          │
...
│  1180   │                           'clientCommand06Disable'                            │
│  1181   │                            'clientCommand07Enable'                            │
│  1182   │                           'clientCommand07Disable'                            │
│  1183   │                            'clientCommand08Enable'                            │
│  1184   │                           'clientCommand08Disable'                            │
│  1185   │                            'clientCommand09Enable'                            │
│  1186   │                           'clientCommand09Disable'                            │
...
│  1220   │                           'pluginTwoRule02Disable'                            │
│  1221   │                           'pluginTwoCommandsEnable'                           │
│  1222   │                          'pluginTwoCommandsDisable'                           │
│  1223   │                          'pluginTwoCommand01Enable'                           │
│  1224   │                          'pluginTwoCommand01Disable'                          │
│  1225   │                          'pluginTwoCommand02Enable'                           │
│  1226   │                          'pluginTwoCommand02Disable'                          │
│  1227   │                              'pluginTwoWorkflow'                              │
└─────────┴───────────────────────────────────────────────────────────────────────────────┘
>
```

You can run any of these workflows simply by typing the command:
workflow <Workflow-Name> and press enter.
I recommend the following command:
```
  workflow allBusinessRulesWorkflows
```

This will run all of the client defined business rules and all of the framework defined business rules sequentially.
Client defined business rules can be found in the path:
```
./test/testHarness/src/businessRules/clientRules/*.js
```

Framework defined business rules can be found in the path:
```
./src/businessRules/rules/*.js
```

All of these business rules are merged at runtime as a function of how the haystacks framework is implemented at the architectural level.

The output should look something like this (abbreviated because the output is very long!)
```
>workflow allClientAndFrameworkBusinessRules
Rule output is: "2"
Rule output is: true
Rule output is: [2,2]
Rule output is: 2
Rule output is: true
Rule output is: true
Rule output is: true
Rule output is: true
Rule output is: 1
Rule output is: 1
Rule output is: 1
Rule output is: 1
Rule output is: "String"
Rule output is: "String"
Rule output is: "String"
Rule output is: "String"
Rule output is: false
Rule output is: false
Rule output is: false
Rule output is: false
Rule output is: true
Rule output is: true
Rule output is: true
Rule output is: true
Rule output is: true
Rule output is: true
Rule output is: true
Rule output is: true
Rule output is: false
Rule output is: false
Rule output is: false
Rule output is: false
Rule output is: "input[name=\"emailAddress\"][class=\"username\"]"
Rule output is: "input[name=\"emailAddress\"][class=\"username\"]"
Rule output is: "input[name=\"emailAddress\"][class=\"username\"]"
Rule output is: "input[name=\"emailAddress\"][class=\"username\"]"
Rule output is: "C:\\"
...
Rule output is: "abcorp3.com"
Rule output is: "Eml_YwG2*a+aVw$50r7^^UsR6yu)Y7HpYa=UVNtun+XK9XZRAhl-fykl^ihim=R=nv(DbCXhaQxOS#nNyLBwb-phabcorp3.com"
Rule output is: "abcorp3.com"
Rule output is: "abcorp3.com"
Rule output is: "b4ZPKRMUzs3Wo9gA2iCeVZxfvTVkQrA0PSRVrEnRLAgDmEI@CnLYKFocPFq3joEJqo2Q9HetCStfbGeE40sVU2XXdbgdQz.ZjI"
Rule output is: "KKGoTMUYQM8Jy2FL16QEfBZ8dFxf0E4ttObgDEMEEsyDSEkS@Im6jtitvIC4iQwVAo6I6z6Hmz5m8EHxjmhxOBV8Hsvznuh4Q.mN"
Rule output is: "eZqPmQNRN9FpbtgOfCsykHetiAnHpK0a32uRij62n0WbXJLA@5haQe1mhm1v0GKEBHjIa322V1hiTpUUjoJKoZeF5EaDUMMqm.Bt"
Rule output is: "oC1Y1AdEjH56oTugU7Pc7LbeMiuDCLspYf1SDmdR7NkTLCLX@miuGeYmSda9BEQohU1gbMhy6PgAEFq8GbmMhgssLtRVxDCWt.tV"
Rule output is: "A3v0VDaksZCptpL7NNnhfKIyEuD6vJ6RtiT0pAroTqAEtnL@o5tF40S8Q8KAvQOtDkYm1ZM6anYCfDwr4KR2ctREAtEnsf.fIM"
Rule output is: "szFhjHqAPyG3c8u3Rn8E3QED9Evl8w6Ux5J86OOctDWqeHh@M4rCfplM1kUYmEnnNGyFsqtp1sdyNciROZuEDTpXd9p6P7.ymY"
Rule output is: "ezY008VBlh07p1tlREqha4lmEbdbhHNfTwZCEmBlEEnIrpgm@Z8YXmxdpqcOfNezcxLwHi7zmF4iEDBPxHRqT8QSxYcm5j5pX.JC"
Rule output is: "L7wo8luWcIvlpayptIa9gsI8uHFK8RwCNdtQE58L4D57ALs@8pLuwaDEp67vDK3mRP99yNyOkWRgI66jDtpRqE6OtwqWRR.NDk"
Rule output is: "zok3kaFcbeaITvmE23FNhe7vpdMpCIa1dIAjN1pOmkXzExNW@Ed7gPeWh5bVIAQswGlZs3pa7B6v17rtkhtCrUywmWMptWSmZ.el"
Rule output is: "TJUiCQ4ZKmJ3arNd4WykFIie76zsmtJEBwSyR9cGoSiBEZ1s@5uyWNGewJUNenJJy78Sgptyo45wNyeFEBRw0pHfdyoztfLiQ.bg"
Rule output is: "@UJz"
Rule output is: "lx"
Rule output is: "@.mx"
Rule output is: "9QqwojbJAYsMaK41NFHAKkyjUcTXS5ON1inj1P8o4CLl0wzPvMwSZhPnyVAYVUwJzAE2m2dYuBuannW9qnsXmJuMsvdB6c9e2ZC@."
Rule output is: "gb9PCgtdZp46AwHwV9KaHVw6tkpi7HmjwVfOCdYLm7o1E3nDZFQ8BXxJeNtYrZCd5I55BPBzy3YTeksFR22gDWcbNPdzKf5h9E4E@."
Rule output is: ".hH"
Rule output is: ".sO"
Rule output is: "@.yyi"
Rule output is: "."
Rule output is: "LyH"
>
```

Now that all the business rules have been run sequentially you can run this command to compute statistical analysis on the performance data gathered on the execution of these business rules.
```
  businessRulesMetrics
```

This will compute and then display the performance statistics from the workflow you just performed:
```
>businessRulesMetrics
┌─────────┬────────────────────────────────────────────────────────────────────────┬─────────┬─────────────────────┐
│ (index) │                                  Name                                  │ Average │  StandardDeviation  │
├─────────┼────────────────────────────────────────────────────────────────────────┼─────────┼─────────────────────┤
│    0    │                          'mostPopularNumber'                           │    5    │          1          │
│    1    │                          'isAlmostPalindrome'                          │   0.5   │         0.5         │
│    2    │                          'threePointAverage'                           │   0.5   │         0.5         │
│    3    │                             'arrayCounter'                             │    0    │          0          │
│    4    │                           'stringToBoolean'                            │    0    │          0          │
│    5    │                           'stringToDataType'                           │  0.25   │ 0.4330127018922193  │
│    6    │                       'determineObjectDataType'                        │    0    │          0          │
│    7    │                              'isBoolean'                               │  0.125  │ 0.33071891388307384 │
│    8    │                              'isInteger'                               │  0.125  │ 0.33071891388307384 │
│    9    │                               'isFloat'                                │    0    │          0          │
│   10    │                               'isString'                               │  0.125  │ 0.33071891388307384 │
│   11    │                      'singleQuoteSwapAfterEquals'                      │  0.75   │ 0.6614378277661477  │
│   12    │                     'swapForwardSlashToBackSlash'                      │  0.125  │ 0.33071891388307384 │
│   13    │                     'swapBackSlashToForwardSlash'                      │    0    │          0          │
│   14    │              'swapDoubleForwardSlashToSingleForwardSlash'              │    0    │          0          │
│   15    │                 'swapDoubleBackSlashToSingleBackSlash'                 │    0    │          0          │
│   16    │                         'getUserNameFromEmail'                         │  0.125  │ 0.33071891388307384 │
│   17    │                        'replaceSpacesWithPlus'                         │  0.25   │ 0.4330127018922193  │
│   18    │                      'replaceColonWithUnderscore'                      │    0    │          0          │
│   19    │                    'replaceCharacterWithCharacter'                     │  0.125  │ 0.33071891388307384 │
│   20    │                    'cleanCarriageReturnFromString'                     │  0.25   │ 0.4330127018922193  │
│   21    │                       'convertStringToLowerCase'                       │  0.125  │ 0.33071891388307384 │
│   22    │                       'convertStringToUpperCase'                       │  0.25   │ 0.4330127018922193  │
│   23    │                         'getFileNameFromPath'                          │    0    │          0          │
│   24    │                           'getFileExtension'                           │  0.25   │ 0.4330127018922193  │
│   25    │                      'removeDotFromFileExtension'                      │  0.25   │ 0.4330127018922193  │
│   26    │                   'removeFileExtensionFromFileName'                    │    0    │          0          │
│   27    │            'aggregateNumericalDifferenceBetweenTwoStrings'             │  5.75   │  3.191786333700926  │
│   28    │                    'convertCamelCaseStringToArray'                     │    0    │          0          │
│   29    │                    'convertArrayToCamelCaseString'                     │   0.5   │         0.5         │
│   30    │                        'mapWordToCamelCaseWord'                        │  0.25   │ 0.4330127018922193  │
│   31    │                     'simplifyAndConsolidateString'                     │  0.125  │ 0.33071891388307384 │
│   32    │               'compareSimplifiedAndConsolidatedStrings'                │  0.375  │ 0.9921567416492215  │
│   33    │             'doesArrayContainLowerCaseConsolidatedString'              │ 22.875  │ 3.7893765978060294  │
│   34    │                      'doesArrayContainCharacter'                       │  0.125  │ 0.33071891388307384 │
│   35    │                       'removeCharacterFromArray'                       │  0.375  │ 0.4841229182759271  │
│   36    │                      'ascertainMatchingFilenames'                      │  0.375  │ 0.4841229182759271  │
│   37    │                       'doesArrayContainFilename'                       │  0.875  │ 0.5994789404140899  │
│   38    │                  'getDataCatagoryFromDataContextName'                  │    0    │          0          │
│   39    │             'getDataCatagoryDetailNameFromDataContextName'             │  0.125  │ 0.33071891388307384 │
│   40    │                  'getKeywordNameFromDataContextName'                   │  0.25   │ 0.4330127018922193  │
│   41    │                         'parseSystemRootPath'                          │    0    │          0          │
│   42    │                 'removeXnumberOfFoldersFromEndOfPath'                  │  0.25   │ 0.4330127018922193  │
│   43    │                    'getFirstTopLevelFolderFromPath'                    │  0.375  │ 0.4841229182759271  │
│   44    │                                'isOdd'                                 │  0.125  │ 0.33071891388307384 │
│   45    │                                'isEven'                                │  0.375  │ 0.4841229182759271  │
│   46    │                       'replaceCharacterAtIndex'                        │    0    │          0          │
│   47    │          'randomlyGenerateMixedCaseLetterOrSpecialCharacter'           │   0.8   │ 1.1661903789690602  │
│   48    │          'randomlyGenerateUpperCaseLetterOrSpecialCharacter'           │   0.1   │ 0.30000000000000004 │
│   49    │          'randomlyGenerateLowerCaseLetterOrSpecialCharacter'           │   0.5   │  0.806225774829855  │
│   50    │   'randomlyGenerateEitherMixedCaseLetterOrNumberOrSpecialCharacter'    │   0.1   │ 0.30000000000000004 │
│   51    │   'randomlyGenerateEitherUpperCaseLetterOrNumberOrSpecialCharacter'    │   0.3   │ 0.4582575694955839  │
│   52    │   'randomlyGenerateEitherLowerCaseLetterOrNumberOrSpecialCharacter'    │   0.2   │ 0.5099019513592785  │
│   53    │            'randomlyGenerateMixedCaseAlphaNumericCharacter'            │   0.2   │ 0.4000000000000001  │
│   54    │            'randomlyGenerateUpperCaseAlphaNumericCharacter'            │   0.3   │ 0.4582575694955839  │
│   55    │            'randomlyGenerateLowerCaseAlphaNumericCharacter'            │  0.05   │ 0.21794494717703367 │
│   56    │                   'randomlyGenerateNumericCharacter'                   │   0.4   │ 0.7348469228349535  │
│   57    │                   'randomlyGenerateSpecialCharacter'                   │  0.15   │ 0.35707142142714243 │
│   58    │                    'randomlyGenerateNumberInRange'                     │   0.2   │ 0.4000000000000001  │
│   59    │                     'randomlyGenerateBooleanValue'                     │    0    │          0          │
│   60    │             'randomlyGenerateMixedCaseAlphabeticCharacter'             │  0.35   │ 0.9096702699330127  │
│   61    │                    'convertNumberToUpperCaseLetter'                    │   0.1   │ 0.30000000000000004 │
│   62    │                    'convertNumberToLowerCaseLetter'                    │  0.05   │ 0.2179449471770336  │
│   63    │                 'generateRandomMixedCaseTextByLength'                  │  16.4   │  5.31413210223457   │
│   64    │                 'generateRandomUpperCaseTextByLength'                  │  18.4   │ 11.015443704181871  │
│   65    │                 'generateRandomLowerCaseTextByLength'                  │  18.75  │  12.38900722414835  │
│   66    │       'generateRandomMixedCaseTextWithSpecialCharactersByLength'       │  15.1   │  4.667976006793523  │
│   67    │       'generateRandomUpperCaseTextWithSpecialCharactersByLength'       │  23.25  │ 21.942823428173504  │
│   68    │       'generateRandomLowerCaseTextWithSpecialCharactersByLength'       │  23.85  │ 17.419170473934745  │
│   69    │           'generateRandomMixedCaseAlphaNumericCodeByLength'            │  21.7   │ 15.537374295549423  │
│   70    │           'generateRandomUpperCaseAlphaNumericCodeByLength'            │  19.95  │ 12.567716578599311  │
│   71    │           'generateRandomLowerCaseAlphaNumericCodeByLength'            │  17.7   │  10.49809506529637  │
│   72    │                  'generateRandomNumericCodeByLength'                   │  15.45  │  5.064336086793609  │
│   73    │ 'generateRandomMixedCaseAlphaNumericCodeWithSpecialCharactersByLength' │  19.9   │ 17.731046218427156  │
│   74    │ 'generateRandomUpperCaseAlphaNumericCodeWithSpecialCharactersByLength' │  20.65  │ 10.683047318064261  │
│   75    │ 'generateRandomLowerCaseAlphaNumericCodeWithSpecialCharactersByLength' │  16.65  │  4.703987670051868  │
│   76    │              'generateRandomSpecialCharacterCodeByLength'              │  11.3   │  5.16817182376902   │
│   77    │                          'generateValidEmail'                          │ 16.225  │  8.597928529593625  │
│   78    │                         'generateInvalidEmail'                         │   6.2   │  7.950471684120383  │
└─────────┴────────────────────────────────────────────────────────────────────────┴─────────┴─────────────────────┘
>
```

Now you can run the commandMetrics command which will compute the performance statistics for the commands that have been executed:
```
  commandMetrics
```

The following table will output:
```
>commandMetrics
┌─────────┬────────────────────────┬──────────────────────┬─────────────────────┐
│ (index) │          Name          │       Average        │  StandardDeviation  │
├─────────┼────────────────────────┼──────────────────────┼─────────────────────┤
│    0    │       'workflow'       │ 0.24581005586592178  │ 0.5450865214592391  │
│    1    │   'commandSequencer'   │  0.6614583333333334  │  4.564741136771489  │
│    2    │         'name'         │ 0.025906735751295335 │ 0.35804306772992056 │
│    3    │       'version'        │ 0.005154639175257732 │ 0.07142573433671312 │
│    4    │        'about'         │ 0.005128205128205128 │   0.071244249007    │
│    5    │     'clearScreen'      │  4.497512437810945   │  25.53447218481813  │
│    6    │         'help'         │  0.3804878048780488  │ 3.0341334490947256  │
│    7    │     'workflowHelp'     │  0.4807692307692308  │  4.581809545011579  │
│    8    │     'businessRule'     │      6.34453125      │  10.50254514347171  │
│    9    │   'commandGenerator'   │  0.1411682892906815  │ 0.7206637989181904  │
│   10    │ 'businessRulesMetrics' │  4.556636553161918   │  172.7320307136272  │
└─────────┴────────────────────────┴──────────────────────┴─────────────────────┘
>
```
You can print out a log of all the commands you have entered so far by typing the command:
```
  printUserCommandsLog
```

Which will output something like this:

```
>printUserCommandsLog
Workflow startup,
?,
workflow?,
?,
workfow?,
workflow?,
workflow allBusinessRulesWorkflows,
businessRulesMetrics,
commandMetrics,
?,
printUserCommandsLog
>
```

You can print out a log of all the commands executed by the system, including all commands that were decomposed as part of other workflow commands by entering the command:
```
  printAllCommandsLog
```

The output will look something like this:

```
>printAllCommandsLog
Workflow startup,
name application true,
version,
about,
?,
workflow?,
?,
workfow?,
workflow?,
workflow allBusinessRulesWorkflows,
workflow allBusinessRulesArrayParsingWorkflows,
workflow allBusinessRulesStringParsingWorkflows,
workflow characterGeneration,
workflow mathOperations,
workflow stringGeneration,
workflow stringParsingUtilities,
workflow characterArrayParsing,
workflow pathArrayParsing,
workflow wordArrayParsing,
workflow doesArrayContainCharacter,
workflow removeCharacterFromArray,
workflow replaceCharacterAtIndex,
bizRul doesArrayContainCharacter $ [the,answer,to,life,the,universe,and,everything,is,$42],bizRul doesArrayContainCharacter $ [the,answer,to,life,the,universe,and,everything,is,$42],bizRul doesArrayContainCharacter $ [the,answer,to,life,the,universe,and,everything,is,$42],bizRul doesArrayContainCharacter $ [the,answer,to,life,the,universe,and,everything,is,$42],
bizRul removeCharacterFromArray $ [the,answer,to,life,the,universe,and,everything,is,$42],bizRul removeCharacterFromArray $ [the,answer,to,life,the,universe,and,everything,is,$42],bizRul removeCharacterFromArray $ [the,answer,to,life,the,universe,and,everything,is,$42],bizRul removeCharacterFromArray $ [the,answer,to,life,the,universe,and,everything,is,$42],
bizRul replaceCharacterAtIndex aggregateNumericalDifferenceBetweenTwoStrings [10,$],bizRul replaceCharacterAtIndex aggregateNumericalDifferenceBetweenTwoStrings [10,$],bizRul replaceCharacterAtIndex aggregateNumericalDifferenceBetweenTwoStrings [10,$],bizRul replaceCharacterAtIndex aggregateNumericalDifferenceBetweenTwoStrings [10,$],
workflow doesArrayContainFilename,
workflow getFileAndPathListForPath,
bizRul doesArrayContainFilename [20200603-142834-763_0.3.2_haystacks.zip,20200603-144529-749_0.3.3_haystacks.zip,20200604-133509-704_0.4.0_haystacks.zip,20200604-133546-749_0.4.1_haystacks.zip,20200604-160655-262_0.4.2_haystacks.zip,20200604-161819-191_0.4.3_haystacks.zip,20200604-173727-348_0.4.4_haystacks.zip,20200604-193551-258_0.5.0_haystacks.zip,20200604-193629-853_0.5.1_haystacks.zip,20200605-083055-193_0.5.2_haystacks.zip,20200610-170634-141_0.5.3_haystacks.zip,20200615-162658-576_0.5.4_haystacks.zip,20200617-150430-416_0.5.5_haystacks.zip,20200618-134424-575_0.5.6_haystacks.zip] 20200604-193551-258_0.5.0_haystacks.zip,bizRul doesArrayContainFilename [20200603-142834-763_0.3.2_haystacks.zip,20200603-144529-749_0.3.3_haystacks.zip,20200604-133509-704_0.4.0_haystacks.zip,20200604-133546-749_0.4.1_haystacks.zip,20200604-160655-262_0.4.2_haystacks.zip,20200604-161819-191_0.4.3_haystacks.zip,20200604-173727-348_0.4.4_haystacks.zip,20200604-193551-258_0.5.0_haystacks.zip,20200604-193629-853_0.5.1_haystacks.zip,20200605-083055-193_0.5.2_haystacks.zip,20200610-170634-141_0.5.3_haystacks.zip,20200615-162658-576_0.5.4_haystacks.zip,20200617-150430-416_0.5.5_haystacks.zip,20200618-134424-575_0.5.6_haystacks.zip] 20200604-193551-258_0.5.0_haystacks.zip,bizRul doesArrayContainFilename [20200603-142834-763_0.3.2_haystacks.zip,20200603-144529-749_0.3.3_haystacks.zip,20200604-133509-704_0.4.0_haystacks.zip,20200604-133546-749_0.4.1_haystacks.zip,20200604-160655-262_0.4.2_haystacks.zip,20200604-161819-191_0.4.3_haystacks.zip,20200604-173727-348_0.4.4_haystacks.zip,20200604-193551-258_0.5.0_haystacks.zip,20200604-193629-853_0.5.1_haystacks.zip,20200605-083055-193_0.5.2_haystacks.zip,20200610-170634-141_0.5.3_haystacks.zip,20200615-162658-576_0.5.4_haystacks.zip,20200617-150430-416_0.5.5_haystacks.zip,20200618-134424-575_0.5.6_haystacks.zip] 20200604-193551-258_0.5.0_haystacks.zip,bizRul doesArrayContainFilename [20200603-142834-763_0.3.2_haystacks.zip,20200603-144529-749_0.3.3_haystacks.zip,20200604-133509-704_0.4.0_haystacks.zip,20200604-133546-749_0.4.1_haystacks.zip,20200604-160655-262_0.4.2_haystacks.zip,20200604-161819-191_0.4.3_haystacks.zip,20200604-173727-348_0.4.4_haystacks.zip,20200604-193551-258_0.5.0_haystacks.zip,20200604-193629-853_0.5.1_haystacks.zip,20200605-083055-193_0.5.2_haystacks.zip,20200610-170634-141_0.5.3_haystacks.zip,20200615-162658-576_0.5.4_haystacks.zip,20200617-150430-416_0.5.5_haystacks.zip,20200618-134424-575_0.5.6_haystacks.zip] 20200604-193551-258_0.5.0_haystacks.zip,
bizRul getFileAndPathListForPath C:/haystacks-async/test/testHarness/logs/ 20,bizRul getFileAndPathListForPath C:/haystacks-async/test/testHarness/logs/ 20,bizRul getFileAndPathListForPath C:/haystacks-async/test/testHarness/logs/ 20,bizRul getFileAndPathListForPath C:/haystacks-async/test/testHarness/logs/ 20,
workflow convertCamelCaseStringToArray,
workflow convertArrayToCamelCaseString,
workflow doesArrayContainLowerCaseConsolidatedString,
bizRul convertCamelCaseStringToArray TheAnswerToLifeTheUniverseAndEverythingIs42,bizRul convertCamelCaseStringToArray TheAnswerToLifeTheUniverseAndEverythingIs42,bizRul convertCamelCaseStringToArray TheAnswerToLifeTheUniverseAndEverythingIs42,bizRul convertCamelCaseStringToArray TheAnswerToLifeTheUniverseAndEverythingIs42,
bizRul convertArrayToCamelCaseString [the,answer,to,life,the,universe,and,everything,is,42],bizRul convertArrayToCamelCaseString [the,answer,to,life,the,universe,and,everything,is,42],bizRul convertArrayToCamelCaseString [the,answer,to,life,the,universe,and,everything,is,42],bizRul convertArrayToCamelCaseString [the,answer,to,life,the,universe,and,everything,is,42],
bizRul doesArrayContainLowerCaseConsolidatedString [the,answer,to,life,the,universe,and,everything,is,42] everything,bizRul doesArrayContainLowerCaseConsolidatedString [the,answer,to,life,the,universe,and,everything,is,42] everything,bizRul doesArrayContainLowerCaseConsolidatedString [the,answer,to,life,the,universe,and,everything,is,42] everything,bizRul doesArrayContainLowerCaseConsolidatedString [the,answer,to,life,the,universe,and,everything,is,42] everything,
workflow characterStringParsing,
workflow dataStringParsing,
workflow fileStringParsing,
workflow wordStringParsing,
workflow singleQuoteSwapAfterEquals,
workflow swapForwardSlashToBackSlash,
workflow swapBackSlashToForwardSlash,
workflow swapDoubleForwardSlashToSingleForwardSlash,
workflow swapDoubleBackSlashToSingleBackSlash,
workflow replaceSpacesWithPlus,
workflow replaceColonWithUnderscore,
workflow cleanCarriageReturnFromString,
workflow convertStringToLowerCase,
workflow convertStringToUpperCase,
bizrul singleQuoteSwapAfterEquals input[name='emailAddress'][class='username'],bizrul singleQuoteSwapAfterEquals input[name='emailAddress'][class='username'],bizrul singleQuoteSwapAfterEquals input[name='emailAddress'][class='username'],bizrul singleQuoteSwapAfterEquals input[name='emailAddress'][class='username'],
bizrul swapForwardSlashToBackSlash C:/,bizrul swapForwardSlashToBackSlash C:/,bizrul swapForwardSlashToBackSlash C:/,bizrul swapForwardSlashToBackSlash C:/,
bizrul swapBackSlashToForwardSlash C:\,bizrul swapBackSlashToForwardSlash C:\,bizrul swapBackSlashToForwardSlash C:\,bizrul swapBackSlashToForwardSlash C:\,
bizrul swapDoubleForwardSlashToSingleForwardSlash http://,bizrul swapDoubleForwardSlashToSingleForwardSlash http://,bizrul swapDoubleForwardSlashToSingleForwardSlash http://,bizrul swapDoubleForwardSlashToSingleForwardSlash http://,
bizrul swapDoubleBackSlashToSingleBackSlash http:\\,bizrul swapDoubleBackSlashToSingleBackSlash http:\\,bizrul swapDoubleBackSlashToSingleBackSlash http:\\,bizrul swapDoubleBackSlashToSingleBackSlash http:\\,
bizRul replaceSpacesWithPlus `Hello My Name Is: Blaaa`,bizRul replaceSpacesWithPlus `Hello My Name Is: Blaaa`,bizRul replaceSpacesWithPlus `Hello My Name Is: Blaaa`,bizRul replaceSpacesWithPlus `Hello My Name Is: Blaaa`,
bizRul replaceColonWithUnderscore Ok:So:Give_this_a:try,bizRul replaceColonWithUnderscore Ok:So:Give_this_a:try,bizRul replaceColonWithUnderscore Ok:So:Give_this_a:try,bizRul replaceColonWithUnderscore Ok:So:Give_this_a:try,
bizRul cleanCarriageReturnFromString `This
          is
          a
          string
          with
          many
          newline
          characters.`,bizRul cleanCarriageReturnFromString `This
          is
          a
          string
          with
          many
          newline
          characters.`,bizRul cleanCarriageReturnFromString `This
          is
          a
          string
          with
          many
          newline
          characters.`,bizRul cleanCarriageReturnFromString `This
          is
          a
          string
          with
          many
          newline
          characters.`,
bizRul convertStringToLowerCase GENERATERANDOMLOWERCASETEXTWITHSPECIALCHARACTERBYLENGTH123456!@#$%^,bizRul convertStringToLowerCase GENERATERANDOMLOWERCASETEXTWITHSPECIALCHARACTERBYLENGTH123456!@#$%^,bizRul convertStringToLowerCase GENERATERANDOMLOWERCASETEXTWITHSPECIALCHARACTERBYLENGTH123456!@#$%^,bizRul convertStringToLowerCase GENERATERANDOMLOWERCASETEXTWITHSPECIALCHARACTERBYLENGTH123456!@#$%^,
bizRul convertStringToUpperCase generaterandomlowercasetextwithspecialcharacterbylength123456!@#$%^,bizRul convertStringToUpperCase generaterandomlowercasetextwithspecialcharacterbylength123456!@#$%^,bizRul convertStringToUpperCase generaterandomlowercasetextwithspecialcharacterbylength123456!@#$%^,bizRul convertStringToUpperCase generaterandomlowercasetextwithspecialcharacterbylength123456!@#$%^,
workflow getUserNameFromEmail,
workflow getDataCategoryFromDataContextName,
workflow getDataCategoryDetailNameFromDataContextName,
workflow getKeywordNameFromDataContextName,
bizrul getUserNameFromEmail Iceversaka@hotmail.com,bizrul getUserNameFromEmail Iceversaka@hotmail.com,bizrul getUserNameFromEmail Iceversaka@hotmail.com,bizrul getUserNameFromEmail Iceversaka@hotmail.com,
bizRul getDataCategoryFromDataContextName Page_ProjectList,bizRul getDataCategoryFromDataContextName Page_ProjectList,bizRul getDataCategoryFromDataContextName Page_ProjectList,bizRul getDataCategoryFromDataContextName Page_ProjectList,
bizRul getDataCategoryDetailNameFromDataContextName Page_ProjectList,bizRul getDataCategoryDetailNameFromDataContextName Page_ProjectList,bizRul getDataCategoryDetailNameFromDataContextName Page_ProjectList,bizRul getDataCategoryDetailNameFromDataContextName Page_ProjectList,
bizRul getKeywordNameFromDataContextName Keywords_ProjectDetails_DeleteEntireProject,bizRul getKeywordNameFromDataContextName Keywords_ProjectDetails_DeleteEntireProject,bizRul getKeywordNameFromDataContextName Keywords_ProjectDetails_DeleteEntireProject,bizRul getKeywordNameFromDataContextName Keywords_ProjectDetails_DeleteEntireProject,
workflow getFileNameFromPath,
workflow getFileExtension,
workflow removeDotFromFileExtension,
workflow removeFileExtensionFromFileName,
workflow ascertainMatchingFilenames,
workflow removeXnumberOfFoldersFromEndOfPath,
workflow getFirstTopLevelFolderFromPath,
bizRul getFileNameFromPath C:\NodeJS-App\src\Application\NodeJS-App\application.js,bizRul getFileNameFromPath C:\NodeJS-App\src\Application\NodeJS-App\application.js,bizRul getFileNameFromPath C:\NodeJS-App\src\Application\NodeJS-App\application.js,bizRul getFileNameFromPath C:\NodeJS-App\src\Application\NodeJS-App\application.js,
bizRul getFileExtension C:\NodeJS-App\src\Application\NodeJS-App\application.js,bizRul getFileExtension C:\NodeJS-App\src\Application\NodeJS-App\application.js,bizRul getFileExtension C:\NodeJS-App\src\Application\NodeJS-App\application.js,bizRul getFileExtension C:\NodeJS-App\src\Application\NodeJS-App\application.js,
bizRul removeDotFromFileExtension .exe,bizRul removeDotFromFileExtension .exe,bizRul removeDotFromFileExtension .exe,bizRul removeDotFromFileExtension .exe,
bizRul removeFileExtensionFromFileName application.js,bizRul removeFileExtensionFromFileName application.js,bizRul removeFileExtensionFromFileName application.js,bizRul removeFileExtensionFromFileName application.js,
bizRul ascertainMatchingFilenames C:\haystacks\test\resources\configuration\configuration.json C:\haystacks\src\executrix\lexical.js,bizRul ascertainMatchingFilenames C:\haystacks\test\resources\configuration\configuration.json C:\haystacks\src\executrix\lexical.js,bizRul ascertainMatchingFilenames C:\haystacks\test\resources\configuration\configuration.json C:\haystacks\src\executrix\lexical.js,bizRul ascertainMatchingFilenames C:\haystacks\test\resources\configuration\configuration.json C:\haystacks\src\executrix\lexical.js,
bizRul removeXnumberOfFoldersFromEndOfPath C:\haystacks\src\commandsBlob\commands 2,bizRul removeXnumberOfFoldersFromEndOfPath C:\haystacks\src\commandsBlob\commands 2,bizRul removeXnumberOfFoldersFromEndOfPath C:\haystacks\src\commandsBlob\commands 2,bizRul removeXnumberOfFoldersFromEndOfPath C:\haystacks\src\commandsBlob\commands 2,
bizRul getFirstTopLevelFolderFromPath C:\haystacks\src\commandsBlob\commands\,bizRul getFirstTopLevelFolderFromPath C:\haystacks\src\commandsBlob\commands\,bizRul getFirstTopLevelFolderFromPath C:\haystacks\src\commandsBlob\commands\,bizRul getFirstTopLevelFolderFromPath C:\haystacks\src\commandsBlob\commands\,
```

It is also possible to clear these command logs independently with the commands:
```
  clearUserCommandsLog
  clearAllCommandsLog
```

If you want to control the ability to clear these logs, or the ability to generate them in the first place for any reason, the settings are found in the file located here: ./test/testHarness/src/resources/configuration/application.system.json
The settings to control these behaviors are:
```
  "system.logUserEnteredCommands": true,
  "system.logAllCommands": true,
  "system.enableUserCommandsLogClearing": true,
  "system.enableAllCommandsLogClearing": true,
```

There are some application specific commands you can use when you build your own application. If you copy the contents of the testHarness folder and use that code as a template to build your own application, it has some pre-built commands that your application can use to help your users, and also help you as a developer of your application. The useful application specific commands are:
```
  applicationHelp
  applicationWorkflowHelp
  validateApplicationConstants
  validateApplicationCommandAliases
  validateApplicationWorkflows
  allApplicationValidations
```

The first two of these commands: applicationHelp and applicationWorkflowHelp can be abbreviated as follows for simplicity:
```
  app?
  AppWflow?
```

The commands: validateApplicationConstants, validateApplicationCommandAliases, validateApplicationWorkflows, and allApplicationValidations
Will execute constants validation for the application constants and all of the loaded plugin constants. If no plugins are loaded and/or the enablePluginLoader setting is disabled, then no plugin constants validation will be run.
The same goes for all of these validation commands which are looking for duplicate command aliases and workflows respectively.
It may also be valuable to occasionally run the Haystacks validation commands, not always just the application specific validation commands to check and make sure you haven't created any collisions with haystacks defined command aliases or haystacks defined workflows.
Unfortunately, these commands currently take a significant amount of time.
There will be a future effort to improve the data efficiency of the system at some point in the future by moving the back-end data structures to a Red-Black Binary Search Tree or RB-BST.
This will take a significant effort given all the algorithms that will need to be implemented for how all the haystacks sub-systems are interfacing with the data. The data is often represented in a hierarchy format, with heirarchal namespace context information. Preserving this functionality especially for recursive functions will be a challenge to overcome, but not impossible.

# Exit / Quit
To exit the application simply type the command:
```
  x
```
or X, or exist or Exit or quit, etc...

```
>x
END command parser
END main program loop
Exiting TEST HARNESS APPLICATION
END testHarness.application Function

C:\haystacks-async>
```

# Debugging
If you want to or need to debug any part of the application, or you are building on some business rules and adding functions that you want to debug.
Simply continue to following the existing patterns in the code then add your functions to the appropriate file <fileName>.json under the following path:
./src/resources/configuration/debugSettings/...
Or in the testHarness:
./test/testHarness/src/resources/configuration/debugSettings/...

If you want to debug any function in the entire framework you can find the related .json file open it and change either the file level log setting or the function level log setting like so:

Let us assume we want to debug the framework system commands.
We can load the file found at the following path:
./src/resources/configuration/debugSettings/commandsBlob/commands/system.json

You'll see some JSON code that looks like this:
```
{
  "debugFiles|debugSetting.framework.commandsBlob.commands.system": false,
  "debugFiles|debugSetting.framework.commandsBlob.commands.system@ModuleFontStyle": "Bold|Underline",
  "debugFiles|debugSetting.framework.commandsBlob.commands.system@FunctionFontStyle": "Bold|Underline",
  "debugFiles|debugSetting.framework.commandsBlob.commands.system@MessageFontStyle": "Underline",
  "debugFiles|debugSetting.framework.commandsBlob.commands.system@DataFontStyle": "Bold",
  "debugFiles|debugSetting.framework.commandsBlob.commands.system@ModuleFontColor": "255,127,0",
  "debugFiles|debugSetting.framework.commandsBlob.commands.system@FunctionFontColor": "0,0,0",
  "debugFiles|debugSetting.framework.commandsBlob.commands.system@MessageFontColor": "255,127,0",
  "debugFiles|debugSetting.framework.commandsBlob.commands.system@DataFontColor": "0,0,0",
  "debugFiles|debugSetting.framework.commandsBlob.commands.system@ModuleFontBackgroundColor": "211,211,211",
  "debugFiles|debugSetting.framework.commandsBlob.commands.system@FunctionFontBackgroundColor": "255,255,255",
  "debugFiles|debugSetting.framework.commandsBlob.commands.system@MessageFontBackgroundColor": "211,211,211",
  "debugFiles|debugSetting.framework.commandsBlob.commands.system@DataFontBackgroundColor": "255,255,255",
  "debugFunctions|debugSetting.framework.commandsBlob.commands.system.echoCommand": false,
  "debugFunctions|debugSetting.framework.commandsBlob.commands.system.echoCommand@ModuleFontStyle": "Default",
  "debugFunctions|debugSetting.framework.commandsBlob.commands.system.echoCommand@FunctionFontStyle": "Default",
  "debugFunctions|debugSetting.framework.commandsBlob.commands.system.echoCommand@MessageFontStyle": "Default",
  "debugFunctions|debugSetting.framework.commandsBlob.commands.system.echoCommand@DataFontStyle": "Default",
  "debugFunctions|debugSetting.framework.commandsBlob.commands.system.echoCommand@ModuleFontColor": "Blue",
  "debugFunctions|debugSetting.framework.commandsBlob.commands.system.echoCommand@FunctionFontColor": "Blue",
  "debugFunctions|debugSetting.framework.commandsBlob.commands.system.echoCommand@MessageFontColor": "Blue",
  "debugFunctions|debugSetting.framework.commandsBlob.commands.system.echoCommand@DataFontColor": "Yellow",
  "debugFunctions|debugSetting.framework.commandsBlob.commands.system.echoCommand@ModuleFontBackgroundColor": "Black",
  "debugFunctions|debugSetting.framework.commandsBlob.commands.system.echoCommand@FunctionFontBackgroundColor": "Black",
  "debugFunctions|debugSetting.framework.commandsBlob.commands.system.echoCommand@MessageFontBackgroundColor": "Black",
  "debugFunctions|debugSetting.framework.commandsBlob.commands.system.echoCommand@DataFontBackgroundColor": "Black",
  "debugFunctions|debugSetting.framework.commandsBlob.commands.system.exit": false,
  "debugFunctions|debugSetting.framework.commandsBlob.commands.system.exit@ModuleFontStyle": "Default",
  "debugFunctions|debugSetting.framework.commandsBlob.commands.system.exit@FunctionFontStyle": "Default",
  ...
}
```

Pay special attention to the following 3 entries:
```
"debugFiles|debugSetting.framework.commandsBlob.commands.system": false,
...
"debugFunctions|debugSetting.framework.commandsBlob.commands.system.echoCommand": false,
...
"debugFunctions|debugSetting.framework.commandsBlob.commands.system.exit": false,
```

The first of these is the setting to enable logging of all commands in the system.js file.
The second line is the setting to enable logging for the echoCommand command ONLY.
The third line