fable 3.0.3 → 3.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/fable.js CHANGED
@@ -1149,23 +1149,121 @@
1149
1149
  }
1150
1150
  module.exports = libNPMModuleWrapper;
1151
1151
  }, {
1152
- "./Fable.js": 17
1152
+ "./Fable.js": 18
1153
1153
  }],
1154
1154
  16: [function (require, module, exports) {
1155
1155
  class FableUtility {
1156
- constructor(pFable) {
1156
+ constructor(pFable, pTemplateText) {
1157
1157
  this.fable = pFable;
1158
+
1159
+ // These are the exact regex's used in lodash/underscore
1160
+ // TODO: Switch this to precedent
1161
+ this.Matchers = {
1162
+ Evaluate: /<%([\s\S]+?)%>/g,
1163
+ Interpolate: /<%=([\s\S]+?)%>/g,
1164
+ Escaper: /\\|'|\r|\n|\t|\u2028|\u2029/g,
1165
+ Unescaper: /\\(\\|'|r|n|t|u2028|u2029)/g,
1166
+ // This is how underscore does it, so we are keeping it for now.
1167
+ GuaranteedNonMatch: /.^/
1168
+ };
1169
+
1170
+ // This is a helper for the escaper and unescaper functions.
1171
+ // Right now we are going to keep what underscore is doing, but, not forever.
1172
+ this.templateEscapes = {
1173
+ '\\': '\\',
1174
+ "'": "'",
1175
+ 'r': '\r',
1176
+ '\r': 'r',
1177
+ 'n': '\n',
1178
+ '\n': 'n',
1179
+ 't': '\t',
1180
+ '\t': 't',
1181
+ 'u2028': '\u2028',
1182
+ '\u2028': 'u2028',
1183
+ 'u2029': '\u2029',
1184
+ '\u2029': 'u2029'
1185
+ };
1186
+
1187
+ // This is defined as such to underscore that it is a dynamic programming
1188
+ // function on this class.
1189
+ this.renderFunction = () => {
1190
+ return ``;
1191
+ };
1158
1192
  }
1159
1193
 
1160
- // Underscore and lodash both had a behavior, _.extend, which merged objects
1194
+ // Underscore and lodash have a behavior, _.extend, which merges objects.
1161
1195
  // Now that es6 gives us this, use the native thingy.
1162
1196
  extend(pDestinationObject, ...pSourceObjects) {
1163
1197
  return Object.assign(pDestinationObject, ...pSourceObjects);
1164
1198
  }
1199
+ renderTemplate(pData) {
1200
+ return this.renderFunction(pData);
1201
+ }
1202
+ templateFunction(pData) {
1203
+ let fRenderTemplateBound = this.renderTemplate.bind(this);
1204
+ return fRenderTemplateBound;
1205
+ }
1206
+
1207
+ // Underscore and lodash have a behavior, _.template, which compiles a
1208
+ // string-based template with code snippets into simple executable pieces,
1209
+ // with the added twist of returning a precompiled function ready to go.
1210
+ //
1211
+ // NOTE: This does not implement underscore escape expressions
1212
+ // NOTE: This does not implement underscore magic browser variable assignment
1213
+ //
1214
+ // This is an implementation of that.
1215
+ // TODO: Make this use precedent, add configuration, add debugging.
1216
+ buildTemplateFunction(pTemplateText, pData) {
1217
+ // For now this is being kept in a weird form ... this is to mimic the old
1218
+ // underscore code until this is rewritten using precedent.
1219
+ this.TemplateSource = "__p+='" + pTemplateText.replace(this.Matchers.Escaper, pMatch => {
1220
+ return `\\${this.templateEscapes[pMatch]}`;
1221
+ }).replace(this.Matchers.Interpolate || this.Matchers.GuaranteedNonMatch, (pMatch, pCode) => {
1222
+ return `'+\n(${decodeURIComponent(pCode)})+\n'`;
1223
+ }).replace(this.Matchers.Evaluate || this.Matchers.GuaranteedNonMatch, (pMatch, pCode) => {
1224
+ return `';\n${decodeURIComponent(pCode)}\n;__p+='`;
1225
+ }) + `';\n`;
1226
+ this.TemplateSource = `with(pTemplateDataObject||{}){\n${this.TemplateSource}}\n`;
1227
+ this.TemplateSource = `var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n${this.TemplateSource}return __p;\n`;
1228
+ this.renderFunction = new Function('pTemplateDataObject', this.TemplateSource);
1229
+ if (typeof pData != 'undefined') {
1230
+ return this.renderFunction(pData);
1231
+ }
1232
+
1233
+ // Provide the compiled function source as a convenience for build time
1234
+ // precompilation.
1235
+ this.TemplateSourceCompiled = 'function(obj){\n' + this.TemplateSource + '}';
1236
+ return this.templateFunction();
1237
+ }
1165
1238
  }
1166
1239
  module.exports = FableUtility;
1167
1240
  }, {}],
1168
1241
  17: [function (require, module, exports) {
1242
+ const libFableUtilityTemplate = require('./Fable-Utility-Template.js');
1243
+ class FableUtility {
1244
+ constructor(pFable) {
1245
+ this.fable = pFable;
1246
+ }
1247
+
1248
+ // Underscore and lodash have a behavior, _.extend, which merges objects.
1249
+ // Now that es6 gives us this, use the native thingy.
1250
+ extend(pDestinationObject, ...pSourceObjects) {
1251
+ return Object.assign(pDestinationObject, ...pSourceObjects);
1252
+ }
1253
+
1254
+ // Underscore and lodash have a behavior, _.template, which compiles a
1255
+ // string-based template with code snippets into simple executable pieces,
1256
+ // with the added twist of returning a precompiled function ready to go.
1257
+ template(pTemplateText, pData) {
1258
+ let tmpTemplate = new libFableUtilityTemplate(this.fable, pTemplateText);
1259
+ return tmpTemplate.buildTemplateFunction(pTemplateText, pData);
1260
+ }
1261
+ }
1262
+ module.exports = FableUtility;
1263
+ }, {
1264
+ "./Fable-Utility-Template.js": 16
1265
+ }],
1266
+ 18: [function (require, module, exports) {
1169
1267
  /**
1170
1268
  * Fable Application Services Support Library
1171
1269
  * @license MIT
@@ -1198,7 +1296,7 @@
1198
1296
  }
1199
1297
  module.exports = Fable;
1200
1298
  }, {
1201
- "./Fable-Utility.js": 16,
1299
+ "./Fable-Utility.js": 17,
1202
1300
  "fable-log": 5,
1203
1301
  "fable-settings": 8,
1204
1302
  "fable-uuid": 10
package/dist/fable.min.js CHANGED
@@ -1,4 +1,4 @@
1
- !function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Fable=t()}}((function(){return function t(e,r,s){function n(i,a){if(!r[i]){if(!e[i]){var l="function"==typeof require&&require;if(!a&&l)return l(i,!0);if(o)return o(i,!0);var u=new Error("Cannot find module '"+i+"'");throw u.code="MODULE_NOT_FOUND",u}var h=r[i]={exports:{}};e[i][0].call(h.exports,(function(t){return n(e[i][1][t]||t)}),h,h.exports,t,e,r,s)}return r[i].exports}for(var o="function"==typeof require&&require,i=0;i<s.length;i++)n(s[i]);return n}({1:[function(t,e,r){e.exports=
1
+ !function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Fable=t()}}((function(){return function t(e,r,n){function s(i,a){if(!r[i]){if(!e[i]){var l="function"==typeof require&&require;if(!a&&l)return l(i,!0);if(o)return o(i,!0);var u=new Error("Cannot find module '"+i+"'");throw u.code="MODULE_NOT_FOUND",u}var h=r[i]={exports:{}};e[i][0].call(h.exports,(function(t){return s(e[i][1][t]||t)}),h,h.exports,t,e,r,n)}return r[i].exports}for(var o="function"==typeof require&&require,i=0;i<n.length;i++)s(n[i]);return s}({1:[function(t,e,r){e.exports=
2
2
  /**
3
3
  * Base Logger Class
4
4
  *
@@ -14,7 +14,7 @@ class{constructor(t,e){this._Settings=t,this.loggerUUID=this.generateInsecureUUI
14
14
  *
15
15
  * @author Steven Velozo <steven@velozo.com>
16
16
  */
17
- getDefaultProviders=()=>{let e={};return e.console=t("./Fable-Log-Logger-Console.js"),e.default=e.console,e},e.exports=getDefaultProviders()},{"./Fable-Log-Logger-Console.js":4}],3:[function(t,e,r){e.exports=[{loggertype:"console",streamtype:"console",level:"trace"}]},{}],4:[function(t,e,r){let s=t("./Fable-Log-BaseLogger.js");e.exports=class extends s{constructor(t,e){super(t),this._ShowTimeStamps=!!t.hasOwnProperty("showtimestamps")&&1==t.showtimestamps,this._FormattedTimeStamps=!!t.hasOwnProperty("formattedtimestamps")&&1==t.formattedtimestamps,this._ContextMessage=t.hasOwnProperty("Context")?`(${t.Context})`:e._Settings.hasOwnProperty("Product")?`(${e._Settings.Product})`:"Unnamed_Log_Context",this._OutputLogLinesToConsole=!t.hasOwnProperty("outputloglinestoconsole")||t.outputloglinestoconsole,this._OutputObjectsToConsole=!t.hasOwnProperty("outputobjectstoconsole")||t.outputobjectstoconsole,this.prefixCache={};for(let t=0;t<=this.levels.length;t++)this.prefixCache[this.levels[t]]=`[${this.levels[t]}] ${this._ContextMessage}: `,this._ShowTimeStamps&&(this.prefixCache[this.levels[t]]=" "+this.prefixCache[this.levels[t]])}write(t,e,r){let s="";this._ShowTimeStamps&&this._FormattedTimeStamps?s=(new Date).toISOString():this._ShowTimeStamps&&(s=+new Date);let n=`${s}${this.prefixCache[t]}${e}`;return this._OutputLogLinesToConsole&&console.log(n),this._OutputObjectsToConsole&&void 0!==r&&console.log(JSON.stringify(r,null,2)),n}}},{"./Fable-Log-BaseLogger.js":1}],5:[function(t,e,r){
17
+ getDefaultProviders=()=>{let e={};return e.console=t("./Fable-Log-Logger-Console.js"),e.default=e.console,e},e.exports=getDefaultProviders()},{"./Fable-Log-Logger-Console.js":4}],3:[function(t,e,r){e.exports=[{loggertype:"console",streamtype:"console",level:"trace"}]},{}],4:[function(t,e,r){let n=t("./Fable-Log-BaseLogger.js");e.exports=class extends n{constructor(t,e){super(t),this._ShowTimeStamps=!!t.hasOwnProperty("showtimestamps")&&1==t.showtimestamps,this._FormattedTimeStamps=!!t.hasOwnProperty("formattedtimestamps")&&1==t.formattedtimestamps,this._ContextMessage=t.hasOwnProperty("Context")?`(${t.Context})`:e._Settings.hasOwnProperty("Product")?`(${e._Settings.Product})`:"Unnamed_Log_Context",this._OutputLogLinesToConsole=!t.hasOwnProperty("outputloglinestoconsole")||t.outputloglinestoconsole,this._OutputObjectsToConsole=!t.hasOwnProperty("outputobjectstoconsole")||t.outputobjectstoconsole,this.prefixCache={};for(let t=0;t<=this.levels.length;t++)this.prefixCache[this.levels[t]]=`[${this.levels[t]}] ${this._ContextMessage}: `,this._ShowTimeStamps&&(this.prefixCache[this.levels[t]]=" "+this.prefixCache[this.levels[t]])}write(t,e,r){let n="";this._ShowTimeStamps&&this._FormattedTimeStamps?n=(new Date).toISOString():this._ShowTimeStamps&&(n=+new Date);let s=`${n}${this.prefixCache[t]}${e}`;return this._OutputLogLinesToConsole&&console.log(s),this._OutputObjectsToConsole&&void 0!==r&&console.log(JSON.stringify(r,null,2)),s}}},{"./Fable-Log-BaseLogger.js":1}],5:[function(t,e,r){
18
18
  /**
19
19
  * Fable Logging Add-on
20
20
  *
@@ -23,7 +23,7 @@ getDefaultProviders=()=>{let e={};return e.console=t("./Fable-Log-Logger-Console
23
23
  * @author Steven Velozo <steven@velozo.com>
24
24
  * @module Fable Logger
25
25
  */
26
- class s{constructor(e,r){let s="object"==typeof e?e:{};this._Settings=s,this._Providers=t("./Fable-Log-DefaultProviders-Node.js"),this._StreamDefinitions=s.hasOwnProperty("LogStreams")?s.LogStreams:t("./Fable-Log-DefaultStreams.json"),this.logStreams=[],this.logProviders={},this.activeLogStreams={},this.logStreamsTrace=[],this.logStreamsDebug=[],this.logStreamsInfo=[],this.logStreamsWarn=[],this.logStreamsError=[],this.logStreamsFatal=[],this.datumDecorator=t=>t,this.uuid="string"==typeof s.Product?s.Product:"Default"}addLogger(t,e){if(this.activeLogStreams.hasOwnProperty(t.loggerUUID))return!1;switch(this.logStreams.push(t),this.activeLogStreams[t.loggerUUID]=!0,e){case"trace":this.logStreamsTrace.push(t);case"debug":this.logStreamsDebug.push(t);case"info":this.logStreamsInfo.push(t);case"warn":this.logStreamsWarn.push(t);case"error":this.logStreamsError.push(t);case"fatal":this.logStreamsFatal.push(t)}return!0}setDatumDecorator(t){this.datumDecorator="function"==typeof t?t:t=>t}trace(t,e){const r=this.datumDecorator(e);for(let e=0;e<this.logStreamsTrace.length;e++)this.logStreamsTrace[e].trace(t,r)}debug(t,e){const r=this.datumDecorator(e);for(let e=0;e<this.logStreamsDebug.length;e++)this.logStreamsDebug[e].debug(t,r)}info(t,e){const r=this.datumDecorator(e);for(let e=0;e<this.logStreamsInfo.length;e++)this.logStreamsInfo[e].info(t,r)}warn(t,e){const r=this.datumDecorator(e);for(let e=0;e<this.logStreamsWarn.length;e++)this.logStreamsWarn[e].warn(t,r)}error(t,e){const r=this.datumDecorator(e);for(let e=0;e<this.logStreamsError.length;e++)this.logStreamsError[e].error(t,r)}fatal(t,e){const r=this.datumDecorator(e);for(let e=0;e<this.logStreamsFatal.length;e++)this.logStreamsFatal[e].fatal(t,r)}initialize(){for(let t=0;t<this._StreamDefinitions.length;t++){let e=Object.assign({loggertype:"default",streamtype:"console",level:"info"},this._StreamDefinitions[t]);this._Providers.hasOwnProperty(e.loggertype)?this.addLogger(new this._Providers[e.loggertype](e,this),e.level):console.log(`Error initializing log stream: bad loggertype in stream definition ${JSON.stringify(e)}`)}for(let t=0;t<this.logStreams.length;t++)this.logStreams[t].initialize()}logTime(t,e){let r=void 0!==t?t:"Time",s=new Date;this.info(`${r} ${s} (epoch ${+s})`,e)}getTimeStamp(){return+new Date}getTimeDelta(t){return+new Date-t}logTimeDelta(t,e,r){let s=void 0!==e?e:"Time Measurement",n=+new Date;this.info(`${s} logged at (epoch ${+n}) took (${t}ms)`,r)}logTimeDeltaHuman(t,e,r){let s=void 0!==e?e:"Time Measurement",n=+new Date,o=parseInt(t%1e3),i=parseInt(t/1e3%60),a=parseInt(t/6e4%60),l=parseInt(t/36e5);o=o<10?"00"+o:o<100?"0"+o:o,i=i<10?"0"+i:i,a=a<10?"0"+a:a,l=l<10?"0"+l:l,this.info(`${s} logged at (epoch ${+n}) took (${t}ms) or (${l}:${a}:${i}.${o})`,r)}logTimeDeltaRelative(t,e,r){this.logTimeDelta(this.getTimeDelta(t),e,r)}logTimeDeltaRelativeHuman(t,e,r){this.logTimeDeltaHuman(this.getTimeDelta(t),e,r)}}e.exports={new:function(t){return new s(t)},FableLog:s}},{"./Fable-Log-DefaultProviders-Node.js":2,"./Fable-Log-DefaultStreams.json":3}],6:[function(t,e,r){e.exports={Product:"ApplicationNameHere",ProductVersion:"0.0.0",ConfigFile:!1,LogStreams:[{level:"trace"}]}},{}],7:[function(t,e,r){(function(t){(function(){e.exports=
26
+ class n{constructor(e,r){let n="object"==typeof e?e:{};this._Settings=n,this._Providers=t("./Fable-Log-DefaultProviders-Node.js"),this._StreamDefinitions=n.hasOwnProperty("LogStreams")?n.LogStreams:t("./Fable-Log-DefaultStreams.json"),this.logStreams=[],this.logProviders={},this.activeLogStreams={},this.logStreamsTrace=[],this.logStreamsDebug=[],this.logStreamsInfo=[],this.logStreamsWarn=[],this.logStreamsError=[],this.logStreamsFatal=[],this.datumDecorator=t=>t,this.uuid="string"==typeof n.Product?n.Product:"Default"}addLogger(t,e){if(this.activeLogStreams.hasOwnProperty(t.loggerUUID))return!1;switch(this.logStreams.push(t),this.activeLogStreams[t.loggerUUID]=!0,e){case"trace":this.logStreamsTrace.push(t);case"debug":this.logStreamsDebug.push(t);case"info":this.logStreamsInfo.push(t);case"warn":this.logStreamsWarn.push(t);case"error":this.logStreamsError.push(t);case"fatal":this.logStreamsFatal.push(t)}return!0}setDatumDecorator(t){this.datumDecorator="function"==typeof t?t:t=>t}trace(t,e){const r=this.datumDecorator(e);for(let e=0;e<this.logStreamsTrace.length;e++)this.logStreamsTrace[e].trace(t,r)}debug(t,e){const r=this.datumDecorator(e);for(let e=0;e<this.logStreamsDebug.length;e++)this.logStreamsDebug[e].debug(t,r)}info(t,e){const r=this.datumDecorator(e);for(let e=0;e<this.logStreamsInfo.length;e++)this.logStreamsInfo[e].info(t,r)}warn(t,e){const r=this.datumDecorator(e);for(let e=0;e<this.logStreamsWarn.length;e++)this.logStreamsWarn[e].warn(t,r)}error(t,e){const r=this.datumDecorator(e);for(let e=0;e<this.logStreamsError.length;e++)this.logStreamsError[e].error(t,r)}fatal(t,e){const r=this.datumDecorator(e);for(let e=0;e<this.logStreamsFatal.length;e++)this.logStreamsFatal[e].fatal(t,r)}initialize(){for(let t=0;t<this._StreamDefinitions.length;t++){let e=Object.assign({loggertype:"default",streamtype:"console",level:"info"},this._StreamDefinitions[t]);this._Providers.hasOwnProperty(e.loggertype)?this.addLogger(new this._Providers[e.loggertype](e,this),e.level):console.log(`Error initializing log stream: bad loggertype in stream definition ${JSON.stringify(e)}`)}for(let t=0;t<this.logStreams.length;t++)this.logStreams[t].initialize()}logTime(t,e){let r=void 0!==t?t:"Time",n=new Date;this.info(`${r} ${n} (epoch ${+n})`,e)}getTimeStamp(){return+new Date}getTimeDelta(t){return+new Date-t}logTimeDelta(t,e,r){let n=void 0!==e?e:"Time Measurement",s=+new Date;this.info(`${n} logged at (epoch ${+s}) took (${t}ms)`,r)}logTimeDeltaHuman(t,e,r){let n=void 0!==e?e:"Time Measurement",s=+new Date,o=parseInt(t%1e3),i=parseInt(t/1e3%60),a=parseInt(t/6e4%60),l=parseInt(t/36e5);o=o<10?"00"+o:o<100?"0"+o:o,i=i<10?"0"+i:i,a=a<10?"0"+a:a,l=l<10?"0"+l:l,this.info(`${n} logged at (epoch ${+s}) took (${t}ms) or (${l}:${a}:${i}.${o})`,r)}logTimeDeltaRelative(t,e,r){this.logTimeDelta(this.getTimeDelta(t),e,r)}logTimeDeltaRelativeHuman(t,e,r){this.logTimeDeltaHuman(this.getTimeDelta(t),e,r)}}e.exports={new:function(t){return new n(t)},FableLog:n}},{"./Fable-Log-DefaultProviders-Node.js":2,"./Fable-Log-DefaultStreams.json":3}],6:[function(t,e,r){e.exports={Product:"ApplicationNameHere",ProductVersion:"0.0.0",ConfigFile:!1,LogStreams:[{level:"trace"}]}},{}],7:[function(t,e,r){(function(t){(function(){e.exports=
27
27
  /**
28
28
  * Fable Settings Template Processor
29
29
  *
@@ -34,7 +34,7 @@ class s{constructor(e,r){let s="object"==typeof e?e:{};this._Settings=s,this._Pr
34
34
  * @author Steven Velozo <steven@velozo.com>
35
35
  * @module Fable Settings
36
36
  */
37
- class{constructor(e){this.templateProcessor=new e.precedent,this.templateProcessor.addPattern("${","}",(e=>{let r=e.trim(),s=r.indexOf("|"),n=r.substring(s+1),o=s>-1?r.substring(0,s):r;return t.env.hasOwnProperty(o)?t.env[o]:n}))}parseSetting(t){return this.templateProcessor.parseString(t)}}}).call(this)}).call(this,t("_process"))},{_process:14}],8:[function(t,e,r){
37
+ class{constructor(e){this.templateProcessor=new e.precedent,this.templateProcessor.addPattern("${","}",(e=>{let r=e.trim(),n=r.indexOf("|"),s=r.substring(n+1),o=n>-1?r.substring(0,n):r;return t.env.hasOwnProperty(o)?t.env[o]:s}))}parseSetting(t){return this.templateProcessor.parseString(t)}}}).call(this)}).call(this,t("_process"))},{_process:14}],8:[function(t,e,r){
38
38
  /**
39
39
  * Fable Settings Add-on
40
40
  *
@@ -43,7 +43,7 @@ class{constructor(e){this.templateProcessor=new e.precedent,this.templateProcess
43
43
  * @author Steven Velozo <steven@velozo.com>
44
44
  * @module Fable Settings
45
45
  */
46
- const s=t("precedent"),n=t("./Fable-Settings-TemplateProcessor.js");class o{constructor(e){this.dependencies={precedent:s},this.settingsTemplateProcessor=new n(this.dependencies),this._configureEnvTemplating(e),this.default=this.buildDefaultSettings();let r=this.merge(e,this.buildDefaultSettings());if(this.base=JSON.parse(JSON.stringify(r)),r.DefaultConfigFile)try{r=this.merge(t(r.DefaultConfigFile),r)}catch(t){console.log("Fable-Settings Warning: Default configuration file specified but there was a problem loading it. Falling back to base."),console.log(" Loading Exception: "+t)}if(r.ConfigFile)try{r=this.merge(t(r.ConfigFile),r)}catch(t){console.log("Fable-Settings Warning: Configuration file specified but there was a problem loading it. Falling back to base."),console.log(" Loading Exception: "+t)}this.settings=r}buildDefaultSettings(){return JSON.parse(JSON.stringify(t("./Fable-Settings-Default")))}_configureEnvTemplating(t){this._PerformEnvTemplating=!t||!0!==t.NoEnvReplacement}_resolveEnv(t){for(const e in t)"object"==typeof t[e]?this._resolveEnv(t[e]):"string"==typeof t[e]&&(t[e]=this.settingsTemplateProcessor.parseSetting(t[e]))}_isObject(t){return"object"==typeof t&&!Array.isArray(t)}_deepMergeObjects(t,e){if(e&&this._isObject(e))return Object.keys(e).forEach((r=>{const s=e[r];if(this._isObject(s)){const e=t[r];if(e&&this._isObject(e))return void this._deepMergeObjects(e,s)}t[r]=s})),t}merge(t,e){let r="object"==typeof t?t:{},s="object"==typeof e?e:this.settings,n=JSON.parse(JSON.stringify(r));return s=this._deepMergeObjects(s,n),this._PerformEnvTemplating&&this._resolveEnv(s),this._configureEnvTemplating(s),s}fill(t){let e="object"==typeof t?t:{},r=JSON.parse(JSON.stringify(e));return this.settings=this._deepMergeObjects(r,this.settings),this.settings}}e.exports={new:function(t){return new o(t)},FableSettings:o}},{"./Fable-Settings-Default":6,"./Fable-Settings-TemplateProcessor.js":7,precedent:11}],9:[function(t,e,r){e.exports=
46
+ const n=t("precedent"),s=t("./Fable-Settings-TemplateProcessor.js");class o{constructor(e){this.dependencies={precedent:n},this.settingsTemplateProcessor=new s(this.dependencies),this._configureEnvTemplating(e),this.default=this.buildDefaultSettings();let r=this.merge(e,this.buildDefaultSettings());if(this.base=JSON.parse(JSON.stringify(r)),r.DefaultConfigFile)try{r=this.merge(t(r.DefaultConfigFile),r)}catch(t){console.log("Fable-Settings Warning: Default configuration file specified but there was a problem loading it. Falling back to base."),console.log(" Loading Exception: "+t)}if(r.ConfigFile)try{r=this.merge(t(r.ConfigFile),r)}catch(t){console.log("Fable-Settings Warning: Configuration file specified but there was a problem loading it. Falling back to base."),console.log(" Loading Exception: "+t)}this.settings=r}buildDefaultSettings(){return JSON.parse(JSON.stringify(t("./Fable-Settings-Default")))}_configureEnvTemplating(t){this._PerformEnvTemplating=!t||!0!==t.NoEnvReplacement}_resolveEnv(t){for(const e in t)"object"==typeof t[e]?this._resolveEnv(t[e]):"string"==typeof t[e]&&(t[e]=this.settingsTemplateProcessor.parseSetting(t[e]))}_isObject(t){return"object"==typeof t&&!Array.isArray(t)}_deepMergeObjects(t,e){if(e&&this._isObject(e))return Object.keys(e).forEach((r=>{const n=e[r];if(this._isObject(n)){const e=t[r];if(e&&this._isObject(e))return void this._deepMergeObjects(e,n)}t[r]=n})),t}merge(t,e){let r="object"==typeof t?t:{},n="object"==typeof e?e:this.settings,s=JSON.parse(JSON.stringify(r));return n=this._deepMergeObjects(n,s),this._PerformEnvTemplating&&this._resolveEnv(n),this._configureEnvTemplating(n),n}fill(t){let e="object"==typeof t?t:{},r=JSON.parse(JSON.stringify(e));return this.settings=this._deepMergeObjects(r,this.settings),this.settings}}e.exports={new:function(t){return new o(t)},FableSettings:o}},{"./Fable-Settings-Default":6,"./Fable-Settings-TemplateProcessor.js":7,precedent:11}],9:[function(t,e,r){e.exports=
47
47
  /**
48
48
  * Random Byte Generator - Browser version
49
49
  *
@@ -60,7 +60,7 @@ class{constructor(){this.getRandomValues="undefined"!=typeof crypto&&crypto.getR
60
60
  * @author Steven Velozo <steven@velozo.com>
61
61
  * @module Fable UUID
62
62
  */
63
- var s=t("./Fable-UUID-Random.js");class n{constructor(t){this._UUIDModeRandom=!("object"!=typeof t||!t.hasOwnProperty("UUIDModeRandom"))&&1==t.UUIDModeRandom,this._UUIDLength="object"==typeof t&&t.hasOwnProperty("UUIDLength")?t.UUIDLength+0:8,this._UUIDRandomDictionary="object"==typeof t&&t.hasOwnProperty("UUIDDictionary")?t.UUIDDictionary+0:"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",this.randomByteGenerator=new s,this._HexLookup=[];for(let t=0;t<256;++t)this._HexLookup[t]=(t+256).toString(16).substr(1)}bytesToUUID(t){let e=0;return[this._HexLookup[t[e++]],this._HexLookup[t[e++]],this._HexLookup[t[e++]],this._HexLookup[t[e++]],"-",this._HexLookup[t[e++]],this._HexLookup[t[e++]],"-",this._HexLookup[t[e++]],this._HexLookup[t[e++]],"-",this._HexLookup[t[e++]],this._HexLookup[t[e++]],"-",this._HexLookup[t[e++]],this._HexLookup[t[e++]],this._HexLookup[t[e++]],this._HexLookup[t[e++]],this._HexLookup[t[e++]],this._HexLookup[t[e++]]].join("")}generateUUIDv4(){new Array(16);var t=this.randomByteGenerator.generate();return t[6]=15&t[6]|64,t[8]=63&t[8]|128,this.bytesToUUID(t)}generateRandom(){let t="";for(let e=0;e<this._UUIDLength;e++)t+=this._UUIDRandomDictionary.charAt(Math.floor(Math.random()*(this._UUIDRandomDictionary.length-1)));return t}getUUID(){return this._UUIDModeRandom?this.generateRandom():this.generateUUIDv4()}}e.exports={new:function(t){return new n(t)},FableUUID:n}},{"./Fable-UUID-Random.js":9}],11:[function(t,e,r){
63
+ var n=t("./Fable-UUID-Random.js");class s{constructor(t){this._UUIDModeRandom=!("object"!=typeof t||!t.hasOwnProperty("UUIDModeRandom"))&&1==t.UUIDModeRandom,this._UUIDLength="object"==typeof t&&t.hasOwnProperty("UUIDLength")?t.UUIDLength+0:8,this._UUIDRandomDictionary="object"==typeof t&&t.hasOwnProperty("UUIDDictionary")?t.UUIDDictionary+0:"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",this.randomByteGenerator=new n,this._HexLookup=[];for(let t=0;t<256;++t)this._HexLookup[t]=(t+256).toString(16).substr(1)}bytesToUUID(t){let e=0;return[this._HexLookup[t[e++]],this._HexLookup[t[e++]],this._HexLookup[t[e++]],this._HexLookup[t[e++]],"-",this._HexLookup[t[e++]],this._HexLookup[t[e++]],"-",this._HexLookup[t[e++]],this._HexLookup[t[e++]],"-",this._HexLookup[t[e++]],this._HexLookup[t[e++]],"-",this._HexLookup[t[e++]],this._HexLookup[t[e++]],this._HexLookup[t[e++]],this._HexLookup[t[e++]],this._HexLookup[t[e++]],this._HexLookup[t[e++]]].join("")}generateUUIDv4(){new Array(16);var t=this.randomByteGenerator.generate();return t[6]=15&t[6]|64,t[8]=63&t[8]|128,this.bytesToUUID(t)}generateRandom(){let t="";for(let e=0;e<this._UUIDLength;e++)t+=this._UUIDRandomDictionary.charAt(Math.floor(Math.random()*(this._UUIDRandomDictionary.length-1)));return t}getUUID(){return this._UUIDModeRandom?this.generateRandom():this.generateUUIDv4()}}e.exports={new:function(t){return new s(t)},FableUUID:s}},{"./Fable-UUID-Random.js":9}],11:[function(t,e,r){
64
64
  /**
65
65
  * Precedent Meta-Templating
66
66
  *
@@ -70,7 +70,7 @@ var s=t("./Fable-UUID-Random.js");class n{constructor(t){this._UUIDModeRandom=!(
70
70
  *
71
71
  * @description Process text streams, parsing out meta-template expressions.
72
72
  */
73
- var s=t("./WordTree.js"),n=t("./StringParser.js");e.exports=class{constructor(){this.WordTree=new s,this.StringParser=new n,this.ParseTree=this.WordTree.ParseTree}addPattern(t,e,r){return this.WordTree.addPattern(t,e,r)}parseString(t){return this.StringParser.parseString(t,this.ParseTree)}}},{"./StringParser.js":12,"./WordTree.js":13}],12:[function(t,e,r){e.exports=
73
+ var n=t("./WordTree.js"),s=t("./StringParser.js");e.exports=class{constructor(){this.WordTree=new n,this.StringParser=new s,this.ParseTree=this.WordTree.ParseTree}addPattern(t,e,r){return this.WordTree.addPattern(t,e,r)}parseString(t){return this.StringParser.parseString(t,this.ParseTree)}}},{"./StringParser.js":12,"./WordTree.js":13}],12:[function(t,e,r){e.exports=
74
74
  /**
75
75
  * String Parser
76
76
  *
@@ -80,7 +80,7 @@ var s=t("./WordTree.js"),n=t("./StringParser.js");e.exports=class{constructor(){
80
80
  *
81
81
  * @description Parse a string, properly processing each matched token in the word tree.
82
82
  */
83
- class{constructor(){}newParserState(t){return{ParseTree:t,Output:"",OutputBuffer:"",Pattern:!1,PatternMatch:!1,PatternMatchOutputBuffer:""}}assignNode(t,e){e.PatternMatch=t,e.PatternMatch.hasOwnProperty("PatternEnd")&&(e.Pattern=e.PatternMatch)}appendOutputBuffer(t,e){e.OutputBuffer+=t}flushOutputBuffer(t){t.Output+=t.OutputBuffer,t.OutputBuffer=""}checkPatternEnd(t){t.OutputBuffer.length>=t.Pattern.PatternEnd.length+t.Pattern.PatternStart.length&&t.OutputBuffer.substr(-t.Pattern.PatternEnd.length)===t.Pattern.PatternEnd&&(t.OutputBuffer=t.Pattern.Parse(t.OutputBuffer.substr(t.Pattern.PatternStart.length,t.OutputBuffer.length-(t.Pattern.PatternStart.length+t.Pattern.PatternEnd.length))),this.flushOutputBuffer(t),t.Pattern=!1,t.PatternMatch=!1)}parseCharacter(t,e){!e.PatternMatch&&e.ParseTree.hasOwnProperty(t)?(this.assignNode(e.ParseTree[t],e),this.appendOutputBuffer(t,e)):e.PatternMatch?(e.PatternMatch.hasOwnProperty(t)&&this.assignNode(e.PatternMatch[t],e),this.appendOutputBuffer(t,e),e.Pattern&&this.checkPatternEnd(e)):e.Output+=t}parseString(t,e){let r=this.newParserState(e);for(var s=0;s<t.length;s++)this.parseCharacter(t[s],r);return this.flushOutputBuffer(r),r.Output}}},{}],13:[function(t,e,r){e.exports=
83
+ class{constructor(){}newParserState(t){return{ParseTree:t,Output:"",OutputBuffer:"",Pattern:!1,PatternMatch:!1,PatternMatchOutputBuffer:""}}assignNode(t,e){e.PatternMatch=t,e.PatternMatch.hasOwnProperty("PatternEnd")&&(e.Pattern=e.PatternMatch)}appendOutputBuffer(t,e){e.OutputBuffer+=t}flushOutputBuffer(t){t.Output+=t.OutputBuffer,t.OutputBuffer=""}checkPatternEnd(t){t.OutputBuffer.length>=t.Pattern.PatternEnd.length+t.Pattern.PatternStart.length&&t.OutputBuffer.substr(-t.Pattern.PatternEnd.length)===t.Pattern.PatternEnd&&(t.OutputBuffer=t.Pattern.Parse(t.OutputBuffer.substr(t.Pattern.PatternStart.length,t.OutputBuffer.length-(t.Pattern.PatternStart.length+t.Pattern.PatternEnd.length))),this.flushOutputBuffer(t),t.Pattern=!1,t.PatternMatch=!1)}parseCharacter(t,e){!e.PatternMatch&&e.ParseTree.hasOwnProperty(t)?(this.assignNode(e.ParseTree[t],e),this.appendOutputBuffer(t,e)):e.PatternMatch?(e.PatternMatch.hasOwnProperty(t)&&this.assignNode(e.PatternMatch[t],e),this.appendOutputBuffer(t,e),e.Pattern&&this.checkPatternEnd(e)):e.Output+=t}parseString(t,e){let r=this.newParserState(e);for(var n=0;n<t.length;n++)this.parseCharacter(t[n],r);return this.flushOutputBuffer(r),r.Output}}},{}],13:[function(t,e,r){e.exports=
84
84
  /**
85
85
  * Word Tree
86
86
  *
@@ -90,11 +90,11 @@ class{constructor(){}newParserState(t){return{ParseTree:t,Output:"",OutputBuffer
90
90
  *
91
91
  * @description Create a tree (directed graph) of Javascript objects, one character per object.
92
92
  */
93
- class{constructor(){this.ParseTree={}}addChild(t,e,r){return t.hasOwnProperty(e[r])||(t[e[r]]={}),t[e[r]]}addPattern(t,e,r){if(t.length<1)return!1;if("string"==typeof e&&e.length<1)return!1;let s=this.ParseTree;for(var n=0;n<t.length;n++)s=this.addChild(s,t,n);return s.PatternStart=t,s.PatternEnd="string"==typeof e&&e.length>0?e:t,s.Parse="function"==typeof r?r:"string"==typeof r?()=>r:t=>t,!0}}},{}],14:[function(t,e,r){var s,n,o=e.exports={};function i(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}function l(t){if(s===setTimeout)return setTimeout(t,0);if((s===i||!s)&&setTimeout)return s=setTimeout,setTimeout(t,0);try{return s(t,0)}catch(e){try{return s.call(null,t,0)}catch(e){return s.call(this,t,0)}}}!function(){try{s="function"==typeof setTimeout?setTimeout:i}catch(t){s=i}try{n="function"==typeof clearTimeout?clearTimeout:a}catch(t){n=a}}();var u,h=[],g=!1,c=-1;function f(){g&&u&&(g=!1,u.length?h=u.concat(h):c=-1,h.length&&p())}function p(){if(!g){var t=l(f);g=!0;for(var e=h.length;e;){for(u=h,h=[];++c<e;)u&&u[c].run();c=-1,e=h.length}u=null,g=!1,function(t){if(n===clearTimeout)return clearTimeout(t);if((n===a||!n)&&clearTimeout)return n=clearTimeout,clearTimeout(t);try{return n(t)}catch(e){try{return n.call(null,t)}catch(e){return n.call(this,t)}}}(t)}}function d(t,e){this.fun=t,this.array=e}function m(){}o.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var r=1;r<arguments.length;r++)e[r-1]=arguments[r];h.push(new d(t,e)),1!==h.length||g||l(p)},d.prototype.run=function(){this.fun.apply(null,this.array)},o.title="browser",o.browser=!0,o.env={},o.argv=[],o.version="",o.versions={},o.on=m,o.addListener=m,o.once=m,o.off=m,o.removeListener=m,o.removeAllListeners=m,o.emit=m,o.prependListener=m,o.prependOnceListener=m,o.listeners=function(t){return[]},o.binding=function(t){throw new Error("process.binding is not supported")},o.cwd=function(){return"/"},o.chdir=function(t){throw new Error("process.chdir is not supported")},o.umask=function(){return 0}},{}],15:[function(t,e,r){var s=t("./Fable.js");"object"!=typeof window||window.hasOwnProperty("Fable")||(window.Fable=s),e.exports=s},{"./Fable.js":17}],16:[function(t,e,r){e.exports=class{constructor(t){this.fable=t}extend(t,...e){return Object.assign(t,...e)}}},{}],17:[function(t,e,r){
93
+ class{constructor(){this.ParseTree={}}addChild(t,e,r){return t.hasOwnProperty(e[r])||(t[e[r]]={}),t[e[r]]}addPattern(t,e,r){if(t.length<1)return!1;if("string"==typeof e&&e.length<1)return!1;let n=this.ParseTree;for(var s=0;s<t.length;s++)n=this.addChild(n,t,s);return n.PatternStart=t,n.PatternEnd="string"==typeof e&&e.length>0?e:t,n.Parse="function"==typeof r?r:"string"==typeof r?()=>r:t=>t,!0}}},{}],14:[function(t,e,r){var n,s,o=e.exports={};function i(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}function l(t){if(n===setTimeout)return setTimeout(t,0);if((n===i||!n)&&setTimeout)return n=setTimeout,setTimeout(t,0);try{return n(t,0)}catch(e){try{return n.call(null,t,0)}catch(e){return n.call(this,t,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:i}catch(t){n=i}try{s="function"==typeof clearTimeout?clearTimeout:a}catch(t){s=a}}();var u,h=[],c=!1,g=-1;function p(){c&&u&&(c=!1,u.length?h=u.concat(h):g=-1,h.length&&f())}function f(){if(!c){var t=l(p);c=!0;for(var e=h.length;e;){for(u=h,h=[];++g<e;)u&&u[g].run();g=-1,e=h.length}u=null,c=!1,function(t){if(s===clearTimeout)return clearTimeout(t);if((s===a||!s)&&clearTimeout)return s=clearTimeout,clearTimeout(t);try{return s(t)}catch(e){try{return s.call(null,t)}catch(e){return s.call(this,t)}}}(t)}}function d(t,e){this.fun=t,this.array=e}function m(){}o.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var r=1;r<arguments.length;r++)e[r-1]=arguments[r];h.push(new d(t,e)),1!==h.length||c||l(f)},d.prototype.run=function(){this.fun.apply(null,this.array)},o.title="browser",o.browser=!0,o.env={},o.argv=[],o.version="",o.versions={},o.on=m,o.addListener=m,o.once=m,o.off=m,o.removeListener=m,o.removeAllListeners=m,o.emit=m,o.prependListener=m,o.prependOnceListener=m,o.listeners=function(t){return[]},o.binding=function(t){throw new Error("process.binding is not supported")},o.cwd=function(){return"/"},o.chdir=function(t){throw new Error("process.chdir is not supported")},o.umask=function(){return 0}},{}],15:[function(t,e,r){var n=t("./Fable.js");"object"!=typeof window||window.hasOwnProperty("Fable")||(window.Fable=n),e.exports=n},{"./Fable.js":18}],16:[function(t,e,r){e.exports=class{constructor(t,e){this.fable=t,this.Matchers={Evaluate:/<%([\s\S]+?)%>/g,Interpolate:/<%=([\s\S]+?)%>/g,Escaper:/\\|'|\r|\n|\t|\u2028|\u2029/g,Unescaper:/\\(\\|'|r|n|t|u2028|u2029)/g,GuaranteedNonMatch:/.^/},this.templateEscapes={"\\":"\\","'":"'",r:"\r","\r":"r",n:"\n","\n":"n",t:"\t","\t":"t",u2028:"\u2028","\u2028":"u2028",u2029:"\u2029","\u2029":"u2029"},this.renderFunction=()=>""}extend(t,...e){return Object.assign(t,...e)}renderTemplate(t){return this.renderFunction(t)}templateFunction(t){return this.renderTemplate.bind(this)}buildTemplateFunction(t,e){return this.TemplateSource="__p+='"+t.replace(this.Matchers.Escaper,(t=>`\\${this.templateEscapes[t]}`)).replace(this.Matchers.Interpolate||this.Matchers.GuaranteedNonMatch,((t,e)=>`'+\n(${decodeURIComponent(e)})+\n'`)).replace(this.Matchers.Evaluate||this.Matchers.GuaranteedNonMatch,((t,e)=>`';\n${decodeURIComponent(e)}\n;__p+='`))+"';\n",this.TemplateSource=`with(pTemplateDataObject||{}){\n${this.TemplateSource}}\n`,this.TemplateSource=`var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n${this.TemplateSource}return __p;\n`,this.renderFunction=new Function("pTemplateDataObject",this.TemplateSource),void 0!==e?this.renderFunction(e):(this.TemplateSourceCompiled="function(obj){\n"+this.TemplateSource+"}",this.templateFunction())}}},{}],17:[function(t,e,r){const n=t("./Fable-Utility-Template.js");e.exports=class{constructor(t){this.fable=t}extend(t,...e){return Object.assign(t,...e)}template(t,e){return new n(this.fable,t).buildTemplateFunction(t,e)}}},{"./Fable-Utility-Template.js":16}],18:[function(t,e,r){
94
94
  /**
95
95
  * Fable Application Services Support Library
96
96
  * @license MIT
97
97
  * @author <steven@velozo.com>
98
98
  */
99
- const s=t("fable-settings").FableSettings,n=t("fable-uuid").FableUUID,o=t("fable-log").FableLog,i=t("./Fable-Utility.js");e.exports=class{constructor(t){let e=new s(t);this.settingsManager=e,this.libUUID=new n(this.settingsManager.settings),this.log=new o(this.settingsManager.settings),this.log.initialize(),this.Utility=new i(this)}get settings(){return this.settingsManager.settings}get fable(){return this}getUUID(){return this.libUUID.getUUID()}}},{"./Fable-Utility.js":16,"fable-log":5,"fable-settings":8,"fable-uuid":10}]},{},[15])(15)}));
99
+ const n=t("fable-settings").FableSettings,s=t("fable-uuid").FableUUID,o=t("fable-log").FableLog,i=t("./Fable-Utility.js");e.exports=class{constructor(t){let e=new n(t);this.settingsManager=e,this.libUUID=new s(this.settingsManager.settings),this.log=new o(this.settingsManager.settings),this.log.initialize(),this.Utility=new i(this)}get settings(){return this.settingsManager.settings}get fable(){return this}getUUID(){return this.libUUID.getUUID()}}},{"./Fable-Utility.js":17,"fable-log":5,"fable-settings":8,"fable-uuid":10}]},{},[15])(15)}));
100
100
  //# sourceMappingURL=fable.min.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["node_modules/browser-pack/_prelude.js","node_modules/fable-log/source/Fable-Log-BaseLogger.js","fable.min.js","node_modules/fable-log/source/Fable-Log-DefaultProviders-Web.js","node_modules/fable-log/source/Fable-Log-DefaultStreams.json","node_modules/fable-log/source/Fable-Log-Logger-Console.js","node_modules/fable-log/source/Fable-Log.js","node_modules/fable-settings/source/Fable-Settings-Default.json","node_modules/fable-settings/source/Fable-Settings-TemplateProcessor.js","node_modules/fable-settings/source/Fable-Settings.js","node_modules/fable-uuid/source/Fable-UUID-Random-Browser.js","node_modules/fable-uuid/source/Fable-UUID.js","node_modules/precedent/source/Precedent.js","node_modules/precedent/source/StringParser.js","node_modules/precedent/source/WordTree.js","node_modules/process/browser.js","source/Fable-Browser-Shim.js","source/Fable-Utility.js","source/Fable.js"],"names":["f","exports","module","define","amd","window","global","self","this","Fable","r","e","n","t","o","i","c","require","u","a","Error","code","p","call","length","constructor","pLogStreamSettings","pFableLog","_Settings","loggerUUID","generateInsecureUUID","levels","tmpDate","Date","getTime","replace","pCharacter","tmpRandomData","Math","random","floor","toString","initialize","trace","pLogText","pLogObject","write","debug","info","warn","error","fatal","pLogLevel","getDefaultProviders","tmpDefaultProviders","console","default","loggertype","streamtype","level","libBaseLogger","super","_ShowTimeStamps","hasOwnProperty","showtimestamps","_FormattedTimeStamps","formattedtimestamps","_ContextMessage","Context","Product","_OutputLogLinesToConsole","outputloglinestoconsole","_OutputObjectsToConsole","outputobjectstoconsole","prefixCache","pLevel","pObject","tmpTimeStamp","toISOString","tmpLogLine","log","JSON","stringify","FableLog","pFableSettings","pFable","tmpSettings","_Providers","_StreamDefinitions","LogStreams","logStreams","logProviders","activeLogStreams","logStreamsTrace","logStreamsDebug","logStreamsInfo","logStreamsWarn","logStreamsError","logStreamsFatal","datumDecorator","pDatum","uuid","addLogger","pLogger","push","setDatumDecorator","fDatumDecorator","pMessage","tmpDecoratedDatum","tmpStreamDefinition","Object","assign","logTime","tmpMessage","tmpTime","getTimeStamp","getTimeDelta","pTimeStamp","logTimeDelta","pTimeDelta","tmpEndTime","logTimeDeltaHuman","tmpMs","parseInt","tmpSeconds","tmpMinutes","tmpHours","logTimeDeltaRelative","pStartTime","logTimeDeltaRelativeHuman","new","pSettings","ProductVersion","ConfigFile","process","pDependencies","templateProcessor","precedent","addPattern","pTemplateValue","tmpTemplateValue","trim","tmpSeparatorIndex","indexOf","tmpDefaultValue","substring","tmpEnvironmentVariableName","env","parseSetting","pString","parseString","_process","libPrecedent","libFableSettingsTemplateProcessor","FableSettings","dependencies","settingsTemplateProcessor","_configureEnvTemplating","buildDefaultSettings","merge","base","parse","DefaultConfigFile","pException","settings","_PerformEnvTemplating","NoEnvReplacement","_resolveEnv","tmpKey","_isObject","value","Array","isArray","_deepMergeObjects","toObject","fromObject","keys","forEach","key","fromValue","toValue","pSettingsFrom","pSettingsTo","tmpSettingsFrom","tmpSettingsTo","tmpSettingsFromCopy","fill","getRandomValues","crypto","bind","msCrypto","generateWhatWGBytes","tmpBuffer","Uint8Array","generateRandomBytes","tmpValue","generate","libRandomByteGenerator","FableUUID","_UUIDModeRandom","UUIDModeRandom","_UUIDLength","UUIDLength","_UUIDRandomDictionary","UUIDDictionary","randomByteGenerator","_HexLookup","substr","bytesToUUID","pBuffer","join","generateUUIDv4","tmpRandomBytes","generateRandom","tmpUUID","charAt","getUUID","libWordTree","libStringParser","WordTree","StringParser","ParseTree","pPatternStart","pPatternEnd","pParser","newParserState","pParseTree","Output","OutputBuffer","Pattern","PatternMatch","PatternMatchOutputBuffer","assignNode","pNode","pParserState","appendOutputBuffer","flushOutputBuffer","checkPatternEnd","PatternEnd","PatternStart","Parse","parseCharacter","tmpParserState","addChild","pTree","pPattern","pIndex","tmpLeaf","pData","cachedSetTimeout","cachedClearTimeout","defaultSetTimout","defaultClearTimeout","runTimeout","fun","setTimeout","clearTimeout","currentQueue","queue","draining","queueIndex","cleanUpNextTick","concat","drainQueue","timeout","len","run","marker","runClearTimeout","Item","array","noop","nextTick","args","arguments","prototype","apply","title","browser","argv","version","versions","on","addListener","once","off","removeListener","removeAllListeners","emit","prependListener","prependOnceListener","listeners","name","binding","cwd","chdir","dir","umask","libNPMModuleWrapper","fable","extend","pDestinationObject","pSourceObjects","libFableSettings","libFableUUID","libFableLog","libFableUtility","settingsManager","libUUID","Utility"],"mappings":"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","file":"fable.min.js","sourcesContent":["(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()","/**\n* Base Logger Class\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*/\n\nclass BaseLogger\n{\n\tconstructor(pLogStreamSettings, pFableLog)\n\t{\n\t\t// This should not possibly be able to be instantiated without a settings object\n\t\tthis._Settings = pLogStreamSettings;\n\n\t\t// The base logger does nothing but associate a UUID with itself\n\t\t// We added this as the mechanism for tracking loggers to allow multiple simultaneous streams\n\t\t// to the same provider.\n\t\tthis.loggerUUID = this.generateInsecureUUID();\n\n\t\t// Eventually we can use this array to ompute which levels the provider allows.\n\t\t// For now it's just used to precompute some string concatenations.\n\t\tthis.levels = (\n\t\t\t[\n\t\t\t\t\"trace\",\n\t\t\t\t\"debug\",\n\t\t\t\t\"info\",\n\t\t\t\t\"warn\",\n\t\t\t\t\"error\",\n\t\t\t\t\"fatal\"\n\t\t\t]);\n\t}\n\n\t// This is meant to generate programmatically insecure UUIDs to identify loggers\n\tgenerateInsecureUUID()\n\t{\n\t\tlet tmpDate = new Date().getTime();\n\t\tlet tmpUUID = 'LOGSTREAM-xxxxxx-yxxxxx'.replace(/[xy]/g,\n\t\t\t\t(pCharacter) =>\n\t\t\t\t{\n\t\t\t\t\t// Funny algorithm from w3resource that is twister-ish without the deep math and security\n\t\t\t\t\t// ..but good enough for unique log stream identifiers\n\t\t\t\t\tlet tmpRandomData = (tmpDate + Math.random()*16)%16 | 0;\n\t\t\t\t\ttmpDate = Math.floor(tmpDate/16);\n\n\t\t\t\t\treturn (pCharacter =='x' ? tmpRandomData : (tmpRandomData&0x3|0x8)).toString(16);\n\t\t\t\t});\n\t\treturn tmpUUID;\n\t}\n\n\tinitialize()\n\t{\n\t\t// No operation.\n\t}\n\n\ttrace(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"trace\", pLogText, pLogObject);\n\t}\n\n\tdebug(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"debug\", pLogText, pLogObject);\n\t}\n\n\tinfo(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"info\", pLogText, pLogObject);\n\t}\n\n\twarn(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"warn\", pLogText, pLogObject);\n\t}\n\n\terror(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"error\", pLogText, pLogObject);\n\t}\n\n\tfatal(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"fatal\", pLogText, pLogObject);\n\t}\n\n\twrite(pLogLevel, pLogText, pLogObject)\n\t{\n\t\t// The base logger does nothing.\n\t\treturn true;\n\t}\n}\n\nmodule.exports = BaseLogger;\n","(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.Fable = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){\n/**\n* Base Logger Class\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*/\n\nclass BaseLogger\n{\n\tconstructor(pLogStreamSettings, pFableLog)\n\t{\n\t\t// This should not possibly be able to be instantiated without a settings object\n\t\tthis._Settings = pLogStreamSettings;\n\n\t\t// The base logger does nothing but associate a UUID with itself\n\t\t// We added this as the mechanism for tracking loggers to allow multiple simultaneous streams\n\t\t// to the same provider.\n\t\tthis.loggerUUID = this.generateInsecureUUID();\n\n\t\t// Eventually we can use this array to ompute which levels the provider allows.\n\t\t// For now it's just used to precompute some string concatenations.\n\t\tthis.levels = (\n\t\t\t[\n\t\t\t\t\"trace\",\n\t\t\t\t\"debug\",\n\t\t\t\t\"info\",\n\t\t\t\t\"warn\",\n\t\t\t\t\"error\",\n\t\t\t\t\"fatal\"\n\t\t\t]);\n\t}\n\n\t// This is meant to generate programmatically insecure UUIDs to identify loggers\n\tgenerateInsecureUUID()\n\t{\n\t\tlet tmpDate = new Date().getTime();\n\t\tlet tmpUUID = 'LOGSTREAM-xxxxxx-yxxxxx'.replace(/[xy]/g,\n\t\t\t\t(pCharacter) =>\n\t\t\t\t{\n\t\t\t\t\t// Funny algorithm from w3resource that is twister-ish without the deep math and security\n\t\t\t\t\t// ..but good enough for unique log stream identifiers\n\t\t\t\t\tlet tmpRandomData = (tmpDate + Math.random()*16)%16 | 0;\n\t\t\t\t\ttmpDate = Math.floor(tmpDate/16);\n\n\t\t\t\t\treturn (pCharacter =='x' ? tmpRandomData : (tmpRandomData&0x3|0x8)).toString(16);\n\t\t\t\t});\n\t\treturn tmpUUID;\n\t}\n\n\tinitialize()\n\t{\n\t\t// No operation.\n\t}\n\n\ttrace(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"trace\", pLogText, pLogObject);\n\t}\n\n\tdebug(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"debug\", pLogText, pLogObject);\n\t}\n\n\tinfo(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"info\", pLogText, pLogObject);\n\t}\n\n\twarn(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"warn\", pLogText, pLogObject);\n\t}\n\n\terror(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"error\", pLogText, pLogObject);\n\t}\n\n\tfatal(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"fatal\", pLogText, pLogObject);\n\t}\n\n\twrite(pLogLevel, pLogText, pLogObject)\n\t{\n\t\t// The base logger does nothing.\n\t\treturn true;\n\t}\n}\n\nmodule.exports = BaseLogger;\n\n},{}],2:[function(require,module,exports){\n/**\n* Default Logger Provider Function\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*/\n\n// Return the providers that are available without extensions loaded\ngetDefaultProviders = () =>\n{\n\tlet tmpDefaultProviders = {};\n\n\ttmpDefaultProviders.console = require('./Fable-Log-Logger-Console.js');\n\n\ttmpDefaultProviders.default = tmpDefaultProviders.console;\n\n\treturn tmpDefaultProviders;\n}\n\nmodule.exports = getDefaultProviders();\n},{\"./Fable-Log-Logger-Console.js\":4}],3:[function(require,module,exports){\nmodule.exports=[\n {\n \"loggertype\": \"console\",\n \"streamtype\": \"console\",\n \"level\": \"trace\"\n }\n]\n},{}],4:[function(require,module,exports){\nlet libBaseLogger = require('./Fable-Log-BaseLogger.js');\n\nclass ConsoleLogger extends libBaseLogger\n{\n\tconstructor(pLogStreamSettings, pFableLog)\n\t{\n\t\tsuper(pLogStreamSettings);\n\n\t\tthis._ShowTimeStamps = pLogStreamSettings.hasOwnProperty('showtimestamps') ? (pLogStreamSettings.showtimestamps == true) : false;\n\t\tthis._FormattedTimeStamps = pLogStreamSettings.hasOwnProperty('formattedtimestamps') ? (pLogStreamSettings.formattedtimestamps == true) : false;\n\n\t\tthis._ContextMessage = pLogStreamSettings.hasOwnProperty('Context') ? `(${pLogStreamSettings.Context})` : \n\t\t\t\t\t\t\t\tpFableLog._Settings.hasOwnProperty('Product') ? `(${pFableLog._Settings.Product})` :\n\t\t\t\t\t\t\t\t'Unnamed_Log_Context';\n\n\t\t// Allow the user to decide what gets output to the console\n\t\tthis._OutputLogLinesToConsole = pLogStreamSettings.hasOwnProperty('outputloglinestoconsole') ? pLogStreamSettings.outputloglinestoconsole : true;\n\t\tthis._OutputObjectsToConsole = pLogStreamSettings.hasOwnProperty('outputobjectstoconsole') ? pLogStreamSettings.outputobjectstoconsole : true;\n\n\t\t// Precompute the prefix for each level\n\t\tthis.prefixCache = {};\n\t\tfor (let i = 0; i <= this.levels.length; i++)\n\t\t{\n\t\t\tthis.prefixCache[this.levels[i]] = `[${this.levels[i]}] ${this._ContextMessage}: `;\n\n\t\t\tif (this._ShowTimeStamps)\n\t\t\t{\n\t\t\t\t// If there is a timestamp we need a to prepend space before the prefixcache string, since the timestamp comes first\n\t\t\t\tthis.prefixCache[this.levels[i]] = ' '+this.prefixCache[this.levels[i]];\n\t\t\t}\n\t\t}\n\t}\n\n\twrite(pLevel, pLogText, pObject)\n\t{\n\t\tlet tmpTimeStamp = '';\n\t\tif (this._ShowTimeStamps && this._FormattedTimeStamps)\n\t\t{\n\t\t\ttmpTimeStamp = (new Date()).toISOString();\n\t\t}\n\t\telse if (this._ShowTimeStamps)\n\t\t{\n\t\t\ttmpTimeStamp = +new Date();\n\t\t}\n\n\t\tlet tmpLogLine = `${tmpTimeStamp}${this.prefixCache[pLevel]}${pLogText}`;\n\n\t\tif (this._OutputLogLinesToConsole)\n\t\t{\n\t\t\tconsole.log(tmpLogLine);\n\t\t}\n\n\t\t// Write out the object on a separate line if it is passed in\n\t\tif (this._OutputObjectsToConsole && (typeof(pObject) !== 'undefined'))\n\t\t{\n\t\t\tconsole.log(JSON.stringify(pObject, null, 2));\n\t\t}\n\n\t\t// Provide an easy way to be overridden and be consistent\n\t\treturn tmpLogLine;\n\t}\n}\n\nmodule.exports = ConsoleLogger;\n},{\"./Fable-Log-BaseLogger.js\":1}],5:[function(require,module,exports){\n/**\n* Fable Logging Add-on\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n* @module Fable Logger\n*/\n\n/**\n* Fable Solution Log Wrapper Main Class\n*\n* @class FableLog\n* @constructor\n*/\nclass FableLog\n{\n\tconstructor(pFableSettings, pFable)\n\t{\n\t\tlet tmpSettings = (typeof(pFableSettings) === 'object') ? pFableSettings : {}\n\t\tthis._Settings = tmpSettings;\n\n\t\tthis._Providers = require('./Fable-Log-DefaultProviders-Node.js');\n\n\t\tthis._StreamDefinitions = (tmpSettings.hasOwnProperty('LogStreams')) ? tmpSettings.LogStreams : require('./Fable-Log-DefaultStreams.json');\n\n\t\tthis.logStreams = [];\n\n\t\t// This object gets decorated for one-time instantiated providers that\n\t\t// have multiple outputs, such as bunyan.\n\t\tthis.logProviders = {};\n\n\t\t// A hash list of the GUIDs for each log stream, so they can't be added to the set more than one time\n\t\tthis.activeLogStreams = {};\n\n\t\tthis.logStreamsTrace = [];\n\t\tthis.logStreamsDebug = [];\n\t\tthis.logStreamsInfo = [];\n\t\tthis.logStreamsWarn = [];\n\t\tthis.logStreamsError = [];\n\t\tthis.logStreamsFatal = [];\n\n\t\tthis.datumDecorator = (pDatum) => pDatum;\n\n\t\tthis.uuid = (typeof(tmpSettings.Product) === 'string') ? tmpSettings.Product : 'Default';\n\t}\n\n\taddLogger(pLogger, pLevel)\n\t{\n\t\t// Bail out if we've already created one.\n\t\tif (this.activeLogStreams.hasOwnProperty(pLogger.loggerUUID))\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\t// Add it to the streams and to the mutex\n\t\tthis.logStreams.push(pLogger);\n\t\tthis.activeLogStreams[pLogger.loggerUUID] = true;\n\n\t\t// Make sure a kosher level was passed in\n\t\tswitch (pLevel)\n\t\t{\n\t\t\tcase 'trace':\n\t\t\t\tthis.logStreamsTrace.push(pLogger);\n\t\t\tcase 'debug':\n\t\t\t\tthis.logStreamsDebug.push(pLogger);\n\t\t\tcase 'info':\n\t\t\t\tthis.logStreamsInfo.push(pLogger);\n\t\t\tcase 'warn':\n\t\t\t\tthis.logStreamsWarn.push(pLogger);\n\t\t\tcase 'error':\n\t\t\t\tthis.logStreamsError.push(pLogger);\n\t\t\tcase 'fatal':\n\t\t\t\tthis.logStreamsFatal.push(pLogger);\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tsetDatumDecorator(fDatumDecorator)\n\t{\n\t\tif (typeof(fDatumDecorator) === 'function')\n\t\t{\n\t\t\tthis.datumDecorator = fDatumDecorator;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tthis.datumDecorator = (pDatum) => pDatum;\n\t\t}\n\t}\n\n\ttrace(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsTrace.length; i++)\n\t\t{\n\t\t\tthis.logStreamsTrace[i].trace(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\tdebug(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsDebug.length; i++)\n\t\t{\n\t\t\tthis.logStreamsDebug[i].debug(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\tinfo(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsInfo.length; i++)\n\t\t{\n\t\t\tthis.logStreamsInfo[i].info(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\twarn(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsWarn.length; i++)\n\t\t{\n\t\t\tthis.logStreamsWarn[i].warn(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\terror(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsError.length; i++)\n\t\t{\n\t\t\tthis.logStreamsError[i].error(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\tfatal(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsFatal.length; i++)\n\t\t{\n\t\t\tthis.logStreamsFatal[i].fatal(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\tinitialize()\n\t{\n\t\t// \"initialize\" each logger as defined in the logging parameters\n\t\tfor (let i = 0; i < this._StreamDefinitions.length; i++)\n\t\t{\n\t\t\tlet tmpStreamDefinition = Object.assign({loggertype:'default',streamtype:'console',level:'info'},this._StreamDefinitions[i]);\n\n\t\t\tif (!this._Providers.hasOwnProperty(tmpStreamDefinition.loggertype))\n\t\t\t{\n\t\t\t\tconsole.log(`Error initializing log stream: bad loggertype in stream definition ${JSON.stringify(tmpStreamDefinition)}`);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.addLogger(new this._Providers[tmpStreamDefinition.loggertype](tmpStreamDefinition, this), tmpStreamDefinition.level);\n\t\t\t}\n\t\t}\n\n\t\t// Now initialize each one.\n\t\tfor (let i = 0; i < this.logStreams.length; i++)\n\t\t{\n\t\t\tthis.logStreams[i].initialize();\n\t\t}\n\t}\n\n\tlogTime(pMessage, pDatum)\n\t{\n\t\tlet tmpMessage = (typeof(pMessage) !== 'undefined') ? pMessage : 'Time';\n\t\tlet tmpTime = new Date();\n\t\tthis.info(`${tmpMessage} ${tmpTime} (epoch ${+tmpTime})`, pDatum);\n\t}\n\n\t// Get a timestamp\n\tgetTimeStamp()\n\t{\n\t\treturn +new Date();\n\t}\n\n\tgetTimeDelta(pTimeStamp)\n\t{\n\t\tlet tmpEndTime = +new Date();\n\t\treturn tmpEndTime-pTimeStamp;\n\t}\n\n\t// Log the delta between a timestamp, and now with a message\n\tlogTimeDelta(pTimeDelta, pMessage, pDatum)\n\t{\n\t\tlet tmpMessage = (typeof(pMessage) !== 'undefined') ? pMessage : 'Time Measurement';\n\t\tlet tmpDatum = (typeof(pDatum) === 'object') ? pDatum : {};\n\n\t\tlet tmpEndTime = +new Date();\n\n\t\tthis.info(`${tmpMessage} logged at (epoch ${+tmpEndTime}) took (${pTimeDelta}ms)`, pDatum);\n\t}\n\n\tlogTimeDeltaHuman(pTimeDelta, pMessage, pDatum)\n\t{\n\t\tlet tmpMessage = (typeof(pMessage) !== 'undefined') ? pMessage : 'Time Measurement';\n\n\t\tlet tmpEndTime = +new Date();\n\n\t\tlet tmpMs = parseInt(pTimeDelta%1000);\n\t\tlet tmpSeconds = parseInt((pTimeDelta/1000)%60);\n\t\tlet tmpMinutes = parseInt((pTimeDelta/(1000*60))%60);\n\t\tlet tmpHours = parseInt(pTimeDelta/(1000*60*60));\n\n\t\ttmpMs = (tmpMs < 10) ? \"00\"+tmpMs : (tmpMs < 100) ? \"0\"+tmpMs : tmpMs;\n\t\ttmpSeconds = (tmpSeconds < 10) ? \"0\"+tmpSeconds : tmpSeconds;\n\t\ttmpMinutes = (tmpMinutes < 10) ? \"0\"+tmpMinutes : tmpMinutes;\n\t\ttmpHours = (tmpHours < 10) ? \"0\"+tmpHours : tmpHours;\n\n\t\tthis.info(`${tmpMessage} logged at (epoch ${+tmpEndTime}) took (${pTimeDelta}ms) or (${tmpHours}:${tmpMinutes}:${tmpSeconds}.${tmpMs})`, pDatum);\n\t}\n\n\tlogTimeDeltaRelative(pStartTime, pMessage, pDatum)\n\t{\n\t\tthis.logTimeDelta(this.getTimeDelta(pStartTime), pMessage, pDatum);\n\t}\n\n\tlogTimeDeltaRelativeHuman(pStartTime, pMessage, pDatum)\n\t{\n\t\tthis.logTimeDeltaHuman(this.getTimeDelta(pStartTime), pMessage, pDatum);\n\t}\n}\n\n// This is for backwards compatibility\nfunction autoConstruct(pSettings)\n{\n\treturn new FableLog(pSettings);\n}\n\n\nmodule.exports = {new:autoConstruct, FableLog:FableLog};\n\n},{\"./Fable-Log-DefaultProviders-Node.js\":2,\"./Fable-Log-DefaultStreams.json\":3}],6:[function(require,module,exports){\nmodule.exports={\n\t\"Product\": \"ApplicationNameHere\",\n\t\"ProductVersion\": \"0.0.0\",\n\n\t\"ConfigFile\": false,\n\n\t\"LogStreams\":\n\t[\n\t\t{\n\t\t\t\"level\": \"trace\"\n\t\t}\n\t]\n}\n\n},{}],7:[function(require,module,exports){\n(function (process){(function (){\n/**\n* Fable Settings Template Processor\n*\n* This class allows environment variables to come in via templated expressions, and defaults to be set.\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n* @module Fable Settings\n*/\n\nclass FableSettingsTemplateProcessor\n{\n\tconstructor(pDependencies)\n\t{\n // Use a no-dependencies templating engine to parse out environment variables\n\t\tthis.templateProcessor = new pDependencies.precedent();\n\n // TODO: Make the environment variable wrap expression demarcation characters configurable?\n\t\tthis.templateProcessor.addPattern('${', '}',\n\t\t\t(pTemplateValue)=>\n\t\t\t{\n\t\t\t\tlet tmpTemplateValue = pTemplateValue.trim();\n\n\t\t\t\tlet tmpSeparatorIndex = tmpTemplateValue.indexOf('|');\n\n\t\t\t\t// If there is no pipe, the default value will end up being whatever the variable name is.\n\t\t\t\tlet tmpDefaultValue = tmpTemplateValue.substring(tmpSeparatorIndex+1);\n\n\t\t\t\tlet tmpEnvironmentVariableName = (tmpSeparatorIndex > -1) ? tmpTemplateValue.substring(0, tmpSeparatorIndex) : tmpTemplateValue;\n\n\t\t\t\tif (process.env.hasOwnProperty(tmpEnvironmentVariableName))\n\t\t\t\t{\n\t\t\t\t\treturn process.env[tmpEnvironmentVariableName];\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn tmpDefaultValue;\n\t\t\t\t}\n\t\t\t});\n }\n\n parseSetting(pString)\n {\n return this.templateProcessor.parseString(pString);\n }\n}\n\nmodule.exports = FableSettingsTemplateProcessor;\n}).call(this)}).call(this,require('_process'))\n\n},{\"_process\":14}],8:[function(require,module,exports){\n/**\n* Fable Settings Add-on\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n* @module Fable Settings\n*/\n\nconst libPrecedent = require('precedent');\nconst libFableSettingsTemplateProcessor = require('./Fable-Settings-TemplateProcessor.js');\n\nclass FableSettings\n{\n\tconstructor(pFableSettings)\n\t{\n\t\t// Expose the dependencies for downstream re-use\n\t\tthis.dependencies = (\n\t\t\t{\n\t\t\t\tprecedent: libPrecedent\n\t\t\t});\n\n\t\t// Initialize the settings value template processor\n\t\tthis.settingsTemplateProcessor = new libFableSettingsTemplateProcessor(this.dependencies);\n\n\t\t// set straight away so anything that uses it respects the initial setting\n\t\tthis._configureEnvTemplating(pFableSettings);\n\n\t\tthis.default = this.buildDefaultSettings();\n\n\t\t// Construct a new settings object\n\t\tlet tmpSettings = this.merge(pFableSettings, this.buildDefaultSettings());\n\n\t\t// The base settings object (what they were on initialization, before other actors have altered them)\n\t\tthis.base = JSON.parse(JSON.stringify(tmpSettings));\n\n\t\tif (tmpSettings.DefaultConfigFile)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// If there is a DEFAULT configuration file, try to load and merge it.\n\t\t\t\ttmpSettings = this.merge(require(tmpSettings.DefaultConfigFile), tmpSettings);\n\t\t\t}\n\t\t\tcatch (pException)\n\t\t\t{\n\t\t\t\t// Why this? Often for an app we want settings to work out of the box, but\n\t\t\t\t// would potentially want to have a config file for complex settings.\n\t\t\t\tconsole.log('Fable-Settings Warning: Default configuration file specified but there was a problem loading it. Falling back to base.');\n\t\t\t\tconsole.log(' Loading Exception: '+pException);\n\t\t\t}\n\t\t}\n\n\t\tif (tmpSettings.ConfigFile)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// If there is a configuration file, try to load and merge it.\n\t\t\t\ttmpSettings = this.merge(require(tmpSettings.ConfigFile), tmpSettings);\n\t\t\t}\n\t\t\tcatch (pException)\n\t\t\t{\n\t\t\t\t// Why this? Often for an app we want settings to work out of the box, but\n\t\t\t\t// would potentially want to have a config file for complex settings.\n\t\t\t\tconsole.log('Fable-Settings Warning: Configuration file specified but there was a problem loading it. Falling back to base.');\n\t\t\t\tconsole.log(' Loading Exception: '+pException);\n\t\t\t}\n\t\t}\n\n\t\tthis.settings = tmpSettings;\n\t}\n\n\t// Build a default settings object. Use the JSON jimmy to ensure it is always a new object.\n\tbuildDefaultSettings()\n\t{\n\t\treturn JSON.parse(JSON.stringify(require('./Fable-Settings-Default')));\n\t}\n\n\t// Update the configuration for environment variable templating based on the current settings object\n\t_configureEnvTemplating(pSettings)\n\t{\n\t\t// default environment variable templating to on\n\t\tthis._PerformEnvTemplating = !pSettings || pSettings.NoEnvReplacement !== true;\n\t}\n\n\t// Resolve (recursive) any environment variables found in settings object.\n\t_resolveEnv(pSettings)\n\t{\n\t\tfor (const tmpKey in pSettings)\n\t\t{\n\t\t\tif (typeof(pSettings[tmpKey]) === 'object')\n\t\t\t{\n\t\t\t\tthis._resolveEnv(pSettings[tmpKey]);\n\t\t\t}\n\t\t\telse if (typeof(pSettings[tmpKey]) === 'string')\n\t\t\t{\n\t\t\t\tpSettings[tmpKey] = this.settingsTemplateProcessor.parseSetting(pSettings[tmpKey]);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Check to see if a value is an object (but not an array).\n\t */\n\t_isObject(value)\n\t{\n\t\treturn typeof(value) === 'object' && !Array.isArray(value);\n\t}\n\n\t/**\n\t * Merge two plain objects. Keys that are objects in both will be merged property-wise.\n\t */\n\t_deepMergeObjects(toObject, fromObject)\n\t{\n\t\tif (!fromObject || !this._isObject(fromObject))\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tObject.keys(fromObject).forEach((key) =>\n\t\t{\n\t\t\tconst fromValue = fromObject[key];\n\t\t\tif (this._isObject(fromValue))\n\t\t\t{\n\t\t\t\tconst toValue = toObject[key];\n\t\t\t\tif (toValue && this._isObject(toValue))\n\t\t\t\t{\n\t\t\t\t\t// both are objects, so do a recursive merge\n\t\t\t\t\tthis._deepMergeObjects(toValue, fromValue);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\ttoObject[key] = fromValue;\n\t\t});\n\t\treturn toObject;\n\t}\n\n\t// Merge some new object into the existing settings.\n\tmerge(pSettingsFrom, pSettingsTo)\n\t{\n\t\t// If an invalid settings from object is passed in (e.g. object constructor without passing in anything) this should still work\n\t\tlet tmpSettingsFrom = (typeof(pSettingsFrom) === 'object') ? pSettingsFrom : {};\n\t\t// Default to the settings object if none is passed in for the merge.\n\t\tlet tmpSettingsTo = (typeof(pSettingsTo) === 'object') ? pSettingsTo : this.settings;\n\n\t\t// do not mutate the From object property values\n\t\tlet tmpSettingsFromCopy = JSON.parse(JSON.stringify(tmpSettingsFrom));\n\t\ttmpSettingsTo = this._deepMergeObjects(tmpSettingsTo, tmpSettingsFromCopy);\n\n\t\tif (this._PerformEnvTemplating)\n\t\t{\n\t\t\tthis._resolveEnv(tmpSettingsTo);\n\t\t}\n\t\t// Update env tempating config, since we just updated the config object, and it may have changed\n\t\tthis._configureEnvTemplating(tmpSettingsTo);\n\n\t\treturn tmpSettingsTo;\n\t}\n\n\t// Fill in settings gaps without overwriting settings that are already there\n\tfill(pSettingsFrom)\n\t{\n\t\t// If an invalid settings from object is passed in (e.g. object constructor without passing in anything) this should still work\n\t\tlet tmpSettingsFrom = (typeof(pSettingsFrom) === 'object') ? pSettingsFrom : {};\n\n\t\t// do not mutate the From object property values\n\t\tlet tmpSettingsFromCopy = JSON.parse(JSON.stringify(tmpSettingsFrom));\n\n\t\tthis.settings = this._deepMergeObjects(tmpSettingsFromCopy, this.settings);\n\n\t\treturn this.settings;\n\t}\n};\n\n// This is for backwards compatibility\nfunction autoConstruct(pSettings)\n{\n\treturn new FableSettings(pSettings);\n}\n\nmodule.exports = {new:autoConstruct, FableSettings:FableSettings};\n},{\"./Fable-Settings-Default\":6,\"./Fable-Settings-TemplateProcessor.js\":7,\"precedent\":11}],9:[function(require,module,exports){\n/**\n* Random Byte Generator - Browser version\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*/\n\n// Adapted from node-uuid (https://github.com/kelektiv/node-uuid)\n// Unique ID creation requires a high quality random # generator. In the\n// browser this is a little complicated due to unknown quality of Math.random()\n// and inconsistent support for the `crypto` API. We do the best we can via\n// feature-detection\nclass RandomBytes\n{\n\tconstructor()\n\t{\n\n\t\t// getRandomValues needs to be invoked in a context where \"this\" is a Crypto\n\t\t// implementation. Also, find the complete implementation of crypto on IE11.\n\t\tthis.getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||\n \t\t(typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));\n\t}\n\n\t// WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto\n\tgenerateWhatWGBytes()\n\t{\n\t\tlet tmpBuffer = new Uint8Array(16); // eslint-disable-line no-undef\n\n\t\tthis.getRandomValues(tmpBuffer);\n\t\treturn tmpBuffer;\n\t}\n\n\t// Math.random()-based (RNG)\n\tgenerateRandomBytes()\n\t{\n\t\t// If all else fails, use Math.random(). It's fast, but is of unspecified\n\t\t// quality.\n\t\tlet tmpBuffer = new Uint8Array(16); // eslint-disable-line no-undef\n\n\t\tfor (let i = 0, tmpValue; i < 16; i++)\n\t\t{\n\t\t\tif ((i & 0x03) === 0)\n\t\t\t{\n\t\t\t\ttmpValue = Math.random() * 0x100000000;\n\t\t\t}\n\n\t\t\ttmpBuffer[i] = tmpValue >>> ((i & 0x03) << 3) & 0xff;\n\t\t}\n\n\t\treturn tmpBuffer;\n\t}\n\n\tgenerate()\n\t{\n\t\tif (this.getRandomValues)\n\t\t{\n\t\t\treturn this.generateWhatWGBytes();\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn this.generateRandomBytes();\n\t\t}\n\t}\n}\n\nmodule.exports = RandomBytes;\n\n},{}],10:[function(require,module,exports){\n/**\n* Fable UUID Generator\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n* @module Fable UUID\n*/\n\n/**\n* Fable Solution UUID Generation Main Class\n*\n* @class FableUUID\n* @constructor\n*/\n\nvar libRandomByteGenerator = require('./Fable-UUID-Random.js')\n\nclass FableUUID\n{\n\tconstructor(pSettings)\n\t{\n\t\t// Determine if the module is in \"Random UUID Mode\" which means just use the random character function rather than the v4 random UUID spec.\n\t\t// Note this allows UUIDs of various lengths (including very short ones) although guaranteed uniqueness goes downhill fast.\n\t\tthis._UUIDModeRandom = (typeof(pSettings) === 'object') && (pSettings.hasOwnProperty('UUIDModeRandom')) ? (pSettings.UUIDModeRandom == true) : false;\n\t\t// These two properties are only useful if we are in Random mode. Otherwise it generates a v4 spec\n\t\t// Length for \"Random UUID Mode\" is set -- if not set it to 8\n\t\tthis._UUIDLength = (typeof(pSettings) === 'object') && (pSettings.hasOwnProperty('UUIDLength')) ? (pSettings.UUIDLength + 0) : 8;\n\t\t// Dictionary for \"Random UUID Mode\"\n\t\tthis._UUIDRandomDictionary = (typeof(pSettings) === 'object') && (pSettings.hasOwnProperty('UUIDDictionary')) ? (pSettings.UUIDDictionary + 0) : '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n\n\t\tthis.randomByteGenerator = new libRandomByteGenerator();\n\n\t\t// Lookup table for hex codes\n\t\tthis._HexLookup = [];\n\t\tfor (let i = 0; i < 256; ++i)\n\t\t{\n\t\t\tthis._HexLookup[i] = (i + 0x100).toString(16).substr(1);\n\t\t}\n\t}\n\n\t// Adapted from node-uuid (https://github.com/kelektiv/node-uuid)\n\tbytesToUUID(pBuffer)\n\t{\n\t\tlet i = 0;\n\t\t// join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4\n\t\treturn ([\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], \n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], '-',\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], '-',\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], '-',\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], '-',\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]]\n\t\t\t\t]).join('');\n\t}\n\n\t// Adapted from node-uuid (https://github.com/kelektiv/node-uuid)\n\tgenerateUUIDv4()\n\t{\n\t\tlet tmpBuffer = new Array(16);\n\t\tvar tmpRandomBytes = this.randomByteGenerator.generate();\n\n\t\t// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n\t\ttmpRandomBytes[6] = (tmpRandomBytes[6] & 0x0f) | 0x40;\n\t\ttmpRandomBytes[8] = (tmpRandomBytes[8] & 0x3f) | 0x80;\n\n\t\treturn this.bytesToUUID(tmpRandomBytes);\n\t}\n\n\t// Simple random UUID generation\n\tgenerateRandom()\n\t{\n\t\tlet tmpUUID = '';\n\n\t\tfor (let i = 0; i < this._UUIDLength; i++)\n\t\t{\n\t\t\ttmpUUID += this._UUIDRandomDictionary.charAt(Math.floor(Math.random() * (this._UUIDRandomDictionary.length-1)));\n\t\t}\n\n\t\treturn tmpUUID;\n\t}\n\n\t// Adapted from node-uuid (https://github.com/kelektiv/node-uuid)\n\tgetUUID()\n\t{\n\t\tif (this._UUIDModeRandom)\n\t\t{\n\t\t\treturn this.generateRandom();\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn this.generateUUIDv4();\n\t\t}\n\t}\n}\n\n// This is for backwards compatibility\nfunction autoConstruct(pSettings)\n{\n\treturn new FableUUID(pSettings);\n}\n\n\nmodule.exports = {new:autoConstruct, FableUUID:FableUUID};\n\n},{\"./Fable-UUID-Random.js\":9}],11:[function(require,module,exports){\n/**\n* Precedent Meta-Templating\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Process text streams, parsing out meta-template expressions.\n*/\nvar libWordTree = require(`./WordTree.js`);\nvar libStringParser = require(`./StringParser.js`);\n\nclass Precedent\n{\n\t/**\n\t * Precedent Constructor\n\t */\n\tconstructor()\n\t{\n\t\tthis.WordTree = new libWordTree();\n\t\t\n\t\tthis.StringParser = new libStringParser();\n\n\t\tthis.ParseTree = this.WordTree.ParseTree;\n\t}\n\t\n\t/**\n\t * Add a Pattern to the Parse Tree\n\t * @method addPattern\n\t * @param {Object} pTree - A node on the parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - callback function\n\t * @return {bool} True if adding the pattern was successful\n\t */\n\taddPattern(pPatternStart, pPatternEnd, pParser)\n\t{\n\t\treturn this.WordTree.addPattern(pPatternStart, pPatternEnd, pParser);\n\t}\n\t\n\t/**\n\t * Parse a string with the existing parse tree\n\t * @method parseString\n\t * @param {string} pString - The string to parse\n\t * @return {string} The result from the parser\n\t */\n\tparseString(pString)\n\t{\n\t\treturn this.StringParser.parseString(pString, this.ParseTree);\n\t}\n}\n\nmodule.exports = Precedent;\n\n},{\"./StringParser.js\":12,\"./WordTree.js\":13}],12:[function(require,module,exports){\n/**\n* String Parser\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Parse a string, properly processing each matched token in the word tree.\n*/\n\nclass StringParser\n{\n\t/**\n\t * StringParser Constructor\n\t */\n\tconstructor()\n\t{\n\t}\n\t\n\t/**\n\t * Create a fresh parsing state object to work with.\n\t * @method newParserState\n\t * @param {Object} pParseTree - A node on the parse tree to begin parsing from (usually root)\n\t * @return {Object} A new parser state object for running a character parser on\n\t * @private\n\t */\n\tnewParserState (pParseTree)\n\t{\n\t\treturn (\n\t\t{\n\t\t\tParseTree: pParseTree,\n\n\t\t\tOutput: '',\n\t\t\tOutputBuffer: '',\n\n\t\t\tPattern: false,\n\n\t\t\tPatternMatch: false,\n\t\t\tPatternMatchOutputBuffer: ''\n\t\t});\n\t}\n\t\t\n\t/**\n\t * Assign a node of the parser tree to be the next potential match.\n\t * If the node has a PatternEnd property, it is a valid match and supercedes the last valid match (or becomes the initial match).\n\t * @method assignNode\n\t * @param {Object} pNode - A node on the parse tree to assign\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tassignNode (pNode, pParserState)\n\t{\n\t\tpParserState.PatternMatch = pNode;\n\n\t\t// If the pattern has a END we can assume it has a parse function...\n\t\tif (pParserState.PatternMatch.hasOwnProperty('PatternEnd'))\n\t\t{\n\t\t\t// ... this is the legitimate start of a pattern.\n\t\t\tpParserState.Pattern = pParserState.PatternMatch;\n\t\t}\n\t}\n\t\n\t/**\n\t * Append a character to the output buffer in the parser state.\n\t * This output buffer is used when a potential match is being explored, or a match is being explored.\n\t * @method appendOutputBuffer\n\t * @param {string} pCharacter - The character to append\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tappendOutputBuffer (pCharacter, pParserState)\n\t{\n\t\tpParserState.OutputBuffer += pCharacter;\n\t}\n\t\n\t/**\n\t * Flush the output buffer to the output and clear it.\n\t * @method flushOutputBuffer\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tflushOutputBuffer (pParserState)\n\t{\n\t\tpParserState.Output += pParserState.OutputBuffer;\n\t\tpParserState.OutputBuffer = '';\n\t}\n\n\t\n\t/**\n\t * Check if the pattern has ended. If it has, properly flush the buffer and start looking for new patterns.\n\t * @method checkPatternEnd\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tcheckPatternEnd (pParserState)\n\t{\n\t\tif ((pParserState.OutputBuffer.length >= pParserState.Pattern.PatternEnd.length+pParserState.Pattern.PatternStart.length) && \n\t\t\t(pParserState.OutputBuffer.substr(-pParserState.Pattern.PatternEnd.length) === pParserState.Pattern.PatternEnd))\n\t\t{\n\t\t\t// ... this is the end of a pattern, cut off the end tag and parse it.\n\t\t\t// Trim the start and end tags off the output buffer now\n\t\t\tpParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStart.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStart.length+pParserState.Pattern.PatternEnd.length)));\n\t\t\t// Flush the output buffer.\n\t\t\tthis.flushOutputBuffer(pParserState);\n\t\t\t// End pattern mode\n\t\t\tpParserState.Pattern = false;\n\t\t\tpParserState.PatternMatch = false;\n\t\t}\n\t}\n\t\n\t/**\n\t * Parse a character in the buffer.\n\t * @method parseCharacter\n\t * @param {string} pCharacter - The character to append\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tparseCharacter (pCharacter, pParserState)\n\t{\n\t\t// (1) If we aren't in a pattern match, and we aren't potentially matching, and this may be the start of a new pattern....\n\t\tif (!pParserState.PatternMatch && pParserState.ParseTree.hasOwnProperty(pCharacter))\n\t\t{\n\t\t\t// ... assign the node as the matched node.\n\t\t\tthis.assignNode(pParserState.ParseTree[pCharacter], pParserState);\n\t\t\tthis.appendOutputBuffer(pCharacter, pParserState);\n\t\t}\n\t\t// (2) If we are in a pattern match (actively seeing if this is part of a new pattern token)\n\t\telse if (pParserState.PatternMatch)\n\t\t{\n\t\t\t// If the pattern has a subpattern with this key\n\t\t\tif (pParserState.PatternMatch.hasOwnProperty(pCharacter))\n\t\t\t{\n\t\t\t\t// Continue matching patterns.\n\t\t\t\tthis.assignNode(pParserState.PatternMatch[pCharacter], pParserState);\n\t\t\t}\n\t\t\tthis.appendOutputBuffer(pCharacter, pParserState);\n\t\t\tif (pParserState.Pattern)\n\t\t\t{\n\t\t\t\t// ... Check if this is the end of the pattern (if we are matching a valid pattern)...\n\t\t\t\tthis.checkPatternEnd(pParserState);\n\t\t\t}\n\t\t}\n\t\t// (3) If we aren't in a pattern match or pattern, and this isn't the start of a new pattern (RAW mode)....\n\t\telse\n\t\t{\n\t\t\tpParserState.Output += pCharacter;\n\t\t}\n\t}\n\t\n\t/**\n\t * Parse a string for matches, and process any template segments that occur.\n\t * @method parseString\n\t * @param {string} pString - The string to parse.\n\t * @param {Object} pParseTree - The parse tree to begin parsing from (usually root)\n\t */\n\tparseString (pString, pParseTree)\n\t{\n\t\tlet tmpParserState = this.newParserState(pParseTree);\n\n\t\tfor (var i = 0; i < pString.length; i++)\n\t\t{\n\t\t\t// TODO: This is not fast.\n\t\t\tthis.parseCharacter(pString[i], tmpParserState);\n\t\t}\n\t\t\n\t\tthis.flushOutputBuffer(tmpParserState);\n\t\t\n\t\treturn tmpParserState.Output;\n\t}\n}\n\nmodule.exports = StringParser;\n\n},{}],13:[function(require,module,exports){\n/**\n* Word Tree\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Create a tree (directed graph) of Javascript objects, one character per object.\n*/\n\nclass WordTree\n{\n\t/**\n\t * WordTree Constructor\n\t */\n\tconstructor()\n\t{\n\t\tthis.ParseTree = {};\n\t}\n\t\n\t/** \n\t * Add a child character to a Parse Tree node\n\t * @method addChild\n\t * @param {Object} pTree - A parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - The index of the character in the pattern\n\t * @returns {Object} The resulting leaf node that was added (or found)\n\t * @private\n\t */\n\taddChild (pTree, pPattern, pIndex)\n\t{\n\t\tif (!pTree.hasOwnProperty(pPattern[pIndex]))\n\t\t\tpTree[pPattern[pIndex]] = {};\n\t\t\n\t\treturn pTree[pPattern[pIndex]];\n\t}\n\t\n\t/** Add a Pattern to the Parse Tree\n\t * @method addPattern\n\t * @param {Object} pPatternStart - The starting string for the pattern (e.g. \"${\")\n\t * @param {string} pPatternEnd - The ending string for the pattern (e.g. \"}\")\n\t * @param {number} pParser - The function to parse if this is the matched pattern, once the Pattern End is met. If this is a string, a simple replacement occurs.\n\t * @return {bool} True if adding the pattern was successful\n\t */\n\taddPattern (pPatternStart, pPatternEnd, pParser)\n\t{\n\t\tif (pPatternStart.length < 1)\n\t\t\treturn false;\n\n\t\tif ((typeof(pPatternEnd) === 'string') && (pPatternEnd.length < 1))\n\t\t\treturn false;\n\n\t\tlet tmpLeaf = this.ParseTree;\n\n\t\t// Add the tree of leaves iteratively\n\t\tfor (var i = 0; i < pPatternStart.length; i++)\n\t\t\ttmpLeaf = this.addChild(tmpLeaf, pPatternStart, i);\n\n\t\ttmpLeaf.PatternStart = pPatternStart;\n\t\ttmpLeaf.PatternEnd = ((typeof(pPatternEnd) === 'string') && (pPatternEnd.length > 0)) ? pPatternEnd : pPatternStart;\n\t\ttmpLeaf.Parse = (typeof(pParser) === 'function') ? pParser : \n\t\t\t\t\t\t(typeof(pParser) === 'string') ? () => { return pParser; } :\n\t\t\t\t\t\t(pData) => { return pData; };\n\n\t\treturn true;\n\t}\n}\n\nmodule.exports = WordTree;\n\n},{}],14:[function(require,module,exports){\n// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n},{}],15:[function(require,module,exports){\nvar libNPMModuleWrapper = require('./Fable.js');\n\nif ((typeof(window) === 'object') && !window.hasOwnProperty('Fable'))\n{\n\twindow.Fable = libNPMModuleWrapper;\n}\n\nmodule.exports = libNPMModuleWrapper;\n},{\"./Fable.js\":17}],16:[function(require,module,exports){\nclass FableUtility\n{\n\tconstructor(pFable)\n\t{\n\t\tthis.fable = pFable;\n\t}\n\n\t// Underscore and lodash both had a behavior, _.extend, which merged objects\n\t// Now that es6 gives us this, use the native thingy.\n\textend(pDestinationObject, ...pSourceObjects)\n\t{\n\t\treturn Object.assign(pDestinationObject, ...pSourceObjects);\n\t}\n}\n\nmodule.exports = FableUtility;\n},{}],17:[function(require,module,exports){\n/**\n* Fable Application Services Support Library\n* @license MIT\n* @author <steven@velozo.com>\n*/\nconst libFableSettings = require('fable-settings').FableSettings;\nconst libFableUUID = require('fable-uuid').FableUUID;\nconst libFableLog = require('fable-log').FableLog;\n\nconst libFableUtility = require('./Fable-Utility.js')\n\nclass Fable\n{\n\tconstructor(pSettings)\n\t{\n\t\tlet tmpSettings = new libFableSettings(pSettings);\n\n\t\tthis.settingsManager = tmpSettings;\n\n\t\t// Instantiate the UUID generator\n\t\tthis.libUUID = new libFableUUID(this.settingsManager.settings);\n\n\t\tthis.log = new libFableLog(this.settingsManager.settings);\n\t\tthis.log.initialize();\n\n\t\tthis.Utility = new libFableUtility(this);\n\t}\n\n\tget settings()\n\t{\n\t\treturn this.settingsManager.settings;\n\t}\n\n\tget fable()\n\t{\n\t\treturn this;\n\t}\n\n\tgetUUID()\n\t{\n\t\treturn this.libUUID.getUUID();\n\t}\n}\n\nmodule.exports = Fable;\n},{\"./Fable-Utility.js\":16,\"fable-log\":5,\"fable-settings\":8,\"fable-uuid\":10}]},{},[15])(15)\n});\n\n","/**\n* Default Logger Provider Function\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*/\n\n// Return the providers that are available without extensions loaded\ngetDefaultProviders = () =>\n{\n\tlet tmpDefaultProviders = {};\n\n\ttmpDefaultProviders.console = require('./Fable-Log-Logger-Console.js');\n\n\ttmpDefaultProviders.default = tmpDefaultProviders.console;\n\n\treturn tmpDefaultProviders;\n}\n\nmodule.exports = getDefaultProviders();","module.exports=[\n {\n \"loggertype\": \"console\",\n \"streamtype\": \"console\",\n \"level\": \"trace\"\n }\n]","let libBaseLogger = require('./Fable-Log-BaseLogger.js');\n\nclass ConsoleLogger extends libBaseLogger\n{\n\tconstructor(pLogStreamSettings, pFableLog)\n\t{\n\t\tsuper(pLogStreamSettings);\n\n\t\tthis._ShowTimeStamps = pLogStreamSettings.hasOwnProperty('showtimestamps') ? (pLogStreamSettings.showtimestamps == true) : false;\n\t\tthis._FormattedTimeStamps = pLogStreamSettings.hasOwnProperty('formattedtimestamps') ? (pLogStreamSettings.formattedtimestamps == true) : false;\n\n\t\tthis._ContextMessage = pLogStreamSettings.hasOwnProperty('Context') ? `(${pLogStreamSettings.Context})` : \n\t\t\t\t\t\t\t\tpFableLog._Settings.hasOwnProperty('Product') ? `(${pFableLog._Settings.Product})` :\n\t\t\t\t\t\t\t\t'Unnamed_Log_Context';\n\n\t\t// Allow the user to decide what gets output to the console\n\t\tthis._OutputLogLinesToConsole = pLogStreamSettings.hasOwnProperty('outputloglinestoconsole') ? pLogStreamSettings.outputloglinestoconsole : true;\n\t\tthis._OutputObjectsToConsole = pLogStreamSettings.hasOwnProperty('outputobjectstoconsole') ? pLogStreamSettings.outputobjectstoconsole : true;\n\n\t\t// Precompute the prefix for each level\n\t\tthis.prefixCache = {};\n\t\tfor (let i = 0; i <= this.levels.length; i++)\n\t\t{\n\t\t\tthis.prefixCache[this.levels[i]] = `[${this.levels[i]}] ${this._ContextMessage}: `;\n\n\t\t\tif (this._ShowTimeStamps)\n\t\t\t{\n\t\t\t\t// If there is a timestamp we need a to prepend space before the prefixcache string, since the timestamp comes first\n\t\t\t\tthis.prefixCache[this.levels[i]] = ' '+this.prefixCache[this.levels[i]];\n\t\t\t}\n\t\t}\n\t}\n\n\twrite(pLevel, pLogText, pObject)\n\t{\n\t\tlet tmpTimeStamp = '';\n\t\tif (this._ShowTimeStamps && this._FormattedTimeStamps)\n\t\t{\n\t\t\ttmpTimeStamp = (new Date()).toISOString();\n\t\t}\n\t\telse if (this._ShowTimeStamps)\n\t\t{\n\t\t\ttmpTimeStamp = +new Date();\n\t\t}\n\n\t\tlet tmpLogLine = `${tmpTimeStamp}${this.prefixCache[pLevel]}${pLogText}`;\n\n\t\tif (this._OutputLogLinesToConsole)\n\t\t{\n\t\t\tconsole.log(tmpLogLine);\n\t\t}\n\n\t\t// Write out the object on a separate line if it is passed in\n\t\tif (this._OutputObjectsToConsole && (typeof(pObject) !== 'undefined'))\n\t\t{\n\t\t\tconsole.log(JSON.stringify(pObject, null, 2));\n\t\t}\n\n\t\t// Provide an easy way to be overridden and be consistent\n\t\treturn tmpLogLine;\n\t}\n}\n\nmodule.exports = ConsoleLogger;","/**\n* Fable Logging Add-on\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n* @module Fable Logger\n*/\n\n/**\n* Fable Solution Log Wrapper Main Class\n*\n* @class FableLog\n* @constructor\n*/\nclass FableLog\n{\n\tconstructor(pFableSettings, pFable)\n\t{\n\t\tlet tmpSettings = (typeof(pFableSettings) === 'object') ? pFableSettings : {}\n\t\tthis._Settings = tmpSettings;\n\n\t\tthis._Providers = require('./Fable-Log-DefaultProviders-Node.js');\n\n\t\tthis._StreamDefinitions = (tmpSettings.hasOwnProperty('LogStreams')) ? tmpSettings.LogStreams : require('./Fable-Log-DefaultStreams.json');\n\n\t\tthis.logStreams = [];\n\n\t\t// This object gets decorated for one-time instantiated providers that\n\t\t// have multiple outputs, such as bunyan.\n\t\tthis.logProviders = {};\n\n\t\t// A hash list of the GUIDs for each log stream, so they can't be added to the set more than one time\n\t\tthis.activeLogStreams = {};\n\n\t\tthis.logStreamsTrace = [];\n\t\tthis.logStreamsDebug = [];\n\t\tthis.logStreamsInfo = [];\n\t\tthis.logStreamsWarn = [];\n\t\tthis.logStreamsError = [];\n\t\tthis.logStreamsFatal = [];\n\n\t\tthis.datumDecorator = (pDatum) => pDatum;\n\n\t\tthis.uuid = (typeof(tmpSettings.Product) === 'string') ? tmpSettings.Product : 'Default';\n\t}\n\n\taddLogger(pLogger, pLevel)\n\t{\n\t\t// Bail out if we've already created one.\n\t\tif (this.activeLogStreams.hasOwnProperty(pLogger.loggerUUID))\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\t// Add it to the streams and to the mutex\n\t\tthis.logStreams.push(pLogger);\n\t\tthis.activeLogStreams[pLogger.loggerUUID] = true;\n\n\t\t// Make sure a kosher level was passed in\n\t\tswitch (pLevel)\n\t\t{\n\t\t\tcase 'trace':\n\t\t\t\tthis.logStreamsTrace.push(pLogger);\n\t\t\tcase 'debug':\n\t\t\t\tthis.logStreamsDebug.push(pLogger);\n\t\t\tcase 'info':\n\t\t\t\tthis.logStreamsInfo.push(pLogger);\n\t\t\tcase 'warn':\n\t\t\t\tthis.logStreamsWarn.push(pLogger);\n\t\t\tcase 'error':\n\t\t\t\tthis.logStreamsError.push(pLogger);\n\t\t\tcase 'fatal':\n\t\t\t\tthis.logStreamsFatal.push(pLogger);\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tsetDatumDecorator(fDatumDecorator)\n\t{\n\t\tif (typeof(fDatumDecorator) === 'function')\n\t\t{\n\t\t\tthis.datumDecorator = fDatumDecorator;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tthis.datumDecorator = (pDatum) => pDatum;\n\t\t}\n\t}\n\n\ttrace(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsTrace.length; i++)\n\t\t{\n\t\t\tthis.logStreamsTrace[i].trace(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\tdebug(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsDebug.length; i++)\n\t\t{\n\t\t\tthis.logStreamsDebug[i].debug(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\tinfo(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsInfo.length; i++)\n\t\t{\n\t\t\tthis.logStreamsInfo[i].info(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\twarn(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsWarn.length; i++)\n\t\t{\n\t\t\tthis.logStreamsWarn[i].warn(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\terror(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsError.length; i++)\n\t\t{\n\t\t\tthis.logStreamsError[i].error(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\tfatal(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsFatal.length; i++)\n\t\t{\n\t\t\tthis.logStreamsFatal[i].fatal(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\tinitialize()\n\t{\n\t\t// \"initialize\" each logger as defined in the logging parameters\n\t\tfor (let i = 0; i < this._StreamDefinitions.length; i++)\n\t\t{\n\t\t\tlet tmpStreamDefinition = Object.assign({loggertype:'default',streamtype:'console',level:'info'},this._StreamDefinitions[i]);\n\n\t\t\tif (!this._Providers.hasOwnProperty(tmpStreamDefinition.loggertype))\n\t\t\t{\n\t\t\t\tconsole.log(`Error initializing log stream: bad loggertype in stream definition ${JSON.stringify(tmpStreamDefinition)}`);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.addLogger(new this._Providers[tmpStreamDefinition.loggertype](tmpStreamDefinition, this), tmpStreamDefinition.level);\n\t\t\t}\n\t\t}\n\n\t\t// Now initialize each one.\n\t\tfor (let i = 0; i < this.logStreams.length; i++)\n\t\t{\n\t\t\tthis.logStreams[i].initialize();\n\t\t}\n\t}\n\n\tlogTime(pMessage, pDatum)\n\t{\n\t\tlet tmpMessage = (typeof(pMessage) !== 'undefined') ? pMessage : 'Time';\n\t\tlet tmpTime = new Date();\n\t\tthis.info(`${tmpMessage} ${tmpTime} (epoch ${+tmpTime})`, pDatum);\n\t}\n\n\t// Get a timestamp\n\tgetTimeStamp()\n\t{\n\t\treturn +new Date();\n\t}\n\n\tgetTimeDelta(pTimeStamp)\n\t{\n\t\tlet tmpEndTime = +new Date();\n\t\treturn tmpEndTime-pTimeStamp;\n\t}\n\n\t// Log the delta between a timestamp, and now with a message\n\tlogTimeDelta(pTimeDelta, pMessage, pDatum)\n\t{\n\t\tlet tmpMessage = (typeof(pMessage) !== 'undefined') ? pMessage : 'Time Measurement';\n\t\tlet tmpDatum = (typeof(pDatum) === 'object') ? pDatum : {};\n\n\t\tlet tmpEndTime = +new Date();\n\n\t\tthis.info(`${tmpMessage} logged at (epoch ${+tmpEndTime}) took (${pTimeDelta}ms)`, pDatum);\n\t}\n\n\tlogTimeDeltaHuman(pTimeDelta, pMessage, pDatum)\n\t{\n\t\tlet tmpMessage = (typeof(pMessage) !== 'undefined') ? pMessage : 'Time Measurement';\n\n\t\tlet tmpEndTime = +new Date();\n\n\t\tlet tmpMs = parseInt(pTimeDelta%1000);\n\t\tlet tmpSeconds = parseInt((pTimeDelta/1000)%60);\n\t\tlet tmpMinutes = parseInt((pTimeDelta/(1000*60))%60);\n\t\tlet tmpHours = parseInt(pTimeDelta/(1000*60*60));\n\n\t\ttmpMs = (tmpMs < 10) ? \"00\"+tmpMs : (tmpMs < 100) ? \"0\"+tmpMs : tmpMs;\n\t\ttmpSeconds = (tmpSeconds < 10) ? \"0\"+tmpSeconds : tmpSeconds;\n\t\ttmpMinutes = (tmpMinutes < 10) ? \"0\"+tmpMinutes : tmpMinutes;\n\t\ttmpHours = (tmpHours < 10) ? \"0\"+tmpHours : tmpHours;\n\n\t\tthis.info(`${tmpMessage} logged at (epoch ${+tmpEndTime}) took (${pTimeDelta}ms) or (${tmpHours}:${tmpMinutes}:${tmpSeconds}.${tmpMs})`, pDatum);\n\t}\n\n\tlogTimeDeltaRelative(pStartTime, pMessage, pDatum)\n\t{\n\t\tthis.logTimeDelta(this.getTimeDelta(pStartTime), pMessage, pDatum);\n\t}\n\n\tlogTimeDeltaRelativeHuman(pStartTime, pMessage, pDatum)\n\t{\n\t\tthis.logTimeDeltaHuman(this.getTimeDelta(pStartTime), pMessage, pDatum);\n\t}\n}\n\n// This is for backwards compatibility\nfunction autoConstruct(pSettings)\n{\n\treturn new FableLog(pSettings);\n}\n\n\nmodule.exports = {new:autoConstruct, FableLog:FableLog};\n","module.exports={\n\t\"Product\": \"ApplicationNameHere\",\n\t\"ProductVersion\": \"0.0.0\",\n\n\t\"ConfigFile\": false,\n\n\t\"LogStreams\":\n\t[\n\t\t{\n\t\t\t\"level\": \"trace\"\n\t\t}\n\t]\n}\n","/**\n* Fable Settings Template Processor\n*\n* This class allows environment variables to come in via templated expressions, and defaults to be set.\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n* @module Fable Settings\n*/\n\nclass FableSettingsTemplateProcessor\n{\n\tconstructor(pDependencies)\n\t{\n // Use a no-dependencies templating engine to parse out environment variables\n\t\tthis.templateProcessor = new pDependencies.precedent();\n\n // TODO: Make the environment variable wrap expression demarcation characters configurable?\n\t\tthis.templateProcessor.addPattern('${', '}',\n\t\t\t(pTemplateValue)=>\n\t\t\t{\n\t\t\t\tlet tmpTemplateValue = pTemplateValue.trim();\n\n\t\t\t\tlet tmpSeparatorIndex = tmpTemplateValue.indexOf('|');\n\n\t\t\t\t// If there is no pipe, the default value will end up being whatever the variable name is.\n\t\t\t\tlet tmpDefaultValue = tmpTemplateValue.substring(tmpSeparatorIndex+1);\n\n\t\t\t\tlet tmpEnvironmentVariableName = (tmpSeparatorIndex > -1) ? tmpTemplateValue.substring(0, tmpSeparatorIndex) : tmpTemplateValue;\n\n\t\t\t\tif (process.env.hasOwnProperty(tmpEnvironmentVariableName))\n\t\t\t\t{\n\t\t\t\t\treturn process.env[tmpEnvironmentVariableName];\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn tmpDefaultValue;\n\t\t\t\t}\n\t\t\t});\n }\n\n parseSetting(pString)\n {\n return this.templateProcessor.parseString(pString);\n }\n}\n\nmodule.exports = FableSettingsTemplateProcessor;","/**\n* Fable Settings Add-on\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n* @module Fable Settings\n*/\n\nconst libPrecedent = require('precedent');\nconst libFableSettingsTemplateProcessor = require('./Fable-Settings-TemplateProcessor.js');\n\nclass FableSettings\n{\n\tconstructor(pFableSettings)\n\t{\n\t\t// Expose the dependencies for downstream re-use\n\t\tthis.dependencies = (\n\t\t\t{\n\t\t\t\tprecedent: libPrecedent\n\t\t\t});\n\n\t\t// Initialize the settings value template processor\n\t\tthis.settingsTemplateProcessor = new libFableSettingsTemplateProcessor(this.dependencies);\n\n\t\t// set straight away so anything that uses it respects the initial setting\n\t\tthis._configureEnvTemplating(pFableSettings);\n\n\t\tthis.default = this.buildDefaultSettings();\n\n\t\t// Construct a new settings object\n\t\tlet tmpSettings = this.merge(pFableSettings, this.buildDefaultSettings());\n\n\t\t// The base settings object (what they were on initialization, before other actors have altered them)\n\t\tthis.base = JSON.parse(JSON.stringify(tmpSettings));\n\n\t\tif (tmpSettings.DefaultConfigFile)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// If there is a DEFAULT configuration file, try to load and merge it.\n\t\t\t\ttmpSettings = this.merge(require(tmpSettings.DefaultConfigFile), tmpSettings);\n\t\t\t}\n\t\t\tcatch (pException)\n\t\t\t{\n\t\t\t\t// Why this? Often for an app we want settings to work out of the box, but\n\t\t\t\t// would potentially want to have a config file for complex settings.\n\t\t\t\tconsole.log('Fable-Settings Warning: Default configuration file specified but there was a problem loading it. Falling back to base.');\n\t\t\t\tconsole.log(' Loading Exception: '+pException);\n\t\t\t}\n\t\t}\n\n\t\tif (tmpSettings.ConfigFile)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// If there is a configuration file, try to load and merge it.\n\t\t\t\ttmpSettings = this.merge(require(tmpSettings.ConfigFile), tmpSettings);\n\t\t\t}\n\t\t\tcatch (pException)\n\t\t\t{\n\t\t\t\t// Why this? Often for an app we want settings to work out of the box, but\n\t\t\t\t// would potentially want to have a config file for complex settings.\n\t\t\t\tconsole.log('Fable-Settings Warning: Configuration file specified but there was a problem loading it. Falling back to base.');\n\t\t\t\tconsole.log(' Loading Exception: '+pException);\n\t\t\t}\n\t\t}\n\n\t\tthis.settings = tmpSettings;\n\t}\n\n\t// Build a default settings object. Use the JSON jimmy to ensure it is always a new object.\n\tbuildDefaultSettings()\n\t{\n\t\treturn JSON.parse(JSON.stringify(require('./Fable-Settings-Default')));\n\t}\n\n\t// Update the configuration for environment variable templating based on the current settings object\n\t_configureEnvTemplating(pSettings)\n\t{\n\t\t// default environment variable templating to on\n\t\tthis._PerformEnvTemplating = !pSettings || pSettings.NoEnvReplacement !== true;\n\t}\n\n\t// Resolve (recursive) any environment variables found in settings object.\n\t_resolveEnv(pSettings)\n\t{\n\t\tfor (const tmpKey in pSettings)\n\t\t{\n\t\t\tif (typeof(pSettings[tmpKey]) === 'object')\n\t\t\t{\n\t\t\t\tthis._resolveEnv(pSettings[tmpKey]);\n\t\t\t}\n\t\t\telse if (typeof(pSettings[tmpKey]) === 'string')\n\t\t\t{\n\t\t\t\tpSettings[tmpKey] = this.settingsTemplateProcessor.parseSetting(pSettings[tmpKey]);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Check to see if a value is an object (but not an array).\n\t */\n\t_isObject(value)\n\t{\n\t\treturn typeof(value) === 'object' && !Array.isArray(value);\n\t}\n\n\t/**\n\t * Merge two plain objects. Keys that are objects in both will be merged property-wise.\n\t */\n\t_deepMergeObjects(toObject, fromObject)\n\t{\n\t\tif (!fromObject || !this._isObject(fromObject))\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tObject.keys(fromObject).forEach((key) =>\n\t\t{\n\t\t\tconst fromValue = fromObject[key];\n\t\t\tif (this._isObject(fromValue))\n\t\t\t{\n\t\t\t\tconst toValue = toObject[key];\n\t\t\t\tif (toValue && this._isObject(toValue))\n\t\t\t\t{\n\t\t\t\t\t// both are objects, so do a recursive merge\n\t\t\t\t\tthis._deepMergeObjects(toValue, fromValue);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\ttoObject[key] = fromValue;\n\t\t});\n\t\treturn toObject;\n\t}\n\n\t// Merge some new object into the existing settings.\n\tmerge(pSettingsFrom, pSettingsTo)\n\t{\n\t\t// If an invalid settings from object is passed in (e.g. object constructor without passing in anything) this should still work\n\t\tlet tmpSettingsFrom = (typeof(pSettingsFrom) === 'object') ? pSettingsFrom : {};\n\t\t// Default to the settings object if none is passed in for the merge.\n\t\tlet tmpSettingsTo = (typeof(pSettingsTo) === 'object') ? pSettingsTo : this.settings;\n\n\t\t// do not mutate the From object property values\n\t\tlet tmpSettingsFromCopy = JSON.parse(JSON.stringify(tmpSettingsFrom));\n\t\ttmpSettingsTo = this._deepMergeObjects(tmpSettingsTo, tmpSettingsFromCopy);\n\n\t\tif (this._PerformEnvTemplating)\n\t\t{\n\t\t\tthis._resolveEnv(tmpSettingsTo);\n\t\t}\n\t\t// Update env tempating config, since we just updated the config object, and it may have changed\n\t\tthis._configureEnvTemplating(tmpSettingsTo);\n\n\t\treturn tmpSettingsTo;\n\t}\n\n\t// Fill in settings gaps without overwriting settings that are already there\n\tfill(pSettingsFrom)\n\t{\n\t\t// If an invalid settings from object is passed in (e.g. object constructor without passing in anything) this should still work\n\t\tlet tmpSettingsFrom = (typeof(pSettingsFrom) === 'object') ? pSettingsFrom : {};\n\n\t\t// do not mutate the From object property values\n\t\tlet tmpSettingsFromCopy = JSON.parse(JSON.stringify(tmpSettingsFrom));\n\n\t\tthis.settings = this._deepMergeObjects(tmpSettingsFromCopy, this.settings);\n\n\t\treturn this.settings;\n\t}\n};\n\n// This is for backwards compatibility\nfunction autoConstruct(pSettings)\n{\n\treturn new FableSettings(pSettings);\n}\n\nmodule.exports = {new:autoConstruct, FableSettings:FableSettings};","/**\n* Random Byte Generator - Browser version\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*/\n\n// Adapted from node-uuid (https://github.com/kelektiv/node-uuid)\n// Unique ID creation requires a high quality random # generator. In the\n// browser this is a little complicated due to unknown quality of Math.random()\n// and inconsistent support for the `crypto` API. We do the best we can via\n// feature-detection\nclass RandomBytes\n{\n\tconstructor()\n\t{\n\n\t\t// getRandomValues needs to be invoked in a context where \"this\" is a Crypto\n\t\t// implementation. Also, find the complete implementation of crypto on IE11.\n\t\tthis.getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||\n \t\t(typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));\n\t}\n\n\t// WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto\n\tgenerateWhatWGBytes()\n\t{\n\t\tlet tmpBuffer = new Uint8Array(16); // eslint-disable-line no-undef\n\n\t\tthis.getRandomValues(tmpBuffer);\n\t\treturn tmpBuffer;\n\t}\n\n\t// Math.random()-based (RNG)\n\tgenerateRandomBytes()\n\t{\n\t\t// If all else fails, use Math.random(). It's fast, but is of unspecified\n\t\t// quality.\n\t\tlet tmpBuffer = new Uint8Array(16); // eslint-disable-line no-undef\n\n\t\tfor (let i = 0, tmpValue; i < 16; i++)\n\t\t{\n\t\t\tif ((i & 0x03) === 0)\n\t\t\t{\n\t\t\t\ttmpValue = Math.random() * 0x100000000;\n\t\t\t}\n\n\t\t\ttmpBuffer[i] = tmpValue >>> ((i & 0x03) << 3) & 0xff;\n\t\t}\n\n\t\treturn tmpBuffer;\n\t}\n\n\tgenerate()\n\t{\n\t\tif (this.getRandomValues)\n\t\t{\n\t\t\treturn this.generateWhatWGBytes();\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn this.generateRandomBytes();\n\t\t}\n\t}\n}\n\nmodule.exports = RandomBytes;\n","/**\n* Fable UUID Generator\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n* @module Fable UUID\n*/\n\n/**\n* Fable Solution UUID Generation Main Class\n*\n* @class FableUUID\n* @constructor\n*/\n\nvar libRandomByteGenerator = require('./Fable-UUID-Random.js')\n\nclass FableUUID\n{\n\tconstructor(pSettings)\n\t{\n\t\t// Determine if the module is in \"Random UUID Mode\" which means just use the random character function rather than the v4 random UUID spec.\n\t\t// Note this allows UUIDs of various lengths (including very short ones) although guaranteed uniqueness goes downhill fast.\n\t\tthis._UUIDModeRandom = (typeof(pSettings) === 'object') && (pSettings.hasOwnProperty('UUIDModeRandom')) ? (pSettings.UUIDModeRandom == true) : false;\n\t\t// These two properties are only useful if we are in Random mode. Otherwise it generates a v4 spec\n\t\t// Length for \"Random UUID Mode\" is set -- if not set it to 8\n\t\tthis._UUIDLength = (typeof(pSettings) === 'object') && (pSettings.hasOwnProperty('UUIDLength')) ? (pSettings.UUIDLength + 0) : 8;\n\t\t// Dictionary for \"Random UUID Mode\"\n\t\tthis._UUIDRandomDictionary = (typeof(pSettings) === 'object') && (pSettings.hasOwnProperty('UUIDDictionary')) ? (pSettings.UUIDDictionary + 0) : '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n\n\t\tthis.randomByteGenerator = new libRandomByteGenerator();\n\n\t\t// Lookup table for hex codes\n\t\tthis._HexLookup = [];\n\t\tfor (let i = 0; i < 256; ++i)\n\t\t{\n\t\t\tthis._HexLookup[i] = (i + 0x100).toString(16).substr(1);\n\t\t}\n\t}\n\n\t// Adapted from node-uuid (https://github.com/kelektiv/node-uuid)\n\tbytesToUUID(pBuffer)\n\t{\n\t\tlet i = 0;\n\t\t// join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4\n\t\treturn ([\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], \n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], '-',\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], '-',\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], '-',\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], '-',\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]]\n\t\t\t\t]).join('');\n\t}\n\n\t// Adapted from node-uuid (https://github.com/kelektiv/node-uuid)\n\tgenerateUUIDv4()\n\t{\n\t\tlet tmpBuffer = new Array(16);\n\t\tvar tmpRandomBytes = this.randomByteGenerator.generate();\n\n\t\t// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n\t\ttmpRandomBytes[6] = (tmpRandomBytes[6] & 0x0f) | 0x40;\n\t\ttmpRandomBytes[8] = (tmpRandomBytes[8] & 0x3f) | 0x80;\n\n\t\treturn this.bytesToUUID(tmpRandomBytes);\n\t}\n\n\t// Simple random UUID generation\n\tgenerateRandom()\n\t{\n\t\tlet tmpUUID = '';\n\n\t\tfor (let i = 0; i < this._UUIDLength; i++)\n\t\t{\n\t\t\ttmpUUID += this._UUIDRandomDictionary.charAt(Math.floor(Math.random() * (this._UUIDRandomDictionary.length-1)));\n\t\t}\n\n\t\treturn tmpUUID;\n\t}\n\n\t// Adapted from node-uuid (https://github.com/kelektiv/node-uuid)\n\tgetUUID()\n\t{\n\t\tif (this._UUIDModeRandom)\n\t\t{\n\t\t\treturn this.generateRandom();\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn this.generateUUIDv4();\n\t\t}\n\t}\n}\n\n// This is for backwards compatibility\nfunction autoConstruct(pSettings)\n{\n\treturn new FableUUID(pSettings);\n}\n\n\nmodule.exports = {new:autoConstruct, FableUUID:FableUUID};\n","/**\n* Precedent Meta-Templating\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Process text streams, parsing out meta-template expressions.\n*/\nvar libWordTree = require(`./WordTree.js`);\nvar libStringParser = require(`./StringParser.js`);\n\nclass Precedent\n{\n\t/**\n\t * Precedent Constructor\n\t */\n\tconstructor()\n\t{\n\t\tthis.WordTree = new libWordTree();\n\t\t\n\t\tthis.StringParser = new libStringParser();\n\n\t\tthis.ParseTree = this.WordTree.ParseTree;\n\t}\n\t\n\t/**\n\t * Add a Pattern to the Parse Tree\n\t * @method addPattern\n\t * @param {Object} pTree - A node on the parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - callback function\n\t * @return {bool} True if adding the pattern was successful\n\t */\n\taddPattern(pPatternStart, pPatternEnd, pParser)\n\t{\n\t\treturn this.WordTree.addPattern(pPatternStart, pPatternEnd, pParser);\n\t}\n\t\n\t/**\n\t * Parse a string with the existing parse tree\n\t * @method parseString\n\t * @param {string} pString - The string to parse\n\t * @return {string} The result from the parser\n\t */\n\tparseString(pString)\n\t{\n\t\treturn this.StringParser.parseString(pString, this.ParseTree);\n\t}\n}\n\nmodule.exports = Precedent;\n","/**\n* String Parser\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Parse a string, properly processing each matched token in the word tree.\n*/\n\nclass StringParser\n{\n\t/**\n\t * StringParser Constructor\n\t */\n\tconstructor()\n\t{\n\t}\n\t\n\t/**\n\t * Create a fresh parsing state object to work with.\n\t * @method newParserState\n\t * @param {Object} pParseTree - A node on the parse tree to begin parsing from (usually root)\n\t * @return {Object} A new parser state object for running a character parser on\n\t * @private\n\t */\n\tnewParserState (pParseTree)\n\t{\n\t\treturn (\n\t\t{\n\t\t\tParseTree: pParseTree,\n\n\t\t\tOutput: '',\n\t\t\tOutputBuffer: '',\n\n\t\t\tPattern: false,\n\n\t\t\tPatternMatch: false,\n\t\t\tPatternMatchOutputBuffer: ''\n\t\t});\n\t}\n\t\t\n\t/**\n\t * Assign a node of the parser tree to be the next potential match.\n\t * If the node has a PatternEnd property, it is a valid match and supercedes the last valid match (or becomes the initial match).\n\t * @method assignNode\n\t * @param {Object} pNode - A node on the parse tree to assign\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tassignNode (pNode, pParserState)\n\t{\n\t\tpParserState.PatternMatch = pNode;\n\n\t\t// If the pattern has a END we can assume it has a parse function...\n\t\tif (pParserState.PatternMatch.hasOwnProperty('PatternEnd'))\n\t\t{\n\t\t\t// ... this is the legitimate start of a pattern.\n\t\t\tpParserState.Pattern = pParserState.PatternMatch;\n\t\t}\n\t}\n\t\n\t/**\n\t * Append a character to the output buffer in the parser state.\n\t * This output buffer is used when a potential match is being explored, or a match is being explored.\n\t * @method appendOutputBuffer\n\t * @param {string} pCharacter - The character to append\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tappendOutputBuffer (pCharacter, pParserState)\n\t{\n\t\tpParserState.OutputBuffer += pCharacter;\n\t}\n\t\n\t/**\n\t * Flush the output buffer to the output and clear it.\n\t * @method flushOutputBuffer\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tflushOutputBuffer (pParserState)\n\t{\n\t\tpParserState.Output += pParserState.OutputBuffer;\n\t\tpParserState.OutputBuffer = '';\n\t}\n\n\t\n\t/**\n\t * Check if the pattern has ended. If it has, properly flush the buffer and start looking for new patterns.\n\t * @method checkPatternEnd\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tcheckPatternEnd (pParserState)\n\t{\n\t\tif ((pParserState.OutputBuffer.length >= pParserState.Pattern.PatternEnd.length+pParserState.Pattern.PatternStart.length) && \n\t\t\t(pParserState.OutputBuffer.substr(-pParserState.Pattern.PatternEnd.length) === pParserState.Pattern.PatternEnd))\n\t\t{\n\t\t\t// ... this is the end of a pattern, cut off the end tag and parse it.\n\t\t\t// Trim the start and end tags off the output buffer now\n\t\t\tpParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStart.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStart.length+pParserState.Pattern.PatternEnd.length)));\n\t\t\t// Flush the output buffer.\n\t\t\tthis.flushOutputBuffer(pParserState);\n\t\t\t// End pattern mode\n\t\t\tpParserState.Pattern = false;\n\t\t\tpParserState.PatternMatch = false;\n\t\t}\n\t}\n\t\n\t/**\n\t * Parse a character in the buffer.\n\t * @method parseCharacter\n\t * @param {string} pCharacter - The character to append\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tparseCharacter (pCharacter, pParserState)\n\t{\n\t\t// (1) If we aren't in a pattern match, and we aren't potentially matching, and this may be the start of a new pattern....\n\t\tif (!pParserState.PatternMatch && pParserState.ParseTree.hasOwnProperty(pCharacter))\n\t\t{\n\t\t\t// ... assign the node as the matched node.\n\t\t\tthis.assignNode(pParserState.ParseTree[pCharacter], pParserState);\n\t\t\tthis.appendOutputBuffer(pCharacter, pParserState);\n\t\t}\n\t\t// (2) If we are in a pattern match (actively seeing if this is part of a new pattern token)\n\t\telse if (pParserState.PatternMatch)\n\t\t{\n\t\t\t// If the pattern has a subpattern with this key\n\t\t\tif (pParserState.PatternMatch.hasOwnProperty(pCharacter))\n\t\t\t{\n\t\t\t\t// Continue matching patterns.\n\t\t\t\tthis.assignNode(pParserState.PatternMatch[pCharacter], pParserState);\n\t\t\t}\n\t\t\tthis.appendOutputBuffer(pCharacter, pParserState);\n\t\t\tif (pParserState.Pattern)\n\t\t\t{\n\t\t\t\t// ... Check if this is the end of the pattern (if we are matching a valid pattern)...\n\t\t\t\tthis.checkPatternEnd(pParserState);\n\t\t\t}\n\t\t}\n\t\t// (3) If we aren't in a pattern match or pattern, and this isn't the start of a new pattern (RAW mode)....\n\t\telse\n\t\t{\n\t\t\tpParserState.Output += pCharacter;\n\t\t}\n\t}\n\t\n\t/**\n\t * Parse a string for matches, and process any template segments that occur.\n\t * @method parseString\n\t * @param {string} pString - The string to parse.\n\t * @param {Object} pParseTree - The parse tree to begin parsing from (usually root)\n\t */\n\tparseString (pString, pParseTree)\n\t{\n\t\tlet tmpParserState = this.newParserState(pParseTree);\n\n\t\tfor (var i = 0; i < pString.length; i++)\n\t\t{\n\t\t\t// TODO: This is not fast.\n\t\t\tthis.parseCharacter(pString[i], tmpParserState);\n\t\t}\n\t\t\n\t\tthis.flushOutputBuffer(tmpParserState);\n\t\t\n\t\treturn tmpParserState.Output;\n\t}\n}\n\nmodule.exports = StringParser;\n","/**\n* Word Tree\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Create a tree (directed graph) of Javascript objects, one character per object.\n*/\n\nclass WordTree\n{\n\t/**\n\t * WordTree Constructor\n\t */\n\tconstructor()\n\t{\n\t\tthis.ParseTree = {};\n\t}\n\t\n\t/** \n\t * Add a child character to a Parse Tree node\n\t * @method addChild\n\t * @param {Object} pTree - A parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - The index of the character in the pattern\n\t * @returns {Object} The resulting leaf node that was added (or found)\n\t * @private\n\t */\n\taddChild (pTree, pPattern, pIndex)\n\t{\n\t\tif (!pTree.hasOwnProperty(pPattern[pIndex]))\n\t\t\tpTree[pPattern[pIndex]] = {};\n\t\t\n\t\treturn pTree[pPattern[pIndex]];\n\t}\n\t\n\t/** Add a Pattern to the Parse Tree\n\t * @method addPattern\n\t * @param {Object} pPatternStart - The starting string for the pattern (e.g. \"${\")\n\t * @param {string} pPatternEnd - The ending string for the pattern (e.g. \"}\")\n\t * @param {number} pParser - The function to parse if this is the matched pattern, once the Pattern End is met. If this is a string, a simple replacement occurs.\n\t * @return {bool} True if adding the pattern was successful\n\t */\n\taddPattern (pPatternStart, pPatternEnd, pParser)\n\t{\n\t\tif (pPatternStart.length < 1)\n\t\t\treturn false;\n\n\t\tif ((typeof(pPatternEnd) === 'string') && (pPatternEnd.length < 1))\n\t\t\treturn false;\n\n\t\tlet tmpLeaf = this.ParseTree;\n\n\t\t// Add the tree of leaves iteratively\n\t\tfor (var i = 0; i < pPatternStart.length; i++)\n\t\t\ttmpLeaf = this.addChild(tmpLeaf, pPatternStart, i);\n\n\t\ttmpLeaf.PatternStart = pPatternStart;\n\t\ttmpLeaf.PatternEnd = ((typeof(pPatternEnd) === 'string') && (pPatternEnd.length > 0)) ? pPatternEnd : pPatternStart;\n\t\ttmpLeaf.Parse = (typeof(pParser) === 'function') ? pParser : \n\t\t\t\t\t\t(typeof(pParser) === 'string') ? () => { return pParser; } :\n\t\t\t\t\t\t(pData) => { return pData; };\n\n\t\treturn true;\n\t}\n}\n\nmodule.exports = WordTree;\n","// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n","var libNPMModuleWrapper = require('./Fable.js');\n\nif ((typeof(window) === 'object') && !window.hasOwnProperty('Fable'))\n{\n\twindow.Fable = libNPMModuleWrapper;\n}\n\nmodule.exports = libNPMModuleWrapper;","class FableUtility\n{\n\tconstructor(pFable)\n\t{\n\t\tthis.fable = pFable;\n\t}\n\n\t// Underscore and lodash both had a behavior, _.extend, which merged objects\n\t// Now that es6 gives us this, use the native thingy.\n\textend(pDestinationObject, ...pSourceObjects)\n\t{\n\t\treturn Object.assign(pDestinationObject, ...pSourceObjects);\n\t}\n}\n\nmodule.exports = FableUtility;","/**\n* Fable Application Services Support Library\n* @license MIT\n* @author <steven@velozo.com>\n*/\nconst libFableSettings = require('fable-settings').FableSettings;\nconst libFableUUID = require('fable-uuid').FableUUID;\nconst libFableLog = require('fable-log').FableLog;\n\nconst libFableUtility = require('./Fable-Utility.js')\n\nclass Fable\n{\n\tconstructor(pSettings)\n\t{\n\t\tlet tmpSettings = new libFableSettings(pSettings);\n\n\t\tthis.settingsManager = tmpSettings;\n\n\t\t// Instantiate the UUID generator\n\t\tthis.libUUID = new libFableUUID(this.settingsManager.settings);\n\n\t\tthis.log = new libFableLog(this.settingsManager.settings);\n\t\tthis.log.initialize();\n\n\t\tthis.Utility = new libFableUtility(this);\n\t}\n\n\tget settings()\n\t{\n\t\treturn this.settingsManager.settings;\n\t}\n\n\tget fable()\n\t{\n\t\treturn this;\n\t}\n\n\tgetUUID()\n\t{\n\t\treturn this.libUUID.getUUID();\n\t}\n}\n\nmodule.exports = Fable;"]}
1
+ {"version":3,"sources":["node_modules/browser-pack/_prelude.js","node_modules/fable-log/source/Fable-Log-BaseLogger.js","fable.min.js","node_modules/fable-log/source/Fable-Log-DefaultProviders-Web.js","node_modules/fable-log/source/Fable-Log-DefaultStreams.json","node_modules/fable-log/source/Fable-Log-Logger-Console.js","node_modules/fable-log/source/Fable-Log.js","node_modules/fable-settings/source/Fable-Settings-Default.json","node_modules/fable-settings/source/Fable-Settings-TemplateProcessor.js","node_modules/fable-settings/source/Fable-Settings.js","node_modules/fable-uuid/source/Fable-UUID-Random-Browser.js","node_modules/fable-uuid/source/Fable-UUID.js","node_modules/precedent/source/Precedent.js","node_modules/precedent/source/StringParser.js","node_modules/precedent/source/WordTree.js","node_modules/process/browser.js","source/Fable-Browser-Shim.js","source/Fable-Utility-Template.js","source/Fable-Utility.js","source/Fable.js"],"names":["f","exports","module","define","amd","window","global","self","this","Fable","r","e","n","t","o","i","c","require","u","a","Error","code","p","call","length","constructor","pLogStreamSettings","pFableLog","_Settings","loggerUUID","generateInsecureUUID","levels","tmpDate","Date","getTime","replace","pCharacter","tmpRandomData","Math","random","floor","toString","initialize","trace","pLogText","pLogObject","write","debug","info","warn","error","fatal","pLogLevel","getDefaultProviders","tmpDefaultProviders","console","default","loggertype","streamtype","level","libBaseLogger","super","_ShowTimeStamps","hasOwnProperty","showtimestamps","_FormattedTimeStamps","formattedtimestamps","_ContextMessage","Context","Product","_OutputLogLinesToConsole","outputloglinestoconsole","_OutputObjectsToConsole","outputobjectstoconsole","prefixCache","pLevel","pObject","tmpTimeStamp","toISOString","tmpLogLine","log","JSON","stringify","FableLog","pFableSettings","pFable","tmpSettings","_Providers","_StreamDefinitions","LogStreams","logStreams","logProviders","activeLogStreams","logStreamsTrace","logStreamsDebug","logStreamsInfo","logStreamsWarn","logStreamsError","logStreamsFatal","datumDecorator","pDatum","uuid","addLogger","pLogger","push","setDatumDecorator","fDatumDecorator","pMessage","tmpDecoratedDatum","tmpStreamDefinition","Object","assign","logTime","tmpMessage","tmpTime","getTimeStamp","getTimeDelta","pTimeStamp","logTimeDelta","pTimeDelta","tmpEndTime","logTimeDeltaHuman","tmpMs","parseInt","tmpSeconds","tmpMinutes","tmpHours","logTimeDeltaRelative","pStartTime","logTimeDeltaRelativeHuman","new","pSettings","ProductVersion","ConfigFile","process","pDependencies","templateProcessor","precedent","addPattern","pTemplateValue","tmpTemplateValue","trim","tmpSeparatorIndex","indexOf","tmpDefaultValue","substring","tmpEnvironmentVariableName","env","parseSetting","pString","parseString","_process","libPrecedent","libFableSettingsTemplateProcessor","FableSettings","dependencies","settingsTemplateProcessor","_configureEnvTemplating","buildDefaultSettings","merge","base","parse","DefaultConfigFile","pException","settings","_PerformEnvTemplating","NoEnvReplacement","_resolveEnv","tmpKey","_isObject","value","Array","isArray","_deepMergeObjects","toObject","fromObject","keys","forEach","key","fromValue","toValue","pSettingsFrom","pSettingsTo","tmpSettingsFrom","tmpSettingsTo","tmpSettingsFromCopy","fill","getRandomValues","crypto","bind","msCrypto","generateWhatWGBytes","tmpBuffer","Uint8Array","generateRandomBytes","tmpValue","generate","libRandomByteGenerator","FableUUID","_UUIDModeRandom","UUIDModeRandom","_UUIDLength","UUIDLength","_UUIDRandomDictionary","UUIDDictionary","randomByteGenerator","_HexLookup","substr","bytesToUUID","pBuffer","join","generateUUIDv4","tmpRandomBytes","generateRandom","tmpUUID","charAt","getUUID","libWordTree","libStringParser","WordTree","StringParser","ParseTree","pPatternStart","pPatternEnd","pParser","newParserState","pParseTree","Output","OutputBuffer","Pattern","PatternMatch","PatternMatchOutputBuffer","assignNode","pNode","pParserState","appendOutputBuffer","flushOutputBuffer","checkPatternEnd","PatternEnd","PatternStart","Parse","parseCharacter","tmpParserState","addChild","pTree","pPattern","pIndex","tmpLeaf","pData","cachedSetTimeout","cachedClearTimeout","defaultSetTimout","defaultClearTimeout","runTimeout","fun","setTimeout","clearTimeout","currentQueue","queue","draining","queueIndex","cleanUpNextTick","concat","drainQueue","timeout","len","run","marker","runClearTimeout","Item","array","noop","nextTick","args","arguments","prototype","apply","title","browser","argv","version","versions","on","addListener","once","off","removeListener","removeAllListeners","emit","prependListener","prependOnceListener","listeners","name","binding","cwd","chdir","dir","umask","libNPMModuleWrapper","pTemplateText","fable","Matchers","Evaluate","Interpolate","Escaper","Unescaper","GuaranteedNonMatch","templateEscapes","u2028","u2029","renderFunction","extend","pDestinationObject","pSourceObjects","renderTemplate","templateFunction","buildTemplateFunction","TemplateSource","pMatch","pCode","decodeURIComponent","Function","TemplateSourceCompiled","libFableUtilityTemplate","template","libFableSettings","libFableUUID","libFableLog","libFableUtility","settingsManager","libUUID","Utility"],"mappings":"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","file":"fable.min.js","sourcesContent":["(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()","/**\n* Base Logger Class\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*/\n\nclass BaseLogger\n{\n\tconstructor(pLogStreamSettings, pFableLog)\n\t{\n\t\t// This should not possibly be able to be instantiated without a settings object\n\t\tthis._Settings = pLogStreamSettings;\n\n\t\t// The base logger does nothing but associate a UUID with itself\n\t\t// We added this as the mechanism for tracking loggers to allow multiple simultaneous streams\n\t\t// to the same provider.\n\t\tthis.loggerUUID = this.generateInsecureUUID();\n\n\t\t// Eventually we can use this array to ompute which levels the provider allows.\n\t\t// For now it's just used to precompute some string concatenations.\n\t\tthis.levels = (\n\t\t\t[\n\t\t\t\t\"trace\",\n\t\t\t\t\"debug\",\n\t\t\t\t\"info\",\n\t\t\t\t\"warn\",\n\t\t\t\t\"error\",\n\t\t\t\t\"fatal\"\n\t\t\t]);\n\t}\n\n\t// This is meant to generate programmatically insecure UUIDs to identify loggers\n\tgenerateInsecureUUID()\n\t{\n\t\tlet tmpDate = new Date().getTime();\n\t\tlet tmpUUID = 'LOGSTREAM-xxxxxx-yxxxxx'.replace(/[xy]/g,\n\t\t\t\t(pCharacter) =>\n\t\t\t\t{\n\t\t\t\t\t// Funny algorithm from w3resource that is twister-ish without the deep math and security\n\t\t\t\t\t// ..but good enough for unique log stream identifiers\n\t\t\t\t\tlet tmpRandomData = (tmpDate + Math.random()*16)%16 | 0;\n\t\t\t\t\ttmpDate = Math.floor(tmpDate/16);\n\n\t\t\t\t\treturn (pCharacter =='x' ? tmpRandomData : (tmpRandomData&0x3|0x8)).toString(16);\n\t\t\t\t});\n\t\treturn tmpUUID;\n\t}\n\n\tinitialize()\n\t{\n\t\t// No operation.\n\t}\n\n\ttrace(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"trace\", pLogText, pLogObject);\n\t}\n\n\tdebug(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"debug\", pLogText, pLogObject);\n\t}\n\n\tinfo(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"info\", pLogText, pLogObject);\n\t}\n\n\twarn(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"warn\", pLogText, pLogObject);\n\t}\n\n\terror(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"error\", pLogText, pLogObject);\n\t}\n\n\tfatal(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"fatal\", pLogText, pLogObject);\n\t}\n\n\twrite(pLogLevel, pLogText, pLogObject)\n\t{\n\t\t// The base logger does nothing.\n\t\treturn true;\n\t}\n}\n\nmodule.exports = BaseLogger;\n","(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.Fable = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){\n/**\n* Base Logger Class\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*/\n\nclass BaseLogger\n{\n\tconstructor(pLogStreamSettings, pFableLog)\n\t{\n\t\t// This should not possibly be able to be instantiated without a settings object\n\t\tthis._Settings = pLogStreamSettings;\n\n\t\t// The base logger does nothing but associate a UUID with itself\n\t\t// We added this as the mechanism for tracking loggers to allow multiple simultaneous streams\n\t\t// to the same provider.\n\t\tthis.loggerUUID = this.generateInsecureUUID();\n\n\t\t// Eventually we can use this array to ompute which levels the provider allows.\n\t\t// For now it's just used to precompute some string concatenations.\n\t\tthis.levels = (\n\t\t\t[\n\t\t\t\t\"trace\",\n\t\t\t\t\"debug\",\n\t\t\t\t\"info\",\n\t\t\t\t\"warn\",\n\t\t\t\t\"error\",\n\t\t\t\t\"fatal\"\n\t\t\t]);\n\t}\n\n\t// This is meant to generate programmatically insecure UUIDs to identify loggers\n\tgenerateInsecureUUID()\n\t{\n\t\tlet tmpDate = new Date().getTime();\n\t\tlet tmpUUID = 'LOGSTREAM-xxxxxx-yxxxxx'.replace(/[xy]/g,\n\t\t\t\t(pCharacter) =>\n\t\t\t\t{\n\t\t\t\t\t// Funny algorithm from w3resource that is twister-ish without the deep math and security\n\t\t\t\t\t// ..but good enough for unique log stream identifiers\n\t\t\t\t\tlet tmpRandomData = (tmpDate + Math.random()*16)%16 | 0;\n\t\t\t\t\ttmpDate = Math.floor(tmpDate/16);\n\n\t\t\t\t\treturn (pCharacter =='x' ? tmpRandomData : (tmpRandomData&0x3|0x8)).toString(16);\n\t\t\t\t});\n\t\treturn tmpUUID;\n\t}\n\n\tinitialize()\n\t{\n\t\t// No operation.\n\t}\n\n\ttrace(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"trace\", pLogText, pLogObject);\n\t}\n\n\tdebug(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"debug\", pLogText, pLogObject);\n\t}\n\n\tinfo(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"info\", pLogText, pLogObject);\n\t}\n\n\twarn(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"warn\", pLogText, pLogObject);\n\t}\n\n\terror(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"error\", pLogText, pLogObject);\n\t}\n\n\tfatal(pLogText, pLogObject)\n\t{\n\t\tthis.write(\"fatal\", pLogText, pLogObject);\n\t}\n\n\twrite(pLogLevel, pLogText, pLogObject)\n\t{\n\t\t// The base logger does nothing.\n\t\treturn true;\n\t}\n}\n\nmodule.exports = BaseLogger;\n\n},{}],2:[function(require,module,exports){\n/**\n* Default Logger Provider Function\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*/\n\n// Return the providers that are available without extensions loaded\ngetDefaultProviders = () =>\n{\n\tlet tmpDefaultProviders = {};\n\n\ttmpDefaultProviders.console = require('./Fable-Log-Logger-Console.js');\n\n\ttmpDefaultProviders.default = tmpDefaultProviders.console;\n\n\treturn tmpDefaultProviders;\n}\n\nmodule.exports = getDefaultProviders();\n},{\"./Fable-Log-Logger-Console.js\":4}],3:[function(require,module,exports){\nmodule.exports=[\n {\n \"loggertype\": \"console\",\n \"streamtype\": \"console\",\n \"level\": \"trace\"\n }\n]\n},{}],4:[function(require,module,exports){\nlet libBaseLogger = require('./Fable-Log-BaseLogger.js');\n\nclass ConsoleLogger extends libBaseLogger\n{\n\tconstructor(pLogStreamSettings, pFableLog)\n\t{\n\t\tsuper(pLogStreamSettings);\n\n\t\tthis._ShowTimeStamps = pLogStreamSettings.hasOwnProperty('showtimestamps') ? (pLogStreamSettings.showtimestamps == true) : false;\n\t\tthis._FormattedTimeStamps = pLogStreamSettings.hasOwnProperty('formattedtimestamps') ? (pLogStreamSettings.formattedtimestamps == true) : false;\n\n\t\tthis._ContextMessage = pLogStreamSettings.hasOwnProperty('Context') ? `(${pLogStreamSettings.Context})` : \n\t\t\t\t\t\t\t\tpFableLog._Settings.hasOwnProperty('Product') ? `(${pFableLog._Settings.Product})` :\n\t\t\t\t\t\t\t\t'Unnamed_Log_Context';\n\n\t\t// Allow the user to decide what gets output to the console\n\t\tthis._OutputLogLinesToConsole = pLogStreamSettings.hasOwnProperty('outputloglinestoconsole') ? pLogStreamSettings.outputloglinestoconsole : true;\n\t\tthis._OutputObjectsToConsole = pLogStreamSettings.hasOwnProperty('outputobjectstoconsole') ? pLogStreamSettings.outputobjectstoconsole : true;\n\n\t\t// Precompute the prefix for each level\n\t\tthis.prefixCache = {};\n\t\tfor (let i = 0; i <= this.levels.length; i++)\n\t\t{\n\t\t\tthis.prefixCache[this.levels[i]] = `[${this.levels[i]}] ${this._ContextMessage}: `;\n\n\t\t\tif (this._ShowTimeStamps)\n\t\t\t{\n\t\t\t\t// If there is a timestamp we need a to prepend space before the prefixcache string, since the timestamp comes first\n\t\t\t\tthis.prefixCache[this.levels[i]] = ' '+this.prefixCache[this.levels[i]];\n\t\t\t}\n\t\t}\n\t}\n\n\twrite(pLevel, pLogText, pObject)\n\t{\n\t\tlet tmpTimeStamp = '';\n\t\tif (this._ShowTimeStamps && this._FormattedTimeStamps)\n\t\t{\n\t\t\ttmpTimeStamp = (new Date()).toISOString();\n\t\t}\n\t\telse if (this._ShowTimeStamps)\n\t\t{\n\t\t\ttmpTimeStamp = +new Date();\n\t\t}\n\n\t\tlet tmpLogLine = `${tmpTimeStamp}${this.prefixCache[pLevel]}${pLogText}`;\n\n\t\tif (this._OutputLogLinesToConsole)\n\t\t{\n\t\t\tconsole.log(tmpLogLine);\n\t\t}\n\n\t\t// Write out the object on a separate line if it is passed in\n\t\tif (this._OutputObjectsToConsole && (typeof(pObject) !== 'undefined'))\n\t\t{\n\t\t\tconsole.log(JSON.stringify(pObject, null, 2));\n\t\t}\n\n\t\t// Provide an easy way to be overridden and be consistent\n\t\treturn tmpLogLine;\n\t}\n}\n\nmodule.exports = ConsoleLogger;\n},{\"./Fable-Log-BaseLogger.js\":1}],5:[function(require,module,exports){\n/**\n* Fable Logging Add-on\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n* @module Fable Logger\n*/\n\n/**\n* Fable Solution Log Wrapper Main Class\n*\n* @class FableLog\n* @constructor\n*/\nclass FableLog\n{\n\tconstructor(pFableSettings, pFable)\n\t{\n\t\tlet tmpSettings = (typeof(pFableSettings) === 'object') ? pFableSettings : {}\n\t\tthis._Settings = tmpSettings;\n\n\t\tthis._Providers = require('./Fable-Log-DefaultProviders-Node.js');\n\n\t\tthis._StreamDefinitions = (tmpSettings.hasOwnProperty('LogStreams')) ? tmpSettings.LogStreams : require('./Fable-Log-DefaultStreams.json');\n\n\t\tthis.logStreams = [];\n\n\t\t// This object gets decorated for one-time instantiated providers that\n\t\t// have multiple outputs, such as bunyan.\n\t\tthis.logProviders = {};\n\n\t\t// A hash list of the GUIDs for each log stream, so they can't be added to the set more than one time\n\t\tthis.activeLogStreams = {};\n\n\t\tthis.logStreamsTrace = [];\n\t\tthis.logStreamsDebug = [];\n\t\tthis.logStreamsInfo = [];\n\t\tthis.logStreamsWarn = [];\n\t\tthis.logStreamsError = [];\n\t\tthis.logStreamsFatal = [];\n\n\t\tthis.datumDecorator = (pDatum) => pDatum;\n\n\t\tthis.uuid = (typeof(tmpSettings.Product) === 'string') ? tmpSettings.Product : 'Default';\n\t}\n\n\taddLogger(pLogger, pLevel)\n\t{\n\t\t// Bail out if we've already created one.\n\t\tif (this.activeLogStreams.hasOwnProperty(pLogger.loggerUUID))\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\t// Add it to the streams and to the mutex\n\t\tthis.logStreams.push(pLogger);\n\t\tthis.activeLogStreams[pLogger.loggerUUID] = true;\n\n\t\t// Make sure a kosher level was passed in\n\t\tswitch (pLevel)\n\t\t{\n\t\t\tcase 'trace':\n\t\t\t\tthis.logStreamsTrace.push(pLogger);\n\t\t\tcase 'debug':\n\t\t\t\tthis.logStreamsDebug.push(pLogger);\n\t\t\tcase 'info':\n\t\t\t\tthis.logStreamsInfo.push(pLogger);\n\t\t\tcase 'warn':\n\t\t\t\tthis.logStreamsWarn.push(pLogger);\n\t\t\tcase 'error':\n\t\t\t\tthis.logStreamsError.push(pLogger);\n\t\t\tcase 'fatal':\n\t\t\t\tthis.logStreamsFatal.push(pLogger);\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tsetDatumDecorator(fDatumDecorator)\n\t{\n\t\tif (typeof(fDatumDecorator) === 'function')\n\t\t{\n\t\t\tthis.datumDecorator = fDatumDecorator;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tthis.datumDecorator = (pDatum) => pDatum;\n\t\t}\n\t}\n\n\ttrace(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsTrace.length; i++)\n\t\t{\n\t\t\tthis.logStreamsTrace[i].trace(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\tdebug(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsDebug.length; i++)\n\t\t{\n\t\t\tthis.logStreamsDebug[i].debug(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\tinfo(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsInfo.length; i++)\n\t\t{\n\t\t\tthis.logStreamsInfo[i].info(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\twarn(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsWarn.length; i++)\n\t\t{\n\t\t\tthis.logStreamsWarn[i].warn(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\terror(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsError.length; i++)\n\t\t{\n\t\t\tthis.logStreamsError[i].error(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\tfatal(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsFatal.length; i++)\n\t\t{\n\t\t\tthis.logStreamsFatal[i].fatal(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\tinitialize()\n\t{\n\t\t// \"initialize\" each logger as defined in the logging parameters\n\t\tfor (let i = 0; i < this._StreamDefinitions.length; i++)\n\t\t{\n\t\t\tlet tmpStreamDefinition = Object.assign({loggertype:'default',streamtype:'console',level:'info'},this._StreamDefinitions[i]);\n\n\t\t\tif (!this._Providers.hasOwnProperty(tmpStreamDefinition.loggertype))\n\t\t\t{\n\t\t\t\tconsole.log(`Error initializing log stream: bad loggertype in stream definition ${JSON.stringify(tmpStreamDefinition)}`);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.addLogger(new this._Providers[tmpStreamDefinition.loggertype](tmpStreamDefinition, this), tmpStreamDefinition.level);\n\t\t\t}\n\t\t}\n\n\t\t// Now initialize each one.\n\t\tfor (let i = 0; i < this.logStreams.length; i++)\n\t\t{\n\t\t\tthis.logStreams[i].initialize();\n\t\t}\n\t}\n\n\tlogTime(pMessage, pDatum)\n\t{\n\t\tlet tmpMessage = (typeof(pMessage) !== 'undefined') ? pMessage : 'Time';\n\t\tlet tmpTime = new Date();\n\t\tthis.info(`${tmpMessage} ${tmpTime} (epoch ${+tmpTime})`, pDatum);\n\t}\n\n\t// Get a timestamp\n\tgetTimeStamp()\n\t{\n\t\treturn +new Date();\n\t}\n\n\tgetTimeDelta(pTimeStamp)\n\t{\n\t\tlet tmpEndTime = +new Date();\n\t\treturn tmpEndTime-pTimeStamp;\n\t}\n\n\t// Log the delta between a timestamp, and now with a message\n\tlogTimeDelta(pTimeDelta, pMessage, pDatum)\n\t{\n\t\tlet tmpMessage = (typeof(pMessage) !== 'undefined') ? pMessage : 'Time Measurement';\n\t\tlet tmpDatum = (typeof(pDatum) === 'object') ? pDatum : {};\n\n\t\tlet tmpEndTime = +new Date();\n\n\t\tthis.info(`${tmpMessage} logged at (epoch ${+tmpEndTime}) took (${pTimeDelta}ms)`, pDatum);\n\t}\n\n\tlogTimeDeltaHuman(pTimeDelta, pMessage, pDatum)\n\t{\n\t\tlet tmpMessage = (typeof(pMessage) !== 'undefined') ? pMessage : 'Time Measurement';\n\n\t\tlet tmpEndTime = +new Date();\n\n\t\tlet tmpMs = parseInt(pTimeDelta%1000);\n\t\tlet tmpSeconds = parseInt((pTimeDelta/1000)%60);\n\t\tlet tmpMinutes = parseInt((pTimeDelta/(1000*60))%60);\n\t\tlet tmpHours = parseInt(pTimeDelta/(1000*60*60));\n\n\t\ttmpMs = (tmpMs < 10) ? \"00\"+tmpMs : (tmpMs < 100) ? \"0\"+tmpMs : tmpMs;\n\t\ttmpSeconds = (tmpSeconds < 10) ? \"0\"+tmpSeconds : tmpSeconds;\n\t\ttmpMinutes = (tmpMinutes < 10) ? \"0\"+tmpMinutes : tmpMinutes;\n\t\ttmpHours = (tmpHours < 10) ? \"0\"+tmpHours : tmpHours;\n\n\t\tthis.info(`${tmpMessage} logged at (epoch ${+tmpEndTime}) took (${pTimeDelta}ms) or (${tmpHours}:${tmpMinutes}:${tmpSeconds}.${tmpMs})`, pDatum);\n\t}\n\n\tlogTimeDeltaRelative(pStartTime, pMessage, pDatum)\n\t{\n\t\tthis.logTimeDelta(this.getTimeDelta(pStartTime), pMessage, pDatum);\n\t}\n\n\tlogTimeDeltaRelativeHuman(pStartTime, pMessage, pDatum)\n\t{\n\t\tthis.logTimeDeltaHuman(this.getTimeDelta(pStartTime), pMessage, pDatum);\n\t}\n}\n\n// This is for backwards compatibility\nfunction autoConstruct(pSettings)\n{\n\treturn new FableLog(pSettings);\n}\n\n\nmodule.exports = {new:autoConstruct, FableLog:FableLog};\n\n},{\"./Fable-Log-DefaultProviders-Node.js\":2,\"./Fable-Log-DefaultStreams.json\":3}],6:[function(require,module,exports){\nmodule.exports={\n\t\"Product\": \"ApplicationNameHere\",\n\t\"ProductVersion\": \"0.0.0\",\n\n\t\"ConfigFile\": false,\n\n\t\"LogStreams\":\n\t[\n\t\t{\n\t\t\t\"level\": \"trace\"\n\t\t}\n\t]\n}\n\n},{}],7:[function(require,module,exports){\n(function (process){(function (){\n/**\n* Fable Settings Template Processor\n*\n* This class allows environment variables to come in via templated expressions, and defaults to be set.\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n* @module Fable Settings\n*/\n\nclass FableSettingsTemplateProcessor\n{\n\tconstructor(pDependencies)\n\t{\n // Use a no-dependencies templating engine to parse out environment variables\n\t\tthis.templateProcessor = new pDependencies.precedent();\n\n // TODO: Make the environment variable wrap expression demarcation characters configurable?\n\t\tthis.templateProcessor.addPattern('${', '}',\n\t\t\t(pTemplateValue)=>\n\t\t\t{\n\t\t\t\tlet tmpTemplateValue = pTemplateValue.trim();\n\n\t\t\t\tlet tmpSeparatorIndex = tmpTemplateValue.indexOf('|');\n\n\t\t\t\t// If there is no pipe, the default value will end up being whatever the variable name is.\n\t\t\t\tlet tmpDefaultValue = tmpTemplateValue.substring(tmpSeparatorIndex+1);\n\n\t\t\t\tlet tmpEnvironmentVariableName = (tmpSeparatorIndex > -1) ? tmpTemplateValue.substring(0, tmpSeparatorIndex) : tmpTemplateValue;\n\n\t\t\t\tif (process.env.hasOwnProperty(tmpEnvironmentVariableName))\n\t\t\t\t{\n\t\t\t\t\treturn process.env[tmpEnvironmentVariableName];\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn tmpDefaultValue;\n\t\t\t\t}\n\t\t\t});\n }\n\n parseSetting(pString)\n {\n return this.templateProcessor.parseString(pString);\n }\n}\n\nmodule.exports = FableSettingsTemplateProcessor;\n}).call(this)}).call(this,require('_process'))\n\n},{\"_process\":14}],8:[function(require,module,exports){\n/**\n* Fable Settings Add-on\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n* @module Fable Settings\n*/\n\nconst libPrecedent = require('precedent');\nconst libFableSettingsTemplateProcessor = require('./Fable-Settings-TemplateProcessor.js');\n\nclass FableSettings\n{\n\tconstructor(pFableSettings)\n\t{\n\t\t// Expose the dependencies for downstream re-use\n\t\tthis.dependencies = (\n\t\t\t{\n\t\t\t\tprecedent: libPrecedent\n\t\t\t});\n\n\t\t// Initialize the settings value template processor\n\t\tthis.settingsTemplateProcessor = new libFableSettingsTemplateProcessor(this.dependencies);\n\n\t\t// set straight away so anything that uses it respects the initial setting\n\t\tthis._configureEnvTemplating(pFableSettings);\n\n\t\tthis.default = this.buildDefaultSettings();\n\n\t\t// Construct a new settings object\n\t\tlet tmpSettings = this.merge(pFableSettings, this.buildDefaultSettings());\n\n\t\t// The base settings object (what they were on initialization, before other actors have altered them)\n\t\tthis.base = JSON.parse(JSON.stringify(tmpSettings));\n\n\t\tif (tmpSettings.DefaultConfigFile)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// If there is a DEFAULT configuration file, try to load and merge it.\n\t\t\t\ttmpSettings = this.merge(require(tmpSettings.DefaultConfigFile), tmpSettings);\n\t\t\t}\n\t\t\tcatch (pException)\n\t\t\t{\n\t\t\t\t// Why this? Often for an app we want settings to work out of the box, but\n\t\t\t\t// would potentially want to have a config file for complex settings.\n\t\t\t\tconsole.log('Fable-Settings Warning: Default configuration file specified but there was a problem loading it. Falling back to base.');\n\t\t\t\tconsole.log(' Loading Exception: '+pException);\n\t\t\t}\n\t\t}\n\n\t\tif (tmpSettings.ConfigFile)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// If there is a configuration file, try to load and merge it.\n\t\t\t\ttmpSettings = this.merge(require(tmpSettings.ConfigFile), tmpSettings);\n\t\t\t}\n\t\t\tcatch (pException)\n\t\t\t{\n\t\t\t\t// Why this? Often for an app we want settings to work out of the box, but\n\t\t\t\t// would potentially want to have a config file for complex settings.\n\t\t\t\tconsole.log('Fable-Settings Warning: Configuration file specified but there was a problem loading it. Falling back to base.');\n\t\t\t\tconsole.log(' Loading Exception: '+pException);\n\t\t\t}\n\t\t}\n\n\t\tthis.settings = tmpSettings;\n\t}\n\n\t// Build a default settings object. Use the JSON jimmy to ensure it is always a new object.\n\tbuildDefaultSettings()\n\t{\n\t\treturn JSON.parse(JSON.stringify(require('./Fable-Settings-Default')));\n\t}\n\n\t// Update the configuration for environment variable templating based on the current settings object\n\t_configureEnvTemplating(pSettings)\n\t{\n\t\t// default environment variable templating to on\n\t\tthis._PerformEnvTemplating = !pSettings || pSettings.NoEnvReplacement !== true;\n\t}\n\n\t// Resolve (recursive) any environment variables found in settings object.\n\t_resolveEnv(pSettings)\n\t{\n\t\tfor (const tmpKey in pSettings)\n\t\t{\n\t\t\tif (typeof(pSettings[tmpKey]) === 'object')\n\t\t\t{\n\t\t\t\tthis._resolveEnv(pSettings[tmpKey]);\n\t\t\t}\n\t\t\telse if (typeof(pSettings[tmpKey]) === 'string')\n\t\t\t{\n\t\t\t\tpSettings[tmpKey] = this.settingsTemplateProcessor.parseSetting(pSettings[tmpKey]);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Check to see if a value is an object (but not an array).\n\t */\n\t_isObject(value)\n\t{\n\t\treturn typeof(value) === 'object' && !Array.isArray(value);\n\t}\n\n\t/**\n\t * Merge two plain objects. Keys that are objects in both will be merged property-wise.\n\t */\n\t_deepMergeObjects(toObject, fromObject)\n\t{\n\t\tif (!fromObject || !this._isObject(fromObject))\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tObject.keys(fromObject).forEach((key) =>\n\t\t{\n\t\t\tconst fromValue = fromObject[key];\n\t\t\tif (this._isObject(fromValue))\n\t\t\t{\n\t\t\t\tconst toValue = toObject[key];\n\t\t\t\tif (toValue && this._isObject(toValue))\n\t\t\t\t{\n\t\t\t\t\t// both are objects, so do a recursive merge\n\t\t\t\t\tthis._deepMergeObjects(toValue, fromValue);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\ttoObject[key] = fromValue;\n\t\t});\n\t\treturn toObject;\n\t}\n\n\t// Merge some new object into the existing settings.\n\tmerge(pSettingsFrom, pSettingsTo)\n\t{\n\t\t// If an invalid settings from object is passed in (e.g. object constructor without passing in anything) this should still work\n\t\tlet tmpSettingsFrom = (typeof(pSettingsFrom) === 'object') ? pSettingsFrom : {};\n\t\t// Default to the settings object if none is passed in for the merge.\n\t\tlet tmpSettingsTo = (typeof(pSettingsTo) === 'object') ? pSettingsTo : this.settings;\n\n\t\t// do not mutate the From object property values\n\t\tlet tmpSettingsFromCopy = JSON.parse(JSON.stringify(tmpSettingsFrom));\n\t\ttmpSettingsTo = this._deepMergeObjects(tmpSettingsTo, tmpSettingsFromCopy);\n\n\t\tif (this._PerformEnvTemplating)\n\t\t{\n\t\t\tthis._resolveEnv(tmpSettingsTo);\n\t\t}\n\t\t// Update env tempating config, since we just updated the config object, and it may have changed\n\t\tthis._configureEnvTemplating(tmpSettingsTo);\n\n\t\treturn tmpSettingsTo;\n\t}\n\n\t// Fill in settings gaps without overwriting settings that are already there\n\tfill(pSettingsFrom)\n\t{\n\t\t// If an invalid settings from object is passed in (e.g. object constructor without passing in anything) this should still work\n\t\tlet tmpSettingsFrom = (typeof(pSettingsFrom) === 'object') ? pSettingsFrom : {};\n\n\t\t// do not mutate the From object property values\n\t\tlet tmpSettingsFromCopy = JSON.parse(JSON.stringify(tmpSettingsFrom));\n\n\t\tthis.settings = this._deepMergeObjects(tmpSettingsFromCopy, this.settings);\n\n\t\treturn this.settings;\n\t}\n};\n\n// This is for backwards compatibility\nfunction autoConstruct(pSettings)\n{\n\treturn new FableSettings(pSettings);\n}\n\nmodule.exports = {new:autoConstruct, FableSettings:FableSettings};\n},{\"./Fable-Settings-Default\":6,\"./Fable-Settings-TemplateProcessor.js\":7,\"precedent\":11}],9:[function(require,module,exports){\n/**\n* Random Byte Generator - Browser version\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*/\n\n// Adapted from node-uuid (https://github.com/kelektiv/node-uuid)\n// Unique ID creation requires a high quality random # generator. In the\n// browser this is a little complicated due to unknown quality of Math.random()\n// and inconsistent support for the `crypto` API. We do the best we can via\n// feature-detection\nclass RandomBytes\n{\n\tconstructor()\n\t{\n\n\t\t// getRandomValues needs to be invoked in a context where \"this\" is a Crypto\n\t\t// implementation. Also, find the complete implementation of crypto on IE11.\n\t\tthis.getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||\n \t\t(typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));\n\t}\n\n\t// WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto\n\tgenerateWhatWGBytes()\n\t{\n\t\tlet tmpBuffer = new Uint8Array(16); // eslint-disable-line no-undef\n\n\t\tthis.getRandomValues(tmpBuffer);\n\t\treturn tmpBuffer;\n\t}\n\n\t// Math.random()-based (RNG)\n\tgenerateRandomBytes()\n\t{\n\t\t// If all else fails, use Math.random(). It's fast, but is of unspecified\n\t\t// quality.\n\t\tlet tmpBuffer = new Uint8Array(16); // eslint-disable-line no-undef\n\n\t\tfor (let i = 0, tmpValue; i < 16; i++)\n\t\t{\n\t\t\tif ((i & 0x03) === 0)\n\t\t\t{\n\t\t\t\ttmpValue = Math.random() * 0x100000000;\n\t\t\t}\n\n\t\t\ttmpBuffer[i] = tmpValue >>> ((i & 0x03) << 3) & 0xff;\n\t\t}\n\n\t\treturn tmpBuffer;\n\t}\n\n\tgenerate()\n\t{\n\t\tif (this.getRandomValues)\n\t\t{\n\t\t\treturn this.generateWhatWGBytes();\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn this.generateRandomBytes();\n\t\t}\n\t}\n}\n\nmodule.exports = RandomBytes;\n\n},{}],10:[function(require,module,exports){\n/**\n* Fable UUID Generator\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n* @module Fable UUID\n*/\n\n/**\n* Fable Solution UUID Generation Main Class\n*\n* @class FableUUID\n* @constructor\n*/\n\nvar libRandomByteGenerator = require('./Fable-UUID-Random.js')\n\nclass FableUUID\n{\n\tconstructor(pSettings)\n\t{\n\t\t// Determine if the module is in \"Random UUID Mode\" which means just use the random character function rather than the v4 random UUID spec.\n\t\t// Note this allows UUIDs of various lengths (including very short ones) although guaranteed uniqueness goes downhill fast.\n\t\tthis._UUIDModeRandom = (typeof(pSettings) === 'object') && (pSettings.hasOwnProperty('UUIDModeRandom')) ? (pSettings.UUIDModeRandom == true) : false;\n\t\t// These two properties are only useful if we are in Random mode. Otherwise it generates a v4 spec\n\t\t// Length for \"Random UUID Mode\" is set -- if not set it to 8\n\t\tthis._UUIDLength = (typeof(pSettings) === 'object') && (pSettings.hasOwnProperty('UUIDLength')) ? (pSettings.UUIDLength + 0) : 8;\n\t\t// Dictionary for \"Random UUID Mode\"\n\t\tthis._UUIDRandomDictionary = (typeof(pSettings) === 'object') && (pSettings.hasOwnProperty('UUIDDictionary')) ? (pSettings.UUIDDictionary + 0) : '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n\n\t\tthis.randomByteGenerator = new libRandomByteGenerator();\n\n\t\t// Lookup table for hex codes\n\t\tthis._HexLookup = [];\n\t\tfor (let i = 0; i < 256; ++i)\n\t\t{\n\t\t\tthis._HexLookup[i] = (i + 0x100).toString(16).substr(1);\n\t\t}\n\t}\n\n\t// Adapted from node-uuid (https://github.com/kelektiv/node-uuid)\n\tbytesToUUID(pBuffer)\n\t{\n\t\tlet i = 0;\n\t\t// join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4\n\t\treturn ([\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], \n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], '-',\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], '-',\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], '-',\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], '-',\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]]\n\t\t\t\t]).join('');\n\t}\n\n\t// Adapted from node-uuid (https://github.com/kelektiv/node-uuid)\n\tgenerateUUIDv4()\n\t{\n\t\tlet tmpBuffer = new Array(16);\n\t\tvar tmpRandomBytes = this.randomByteGenerator.generate();\n\n\t\t// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n\t\ttmpRandomBytes[6] = (tmpRandomBytes[6] & 0x0f) | 0x40;\n\t\ttmpRandomBytes[8] = (tmpRandomBytes[8] & 0x3f) | 0x80;\n\n\t\treturn this.bytesToUUID(tmpRandomBytes);\n\t}\n\n\t// Simple random UUID generation\n\tgenerateRandom()\n\t{\n\t\tlet tmpUUID = '';\n\n\t\tfor (let i = 0; i < this._UUIDLength; i++)\n\t\t{\n\t\t\ttmpUUID += this._UUIDRandomDictionary.charAt(Math.floor(Math.random() * (this._UUIDRandomDictionary.length-1)));\n\t\t}\n\n\t\treturn tmpUUID;\n\t}\n\n\t// Adapted from node-uuid (https://github.com/kelektiv/node-uuid)\n\tgetUUID()\n\t{\n\t\tif (this._UUIDModeRandom)\n\t\t{\n\t\t\treturn this.generateRandom();\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn this.generateUUIDv4();\n\t\t}\n\t}\n}\n\n// This is for backwards compatibility\nfunction autoConstruct(pSettings)\n{\n\treturn new FableUUID(pSettings);\n}\n\n\nmodule.exports = {new:autoConstruct, FableUUID:FableUUID};\n\n},{\"./Fable-UUID-Random.js\":9}],11:[function(require,module,exports){\n/**\n* Precedent Meta-Templating\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Process text streams, parsing out meta-template expressions.\n*/\nvar libWordTree = require(`./WordTree.js`);\nvar libStringParser = require(`./StringParser.js`);\n\nclass Precedent\n{\n\t/**\n\t * Precedent Constructor\n\t */\n\tconstructor()\n\t{\n\t\tthis.WordTree = new libWordTree();\n\t\t\n\t\tthis.StringParser = new libStringParser();\n\n\t\tthis.ParseTree = this.WordTree.ParseTree;\n\t}\n\t\n\t/**\n\t * Add a Pattern to the Parse Tree\n\t * @method addPattern\n\t * @param {Object} pTree - A node on the parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - callback function\n\t * @return {bool} True if adding the pattern was successful\n\t */\n\taddPattern(pPatternStart, pPatternEnd, pParser)\n\t{\n\t\treturn this.WordTree.addPattern(pPatternStart, pPatternEnd, pParser);\n\t}\n\t\n\t/**\n\t * Parse a string with the existing parse tree\n\t * @method parseString\n\t * @param {string} pString - The string to parse\n\t * @return {string} The result from the parser\n\t */\n\tparseString(pString)\n\t{\n\t\treturn this.StringParser.parseString(pString, this.ParseTree);\n\t}\n}\n\nmodule.exports = Precedent;\n\n},{\"./StringParser.js\":12,\"./WordTree.js\":13}],12:[function(require,module,exports){\n/**\n* String Parser\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Parse a string, properly processing each matched token in the word tree.\n*/\n\nclass StringParser\n{\n\t/**\n\t * StringParser Constructor\n\t */\n\tconstructor()\n\t{\n\t}\n\t\n\t/**\n\t * Create a fresh parsing state object to work with.\n\t * @method newParserState\n\t * @param {Object} pParseTree - A node on the parse tree to begin parsing from (usually root)\n\t * @return {Object} A new parser state object for running a character parser on\n\t * @private\n\t */\n\tnewParserState (pParseTree)\n\t{\n\t\treturn (\n\t\t{\n\t\t\tParseTree: pParseTree,\n\n\t\t\tOutput: '',\n\t\t\tOutputBuffer: '',\n\n\t\t\tPattern: false,\n\n\t\t\tPatternMatch: false,\n\t\t\tPatternMatchOutputBuffer: ''\n\t\t});\n\t}\n\t\t\n\t/**\n\t * Assign a node of the parser tree to be the next potential match.\n\t * If the node has a PatternEnd property, it is a valid match and supercedes the last valid match (or becomes the initial match).\n\t * @method assignNode\n\t * @param {Object} pNode - A node on the parse tree to assign\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tassignNode (pNode, pParserState)\n\t{\n\t\tpParserState.PatternMatch = pNode;\n\n\t\t// If the pattern has a END we can assume it has a parse function...\n\t\tif (pParserState.PatternMatch.hasOwnProperty('PatternEnd'))\n\t\t{\n\t\t\t// ... this is the legitimate start of a pattern.\n\t\t\tpParserState.Pattern = pParserState.PatternMatch;\n\t\t}\n\t}\n\t\n\t/**\n\t * Append a character to the output buffer in the parser state.\n\t * This output buffer is used when a potential match is being explored, or a match is being explored.\n\t * @method appendOutputBuffer\n\t * @param {string} pCharacter - The character to append\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tappendOutputBuffer (pCharacter, pParserState)\n\t{\n\t\tpParserState.OutputBuffer += pCharacter;\n\t}\n\t\n\t/**\n\t * Flush the output buffer to the output and clear it.\n\t * @method flushOutputBuffer\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tflushOutputBuffer (pParserState)\n\t{\n\t\tpParserState.Output += pParserState.OutputBuffer;\n\t\tpParserState.OutputBuffer = '';\n\t}\n\n\t\n\t/**\n\t * Check if the pattern has ended. If it has, properly flush the buffer and start looking for new patterns.\n\t * @method checkPatternEnd\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tcheckPatternEnd (pParserState)\n\t{\n\t\tif ((pParserState.OutputBuffer.length >= pParserState.Pattern.PatternEnd.length+pParserState.Pattern.PatternStart.length) && \n\t\t\t(pParserState.OutputBuffer.substr(-pParserState.Pattern.PatternEnd.length) === pParserState.Pattern.PatternEnd))\n\t\t{\n\t\t\t// ... this is the end of a pattern, cut off the end tag and parse it.\n\t\t\t// Trim the start and end tags off the output buffer now\n\t\t\tpParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStart.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStart.length+pParserState.Pattern.PatternEnd.length)));\n\t\t\t// Flush the output buffer.\n\t\t\tthis.flushOutputBuffer(pParserState);\n\t\t\t// End pattern mode\n\t\t\tpParserState.Pattern = false;\n\t\t\tpParserState.PatternMatch = false;\n\t\t}\n\t}\n\t\n\t/**\n\t * Parse a character in the buffer.\n\t * @method parseCharacter\n\t * @param {string} pCharacter - The character to append\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tparseCharacter (pCharacter, pParserState)\n\t{\n\t\t// (1) If we aren't in a pattern match, and we aren't potentially matching, and this may be the start of a new pattern....\n\t\tif (!pParserState.PatternMatch && pParserState.ParseTree.hasOwnProperty(pCharacter))\n\t\t{\n\t\t\t// ... assign the node as the matched node.\n\t\t\tthis.assignNode(pParserState.ParseTree[pCharacter], pParserState);\n\t\t\tthis.appendOutputBuffer(pCharacter, pParserState);\n\t\t}\n\t\t// (2) If we are in a pattern match (actively seeing if this is part of a new pattern token)\n\t\telse if (pParserState.PatternMatch)\n\t\t{\n\t\t\t// If the pattern has a subpattern with this key\n\t\t\tif (pParserState.PatternMatch.hasOwnProperty(pCharacter))\n\t\t\t{\n\t\t\t\t// Continue matching patterns.\n\t\t\t\tthis.assignNode(pParserState.PatternMatch[pCharacter], pParserState);\n\t\t\t}\n\t\t\tthis.appendOutputBuffer(pCharacter, pParserState);\n\t\t\tif (pParserState.Pattern)\n\t\t\t{\n\t\t\t\t// ... Check if this is the end of the pattern (if we are matching a valid pattern)...\n\t\t\t\tthis.checkPatternEnd(pParserState);\n\t\t\t}\n\t\t}\n\t\t// (3) If we aren't in a pattern match or pattern, and this isn't the start of a new pattern (RAW mode)....\n\t\telse\n\t\t{\n\t\t\tpParserState.Output += pCharacter;\n\t\t}\n\t}\n\t\n\t/**\n\t * Parse a string for matches, and process any template segments that occur.\n\t * @method parseString\n\t * @param {string} pString - The string to parse.\n\t * @param {Object} pParseTree - The parse tree to begin parsing from (usually root)\n\t */\n\tparseString (pString, pParseTree)\n\t{\n\t\tlet tmpParserState = this.newParserState(pParseTree);\n\n\t\tfor (var i = 0; i < pString.length; i++)\n\t\t{\n\t\t\t// TODO: This is not fast.\n\t\t\tthis.parseCharacter(pString[i], tmpParserState);\n\t\t}\n\t\t\n\t\tthis.flushOutputBuffer(tmpParserState);\n\t\t\n\t\treturn tmpParserState.Output;\n\t}\n}\n\nmodule.exports = StringParser;\n\n},{}],13:[function(require,module,exports){\n/**\n* Word Tree\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Create a tree (directed graph) of Javascript objects, one character per object.\n*/\n\nclass WordTree\n{\n\t/**\n\t * WordTree Constructor\n\t */\n\tconstructor()\n\t{\n\t\tthis.ParseTree = {};\n\t}\n\t\n\t/** \n\t * Add a child character to a Parse Tree node\n\t * @method addChild\n\t * @param {Object} pTree - A parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - The index of the character in the pattern\n\t * @returns {Object} The resulting leaf node that was added (or found)\n\t * @private\n\t */\n\taddChild (pTree, pPattern, pIndex)\n\t{\n\t\tif (!pTree.hasOwnProperty(pPattern[pIndex]))\n\t\t\tpTree[pPattern[pIndex]] = {};\n\t\t\n\t\treturn pTree[pPattern[pIndex]];\n\t}\n\t\n\t/** Add a Pattern to the Parse Tree\n\t * @method addPattern\n\t * @param {Object} pPatternStart - The starting string for the pattern (e.g. \"${\")\n\t * @param {string} pPatternEnd - The ending string for the pattern (e.g. \"}\")\n\t * @param {number} pParser - The function to parse if this is the matched pattern, once the Pattern End is met. If this is a string, a simple replacement occurs.\n\t * @return {bool} True if adding the pattern was successful\n\t */\n\taddPattern (pPatternStart, pPatternEnd, pParser)\n\t{\n\t\tif (pPatternStart.length < 1)\n\t\t\treturn false;\n\n\t\tif ((typeof(pPatternEnd) === 'string') && (pPatternEnd.length < 1))\n\t\t\treturn false;\n\n\t\tlet tmpLeaf = this.ParseTree;\n\n\t\t// Add the tree of leaves iteratively\n\t\tfor (var i = 0; i < pPatternStart.length; i++)\n\t\t\ttmpLeaf = this.addChild(tmpLeaf, pPatternStart, i);\n\n\t\ttmpLeaf.PatternStart = pPatternStart;\n\t\ttmpLeaf.PatternEnd = ((typeof(pPatternEnd) === 'string') && (pPatternEnd.length > 0)) ? pPatternEnd : pPatternStart;\n\t\ttmpLeaf.Parse = (typeof(pParser) === 'function') ? pParser : \n\t\t\t\t\t\t(typeof(pParser) === 'string') ? () => { return pParser; } :\n\t\t\t\t\t\t(pData) => { return pData; };\n\n\t\treturn true;\n\t}\n}\n\nmodule.exports = WordTree;\n\n},{}],14:[function(require,module,exports){\n// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n},{}],15:[function(require,module,exports){\nvar libNPMModuleWrapper = require('./Fable.js');\n\nif ((typeof(window) === 'object') && !window.hasOwnProperty('Fable'))\n{\n\twindow.Fable = libNPMModuleWrapper;\n}\n\nmodule.exports = libNPMModuleWrapper;\n},{\"./Fable.js\":18}],16:[function(require,module,exports){\nclass FableUtility\n{\n\tconstructor(pFable, pTemplateText)\n\t{\n\t\tthis.fable = pFable;\n\n\t\t// These are the exact regex's used in lodash/underscore\n\t\t// TODO: Switch this to precedent\n\t\tthis.Matchers = (\n\t\t\t{\n\t\t Evaluate: /<%([\\s\\S]+?)%>/g,\n\t\t Interpolate: /<%=([\\s\\S]+?)%>/g,\n\t \t\tEscaper: /\\\\|'|\\r|\\n|\\t|\\u2028|\\u2029/g,\n\t \t\tUnescaper: /\\\\(\\\\|'|r|n|t|u2028|u2029)/g,\n\t\t\t\t// This is how underscore does it, so we are keeping it for now.\n\t \t\tGuaranteedNonMatch: /.^/\n\t\t });\n\n\t // This is a helper for the escaper and unescaper functions.\n\t // Right now we are going to keep what underscore is doing, but, not forever.\n\t this.templateEscapes = {\n\t '\\\\': '\\\\',\n\t \"'\": \"'\",\n\t 'r': '\\r',\n\t '\\r': 'r',\n\t 'n': '\\n',\n\t '\\n': 'n',\n\t 't': '\\t',\n\t '\\t': 't',\n\t 'u2028': '\\u2028',\n\t '\\u2028': 'u2028',\n\t 'u2029': '\\u2029',\n\t '\\u2029': 'u2029'\n\t };\n\n\t // This is defined as such to underscore that it is a dynamic programming\n\t // function on this class.\n\t this.renderFunction = ()=>{return ``};\n\t}\n\n\t// Underscore and lodash have a behavior, _.extend, which merges objects.\n\t// Now that es6 gives us this, use the native thingy.\n\textend(pDestinationObject, ...pSourceObjects)\n\t{\n\t\treturn Object.assign(pDestinationObject, ...pSourceObjects);\n\t}\n\n\trenderTemplate(pData)\n\t{\n\t\treturn this.renderFunction(pData);\n\t}\n\n\ttemplateFunction(pData)\n\t{\n\t\tlet fRenderTemplateBound = this.renderTemplate.bind(this);\n\t\treturn fRenderTemplateBound;\n\t}\n\n\t// Underscore and lodash have a behavior, _.template, which compiles a\n\t// string-based template with code snippets into simple executable pieces,\n\t// with the added twist of returning a precompiled function ready to go.\n\t//\n\t// NOTE: This does not implement underscore escape expressions\n\t// NOTE: This does not implement underscore magic browser variable assignment\n\t//\n\t// This is an implementation of that.\n\t// TODO: Make this use precedent, add configuration, add debugging.\n\tbuildTemplateFunction(pTemplateText, pData)\n {\n \t// For now this is being kept in a weird form ... this is to mimic the old\n \t// underscore code until this is rewritten using precedent.\n this.TemplateSource = \"__p+='\" + pTemplateText\n .replace(this.Matchers.Escaper,\n \t(pMatch)=>\n\t {\n\t return `\\\\${this.templateEscapes[pMatch]}`;\n\t })\n .replace(this.Matchers.Interpolate || this.Matchers.GuaranteedNonMatch,\n \t(pMatch, pCode) =>\n \t{\n\t return `'+\\n(${decodeURIComponent(pCode)})+\\n'`;\n\t })\n\t .replace(this.Matchers.Evaluate || this.Matchers.GuaranteedNonMatch,\n\t\t\t\t(pMatch, pCode) =>\n \t{\n\t return `';\\n${decodeURIComponent(pCode)}\\n;__p+='`;\n\t }) + `';\\n`;\n\n\n this.TemplateSource = `with(pTemplateDataObject||{}){\\n${this.TemplateSource}}\\n`;\n this.TemplateSource = `var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\\n${this.TemplateSource}return __p;\\n`;\n\n this.renderFunction = new Function('pTemplateDataObject', this.TemplateSource);\n\n if (typeof(pData) != 'undefined')\n {\n return this.renderFunction(pData);\n }\n\n // Provide the compiled function source as a convenience for build time\n // precompilation.\n this.TemplateSourceCompiled = 'function(obj){\\n' + this.TemplateSource + '}';\n\n return this.templateFunction();\n\t}\n}\n\nmodule.exports = FableUtility;\n},{}],17:[function(require,module,exports){\nconst libFableUtilityTemplate = require('./Fable-Utility-Template.js');\n\nclass FableUtility\n{\n\tconstructor(pFable)\n\t{\n\t\tthis.fable = pFable;\n\t}\n\n\t// Underscore and lodash have a behavior, _.extend, which merges objects.\n\t// Now that es6 gives us this, use the native thingy.\n\textend(pDestinationObject, ...pSourceObjects)\n\t{\n\t\treturn Object.assign(pDestinationObject, ...pSourceObjects);\n\t}\n\n\t// Underscore and lodash have a behavior, _.template, which compiles a\n\t// string-based template with code snippets into simple executable pieces,\n\t// with the added twist of returning a precompiled function ready to go.\n\ttemplate(pTemplateText, pData)\n\t{\n\t\tlet tmpTemplate = new libFableUtilityTemplate(this.fable, pTemplateText);\n\n\t\treturn tmpTemplate.buildTemplateFunction(pTemplateText, pData);\n\t}\n\n}\n\nmodule.exports = FableUtility;\n},{\"./Fable-Utility-Template.js\":16}],18:[function(require,module,exports){\n/**\n* Fable Application Services Support Library\n* @license MIT\n* @author <steven@velozo.com>\n*/\nconst libFableSettings = require('fable-settings').FableSettings;\nconst libFableUUID = require('fable-uuid').FableUUID;\nconst libFableLog = require('fable-log').FableLog;\n\nconst libFableUtility = require('./Fable-Utility.js')\n\nclass Fable\n{\n\tconstructor(pSettings)\n\t{\n\t\tlet tmpSettings = new libFableSettings(pSettings);\n\n\t\tthis.settingsManager = tmpSettings;\n\n\t\t// Instantiate the UUID generator\n\t\tthis.libUUID = new libFableUUID(this.settingsManager.settings);\n\n\t\tthis.log = new libFableLog(this.settingsManager.settings);\n\t\tthis.log.initialize();\n\n\t\tthis.Utility = new libFableUtility(this);\n\t}\n\n\tget settings()\n\t{\n\t\treturn this.settingsManager.settings;\n\t}\n\n\tget fable()\n\t{\n\t\treturn this;\n\t}\n\n\tgetUUID()\n\t{\n\t\treturn this.libUUID.getUUID();\n\t}\n}\n\nmodule.exports = Fable;\n},{\"./Fable-Utility.js\":17,\"fable-log\":5,\"fable-settings\":8,\"fable-uuid\":10}]},{},[15])(15)\n});\n\n","/**\n* Default Logger Provider Function\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*/\n\n// Return the providers that are available without extensions loaded\ngetDefaultProviders = () =>\n{\n\tlet tmpDefaultProviders = {};\n\n\ttmpDefaultProviders.console = require('./Fable-Log-Logger-Console.js');\n\n\ttmpDefaultProviders.default = tmpDefaultProviders.console;\n\n\treturn tmpDefaultProviders;\n}\n\nmodule.exports = getDefaultProviders();","module.exports=[\n {\n \"loggertype\": \"console\",\n \"streamtype\": \"console\",\n \"level\": \"trace\"\n }\n]","let libBaseLogger = require('./Fable-Log-BaseLogger.js');\n\nclass ConsoleLogger extends libBaseLogger\n{\n\tconstructor(pLogStreamSettings, pFableLog)\n\t{\n\t\tsuper(pLogStreamSettings);\n\n\t\tthis._ShowTimeStamps = pLogStreamSettings.hasOwnProperty('showtimestamps') ? (pLogStreamSettings.showtimestamps == true) : false;\n\t\tthis._FormattedTimeStamps = pLogStreamSettings.hasOwnProperty('formattedtimestamps') ? (pLogStreamSettings.formattedtimestamps == true) : false;\n\n\t\tthis._ContextMessage = pLogStreamSettings.hasOwnProperty('Context') ? `(${pLogStreamSettings.Context})` : \n\t\t\t\t\t\t\t\tpFableLog._Settings.hasOwnProperty('Product') ? `(${pFableLog._Settings.Product})` :\n\t\t\t\t\t\t\t\t'Unnamed_Log_Context';\n\n\t\t// Allow the user to decide what gets output to the console\n\t\tthis._OutputLogLinesToConsole = pLogStreamSettings.hasOwnProperty('outputloglinestoconsole') ? pLogStreamSettings.outputloglinestoconsole : true;\n\t\tthis._OutputObjectsToConsole = pLogStreamSettings.hasOwnProperty('outputobjectstoconsole') ? pLogStreamSettings.outputobjectstoconsole : true;\n\n\t\t// Precompute the prefix for each level\n\t\tthis.prefixCache = {};\n\t\tfor (let i = 0; i <= this.levels.length; i++)\n\t\t{\n\t\t\tthis.prefixCache[this.levels[i]] = `[${this.levels[i]}] ${this._ContextMessage}: `;\n\n\t\t\tif (this._ShowTimeStamps)\n\t\t\t{\n\t\t\t\t// If there is a timestamp we need a to prepend space before the prefixcache string, since the timestamp comes first\n\t\t\t\tthis.prefixCache[this.levels[i]] = ' '+this.prefixCache[this.levels[i]];\n\t\t\t}\n\t\t}\n\t}\n\n\twrite(pLevel, pLogText, pObject)\n\t{\n\t\tlet tmpTimeStamp = '';\n\t\tif (this._ShowTimeStamps && this._FormattedTimeStamps)\n\t\t{\n\t\t\ttmpTimeStamp = (new Date()).toISOString();\n\t\t}\n\t\telse if (this._ShowTimeStamps)\n\t\t{\n\t\t\ttmpTimeStamp = +new Date();\n\t\t}\n\n\t\tlet tmpLogLine = `${tmpTimeStamp}${this.prefixCache[pLevel]}${pLogText}`;\n\n\t\tif (this._OutputLogLinesToConsole)\n\t\t{\n\t\t\tconsole.log(tmpLogLine);\n\t\t}\n\n\t\t// Write out the object on a separate line if it is passed in\n\t\tif (this._OutputObjectsToConsole && (typeof(pObject) !== 'undefined'))\n\t\t{\n\t\t\tconsole.log(JSON.stringify(pObject, null, 2));\n\t\t}\n\n\t\t// Provide an easy way to be overridden and be consistent\n\t\treturn tmpLogLine;\n\t}\n}\n\nmodule.exports = ConsoleLogger;","/**\n* Fable Logging Add-on\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n* @module Fable Logger\n*/\n\n/**\n* Fable Solution Log Wrapper Main Class\n*\n* @class FableLog\n* @constructor\n*/\nclass FableLog\n{\n\tconstructor(pFableSettings, pFable)\n\t{\n\t\tlet tmpSettings = (typeof(pFableSettings) === 'object') ? pFableSettings : {}\n\t\tthis._Settings = tmpSettings;\n\n\t\tthis._Providers = require('./Fable-Log-DefaultProviders-Node.js');\n\n\t\tthis._StreamDefinitions = (tmpSettings.hasOwnProperty('LogStreams')) ? tmpSettings.LogStreams : require('./Fable-Log-DefaultStreams.json');\n\n\t\tthis.logStreams = [];\n\n\t\t// This object gets decorated for one-time instantiated providers that\n\t\t// have multiple outputs, such as bunyan.\n\t\tthis.logProviders = {};\n\n\t\t// A hash list of the GUIDs for each log stream, so they can't be added to the set more than one time\n\t\tthis.activeLogStreams = {};\n\n\t\tthis.logStreamsTrace = [];\n\t\tthis.logStreamsDebug = [];\n\t\tthis.logStreamsInfo = [];\n\t\tthis.logStreamsWarn = [];\n\t\tthis.logStreamsError = [];\n\t\tthis.logStreamsFatal = [];\n\n\t\tthis.datumDecorator = (pDatum) => pDatum;\n\n\t\tthis.uuid = (typeof(tmpSettings.Product) === 'string') ? tmpSettings.Product : 'Default';\n\t}\n\n\taddLogger(pLogger, pLevel)\n\t{\n\t\t// Bail out if we've already created one.\n\t\tif (this.activeLogStreams.hasOwnProperty(pLogger.loggerUUID))\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\t// Add it to the streams and to the mutex\n\t\tthis.logStreams.push(pLogger);\n\t\tthis.activeLogStreams[pLogger.loggerUUID] = true;\n\n\t\t// Make sure a kosher level was passed in\n\t\tswitch (pLevel)\n\t\t{\n\t\t\tcase 'trace':\n\t\t\t\tthis.logStreamsTrace.push(pLogger);\n\t\t\tcase 'debug':\n\t\t\t\tthis.logStreamsDebug.push(pLogger);\n\t\t\tcase 'info':\n\t\t\t\tthis.logStreamsInfo.push(pLogger);\n\t\t\tcase 'warn':\n\t\t\t\tthis.logStreamsWarn.push(pLogger);\n\t\t\tcase 'error':\n\t\t\t\tthis.logStreamsError.push(pLogger);\n\t\t\tcase 'fatal':\n\t\t\t\tthis.logStreamsFatal.push(pLogger);\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tsetDatumDecorator(fDatumDecorator)\n\t{\n\t\tif (typeof(fDatumDecorator) === 'function')\n\t\t{\n\t\t\tthis.datumDecorator = fDatumDecorator;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tthis.datumDecorator = (pDatum) => pDatum;\n\t\t}\n\t}\n\n\ttrace(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsTrace.length; i++)\n\t\t{\n\t\t\tthis.logStreamsTrace[i].trace(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\tdebug(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsDebug.length; i++)\n\t\t{\n\t\t\tthis.logStreamsDebug[i].debug(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\tinfo(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsInfo.length; i++)\n\t\t{\n\t\t\tthis.logStreamsInfo[i].info(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\twarn(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsWarn.length; i++)\n\t\t{\n\t\t\tthis.logStreamsWarn[i].warn(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\terror(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsError.length; i++)\n\t\t{\n\t\t\tthis.logStreamsError[i].error(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\tfatal(pMessage, pDatum)\n\t{\n\t\tconst tmpDecoratedDatum = this.datumDecorator(pDatum);\n\t\tfor (let i = 0; i < this.logStreamsFatal.length; i++)\n\t\t{\n\t\t\tthis.logStreamsFatal[i].fatal(pMessage, tmpDecoratedDatum);\n\t\t}\n\t}\n\n\tinitialize()\n\t{\n\t\t// \"initialize\" each logger as defined in the logging parameters\n\t\tfor (let i = 0; i < this._StreamDefinitions.length; i++)\n\t\t{\n\t\t\tlet tmpStreamDefinition = Object.assign({loggertype:'default',streamtype:'console',level:'info'},this._StreamDefinitions[i]);\n\n\t\t\tif (!this._Providers.hasOwnProperty(tmpStreamDefinition.loggertype))\n\t\t\t{\n\t\t\t\tconsole.log(`Error initializing log stream: bad loggertype in stream definition ${JSON.stringify(tmpStreamDefinition)}`);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.addLogger(new this._Providers[tmpStreamDefinition.loggertype](tmpStreamDefinition, this), tmpStreamDefinition.level);\n\t\t\t}\n\t\t}\n\n\t\t// Now initialize each one.\n\t\tfor (let i = 0; i < this.logStreams.length; i++)\n\t\t{\n\t\t\tthis.logStreams[i].initialize();\n\t\t}\n\t}\n\n\tlogTime(pMessage, pDatum)\n\t{\n\t\tlet tmpMessage = (typeof(pMessage) !== 'undefined') ? pMessage : 'Time';\n\t\tlet tmpTime = new Date();\n\t\tthis.info(`${tmpMessage} ${tmpTime} (epoch ${+tmpTime})`, pDatum);\n\t}\n\n\t// Get a timestamp\n\tgetTimeStamp()\n\t{\n\t\treturn +new Date();\n\t}\n\n\tgetTimeDelta(pTimeStamp)\n\t{\n\t\tlet tmpEndTime = +new Date();\n\t\treturn tmpEndTime-pTimeStamp;\n\t}\n\n\t// Log the delta between a timestamp, and now with a message\n\tlogTimeDelta(pTimeDelta, pMessage, pDatum)\n\t{\n\t\tlet tmpMessage = (typeof(pMessage) !== 'undefined') ? pMessage : 'Time Measurement';\n\t\tlet tmpDatum = (typeof(pDatum) === 'object') ? pDatum : {};\n\n\t\tlet tmpEndTime = +new Date();\n\n\t\tthis.info(`${tmpMessage} logged at (epoch ${+tmpEndTime}) took (${pTimeDelta}ms)`, pDatum);\n\t}\n\n\tlogTimeDeltaHuman(pTimeDelta, pMessage, pDatum)\n\t{\n\t\tlet tmpMessage = (typeof(pMessage) !== 'undefined') ? pMessage : 'Time Measurement';\n\n\t\tlet tmpEndTime = +new Date();\n\n\t\tlet tmpMs = parseInt(pTimeDelta%1000);\n\t\tlet tmpSeconds = parseInt((pTimeDelta/1000)%60);\n\t\tlet tmpMinutes = parseInt((pTimeDelta/(1000*60))%60);\n\t\tlet tmpHours = parseInt(pTimeDelta/(1000*60*60));\n\n\t\ttmpMs = (tmpMs < 10) ? \"00\"+tmpMs : (tmpMs < 100) ? \"0\"+tmpMs : tmpMs;\n\t\ttmpSeconds = (tmpSeconds < 10) ? \"0\"+tmpSeconds : tmpSeconds;\n\t\ttmpMinutes = (tmpMinutes < 10) ? \"0\"+tmpMinutes : tmpMinutes;\n\t\ttmpHours = (tmpHours < 10) ? \"0\"+tmpHours : tmpHours;\n\n\t\tthis.info(`${tmpMessage} logged at (epoch ${+tmpEndTime}) took (${pTimeDelta}ms) or (${tmpHours}:${tmpMinutes}:${tmpSeconds}.${tmpMs})`, pDatum);\n\t}\n\n\tlogTimeDeltaRelative(pStartTime, pMessage, pDatum)\n\t{\n\t\tthis.logTimeDelta(this.getTimeDelta(pStartTime), pMessage, pDatum);\n\t}\n\n\tlogTimeDeltaRelativeHuman(pStartTime, pMessage, pDatum)\n\t{\n\t\tthis.logTimeDeltaHuman(this.getTimeDelta(pStartTime), pMessage, pDatum);\n\t}\n}\n\n// This is for backwards compatibility\nfunction autoConstruct(pSettings)\n{\n\treturn new FableLog(pSettings);\n}\n\n\nmodule.exports = {new:autoConstruct, FableLog:FableLog};\n","module.exports={\n\t\"Product\": \"ApplicationNameHere\",\n\t\"ProductVersion\": \"0.0.0\",\n\n\t\"ConfigFile\": false,\n\n\t\"LogStreams\":\n\t[\n\t\t{\n\t\t\t\"level\": \"trace\"\n\t\t}\n\t]\n}\n","/**\n* Fable Settings Template Processor\n*\n* This class allows environment variables to come in via templated expressions, and defaults to be set.\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n* @module Fable Settings\n*/\n\nclass FableSettingsTemplateProcessor\n{\n\tconstructor(pDependencies)\n\t{\n // Use a no-dependencies templating engine to parse out environment variables\n\t\tthis.templateProcessor = new pDependencies.precedent();\n\n // TODO: Make the environment variable wrap expression demarcation characters configurable?\n\t\tthis.templateProcessor.addPattern('${', '}',\n\t\t\t(pTemplateValue)=>\n\t\t\t{\n\t\t\t\tlet tmpTemplateValue = pTemplateValue.trim();\n\n\t\t\t\tlet tmpSeparatorIndex = tmpTemplateValue.indexOf('|');\n\n\t\t\t\t// If there is no pipe, the default value will end up being whatever the variable name is.\n\t\t\t\tlet tmpDefaultValue = tmpTemplateValue.substring(tmpSeparatorIndex+1);\n\n\t\t\t\tlet tmpEnvironmentVariableName = (tmpSeparatorIndex > -1) ? tmpTemplateValue.substring(0, tmpSeparatorIndex) : tmpTemplateValue;\n\n\t\t\t\tif (process.env.hasOwnProperty(tmpEnvironmentVariableName))\n\t\t\t\t{\n\t\t\t\t\treturn process.env[tmpEnvironmentVariableName];\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn tmpDefaultValue;\n\t\t\t\t}\n\t\t\t});\n }\n\n parseSetting(pString)\n {\n return this.templateProcessor.parseString(pString);\n }\n}\n\nmodule.exports = FableSettingsTemplateProcessor;","/**\n* Fable Settings Add-on\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n* @module Fable Settings\n*/\n\nconst libPrecedent = require('precedent');\nconst libFableSettingsTemplateProcessor = require('./Fable-Settings-TemplateProcessor.js');\n\nclass FableSettings\n{\n\tconstructor(pFableSettings)\n\t{\n\t\t// Expose the dependencies for downstream re-use\n\t\tthis.dependencies = (\n\t\t\t{\n\t\t\t\tprecedent: libPrecedent\n\t\t\t});\n\n\t\t// Initialize the settings value template processor\n\t\tthis.settingsTemplateProcessor = new libFableSettingsTemplateProcessor(this.dependencies);\n\n\t\t// set straight away so anything that uses it respects the initial setting\n\t\tthis._configureEnvTemplating(pFableSettings);\n\n\t\tthis.default = this.buildDefaultSettings();\n\n\t\t// Construct a new settings object\n\t\tlet tmpSettings = this.merge(pFableSettings, this.buildDefaultSettings());\n\n\t\t// The base settings object (what they were on initialization, before other actors have altered them)\n\t\tthis.base = JSON.parse(JSON.stringify(tmpSettings));\n\n\t\tif (tmpSettings.DefaultConfigFile)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// If there is a DEFAULT configuration file, try to load and merge it.\n\t\t\t\ttmpSettings = this.merge(require(tmpSettings.DefaultConfigFile), tmpSettings);\n\t\t\t}\n\t\t\tcatch (pException)\n\t\t\t{\n\t\t\t\t// Why this? Often for an app we want settings to work out of the box, but\n\t\t\t\t// would potentially want to have a config file for complex settings.\n\t\t\t\tconsole.log('Fable-Settings Warning: Default configuration file specified but there was a problem loading it. Falling back to base.');\n\t\t\t\tconsole.log(' Loading Exception: '+pException);\n\t\t\t}\n\t\t}\n\n\t\tif (tmpSettings.ConfigFile)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// If there is a configuration file, try to load and merge it.\n\t\t\t\ttmpSettings = this.merge(require(tmpSettings.ConfigFile), tmpSettings);\n\t\t\t}\n\t\t\tcatch (pException)\n\t\t\t{\n\t\t\t\t// Why this? Often for an app we want settings to work out of the box, but\n\t\t\t\t// would potentially want to have a config file for complex settings.\n\t\t\t\tconsole.log('Fable-Settings Warning: Configuration file specified but there was a problem loading it. Falling back to base.');\n\t\t\t\tconsole.log(' Loading Exception: '+pException);\n\t\t\t}\n\t\t}\n\n\t\tthis.settings = tmpSettings;\n\t}\n\n\t// Build a default settings object. Use the JSON jimmy to ensure it is always a new object.\n\tbuildDefaultSettings()\n\t{\n\t\treturn JSON.parse(JSON.stringify(require('./Fable-Settings-Default')));\n\t}\n\n\t// Update the configuration for environment variable templating based on the current settings object\n\t_configureEnvTemplating(pSettings)\n\t{\n\t\t// default environment variable templating to on\n\t\tthis._PerformEnvTemplating = !pSettings || pSettings.NoEnvReplacement !== true;\n\t}\n\n\t// Resolve (recursive) any environment variables found in settings object.\n\t_resolveEnv(pSettings)\n\t{\n\t\tfor (const tmpKey in pSettings)\n\t\t{\n\t\t\tif (typeof(pSettings[tmpKey]) === 'object')\n\t\t\t{\n\t\t\t\tthis._resolveEnv(pSettings[tmpKey]);\n\t\t\t}\n\t\t\telse if (typeof(pSettings[tmpKey]) === 'string')\n\t\t\t{\n\t\t\t\tpSettings[tmpKey] = this.settingsTemplateProcessor.parseSetting(pSettings[tmpKey]);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Check to see if a value is an object (but not an array).\n\t */\n\t_isObject(value)\n\t{\n\t\treturn typeof(value) === 'object' && !Array.isArray(value);\n\t}\n\n\t/**\n\t * Merge two plain objects. Keys that are objects in both will be merged property-wise.\n\t */\n\t_deepMergeObjects(toObject, fromObject)\n\t{\n\t\tif (!fromObject || !this._isObject(fromObject))\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tObject.keys(fromObject).forEach((key) =>\n\t\t{\n\t\t\tconst fromValue = fromObject[key];\n\t\t\tif (this._isObject(fromValue))\n\t\t\t{\n\t\t\t\tconst toValue = toObject[key];\n\t\t\t\tif (toValue && this._isObject(toValue))\n\t\t\t\t{\n\t\t\t\t\t// both are objects, so do a recursive merge\n\t\t\t\t\tthis._deepMergeObjects(toValue, fromValue);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\ttoObject[key] = fromValue;\n\t\t});\n\t\treturn toObject;\n\t}\n\n\t// Merge some new object into the existing settings.\n\tmerge(pSettingsFrom, pSettingsTo)\n\t{\n\t\t// If an invalid settings from object is passed in (e.g. object constructor without passing in anything) this should still work\n\t\tlet tmpSettingsFrom = (typeof(pSettingsFrom) === 'object') ? pSettingsFrom : {};\n\t\t// Default to the settings object if none is passed in for the merge.\n\t\tlet tmpSettingsTo = (typeof(pSettingsTo) === 'object') ? pSettingsTo : this.settings;\n\n\t\t// do not mutate the From object property values\n\t\tlet tmpSettingsFromCopy = JSON.parse(JSON.stringify(tmpSettingsFrom));\n\t\ttmpSettingsTo = this._deepMergeObjects(tmpSettingsTo, tmpSettingsFromCopy);\n\n\t\tif (this._PerformEnvTemplating)\n\t\t{\n\t\t\tthis._resolveEnv(tmpSettingsTo);\n\t\t}\n\t\t// Update env tempating config, since we just updated the config object, and it may have changed\n\t\tthis._configureEnvTemplating(tmpSettingsTo);\n\n\t\treturn tmpSettingsTo;\n\t}\n\n\t// Fill in settings gaps without overwriting settings that are already there\n\tfill(pSettingsFrom)\n\t{\n\t\t// If an invalid settings from object is passed in (e.g. object constructor without passing in anything) this should still work\n\t\tlet tmpSettingsFrom = (typeof(pSettingsFrom) === 'object') ? pSettingsFrom : {};\n\n\t\t// do not mutate the From object property values\n\t\tlet tmpSettingsFromCopy = JSON.parse(JSON.stringify(tmpSettingsFrom));\n\n\t\tthis.settings = this._deepMergeObjects(tmpSettingsFromCopy, this.settings);\n\n\t\treturn this.settings;\n\t}\n};\n\n// This is for backwards compatibility\nfunction autoConstruct(pSettings)\n{\n\treturn new FableSettings(pSettings);\n}\n\nmodule.exports = {new:autoConstruct, FableSettings:FableSettings};","/**\n* Random Byte Generator - Browser version\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*/\n\n// Adapted from node-uuid (https://github.com/kelektiv/node-uuid)\n// Unique ID creation requires a high quality random # generator. In the\n// browser this is a little complicated due to unknown quality of Math.random()\n// and inconsistent support for the `crypto` API. We do the best we can via\n// feature-detection\nclass RandomBytes\n{\n\tconstructor()\n\t{\n\n\t\t// getRandomValues needs to be invoked in a context where \"this\" is a Crypto\n\t\t// implementation. Also, find the complete implementation of crypto on IE11.\n\t\tthis.getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||\n \t\t(typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));\n\t}\n\n\t// WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto\n\tgenerateWhatWGBytes()\n\t{\n\t\tlet tmpBuffer = new Uint8Array(16); // eslint-disable-line no-undef\n\n\t\tthis.getRandomValues(tmpBuffer);\n\t\treturn tmpBuffer;\n\t}\n\n\t// Math.random()-based (RNG)\n\tgenerateRandomBytes()\n\t{\n\t\t// If all else fails, use Math.random(). It's fast, but is of unspecified\n\t\t// quality.\n\t\tlet tmpBuffer = new Uint8Array(16); // eslint-disable-line no-undef\n\n\t\tfor (let i = 0, tmpValue; i < 16; i++)\n\t\t{\n\t\t\tif ((i & 0x03) === 0)\n\t\t\t{\n\t\t\t\ttmpValue = Math.random() * 0x100000000;\n\t\t\t}\n\n\t\t\ttmpBuffer[i] = tmpValue >>> ((i & 0x03) << 3) & 0xff;\n\t\t}\n\n\t\treturn tmpBuffer;\n\t}\n\n\tgenerate()\n\t{\n\t\tif (this.getRandomValues)\n\t\t{\n\t\t\treturn this.generateWhatWGBytes();\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn this.generateRandomBytes();\n\t\t}\n\t}\n}\n\nmodule.exports = RandomBytes;\n","/**\n* Fable UUID Generator\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n* @module Fable UUID\n*/\n\n/**\n* Fable Solution UUID Generation Main Class\n*\n* @class FableUUID\n* @constructor\n*/\n\nvar libRandomByteGenerator = require('./Fable-UUID-Random.js')\n\nclass FableUUID\n{\n\tconstructor(pSettings)\n\t{\n\t\t// Determine if the module is in \"Random UUID Mode\" which means just use the random character function rather than the v4 random UUID spec.\n\t\t// Note this allows UUIDs of various lengths (including very short ones) although guaranteed uniqueness goes downhill fast.\n\t\tthis._UUIDModeRandom = (typeof(pSettings) === 'object') && (pSettings.hasOwnProperty('UUIDModeRandom')) ? (pSettings.UUIDModeRandom == true) : false;\n\t\t// These two properties are only useful if we are in Random mode. Otherwise it generates a v4 spec\n\t\t// Length for \"Random UUID Mode\" is set -- if not set it to 8\n\t\tthis._UUIDLength = (typeof(pSettings) === 'object') && (pSettings.hasOwnProperty('UUIDLength')) ? (pSettings.UUIDLength + 0) : 8;\n\t\t// Dictionary for \"Random UUID Mode\"\n\t\tthis._UUIDRandomDictionary = (typeof(pSettings) === 'object') && (pSettings.hasOwnProperty('UUIDDictionary')) ? (pSettings.UUIDDictionary + 0) : '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n\n\t\tthis.randomByteGenerator = new libRandomByteGenerator();\n\n\t\t// Lookup table for hex codes\n\t\tthis._HexLookup = [];\n\t\tfor (let i = 0; i < 256; ++i)\n\t\t{\n\t\t\tthis._HexLookup[i] = (i + 0x100).toString(16).substr(1);\n\t\t}\n\t}\n\n\t// Adapted from node-uuid (https://github.com/kelektiv/node-uuid)\n\tbytesToUUID(pBuffer)\n\t{\n\t\tlet i = 0;\n\t\t// join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4\n\t\treturn ([\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], \n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], '-',\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], '-',\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], '-',\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], '-',\n\t\t\t\t\tthis._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]], this._HexLookup[pBuffer[i++]]\n\t\t\t\t]).join('');\n\t}\n\n\t// Adapted from node-uuid (https://github.com/kelektiv/node-uuid)\n\tgenerateUUIDv4()\n\t{\n\t\tlet tmpBuffer = new Array(16);\n\t\tvar tmpRandomBytes = this.randomByteGenerator.generate();\n\n\t\t// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n\t\ttmpRandomBytes[6] = (tmpRandomBytes[6] & 0x0f) | 0x40;\n\t\ttmpRandomBytes[8] = (tmpRandomBytes[8] & 0x3f) | 0x80;\n\n\t\treturn this.bytesToUUID(tmpRandomBytes);\n\t}\n\n\t// Simple random UUID generation\n\tgenerateRandom()\n\t{\n\t\tlet tmpUUID = '';\n\n\t\tfor (let i = 0; i < this._UUIDLength; i++)\n\t\t{\n\t\t\ttmpUUID += this._UUIDRandomDictionary.charAt(Math.floor(Math.random() * (this._UUIDRandomDictionary.length-1)));\n\t\t}\n\n\t\treturn tmpUUID;\n\t}\n\n\t// Adapted from node-uuid (https://github.com/kelektiv/node-uuid)\n\tgetUUID()\n\t{\n\t\tif (this._UUIDModeRandom)\n\t\t{\n\t\t\treturn this.generateRandom();\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn this.generateUUIDv4();\n\t\t}\n\t}\n}\n\n// This is for backwards compatibility\nfunction autoConstruct(pSettings)\n{\n\treturn new FableUUID(pSettings);\n}\n\n\nmodule.exports = {new:autoConstruct, FableUUID:FableUUID};\n","/**\n* Precedent Meta-Templating\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Process text streams, parsing out meta-template expressions.\n*/\nvar libWordTree = require(`./WordTree.js`);\nvar libStringParser = require(`./StringParser.js`);\n\nclass Precedent\n{\n\t/**\n\t * Precedent Constructor\n\t */\n\tconstructor()\n\t{\n\t\tthis.WordTree = new libWordTree();\n\t\t\n\t\tthis.StringParser = new libStringParser();\n\n\t\tthis.ParseTree = this.WordTree.ParseTree;\n\t}\n\t\n\t/**\n\t * Add a Pattern to the Parse Tree\n\t * @method addPattern\n\t * @param {Object} pTree - A node on the parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - callback function\n\t * @return {bool} True if adding the pattern was successful\n\t */\n\taddPattern(pPatternStart, pPatternEnd, pParser)\n\t{\n\t\treturn this.WordTree.addPattern(pPatternStart, pPatternEnd, pParser);\n\t}\n\t\n\t/**\n\t * Parse a string with the existing parse tree\n\t * @method parseString\n\t * @param {string} pString - The string to parse\n\t * @return {string} The result from the parser\n\t */\n\tparseString(pString)\n\t{\n\t\treturn this.StringParser.parseString(pString, this.ParseTree);\n\t}\n}\n\nmodule.exports = Precedent;\n","/**\n* String Parser\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Parse a string, properly processing each matched token in the word tree.\n*/\n\nclass StringParser\n{\n\t/**\n\t * StringParser Constructor\n\t */\n\tconstructor()\n\t{\n\t}\n\t\n\t/**\n\t * Create a fresh parsing state object to work with.\n\t * @method newParserState\n\t * @param {Object} pParseTree - A node on the parse tree to begin parsing from (usually root)\n\t * @return {Object} A new parser state object for running a character parser on\n\t * @private\n\t */\n\tnewParserState (pParseTree)\n\t{\n\t\treturn (\n\t\t{\n\t\t\tParseTree: pParseTree,\n\n\t\t\tOutput: '',\n\t\t\tOutputBuffer: '',\n\n\t\t\tPattern: false,\n\n\t\t\tPatternMatch: false,\n\t\t\tPatternMatchOutputBuffer: ''\n\t\t});\n\t}\n\t\t\n\t/**\n\t * Assign a node of the parser tree to be the next potential match.\n\t * If the node has a PatternEnd property, it is a valid match and supercedes the last valid match (or becomes the initial match).\n\t * @method assignNode\n\t * @param {Object} pNode - A node on the parse tree to assign\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tassignNode (pNode, pParserState)\n\t{\n\t\tpParserState.PatternMatch = pNode;\n\n\t\t// If the pattern has a END we can assume it has a parse function...\n\t\tif (pParserState.PatternMatch.hasOwnProperty('PatternEnd'))\n\t\t{\n\t\t\t// ... this is the legitimate start of a pattern.\n\t\t\tpParserState.Pattern = pParserState.PatternMatch;\n\t\t}\n\t}\n\t\n\t/**\n\t * Append a character to the output buffer in the parser state.\n\t * This output buffer is used when a potential match is being explored, or a match is being explored.\n\t * @method appendOutputBuffer\n\t * @param {string} pCharacter - The character to append\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tappendOutputBuffer (pCharacter, pParserState)\n\t{\n\t\tpParserState.OutputBuffer += pCharacter;\n\t}\n\t\n\t/**\n\t * Flush the output buffer to the output and clear it.\n\t * @method flushOutputBuffer\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tflushOutputBuffer (pParserState)\n\t{\n\t\tpParserState.Output += pParserState.OutputBuffer;\n\t\tpParserState.OutputBuffer = '';\n\t}\n\n\t\n\t/**\n\t * Check if the pattern has ended. If it has, properly flush the buffer and start looking for new patterns.\n\t * @method checkPatternEnd\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tcheckPatternEnd (pParserState)\n\t{\n\t\tif ((pParserState.OutputBuffer.length >= pParserState.Pattern.PatternEnd.length+pParserState.Pattern.PatternStart.length) && \n\t\t\t(pParserState.OutputBuffer.substr(-pParserState.Pattern.PatternEnd.length) === pParserState.Pattern.PatternEnd))\n\t\t{\n\t\t\t// ... this is the end of a pattern, cut off the end tag and parse it.\n\t\t\t// Trim the start and end tags off the output buffer now\n\t\t\tpParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStart.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStart.length+pParserState.Pattern.PatternEnd.length)));\n\t\t\t// Flush the output buffer.\n\t\t\tthis.flushOutputBuffer(pParserState);\n\t\t\t// End pattern mode\n\t\t\tpParserState.Pattern = false;\n\t\t\tpParserState.PatternMatch = false;\n\t\t}\n\t}\n\t\n\t/**\n\t * Parse a character in the buffer.\n\t * @method parseCharacter\n\t * @param {string} pCharacter - The character to append\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tparseCharacter (pCharacter, pParserState)\n\t{\n\t\t// (1) If we aren't in a pattern match, and we aren't potentially matching, and this may be the start of a new pattern....\n\t\tif (!pParserState.PatternMatch && pParserState.ParseTree.hasOwnProperty(pCharacter))\n\t\t{\n\t\t\t// ... assign the node as the matched node.\n\t\t\tthis.assignNode(pParserState.ParseTree[pCharacter], pParserState);\n\t\t\tthis.appendOutputBuffer(pCharacter, pParserState);\n\t\t}\n\t\t// (2) If we are in a pattern match (actively seeing if this is part of a new pattern token)\n\t\telse if (pParserState.PatternMatch)\n\t\t{\n\t\t\t// If the pattern has a subpattern with this key\n\t\t\tif (pParserState.PatternMatch.hasOwnProperty(pCharacter))\n\t\t\t{\n\t\t\t\t// Continue matching patterns.\n\t\t\t\tthis.assignNode(pParserState.PatternMatch[pCharacter], pParserState);\n\t\t\t}\n\t\t\tthis.appendOutputBuffer(pCharacter, pParserState);\n\t\t\tif (pParserState.Pattern)\n\t\t\t{\n\t\t\t\t// ... Check if this is the end of the pattern (if we are matching a valid pattern)...\n\t\t\t\tthis.checkPatternEnd(pParserState);\n\t\t\t}\n\t\t}\n\t\t// (3) If we aren't in a pattern match or pattern, and this isn't the start of a new pattern (RAW mode)....\n\t\telse\n\t\t{\n\t\t\tpParserState.Output += pCharacter;\n\t\t}\n\t}\n\t\n\t/**\n\t * Parse a string for matches, and process any template segments that occur.\n\t * @method parseString\n\t * @param {string} pString - The string to parse.\n\t * @param {Object} pParseTree - The parse tree to begin parsing from (usually root)\n\t */\n\tparseString (pString, pParseTree)\n\t{\n\t\tlet tmpParserState = this.newParserState(pParseTree);\n\n\t\tfor (var i = 0; i < pString.length; i++)\n\t\t{\n\t\t\t// TODO: This is not fast.\n\t\t\tthis.parseCharacter(pString[i], tmpParserState);\n\t\t}\n\t\t\n\t\tthis.flushOutputBuffer(tmpParserState);\n\t\t\n\t\treturn tmpParserState.Output;\n\t}\n}\n\nmodule.exports = StringParser;\n","/**\n* Word Tree\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Create a tree (directed graph) of Javascript objects, one character per object.\n*/\n\nclass WordTree\n{\n\t/**\n\t * WordTree Constructor\n\t */\n\tconstructor()\n\t{\n\t\tthis.ParseTree = {};\n\t}\n\t\n\t/** \n\t * Add a child character to a Parse Tree node\n\t * @method addChild\n\t * @param {Object} pTree - A parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - The index of the character in the pattern\n\t * @returns {Object} The resulting leaf node that was added (or found)\n\t * @private\n\t */\n\taddChild (pTree, pPattern, pIndex)\n\t{\n\t\tif (!pTree.hasOwnProperty(pPattern[pIndex]))\n\t\t\tpTree[pPattern[pIndex]] = {};\n\t\t\n\t\treturn pTree[pPattern[pIndex]];\n\t}\n\t\n\t/** Add a Pattern to the Parse Tree\n\t * @method addPattern\n\t * @param {Object} pPatternStart - The starting string for the pattern (e.g. \"${\")\n\t * @param {string} pPatternEnd - The ending string for the pattern (e.g. \"}\")\n\t * @param {number} pParser - The function to parse if this is the matched pattern, once the Pattern End is met. If this is a string, a simple replacement occurs.\n\t * @return {bool} True if adding the pattern was successful\n\t */\n\taddPattern (pPatternStart, pPatternEnd, pParser)\n\t{\n\t\tif (pPatternStart.length < 1)\n\t\t\treturn false;\n\n\t\tif ((typeof(pPatternEnd) === 'string') && (pPatternEnd.length < 1))\n\t\t\treturn false;\n\n\t\tlet tmpLeaf = this.ParseTree;\n\n\t\t// Add the tree of leaves iteratively\n\t\tfor (var i = 0; i < pPatternStart.length; i++)\n\t\t\ttmpLeaf = this.addChild(tmpLeaf, pPatternStart, i);\n\n\t\ttmpLeaf.PatternStart = pPatternStart;\n\t\ttmpLeaf.PatternEnd = ((typeof(pPatternEnd) === 'string') && (pPatternEnd.length > 0)) ? pPatternEnd : pPatternStart;\n\t\ttmpLeaf.Parse = (typeof(pParser) === 'function') ? pParser : \n\t\t\t\t\t\t(typeof(pParser) === 'string') ? () => { return pParser; } :\n\t\t\t\t\t\t(pData) => { return pData; };\n\n\t\treturn true;\n\t}\n}\n\nmodule.exports = WordTree;\n","// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n","var libNPMModuleWrapper = require('./Fable.js');\n\nif ((typeof(window) === 'object') && !window.hasOwnProperty('Fable'))\n{\n\twindow.Fable = libNPMModuleWrapper;\n}\n\nmodule.exports = libNPMModuleWrapper;","class FableUtility\n{\n\tconstructor(pFable, pTemplateText)\n\t{\n\t\tthis.fable = pFable;\n\n\t\t// These are the exact regex's used in lodash/underscore\n\t\t// TODO: Switch this to precedent\n\t\tthis.Matchers = (\n\t\t\t{\n\t\t Evaluate: /<%([\\s\\S]+?)%>/g,\n\t\t Interpolate: /<%=([\\s\\S]+?)%>/g,\n\t \t\tEscaper: /\\\\|'|\\r|\\n|\\t|\\u2028|\\u2029/g,\n\t \t\tUnescaper: /\\\\(\\\\|'|r|n|t|u2028|u2029)/g,\n\t\t\t\t// This is how underscore does it, so we are keeping it for now.\n\t \t\tGuaranteedNonMatch: /.^/\n\t\t });\n\n\t // This is a helper for the escaper and unescaper functions.\n\t // Right now we are going to keep what underscore is doing, but, not forever.\n\t this.templateEscapes = {\n\t '\\\\': '\\\\',\n\t \"'\": \"'\",\n\t 'r': '\\r',\n\t '\\r': 'r',\n\t 'n': '\\n',\n\t '\\n': 'n',\n\t 't': '\\t',\n\t '\\t': 't',\n\t 'u2028': '\\u2028',\n\t '\\u2028': 'u2028',\n\t 'u2029': '\\u2029',\n\t '\\u2029': 'u2029'\n\t };\n\n\t // This is defined as such to underscore that it is a dynamic programming\n\t // function on this class.\n\t this.renderFunction = ()=>{return ``};\n\t}\n\n\t// Underscore and lodash have a behavior, _.extend, which merges objects.\n\t// Now that es6 gives us this, use the native thingy.\n\textend(pDestinationObject, ...pSourceObjects)\n\t{\n\t\treturn Object.assign(pDestinationObject, ...pSourceObjects);\n\t}\n\n\trenderTemplate(pData)\n\t{\n\t\treturn this.renderFunction(pData);\n\t}\n\n\ttemplateFunction(pData)\n\t{\n\t\tlet fRenderTemplateBound = this.renderTemplate.bind(this);\n\t\treturn fRenderTemplateBound;\n\t}\n\n\t// Underscore and lodash have a behavior, _.template, which compiles a\n\t// string-based template with code snippets into simple executable pieces,\n\t// with the added twist of returning a precompiled function ready to go.\n\t//\n\t// NOTE: This does not implement underscore escape expressions\n\t// NOTE: This does not implement underscore magic browser variable assignment\n\t//\n\t// This is an implementation of that.\n\t// TODO: Make this use precedent, add configuration, add debugging.\n\tbuildTemplateFunction(pTemplateText, pData)\n {\n \t// For now this is being kept in a weird form ... this is to mimic the old\n \t// underscore code until this is rewritten using precedent.\n this.TemplateSource = \"__p+='\" + pTemplateText\n .replace(this.Matchers.Escaper,\n \t(pMatch)=>\n\t {\n\t return `\\\\${this.templateEscapes[pMatch]}`;\n\t })\n .replace(this.Matchers.Interpolate || this.Matchers.GuaranteedNonMatch,\n \t(pMatch, pCode) =>\n \t{\n\t return `'+\\n(${decodeURIComponent(pCode)})+\\n'`;\n\t })\n\t .replace(this.Matchers.Evaluate || this.Matchers.GuaranteedNonMatch,\n\t\t\t\t(pMatch, pCode) =>\n \t{\n\t return `';\\n${decodeURIComponent(pCode)}\\n;__p+='`;\n\t }) + `';\\n`;\n\n\n this.TemplateSource = `with(pTemplateDataObject||{}){\\n${this.TemplateSource}}\\n`;\n this.TemplateSource = `var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\\n${this.TemplateSource}return __p;\\n`;\n\n this.renderFunction = new Function('pTemplateDataObject', this.TemplateSource);\n\n if (typeof(pData) != 'undefined')\n {\n return this.renderFunction(pData);\n }\n\n // Provide the compiled function source as a convenience for build time\n // precompilation.\n this.TemplateSourceCompiled = 'function(obj){\\n' + this.TemplateSource + '}';\n\n return this.templateFunction();\n\t}\n}\n\nmodule.exports = FableUtility;","const libFableUtilityTemplate = require('./Fable-Utility-Template.js');\n\nclass FableUtility\n{\n\tconstructor(pFable)\n\t{\n\t\tthis.fable = pFable;\n\t}\n\n\t// Underscore and lodash have a behavior, _.extend, which merges objects.\n\t// Now that es6 gives us this, use the native thingy.\n\textend(pDestinationObject, ...pSourceObjects)\n\t{\n\t\treturn Object.assign(pDestinationObject, ...pSourceObjects);\n\t}\n\n\t// Underscore and lodash have a behavior, _.template, which compiles a\n\t// string-based template with code snippets into simple executable pieces,\n\t// with the added twist of returning a precompiled function ready to go.\n\ttemplate(pTemplateText, pData)\n\t{\n\t\tlet tmpTemplate = new libFableUtilityTemplate(this.fable, pTemplateText);\n\n\t\treturn tmpTemplate.buildTemplateFunction(pTemplateText, pData);\n\t}\n\n}\n\nmodule.exports = FableUtility;","/**\n* Fable Application Services Support Library\n* @license MIT\n* @author <steven@velozo.com>\n*/\nconst libFableSettings = require('fable-settings').FableSettings;\nconst libFableUUID = require('fable-uuid').FableUUID;\nconst libFableLog = require('fable-log').FableLog;\n\nconst libFableUtility = require('./Fable-Utility.js')\n\nclass Fable\n{\n\tconstructor(pSettings)\n\t{\n\t\tlet tmpSettings = new libFableSettings(pSettings);\n\n\t\tthis.settingsManager = tmpSettings;\n\n\t\t// Instantiate the UUID generator\n\t\tthis.libUUID = new libFableUUID(this.settingsManager.settings);\n\n\t\tthis.log = new libFableLog(this.settingsManager.settings);\n\t\tthis.log.initialize();\n\n\t\tthis.Utility = new libFableUtility(this);\n\t}\n\n\tget settings()\n\t{\n\t\treturn this.settingsManager.settings;\n\t}\n\n\tget fable()\n\t{\n\t\treturn this;\n\t}\n\n\tgetUUID()\n\t{\n\t\treturn this.libUUID.getUUID();\n\t}\n}\n\nmodule.exports = Fable;"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fable",
3
- "version": "3.0.3",
3
+ "version": "3.0.4",
4
4
  "description": "An entity behavior management and API bundling library.",
5
5
  "main": "source/Fable.js",
6
6
  "scripts": {
@@ -0,0 +1,108 @@
1
+ class FableUtility
2
+ {
3
+ constructor(pFable, pTemplateText)
4
+ {
5
+ this.fable = pFable;
6
+
7
+ // These are the exact regex's used in lodash/underscore
8
+ // TODO: Switch this to precedent
9
+ this.Matchers = (
10
+ {
11
+ Evaluate: /<%([\s\S]+?)%>/g,
12
+ Interpolate: /<%=([\s\S]+?)%>/g,
13
+ Escaper: /\\|'|\r|\n|\t|\u2028|\u2029/g,
14
+ Unescaper: /\\(\\|'|r|n|t|u2028|u2029)/g,
15
+ // This is how underscore does it, so we are keeping it for now.
16
+ GuaranteedNonMatch: /.^/
17
+ });
18
+
19
+ // This is a helper for the escaper and unescaper functions.
20
+ // Right now we are going to keep what underscore is doing, but, not forever.
21
+ this.templateEscapes = {
22
+ '\\': '\\',
23
+ "'": "'",
24
+ 'r': '\r',
25
+ '\r': 'r',
26
+ 'n': '\n',
27
+ '\n': 'n',
28
+ 't': '\t',
29
+ '\t': 't',
30
+ 'u2028': '\u2028',
31
+ '\u2028': 'u2028',
32
+ 'u2029': '\u2029',
33
+ '\u2029': 'u2029'
34
+ };
35
+
36
+ // This is defined as such to underscore that it is a dynamic programming
37
+ // function on this class.
38
+ this.renderFunction = ()=>{return ``};
39
+ }
40
+
41
+ // Underscore and lodash have a behavior, _.extend, which merges objects.
42
+ // Now that es6 gives us this, use the native thingy.
43
+ extend(pDestinationObject, ...pSourceObjects)
44
+ {
45
+ return Object.assign(pDestinationObject, ...pSourceObjects);
46
+ }
47
+
48
+ renderTemplate(pData)
49
+ {
50
+ return this.renderFunction(pData);
51
+ }
52
+
53
+ templateFunction(pData)
54
+ {
55
+ let fRenderTemplateBound = this.renderTemplate.bind(this);
56
+ return fRenderTemplateBound;
57
+ }
58
+
59
+ // Underscore and lodash have a behavior, _.template, which compiles a
60
+ // string-based template with code snippets into simple executable pieces,
61
+ // with the added twist of returning a precompiled function ready to go.
62
+ //
63
+ // NOTE: This does not implement underscore escape expressions
64
+ // NOTE: This does not implement underscore magic browser variable assignment
65
+ //
66
+ // This is an implementation of that.
67
+ // TODO: Make this use precedent, add configuration, add debugging.
68
+ buildTemplateFunction(pTemplateText, pData)
69
+ {
70
+ // For now this is being kept in a weird form ... this is to mimic the old
71
+ // underscore code until this is rewritten using precedent.
72
+ this.TemplateSource = "__p+='" + pTemplateText
73
+ .replace(this.Matchers.Escaper,
74
+ (pMatch)=>
75
+ {
76
+ return `\\${this.templateEscapes[pMatch]}`;
77
+ })
78
+ .replace(this.Matchers.Interpolate || this.Matchers.GuaranteedNonMatch,
79
+ (pMatch, pCode) =>
80
+ {
81
+ return `'+\n(${decodeURIComponent(pCode)})+\n'`;
82
+ })
83
+ .replace(this.Matchers.Evaluate || this.Matchers.GuaranteedNonMatch,
84
+ (pMatch, pCode) =>
85
+ {
86
+ return `';\n${decodeURIComponent(pCode)}\n;__p+='`;
87
+ }) + `';\n`;
88
+
89
+
90
+ this.TemplateSource = `with(pTemplateDataObject||{}){\n${this.TemplateSource}}\n`;
91
+ this.TemplateSource = `var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n${this.TemplateSource}return __p;\n`;
92
+
93
+ this.renderFunction = new Function('pTemplateDataObject', this.TemplateSource);
94
+
95
+ if (typeof(pData) != 'undefined')
96
+ {
97
+ return this.renderFunction(pData);
98
+ }
99
+
100
+ // Provide the compiled function source as a convenience for build time
101
+ // precompilation.
102
+ this.TemplateSourceCompiled = 'function(obj){\n' + this.TemplateSource + '}';
103
+
104
+ return this.templateFunction();
105
+ }
106
+ }
107
+
108
+ module.exports = FableUtility;
@@ -1,3 +1,5 @@
1
+ const libFableUtilityTemplate = require('./Fable-Utility-Template.js');
2
+
1
3
  class FableUtility
2
4
  {
3
5
  constructor(pFable)
@@ -5,12 +7,23 @@ class FableUtility
5
7
  this.fable = pFable;
6
8
  }
7
9
 
8
- // Underscore and lodash both had a behavior, _.extend, which merged objects
10
+ // Underscore and lodash have a behavior, _.extend, which merges objects.
9
11
  // Now that es6 gives us this, use the native thingy.
10
12
  extend(pDestinationObject, ...pSourceObjects)
11
13
  {
12
14
  return Object.assign(pDestinationObject, ...pSourceObjects);
13
15
  }
16
+
17
+ // Underscore and lodash have a behavior, _.template, which compiles a
18
+ // string-based template with code snippets into simple executable pieces,
19
+ // with the added twist of returning a precompiled function ready to go.
20
+ template(pTemplateText, pData)
21
+ {
22
+ let tmpTemplate = new libFableUtilityTemplate(this.fable, pTemplateText);
23
+
24
+ return tmpTemplate.buildTemplateFunction(pTemplateText, pData);
25
+ }
26
+
14
27
  }
15
28
 
16
29
  module.exports = FableUtility;
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Unit tests for Fable
3
+ *
4
+ * @license MIT
5
+ *
6
+ * @author Steven Velozo <steven@velozo.com>
7
+ */
8
+
9
+ var libFable = require('../source/Fable.js');
10
+
11
+ var Chai = require("chai");
12
+ var Expect = Chai.expect;
13
+ var Assert = Chai.assert;
14
+
15
+ suite
16
+ (
17
+ 'FableUtility',
18
+ function()
19
+ {
20
+ var testFable = false;
21
+
22
+ setup
23
+ (
24
+ function()
25
+ {
26
+ }
27
+ );
28
+
29
+ suite
30
+ (
31
+ 'Utility',
32
+ function()
33
+ {
34
+ test
35
+ (
36
+ 'Process Template like Underscore',
37
+ function()
38
+ {
39
+ testFable = new libFable();
40
+ let tmpTemplate = testFable.Utility.template('Something');
41
+ Expect(tmpTemplate).to.be.a('function');
42
+ }
43
+ );
44
+ test
45
+ (
46
+ 'Processed Template like Underscore Work Without Variables',
47
+ function()
48
+ {
49
+ testFable = new libFable();
50
+ let tmpTemplate = testFable.Utility.template('Something');
51
+ Expect(tmpTemplate).to.be.a('function');
52
+ Expect(tmpTemplate()).to.equal('Something');
53
+ }
54
+ );
55
+ test
56
+ (
57
+ 'Processed Template like Underscore Work With Variables',
58
+ function()
59
+ {
60
+ testFable = new libFable();
61
+ let tmpTemplate = testFable.Utility.template('There are <%= Count %> things....');
62
+ Expect(tmpTemplate).to.be.a('function');
63
+ Expect(tmpTemplate({Count:1000})).to.equal('There are 1000 things....');
64
+ }
65
+ );
66
+ test
67
+ (
68
+ 'merging objects should work like old underscore did with 1 paramter',
69
+ function()
70
+ {
71
+ testFable = new libFable();
72
+ let tmpResult = testFable.Utility.extend({SomeValue:'here'});
73
+ Expect(tmpResult).to.have.a.property('SomeValue')
74
+ .that.is.a('string');
75
+ Expect(tmpResult.SomeValue).to.equal('here')
76
+ }
77
+ );
78
+ test
79
+ (
80
+ 'merging objects should work like old underscore did with 2 paramter',
81
+ function()
82
+ {
83
+ testFable = new libFable();
84
+ let tmpResult = testFable.Utility.extend({SomeValue:'here',Size:10},{Color:'Red',Size:20});
85
+ Expect(tmpResult).to.have.a.property('SomeValue')
86
+ .that.is.a('string');
87
+ Expect(tmpResult.SomeValue).to.equal('here');
88
+ Expect(tmpResult.Color).to.equal('Red');
89
+ Expect(tmpResult.Size).to.equal(20);
90
+ }
91
+ );
92
+ test
93
+ (
94
+ 'merging objects should work like old underscore did with more paramters',
95
+ function()
96
+ {
97
+ testFable = new libFable();
98
+ let tmpResult = testFable.Utility.extend(
99
+ {SomeValue:'here',Size:10, Race:'Human'},
100
+ {Color:'Red',Size:20, Band:'Metalocalypse'},
101
+ {Name:'Bilbo', Size:15, Race:'Hobbit', Band:'The dead hobbitz'});
102
+ Expect(tmpResult).to.have.a.property('SomeValue')
103
+ .that.is.a('string');
104
+ Expect(tmpResult.SomeValue).to.equal('here')
105
+ Expect(tmpResult.Color).to.equal('Red');
106
+ Expect(tmpResult.Band).to.equal('The dead hobbitz');
107
+ Expect(tmpResult.Race).to.equal('Hobbit');
108
+ Expect(tmpResult.Name).to.equal('Bilbo');
109
+ Expect(tmpResult.Size).to.equal(15);
110
+ }
111
+ );
112
+ }
113
+ );
114
+ }
115
+ );
@@ -99,59 +99,5 @@ suite
99
99
  );
100
100
  }
101
101
  );
102
-
103
- suite
104
- (
105
- 'Utility',
106
- function()
107
- {
108
- test
109
- (
110
- 'merging objects should work like old underscore did with 1 paramter',
111
- function()
112
- {
113
- testFable = new libFable();
114
- let tmpResult = testFable.Utility.extend({SomeValue:'here'});
115
- Expect(tmpResult).to.have.a.property('SomeValue')
116
- .that.is.a('string');
117
- Expect(tmpResult.SomeValue).to.equal('here')
118
- }
119
- );
120
- test
121
- (
122
- 'merging objects should work like old underscore did with 2 paramter',
123
- function()
124
- {
125
- testFable = new libFable();
126
- let tmpResult = testFable.Utility.extend({SomeValue:'here',Size:10},{Color:'Red',Size:20});
127
- Expect(tmpResult).to.have.a.property('SomeValue')
128
- .that.is.a('string');
129
- Expect(tmpResult.SomeValue).to.equal('here');
130
- Expect(tmpResult.Color).to.equal('Red');
131
- Expect(tmpResult.Size).to.equal(20);
132
- }
133
- );
134
- test
135
- (
136
- 'merging objects should work like old underscore did with more paramters',
137
- function()
138
- {
139
- testFable = new libFable();
140
- let tmpResult = testFable.Utility.extend(
141
- {SomeValue:'here',Size:10, Race:'Human'},
142
- {Color:'Red',Size:20, Band:'Metalocalypse'},
143
- {Name:'Bilbo', Size:15, Race:'Hobbit', Band:'The dead hobbitz'});
144
- Expect(tmpResult).to.have.a.property('SomeValue')
145
- .that.is.a('string');
146
- Expect(tmpResult.SomeValue).to.equal('here')
147
- Expect(tmpResult.Color).to.equal('Red');
148
- Expect(tmpResult.Band).to.equal('The dead hobbitz');
149
- Expect(tmpResult.Race).to.equal('Hobbit');
150
- Expect(tmpResult.Name).to.equal('Bilbo');
151
- Expect(tmpResult.Size).to.equal(15);
152
- }
153
- );
154
- }
155
- );
156
102
  }
157
103
  );