fable 3.1.52 → 3.1.55

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
@@ -667,21 +667,28 @@ switch(pLevel){case'trace':this.logStreamsTrace.push(pLogger);case'debug':this.l
667
667
  for(let i=0;i<this._StreamDefinitions.length;i++){let tmpStreamDefinition=Object.assign({loggertype:'default',streamtype:'console',level:'info'},this._StreamDefinitions[i]);if(!(tmpStreamDefinition.loggertype in this._Providers)){console.log(`Error initializing log stream: bad loggertype in stream definition ${JSON.stringify(tmpStreamDefinition)}`);}else{this.addLogger(new this._Providers[tmpStreamDefinition.loggertype](tmpStreamDefinition,this),tmpStreamDefinition.level);}}// Now initialize each one.
668
668
  for(let i=0;i<this.logStreams.length;i++){this.logStreams[i].initialize();}}logTime(pMessage,pDatum){let tmpMessage=typeof pMessage!=='undefined'?pMessage:'Time';let tmpTime=new Date();this.info(`${tmpMessage} ${tmpTime} (epoch ${+tmpTime})`,pDatum);}// Get a timestamp
669
669
  getTimeStamp(){return+new Date();}getTimeDelta(pTimeStamp){let tmpEndTime=+new Date();return tmpEndTime-pTimeStamp;}// Log the delta between a timestamp, and now with a message
670
- logTimeDelta(pTimeDelta,pMessage,pDatum){let tmpMessage=typeof pMessage!=='undefined'?pMessage:'Time Measurement';let tmpDatum=typeof pDatum==='object'?pDatum:{};let tmpEndTime=+new Date();this.info(`${tmpMessage} logged at (epoch ${+tmpEndTime}) took (${pTimeDelta}ms)`,pDatum);}logTimeDeltaHuman(pTimeDelta,pMessage,pDatum){let tmpMessage=typeof pMessage!=='undefined'?pMessage:'Time Measurement';let tmpEndTime=+new Date();let tmpMs=parseInt(pTimeDelta%1000);let tmpSeconds=parseInt(pTimeDelta/1000%60);let tmpMinutes=parseInt(pTimeDelta/(1000*60)%60);let tmpHours=parseInt(pTimeDelta/(1000*60*60));tmpMs=tmpMs<10?"00"+tmpMs:tmpMs<100?"0"+tmpMs:tmpMs;tmpSeconds=tmpSeconds<10?"0"+tmpSeconds:tmpSeconds;tmpMinutes=tmpMinutes<10?"0"+tmpMinutes:tmpMinutes;tmpHours=tmpHours<10?"0"+tmpHours:tmpHours;this.info(`${tmpMessage} logged at (epoch ${+tmpEndTime}) took (${pTimeDelta}ms) or (${tmpHours}:${tmpMinutes}:${tmpSeconds}.${tmpMs})`,pDatum);}logTimeDeltaRelative(pStartTime,pMessage,pDatum){this.logTimeDelta(this.getTimeDelta(pStartTime),pMessage,pDatum);}logTimeDeltaRelativeHuman(pStartTime,pMessage,pDatum){this.logTimeDeltaHuman(this.getTimeDelta(pStartTime),pMessage,pDatum);}}module.exports=FableLog;module.exports.LogProviderBase=require('./Fable-Log-BaseLogger.js');module.exports.LogProviderConsole=require('./Fable-Log-Logger-Console.js');module.exports.LogProviderFlatfile=require('./Fable-Log-Logger-SimpleFlatFile.js');},{"../package.json":51,"./Fable-Log-BaseLogger.js":52,"./Fable-Log-DefaultProviders-Node.js":53,"./Fable-Log-DefaultStreams.json":54,"./Fable-Log-Logger-Console.js":55,"./Fable-Log-Logger-SimpleFlatFile.js":56,"fable-serviceproviderbase":59}],58:[function(require,module,exports){module.exports={"name":"fable-serviceproviderbase","version":"3.0.15","description":"Simple base classes for fable services.","main":"source/Fable-ServiceProviderBase.js","scripts":{"start":"node source/Fable-ServiceProviderBase.js","test":"npx mocha -u tdd -R spec","tests":"npx mocha -u tdd --exit -R spec --grep","coverage":"npx nyc --reporter=lcov --reporter=text-lcov npx mocha -- -u tdd -R spec","build":"npx quack build"},"mocha":{"diff":true,"extension":["js"],"package":"./package.json","reporter":"spec","slow":"75","timeout":"5000","ui":"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},"repository":{"type":"git","url":"https://github.com/stevenvelozo/fable-serviceproviderbase.git"},"keywords":["entity","behavior"],"author":"Steven Velozo <steven@velozo.com> (http://velozo.com/)","license":"MIT","bugs":{"url":"https://github.com/stevenvelozo/fable-serviceproviderbase/issues"},"homepage":"https://github.com/stevenvelozo/fable-serviceproviderbase","devDependencies":{"fable":"^3.0.143","quackage":"^1.0.33"}};},{}],59:[function(require,module,exports){/**
670
+ logTimeDelta(pTimeDelta,pMessage,pDatum){let tmpMessage=typeof pMessage!=='undefined'?pMessage:'Time Measurement';let tmpDatum=typeof pDatum==='object'?pDatum:{};let tmpEndTime=+new Date();this.info(`${tmpMessage} logged at (epoch ${+tmpEndTime}) took (${pTimeDelta}ms)`,pDatum);}logTimeDeltaHuman(pTimeDelta,pMessage,pDatum){let tmpMessage=typeof pMessage!=='undefined'?pMessage:'Time Measurement';let tmpEndTime=+new Date();let tmpMs=parseInt(pTimeDelta%1000);let tmpSeconds=parseInt(pTimeDelta/1000%60);let tmpMinutes=parseInt(pTimeDelta/(1000*60)%60);let tmpHours=parseInt(pTimeDelta/(1000*60*60));tmpMs=tmpMs<10?"00"+tmpMs:tmpMs<100?"0"+tmpMs:tmpMs;tmpSeconds=tmpSeconds<10?"0"+tmpSeconds:tmpSeconds;tmpMinutes=tmpMinutes<10?"0"+tmpMinutes:tmpMinutes;tmpHours=tmpHours<10?"0"+tmpHours:tmpHours;this.info(`${tmpMessage} logged at (epoch ${+tmpEndTime}) took (${pTimeDelta}ms) or (${tmpHours}:${tmpMinutes}:${tmpSeconds}.${tmpMs})`,pDatum);}logTimeDeltaRelative(pStartTime,pMessage,pDatum){this.logTimeDelta(this.getTimeDelta(pStartTime),pMessage,pDatum);}logTimeDeltaRelativeHuman(pStartTime,pMessage,pDatum){this.logTimeDeltaHuman(this.getTimeDelta(pStartTime),pMessage,pDatum);}}module.exports=FableLog;module.exports.LogProviderBase=require('./Fable-Log-BaseLogger.js');module.exports.LogProviderConsole=require('./Fable-Log-Logger-Console.js');module.exports.LogProviderFlatfile=require('./Fable-Log-Logger-SimpleFlatFile.js');},{"../package.json":51,"./Fable-Log-BaseLogger.js":52,"./Fable-Log-DefaultProviders-Node.js":53,"./Fable-Log-DefaultStreams.json":54,"./Fable-Log-Logger-Console.js":55,"./Fable-Log-Logger-SimpleFlatFile.js":56,"fable-serviceproviderbase":59}],58:[function(require,module,exports){module.exports={"name":"fable-serviceproviderbase","version":"3.0.17","description":"Simple base classes for fable services.","main":"source/Fable-ServiceProviderBase.js","scripts":{"start":"node source/Fable-ServiceProviderBase.js","test":"npx mocha -u tdd -R spec","tests":"npx mocha -u tdd --exit -R spec --grep","coverage":"npx nyc --reporter=lcov --reporter=text-lcov npx mocha -- -u tdd -R spec","build":"npx quack build","types":"tsc -p ./tsconfig.build.json","check":"tsc -p . --noEmit"},"types":"types/source/Fable-ServiceProviderBase.d.ts","mocha":{"diff":true,"extension":["js"],"package":"./package.json","reporter":"spec","slow":"75","timeout":"5000","ui":"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},"repository":{"type":"git","url":"https://github.com/stevenvelozo/fable-serviceproviderbase.git"},"keywords":["entity","behavior"],"author":"Steven Velozo <steven@velozo.com> (http://velozo.com/)","license":"MIT","bugs":{"url":"https://github.com/stevenvelozo/fable-serviceproviderbase/issues"},"homepage":"https://github.com/stevenvelozo/fable-serviceproviderbase","devDependencies":{"@types/mocha":"^10.0.10","fable":"^3.1.51","quackage":"^1.0.45","typescript":"^5.9.3"}};},{}],59:[function(require,module,exports){/**
671
671
  * Fable Service Base
672
672
  * @author <steven@velozo.com>
673
- */const libPackage=require('../package.json');class FableServiceProviderBase{// The constructor can be used in two ways:
674
- // 1) With a fable, options object and service hash (the options object and service hash are optional)
675
- // 2) With an object or nothing as the first parameter, where it will be treated as the options object
676
- constructor(pFable,pOptions,pServiceHash){// Check if a fable was passed in; connect it if so
673
+ */const libPackage=require('../package.json');class FableServiceProviderBase{/**
674
+ * The constructor can be used in two ways:
675
+ * 1) With a fable, options object and service hash (the options object and service hash are optional)a
676
+ * 2) With an object or nothing as the first parameter, where it will be treated as the options object
677
+ *
678
+ * @param {import('fable')|Record<string, any>} [pFable] - (optional) The fable instance, or the options object if there is no fable
679
+ * @param {Record<string, any>|string} [pOptions] - (optional) The options object, or the service hash if there is no fable
680
+ * @param {string} [pServiceHash] - (optional) The service hash to identify this service instance
681
+ */constructor(pFable,pOptions,pServiceHash){/** @type {import('fable')} */this.fable;/** @type {string} */this.UUID;/** @type {Record<string, any>} */this.options;/** @type {Record<string, any>} */this.services;/** @type {Record<string, any>} */this.servicesMap;// Check if a fable was passed in; connect it if so
677
682
  if(typeof pFable==='object'&&pFable.isFable){this.connectFable(pFable);}else{this.fable=false;}// Initialize the services map if it wasn't passed in
678
- /** @type {Object} */this._PackageFableServiceProvider=libPackage;// initialize options and UUID based on whether the fable was passed in or not.
683
+ /** @type {Record<string, any>} */this._PackageFableServiceProvider=libPackage;// initialize options and UUID based on whether the fable was passed in or not.
679
684
  if(this.fable){this.UUID=pFable.getUUID();this.options=typeof pOptions==='object'?pOptions:{};}else{// With no fable, check to see if there was an object passed into either of the first two
680
685
  // Parameters, and if so, treat it as the options object
681
686
  this.options=typeof pFable==='object'&&!pFable.isFable?pFable:typeof pOptions==='object'?pOptions:{};this.UUID=`CORE-SVC-${Math.floor(Math.random()*(99999-10000)+10000)}`;}// It's expected that the deriving class will set this
682
687
  this.serviceType=`Unknown-${this.UUID}`;// The service hash is used to identify the specific instantiation of the service in the services map
683
- this.Hash=typeof pServiceHash==='string'?pServiceHash:!this.fable&&typeof pOptions==='string'?pOptions:`${this.UUID}`;}connectFable(pFable){if(typeof pFable!=='object'||!pFable.isFable){let tmpErrorMessage=`Fable Service Provider Base: Cannot connect to Fable, invalid Fable object passed in. The pFable parameter was a [${typeof pFable}].}`;console.log(tmpErrorMessage);return new Error(tmpErrorMessage);}if(!this.fable){this.fable=pFable;}if(!this.log){this.log=this.fable.Logging;}if(!this.services){this.services=this.fable.services;}if(!this.servicesMap){this.servicesMap=this.fable.servicesMap;}return true;}}_defineProperty2(FableServiceProviderBase,"isFableService",true);module.exports=FableServiceProviderBase;// This is left here in case we want to go back to having different code/base class for "core" services
684
- module.exports.CoreServiceProviderBase=FableServiceProviderBase;},{"../package.json":58}],60:[function(require,module,exports){module.exports={"name":"fable-settings","version":"3.0.12","description":"A simple, tolerant configuration chain.","main":"source/Fable-Settings.js","scripts":{"start":"node source/Fable-Settings.js","coverage":"./node_modules/.bin/nyc --reporter=lcov --reporter=text-lcov ./node_modules/mocha/bin/_mocha -- -u tdd -R spec","test":"./node_modules/.bin/mocha -u tdd -R spec","build":"./node_modules/.bin/gulp build","docker-dev-build-image":"docker build ./ -f Dockerfile_LUXURYCode -t retold/fable-settings:local","docker-dev-run":"docker run -it -d --name retold-fable-settings-dev -p 30003:8080 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/fable-settings\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" retold/fable-settings:local"},"mocha":{"diff":true,"extension":["js"],"package":"./package.json","reporter":"spec","slow":"75","timeout":"5000","ui":"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},"repository":{"type":"git","url":"https://github.com/stevenvelozo/fable-settings.git"},"keywords":["configuration"],"author":"Steven Velozo <steven@velozo.com> (http://velozo.com/)","license":"MIT","bugs":{"url":"https://github.com/stevenvelozo/fable-settings/issues"},"homepage":"https://github.com/stevenvelozo/fable-settings","devDependencies":{"quackage":"^1.0.33"},"dependencies":{"fable-serviceproviderbase":"^3.0.15","precedent":"^1.0.15"}};},{}],61:[function(require,module,exports){module.exports={"Product":"ApplicationNameHere","ProductVersion":"0.0.0","ConfigFile":false,"LogStreams":[{"level":"trace"}]};},{}],62:[function(require,module,exports){(function(process){(function(){/**
688
+ this.Hash=typeof pServiceHash==='string'?pServiceHash:!this.fable&&typeof pOptions==='string'?pOptions:`${this.UUID}`;}/**
689
+ * @param {import('fable')} pFable
690
+ */connectFable(pFable){if(typeof pFable!=='object'||!pFable.isFable){let tmpErrorMessage=`Fable Service Provider Base: Cannot connect to Fable, invalid Fable object passed in. The pFable parameter was a [${typeof pFable}].}`;console.log(tmpErrorMessage);return new Error(tmpErrorMessage);}if(!this.fable){this.fable=pFable;}if(!this.log){this.log=this.fable.Logging;}if(!this.services){this.services=this.fable.services;}if(!this.servicesMap){this.servicesMap=this.fable.servicesMap;}return true;}}_defineProperty2(FableServiceProviderBase,"isFableService",true);module.exports=FableServiceProviderBase;// This is left here in case we want to go back to having different code/base class for "core" services
691
+ module.exports.CoreServiceProviderBase=FableServiceProviderBase;},{"../package.json":58}],60:[function(require,module,exports){module.exports={"name":"fable-settings","version":"3.0.14","description":"A simple, tolerant configuration chain.","main":"source/Fable-Settings.js","scripts":{"start":"node source/Fable-Settings.js","coverage":"./node_modules/.bin/nyc --reporter=lcov --reporter=text-lcov ./node_modules/mocha/bin/_mocha -- -u tdd -R spec","test":"./node_modules/.bin/mocha -u tdd -R spec","build":"./node_modules/.bin/gulp build","docker-dev-build-image":"docker build ./ -f Dockerfile_LUXURYCode -t retold/fable-settings:local","docker-dev-run":"docker run -it -d --name retold-fable-settings-dev -p 30003:8080 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/fable-settings\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" retold/fable-settings:local"},"mocha":{"diff":true,"extension":["js"],"package":"./package.json","reporter":"spec","slow":"75","timeout":"5000","ui":"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},"repository":{"type":"git","url":"https://github.com/stevenvelozo/fable-settings.git"},"keywords":["configuration"],"author":"Steven Velozo <steven@velozo.com> (http://velozo.com/)","license":"MIT","bugs":{"url":"https://github.com/stevenvelozo/fable-settings/issues"},"homepage":"https://github.com/stevenvelozo/fable-settings","devDependencies":{"quackage":"^1.0.48"},"dependencies":{"fable-serviceproviderbase":"^3.0.17","precedent":"^1.0.15"}};},{}],61:[function(require,module,exports){module.exports={"Product":"ApplicationNameHere","ProductVersion":"0.0.0","ConfigFile":false,"LogStreams":[{"level":"trace"}]};},{}],62:[function(require,module,exports){(function(process){(function(){/**
685
692
  * Fable Settings Template Processor
686
693
  *
687
694
  * This class allows environment variables to come in via templated expressions, and defaults to be set.
@@ -962,7 +969,7 @@ return false;}// Now see if the function has arguments.
962
969
  let tmpFunctionArguments=_MockFable.DataFormat.stringGetSegments(_MockFable.DataFormat.stringGetEnclosureValueByIndex(tmpSubObjectName.substring(tmpFunctionAddress.length),0),',');if(tmpFunctionArguments.length==0||tmpFunctionArguments[0]==''){// No arguments... just call the function (bound to the scope of the object it is contained withing)
963
970
  if(tmpFunctionAddress in pObject){try{return this.checkAddressExists(pObject[tmpFunctionAddress].apply(pObject),tmpNewAddress,tmpRootObject);}catch(pError){// The function call failed, so the address doesn't exist
964
971
  libSimpleLog(`Error calling function ${tmpFunctionAddress} (address [${pAddress}]): ${pError.message}`);return false;}}else{// The function doesn't exist, so the address doesn't exist
965
- libSimpleLog(`Function ${tmpFunctionAddress} does not exist (address [${pAddress}])`);return false;}}else{let tmpArgumentValues=[];let tmpRootObject=typeof pRootObject=='undefined'?pObject:pRootObject;// Now get the value for each argument
972
+ libSimpleLog(`Function ${tmpFunctionAddress} does not exist (address [${pAddress}])`);return false;}}else{let tmpArgumentValues=[];// Now get the value for each argument
966
973
  for(let i=0;i<tmpFunctionArguments.length;i++){// Resolve the values for each subsequent entry
967
974
  // NOTE: This is where the resolves get really tricky. Recursion within recursion. Programming gom jabbar, yo.
968
975
  tmpArgumentValues.push(this.getObjectValueClass.getValueAtAddress(tmpRootObject,tmpFunctionArguments[i]));}//return this.checkAddressExists(pObject[tmpFunctionAddress].apply(pObject, tmpArgumentValues), tmpNewAddress, tmpRootObject);
@@ -1004,10 +1011,10 @@ return this.checkAddressExists(pObject[tmpBoxedPropertyName][tmpBoxedPropertyRef
1004
1011
  return this.checkAddressExists(pObject[tmpBoxedPropertyName][tmpBoxedPropertyNumber],tmpNewAddress,tmpRootObject);}}// If there is an object property already named for the sub object, but it isn't an object
1005
1012
  // then the system can't set the value in there. Error and abort!
1006
1013
  if(tmpSubObjectName in pObject&&typeof pObject[tmpSubObjectName]!=='object'){return false;}else if(tmpSubObjectName in pObject){// If there is already a subobject pass that to the recursive thingy
1007
- return this.checkAddressExists(pObject[tmpSubObjectName],tmpNewAddress,tmpRootObject);}else{// Create a subobject and then pass that
1008
- pObject[tmpSubObjectName]={};return this.checkAddressExists(pObject[tmpSubObjectName],tmpNewAddress,tmpRootObject);}}}}module.exports=ManyfestObjectAddressResolverCheckAddressExists;},{"./Manyfest-CleanWrapCharacters.js":81,"./Manyfest-LogToConsole.js":83,"./Manyfest-ObjectAddress-GetValue.js":86,"./Manyfest-ObjectAddress-Parser.js":87}],85:[function(require,module,exports){/**
1014
+ return this.checkAddressExists(pObject[tmpSubObjectName],tmpNewAddress,tmpRootObject);}else{// The sub-object doesn't exist, so the address doesn't exist
1015
+ return false;}}}}module.exports=ManyfestObjectAddressResolverCheckAddressExists;},{"./Manyfest-CleanWrapCharacters.js":81,"./Manyfest-LogToConsole.js":83,"./Manyfest-ObjectAddress-GetValue.js":86,"./Manyfest-ObjectAddress-Parser.js":87}],85:[function(require,module,exports){/**
1009
1016
  * @author <steven@velozo.com>
1010
- */let libSimpleLog=require('./Manyfest-LogToConsole.js');let fCleanWrapCharacters=require('./Manyfest-CleanWrapCharacters.js');let fParseConditionals=require(`../source/Manyfest-ParseConditionals.js`);/**
1017
+ */let libSimpleLog=require('./Manyfest-LogToConsole.js');let fCleanWrapCharacters=require('./Manyfest-CleanWrapCharacters.js');let fParseConditionals=require(`../source/Manyfest-ParseConditionals.js`);let _MockFable={DataFormat:require('./Manyfest-ObjectAddress-Parser.js')};/**
1011
1018
  * Object Address Resolver - DeleteValue
1012
1019
  *
1013
1020
  * IMPORTANT NOTE: This code is intentionally more verbose than necessary, to
@@ -1047,9 +1054,9 @@ this.logInfo=typeof pInfoLog=='function'?pInfoLog:libSimpleLog;this.logError=typ
1047
1054
  */deleteValueAtAddress(pObject,pAddress,pParentAddress){// Make sure pObject (the object we are meant to be recursing) is an object (which could be an array or object)
1048
1055
  if(typeof pObject!='object')return undefined;// Make sure pAddress (the address we are resolving) is a string
1049
1056
  if(typeof pAddress!='string')return undefined;// Stash the parent address for later resolution
1050
- let tmpParentAddress="";if(typeof pParentAddress=='string'){tmpParentAddress=pParentAddress;}// TODO: Make this work for things like SomeRootObject.Metadata["Some.People.Use.Bad.Object.Property.Names"]
1051
- let tmpSeparatorIndex=pAddress.indexOf('.');// This is the terminal address string (no more dots so the RECUSION ENDS IN HERE somehow)
1052
- if(tmpSeparatorIndex==-1){// Check if the address refers to a boxed property
1057
+ let tmpParentAddress="";if(typeof pParentAddress=='string'){tmpParentAddress=pParentAddress;}// Use enclosure-aware parser to find the first segment separator
1058
+ let tmpAddressPartBeginning=_MockFable.DataFormat.stringGetFirstSegment(pAddress);// This is the terminal address string (no more dots so the RECUSION ENDS IN HERE somehow)
1059
+ if(tmpAddressPartBeginning.length==pAddress.length){// Check if the address refers to a boxed property
1053
1060
  let tmpBracketStartIndex=pAddress.indexOf('[');let tmpBracketStopIndex=pAddress.indexOf(']');// Check for the Object Set Type marker.
1054
1061
  // Note this will not work with a bracket in the same address box set
1055
1062
  let tmpObjectTypeMarkerIndex=pAddress.indexOf('{}');// Boxed elements look like this:
@@ -1089,7 +1096,7 @@ let tmpKeepRecord=this.checkRecordFilters(pAddress,tmpInputArray[i]);if(tmpKeepR
1089
1096
  tmpInputArray.splice(i,1);}}return true;}// The object has been flagged as an object set, so treat it as such
1090
1097
  else if(tmpObjectTypeMarkerIndex>0){let tmpObjectPropertyName=pAddress.substring(0,tmpObjectTypeMarkerIndex).trim();if(typeof pObject[tmpObjectPropertyName]!='object'){// We asked for a set from an array but it isnt' an array.
1091
1098
  return false;}delete pObject[tmpObjectPropertyName];return true;}else{// Now is the point in recursion to return the value in the address
1092
- delete pObject[pAddress];return true;}}else{let tmpSubObjectName=pAddress.substring(0,tmpSeparatorIndex);let tmpNewAddress=pAddress.substring(tmpSeparatorIndex+1);// BOXED ELEMENTS
1099
+ delete pObject[pAddress];return true;}}else{let tmpSubObjectName=tmpAddressPartBeginning;let tmpNewAddress=pAddress.substring(tmpAddressPartBeginning.length+1);// BOXED ELEMENTS
1093
1100
  // Test if the tmpNewAddress is an array or object
1094
1101
  // Check if it's a boxed property
1095
1102
  let tmpBracketStartIndex=tmpSubObjectName.indexOf('[');let tmpBracketStopIndex=tmpSubObjectName.indexOf(']');// Boxed elements look like this:
@@ -1147,7 +1154,7 @@ if(tmpSubObjectName in pObject&&typeof pObject[tmpSubObjectName]!=='object'){ret
1147
1154
  // Continue to manage the parent address for recursion
1148
1155
  tmpParentAddress=`${tmpParentAddress}${tmpParentAddress.length>0?'.':''}${tmpSubObjectName}`;return this.deleteValueAtAddress(pObject[tmpSubObjectName],tmpNewAddress,tmpParentAddress);}else{// Create a subobject and then pass that
1149
1156
  // Continue to manage the parent address for recursion
1150
- tmpParentAddress=`${tmpParentAddress}${tmpParentAddress.length>0?'.':''}${tmpSubObjectName}`;pObject[tmpSubObjectName]={};return this.deleteValueAtAddress(pObject[tmpSubObjectName],tmpNewAddress,tmpParentAddress);}}}};module.exports=ManyfestObjectAddressResolverDeleteValue;},{"../source/Manyfest-ParseConditionals.js":90,"./Manyfest-CleanWrapCharacters.js":81,"./Manyfest-LogToConsole.js":83}],86:[function(require,module,exports){/**
1157
+ tmpParentAddress=`${tmpParentAddress}${tmpParentAddress.length>0?'.':''}${tmpSubObjectName}`;pObject[tmpSubObjectName]={};return this.deleteValueAtAddress(pObject[tmpSubObjectName],tmpNewAddress,tmpParentAddress);}}}};module.exports=ManyfestObjectAddressResolverDeleteValue;},{"../source/Manyfest-ParseConditionals.js":90,"./Manyfest-CleanWrapCharacters.js":81,"./Manyfest-LogToConsole.js":83,"./Manyfest-ObjectAddress-Parser.js":87}],86:[function(require,module,exports){/**
1151
1158
  * @author <steven@velozo.com>
1152
1159
  */let libSimpleLog=require('./Manyfest-LogToConsole.js');let fCleanWrapCharacters=require('./Manyfest-CleanWrapCharacters.js');let fParseConditionals=require(`../source/Manyfest-ParseConditionals.js`);let _MockFable={DataFormat:require('./Manyfest-ObjectAddress-Parser.js')};/**
1153
1160
  * Object Address Resolver - GetValue
@@ -1226,7 +1233,7 @@ return false;}// Now see if the function has arguments.
1226
1233
  let tmpFunctionArguments=_MockFable.DataFormat.stringGetSegments(_MockFable.DataFormat.stringGetEnclosureValueByIndex(pAddress.substring(tmpFunctionAddress.length),0),',');if(tmpFunctionArguments.length==0||tmpFunctionArguments[0]==''){// No arguments... just call the function (bound to the scope of the object it is contained withing)
1227
1234
  if(tmpFunctionAddress in pObject){try{return pObject[tmpFunctionAddress].apply(pObject);}catch(pError){// The function call failed, so the address doesn't exist
1228
1235
  console.log(`Error in getValueAtAddress calling function ${tmpFunctionAddress} (address [${pAddress}]): ${pError.message}`);return false;}}else{// The function doesn't exist, so the address doesn't exist
1229
- console.log(`Function ${tmpFunctionAddress} does not exist (address [${pAddress}])`);return false;}}else{let tmpArgumentValues=[];let tmpRootObject=typeof pRootObject=='undefined'?pObject:pRootObject;// Now get the value for each argument
1236
+ console.log(`Function ${tmpFunctionAddress} does not exist (address [${pAddress}])`);return false;}}else{let tmpArgumentValues=[];// Now get the value for each argument
1230
1237
  for(let i=0;i<tmpFunctionArguments.length;i++){// Resolve the values for each subsequent entry
1231
1238
  // Check if the argument value is a string literal or a reference to an address
1232
1239
  if(tmpFunctionArguments[i].length>=2&&(tmpFunctionArguments[i].charAt(0)=='"'||tmpFunctionArguments[i].charAt(0)=="'"||tmpFunctionArguments[i].charAt(0)=="`")&&(tmpFunctionArguments[i].charAt(tmpFunctionArguments[i].length-1)=='"'||tmpFunctionArguments[i].charAt(tmpFunctionArguments[i].length-1)=="'"||tmpFunctionArguments[i].charAt(tmpFunctionArguments[i].length-1)=="`")){// This is a string literal
@@ -1268,7 +1275,7 @@ return false;}let tmpInputArray=pObject[tmpBoxedPropertyName];let tmpOutputArray
1268
1275
  let tmpKeepRecord=this.checkRecordFilters(pAddress,tmpInputArray[i]);if(tmpKeepRecord){tmpOutputArray.push(tmpInputArray[i]);}}return tmpOutputArray;}// The object has been flagged as an object set, so treat it as such
1269
1276
  else if(tmpObjectTypeMarkerIndex>0){let tmpObjectPropertyName=pAddress.substring(0,tmpObjectTypeMarkerIndex).trim();if(typeof pObject[tmpObjectPropertyName]!='object'){// We asked for a set from an array but it isnt' an array.
1270
1277
  return false;}return pObject[tmpObjectPropertyName];}else{// Now is the point in recursion to return the value in the address
1271
- if(typeof pObject[pAddress]!=null){return pObject[pAddress];}else{return null;}}}else{//let tmpSubObjectName = pAddress.substring(0, tmpSeparatorIndex);
1278
+ if(typeof pObject[pAddress]!='undefined'){return pObject[pAddress];}else{return undefined;}}}else{//let tmpSubObjectName = pAddress.substring(0, tmpSeparatorIndex);
1272
1279
  //let tmpNewAddress = pAddress.substring(tmpSeparatorIndex+1);
1273
1280
  let tmpSubObjectName=tmpAddressPartBeginning;let tmpNewAddress=pAddress.substring(tmpAddressPartBeginning.length+1);// BOXED ELEMENTS
1274
1281
  // Test if the tmpNewAddress is an array or object
@@ -1293,7 +1300,7 @@ return false;}// Now see if the function has arguments.
1293
1300
  let tmpFunctionArguments=_MockFable.DataFormat.stringGetSegments(_MockFable.DataFormat.stringGetEnclosureValueByIndex(tmpSubObjectName.substring(tmpFunctionAddress.length),0),',');if(tmpFunctionArguments.length==0||tmpFunctionArguments[0]==''){// No arguments... just call the function (bound to the scope of the object it is contained withing)
1294
1301
  if(tmpFunctionAddress in pObject){try{return this.getValueAtAddress(pObject[tmpFunctionAddress].apply(pObject),tmpNewAddress,tmpParentAddress,tmpRootObject);}catch(pError){// The function call failed, so the address doesn't exist
1295
1302
  console.log(`Error in getValueAtAddress calling function ${tmpFunctionAddress} (address [${pAddress}]): ${pError.message}`);return false;}}else{// The function doesn't exist, so the address doesn't exist
1296
- console.log(`Function ${tmpFunctionAddress} does not exist (address [${pAddress}])`);return false;}}else{let tmpArgumentValues=[];let tmpRootObject=typeof pRootObject=='undefined'?pObject:pRootObject;// Now get the value for each argument
1303
+ console.log(`Function ${tmpFunctionAddress} does not exist (address [${pAddress}])`);return false;}}else{let tmpArgumentValues=[];// Now get the value for each argument
1297
1304
  for(let i=0;i<tmpFunctionArguments.length;i++){// Resolve the values for each subsequent entry
1298
1305
  // Check if the argument value is a string literal or a reference to an address
1299
1306
  if(tmpFunctionArguments[i].length>=2&&(tmpFunctionArguments[i].charAt(0)=='"'||tmpFunctionArguments[i].charAt(0)=="'"||tmpFunctionArguments[i].charAt(0)=="`")&&(tmpFunctionArguments[i].charAt(tmpFunctionArguments[i].length-1)=='"'||tmpFunctionArguments[i].charAt(tmpFunctionArguments[i].length-1)=="'"||tmpFunctionArguments[i].charAt(tmpFunctionArguments[i].length-1)=="`")){// This is a string literal
@@ -1370,7 +1377,7 @@ const DEFAULT_START_SYMBOL_MAP={'{':0,'[':1,'(':2};const DEFAULT_END_SYMBOL_MAP=
1370
1377
  * @param {Record<string, number>} [pEnclosureEndSymbolMap]
1371
1378
  *
1372
1379
  * @return {number} - The number of segments in the string
1373
- */stringCountSegments:(pString,pSeparator,pEnclosureStartSymbolMap,pEnclosureEndSymbolMap)=>{let tmpString=typeof pString=='string'?pString:'';let tmpSeparator=typeof pSeparator=='string'?pSeparator:'.';let tmpEnclosureStartSymbolMap=typeof pEnclosureStartSymbolMap=='object'?pEnclosureStartSymbolMap:DEFAULT_START_SYMBOL_MAP;let tmpEnclosureEndSymbolMap=typeof pEnclosureEndSymbolMap=='object'?pEnclosureEndSymbolMap:DEFAULT_END_SYMBOL_MAP;if(pString.length<1){return 0;}let tmpSegmentCount=1;let tmpEnclosureStack=[];for(let i=0;i<tmpString.length;i++){// IF This is the start of a segment
1380
+ */stringCountSegments:(pString,pSeparator,pEnclosureStartSymbolMap,pEnclosureEndSymbolMap)=>{let tmpString=typeof pString=='string'?pString:'';let tmpSeparator=typeof pSeparator=='string'?pSeparator:'.';let tmpEnclosureStartSymbolMap=typeof pEnclosureStartSymbolMap=='object'?pEnclosureStartSymbolMap:DEFAULT_START_SYMBOL_MAP;let tmpEnclosureEndSymbolMap=typeof pEnclosureEndSymbolMap=='object'?pEnclosureEndSymbolMap:DEFAULT_END_SYMBOL_MAP;if(tmpString.length<1){return 0;}let tmpSegmentCount=1;let tmpEnclosureStack=[];for(let i=0;i<tmpString.length;i++){// IF This is the start of a segment
1374
1381
  if(tmpString[i]==tmpSeparator// AND we are not in a nested portion of the string
1375
1382
  &&tmpEnclosureStack.length==0){// Increment the segment count
1376
1383
  tmpSegmentCount++;}// IF This is the start of an enclosure
@@ -1387,7 +1394,7 @@ tmpEnclosureStack.pop();}}return tmpSegmentCount;},/**
1387
1394
  * @param {Record<string, number>} [pEnclosureEndSymbolMap]
1388
1395
  *
1389
1396
  * @return {string} - the first segment in the string as a string
1390
- */stringGetFirstSegment:(pString,pSeparator,pEnclosureStartSymbolMap,pEnclosureEndSymbolMap)=>{let tmpString=typeof pString=='string'?pString:'';let tmpSeparator=typeof pSeparator=='string'?pSeparator:'.';let tmpEnclosureStartSymbolMap=typeof pEnclosureStartSymbolMap=='object'?pEnclosureStartSymbolMap:DEFAULT_START_SYMBOL_MAP;let tmpEnclosureEndSymbolMap=typeof pEnclosureEndSymbolMap=='object'?pEnclosureEndSymbolMap:DEFAULT_END_SYMBOL_MAP;if(pString.length<1){return'';}let tmpEnclosureStack=[];for(let i=0;i<tmpString.length;i++){// IF This is the start of a segment
1397
+ */stringGetFirstSegment:(pString,pSeparator,pEnclosureStartSymbolMap,pEnclosureEndSymbolMap)=>{let tmpString=typeof pString=='string'?pString:'';let tmpSeparator=typeof pSeparator=='string'?pSeparator:'.';let tmpEnclosureStartSymbolMap=typeof pEnclosureStartSymbolMap=='object'?pEnclosureStartSymbolMap:DEFAULT_START_SYMBOL_MAP;let tmpEnclosureEndSymbolMap=typeof pEnclosureEndSymbolMap=='object'?pEnclosureEndSymbolMap:DEFAULT_END_SYMBOL_MAP;if(tmpString.length<1){return'';}let tmpEnclosureStack=[];for(let i=0;i<tmpString.length;i++){// IF This is the start of a segment
1391
1398
  if(tmpString[i]==tmpSeparator// AND we are not in a nested portion of the string
1392
1399
  &&tmpEnclosureStack.length==0){// Return the segment
1393
1400
  return tmpString.substring(0,i);}// IF This is the start of an enclosure
@@ -1404,7 +1411,7 @@ tmpEnclosureStack.pop();}}return tmpString;},/**
1404
1411
  * @param {Record<string, number>} [pEnclosureEndSymbolMap]
1405
1412
  *
1406
1413
  * @return {Array<string>} - the segments in the string as an array of strings
1407
- */stringGetSegments:(pString,pSeparator,pEnclosureStartSymbolMap,pEnclosureEndSymbolMap)=>{let tmpString=typeof pString=='string'?pString:'';let tmpSeparator=typeof pSeparator=='string'?pSeparator:'.';let tmpEnclosureStartSymbolMap=typeof pEnclosureStartSymbolMap=='object'?pEnclosureStartSymbolMap:DEFAULT_START_SYMBOL_MAP;let tmpEnclosureEndSymbolMap=typeof pEnclosureEndSymbolMap=='object'?pEnclosureEndSymbolMap:DEFAULT_END_SYMBOL_MAP;let tmpCurrentSegmentStart=0;let tmpSegmentList=[];if(pString.length<1){return tmpSegmentList;}let tmpEnclosureStack=[];for(let i=0;i<tmpString.length;i++){// IF This is the start of a segment
1414
+ */stringGetSegments:(pString,pSeparator,pEnclosureStartSymbolMap,pEnclosureEndSymbolMap)=>{let tmpString=typeof pString=='string'?pString:'';let tmpSeparator=typeof pSeparator=='string'?pSeparator:'.';let tmpEnclosureStartSymbolMap=typeof pEnclosureStartSymbolMap=='object'?pEnclosureStartSymbolMap:DEFAULT_START_SYMBOL_MAP;let tmpEnclosureEndSymbolMap=typeof pEnclosureEndSymbolMap=='object'?pEnclosureEndSymbolMap:DEFAULT_END_SYMBOL_MAP;let tmpCurrentSegmentStart=0;let tmpSegmentList=[];if(tmpString.length<1){return tmpSegmentList;}let tmpEnclosureStack=[];for(let i=0;i<tmpString.length;i++){// IF This is the start of a segment
1408
1415
  if(tmpString[i]==tmpSeparator// AND we are not in a nested portion of the string
1409
1416
  &&tmpEnclosureStack.length==0){// Return the segment
1410
1417
  tmpSegmentList.push(tmpString.substring(tmpCurrentSegmentStart,i));tmpCurrentSegmentStart=i+1;}// IF This is the start of an enclosure
@@ -1441,7 +1448,7 @@ else if(tmpString[i]==tmpEnclosureEnd){tmpEnclosureDepth--;// Again, only count
1441
1448
  if(tmpEnclosureDepth==0&&tmpMatchedEnclosureIndex&&tmpEnclosedValueEndIndex<=tmpEnclosedValueStartIndex){tmpEnclosedValueEndIndex=i;tmpMatchedEnclosureIndex=false;}}}if(tmpEnclosureCount<=tmpEnclosureIndexToGet){// Return an empty string if the enclosure is not found
1442
1449
  return'';}if(tmpEnclosedValueEndIndex>0&&tmpEnclosedValueEndIndex>tmpEnclosedValueStartIndex){return tmpString.substring(tmpEnclosedValueStartIndex+1,tmpEnclosedValueEndIndex);}else{return tmpString.substring(tmpEnclosedValueStartIndex+1);}}};},{}],88:[function(require,module,exports){/**
1443
1450
  * @author <steven@velozo.com>
1444
- */let libSimpleLog=require('./Manyfest-LogToConsole.js');let fCleanWrapCharacters=require('./Manyfest-CleanWrapCharacters.js');/**
1451
+ */let libSimpleLog=require('./Manyfest-LogToConsole.js');let fCleanWrapCharacters=require('./Manyfest-CleanWrapCharacters.js');let _MockFable={DataFormat:require('./Manyfest-ObjectAddress-Parser.js')};/**
1445
1452
  * Object Address Resolver - SetValue
1446
1453
  *
1447
1454
  * IMPORTANT NOTE: This code is intentionally more verbose than necessary, to
@@ -1472,7 +1479,8 @@ this.logInfo=typeof pInfoLog=='function'?pInfoLog:libSimpleLog;this.logError=typ
1472
1479
  * @return {boolean} True if the value was set, false otherwise
1473
1480
  */setValueAtAddress(pObject,pAddress,pValue){// Make sure pObject is an object
1474
1481
  if(typeof pObject!='object')return false;// Make sure pAddress is a string
1475
- if(typeof pAddress!='string')return false;let tmpSeparatorIndex=pAddress.indexOf('.');if(tmpSeparatorIndex==-1){// Check if it's a boxed property
1482
+ if(typeof pAddress!='string')return false;// Use enclosure-aware parser to find the first segment separator
1483
+ let tmpAddressPartBeginning=_MockFable.DataFormat.stringGetFirstSegment(pAddress);if(tmpAddressPartBeginning.length==pAddress.length){// Check if it's a boxed property
1476
1484
  let tmpBracketStartIndex=pAddress.indexOf('[');let tmpBracketStopIndex=pAddress.indexOf(']');// Boxed elements look like this:
1477
1485
  // MyValues[10]
1478
1486
  // MyValues['Name']
@@ -1503,7 +1511,7 @@ pObject[tmpBoxedPropertyName][tmpBoxedPropertyReference]={};}// Return the value
1503
1511
  //TODO: For cases where we have chained [][] properties, this needs to recurse somehow
1504
1512
  pObject[tmpBoxedPropertyName][tmpBoxedPropertyReference]=pValue;return true;}else{while(pObject[tmpBoxedPropertyName].length<tmpBoxedPropertyNumber+1){// If the subobject doesn't exist, create it
1505
1513
  pObject[tmpBoxedPropertyName].push({});}pObject[tmpBoxedPropertyName][tmpBoxedPropertyNumber]=pValue;return true;}}else{// Now is the time in recursion to set the value in the object
1506
- pObject[pAddress]=pValue;return true;}}else{let tmpSubObjectName=pAddress.substring(0,tmpSeparatorIndex);let tmpNewAddress=pAddress.substring(tmpSeparatorIndex+1);// Test if the tmpNewAddress is an array or object
1514
+ pObject[pAddress]=pValue;return true;}}else{let tmpSubObjectName=tmpAddressPartBeginning;let tmpNewAddress=pAddress.substring(tmpAddressPartBeginning.length+1);// Test if the tmpNewAddress is an array or object
1507
1515
  // Check if it's a boxed property
1508
1516
  let tmpBracketStartIndex=tmpSubObjectName.indexOf('[');let tmpBracketStopIndex=tmpSubObjectName.indexOf(']');// Boxed elements look like this:
1509
1517
  // MyValues[42]
@@ -1544,7 +1552,7 @@ return this.setValueAtAddress(pObject[tmpBoxedPropertyName][tmpBoxedPropertyNumb
1544
1552
  if(tmpSubObjectName in pObject&&typeof pObject[tmpSubObjectName]!=='object'){if(!('__ERROR'in pObject))pObject['__ERROR']={};// Put it in an error object so data isn't lost
1545
1553
  pObject['__ERROR'][pAddress]=pValue;return false;}else if(tmpSubObjectName in pObject){// If there is already a subobject pass that to the recursive thingy
1546
1554
  return this.setValueAtAddress(pObject[tmpSubObjectName],tmpNewAddress,pValue);}else{// Create a subobject and then pass that
1547
- pObject[tmpSubObjectName]={};return this.setValueAtAddress(pObject[tmpSubObjectName],tmpNewAddress,pValue);}}}};module.exports=ManyfestObjectAddressSetValue;},{"./Manyfest-CleanWrapCharacters.js":81,"./Manyfest-LogToConsole.js":83}],89:[function(require,module,exports){/**
1555
+ pObject[tmpSubObjectName]={};return this.setValueAtAddress(pObject[tmpSubObjectName],tmpNewAddress,pValue);}}}};module.exports=ManyfestObjectAddressSetValue;},{"./Manyfest-CleanWrapCharacters.js":81,"./Manyfest-LogToConsole.js":83,"./Manyfest-ObjectAddress-Parser.js":87}],89:[function(require,module,exports){/**
1548
1556
  * @author <steven@velozo.com>
1549
1557
  */let libSimpleLog=require('./Manyfest-LogToConsole.js');/**
1550
1558
  * Object Address Generation
@@ -1604,7 +1612,7 @@ break;}return tmpSchema;}};module.exports=ManyfestObjectAddressGeneration;},{"./
1604
1612
  const _ConditionalStanzaStart='<<~?';const _ConditionalStanzaStartLength=_ConditionalStanzaStart.length;const _ConditionalStanzaEnd='?~>>';const _ConditionalStanzaEndLength=_ConditionalStanzaEnd.length;// Ugh dependency injection. Can't wait to make these all fable services.
1605
1613
  //let libObjectAddressCheckAddressExists = new (require('./Manyfest-ObjectAddress-CheckAddressExists.js'))();
1606
1614
  // Test the condition of a value in a record
1607
- const testCondition=(pManyfest,pRecord,pSearchAddress,pSearchComparator,pValue)=>{switch(pSearchComparator){case'TRUE':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)===true;break;case'FALSE':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)===false;break;case'LNGT':case'LENGTH_GREATER_THAN':switch(typeof pManyfest.getValueAtAddress(pRecord,pSearchAddress)){case'string':return pManyfest.getValueAtAddress(pRecord,pSearchAddress).length>pValue;break;case'object':return pManyfest.getValueAtAddress(pRecord,pSearchAddress).length>pValue;break;default:return false;break;}break;case'LNLT':case'LENGTH_LESS_THAN':switch(typeof pManyfest.getValueAtAddress(pRecord,pSearchAddress)){case'string':return pManyfest.getValueAtAddress(pRecord,pSearchAddress).length<pValue;break;case'object':return pManyfest.getValueAtAddress(pRecord,pSearchAddress).length<pValue;break;default:return false;break;}break;// TODO: Welcome to dependency hell. This fixes itself when we move to fable services.
1615
+ const testCondition=(pManyfest,pRecord,pSearchAddress,pSearchComparator,pValue)=>{switch(pSearchComparator){case'TRUE':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)===true;case'FALSE':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)===false;case'LNGT':case'LENGTH_GREATER_THAN':switch(typeof pManyfest.getValueAtAddress(pRecord,pSearchAddress)){case'string':return pManyfest.getValueAtAddress(pRecord,pSearchAddress).length>pValue;case'object':return pManyfest.getValueAtAddress(pRecord,pSearchAddress).length>pValue;default:return false;break;}break;case'LNLT':case'LENGTH_LESS_THAN':switch(typeof pManyfest.getValueAtAddress(pRecord,pSearchAddress)){case'string':return pManyfest.getValueAtAddress(pRecord,pSearchAddress).length<pValue;case'object':return pManyfest.getValueAtAddress(pRecord,pSearchAddress).length<pValue;default:return false;break;}break;// TODO: Welcome to dependency hell. This fixes itself when we move to fable services.
1608
1616
  // case 'EX':
1609
1617
  // case 'EXISTS':
1610
1618
  // return libObjectAddressCheckAddressExists.checkAddressExists(pRecord, pSearchAddress);
@@ -1613,7 +1621,7 @@ const testCondition=(pManyfest,pRecord,pSearchAddress,pSearchComparator,pValue)=
1613
1621
  // case 'DOES_NOT_EXIST':
1614
1622
  // return !libObjectAddressCheckAddressExists.checkAddressExists(pRecord, pSearchAddress);
1615
1623
  // break;
1616
- case'!=':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)!=pValue;break;case'<':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)<pValue;break;case'>':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)>pValue;break;case'<=':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)<=pValue;break;case'>=':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)>=pValue;break;case'===':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)===pValue;break;case'==':default:return pManyfest.getValueAtAddress(pRecord,pSearchAddress)==pValue;break;}};const parseConditionals=(pManyfest,pAddress,pRecord)=>{let tmpKeepRecord=true;/*
1624
+ case'!=':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)!=pValue;case'<':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)<pValue;case'>':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)>pValue;case'<=':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)<=pValue;case'>=':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)>=pValue;case'===':return pManyfest.getValueAtAddress(pRecord,pSearchAddress)===pValue;case'==':default:return pManyfest.getValueAtAddress(pRecord,pSearchAddress)==pValue;}};const parseConditionals=(pManyfest,pAddress,pRecord)=>{let tmpKeepRecord=true;/*
1617
1625
  Algorithm is simple:
1618
1626
 
1619
1627
  1. Enuerate start points
@@ -1707,9 +1715,8 @@ tmpNewManyfest.hashTranslations.addTranslation(this.hashTranslations.translation
1707
1715
  * @return {Manyfest} The deserialized manifest
1708
1716
  */deserialize(pManifestString){// TODO: Add guards for bad manifest string
1709
1717
  this.loadManifest(JSON.parse(pManifestString));return this;}// Load a manifest from an object
1710
- loadManifest(pManifest){if(typeof pManifest!=='object'){this.logError(`(${this.scope}) Error loading manifest; expecting an object but parameter was type ${typeof pManifest}.`);}let tmpManifest=typeof pManifest=='object'?pManifest:{};let tmpDescriptorKeys=Object.keys(_DefaultConfiguration);for(let i=0;i<tmpDescriptorKeys.length;i++){if(!(tmpDescriptorKeys[i]in tmpManifest)){tmpManifest[tmpDescriptorKeys[i]]=JSON.parse(JSON.stringify(_DefaultConfiguration[tmpDescriptorKeys[i]]));}}if('Scope'in tmpManifest){if(typeof tmpManifest.Scope==='string'){this.scope=tmpManifest.Scope;}else{this.logError(`(${this.scope}) Error loading scope from manifest; expecting a string but property was type ${typeof tmpManifest.Scope}.`,tmpManifest);}}else{this.logError(`(${this.scope}) Error loading scope from manifest object. Property "Scope" does not exist in the root of the object.`,tmpManifest);}if('Descriptors'in tmpManifest){if(typeof tmpManifest.Descriptors==='object'){let tmpDescriptionAddresses=Object.keys(tmpManifest.Descriptors);for(let i=0;i<tmpDescriptionAddresses.length;i++){this.addDescriptor(tmpDescriptionAddresses[i],tmpManifest.Descriptors[tmpDescriptionAddresses[i]]);}}else{this.logError(`(${this.scope}) Error loading description object from manifest object. Expecting an object in 'Manifest.Descriptors' but the property was type ${typeof tmpManifest.Descriptors}.`,tmpManifest);}}else{this.logError(`(${this.scope}) Error loading object description from manifest object. Property "Descriptors" does not exist in the root of the Manifest object.`,tmpManifest);}if('HashTranslations'in tmpManifest){if(typeof tmpManifest.HashTranslations==='object'){for(let i=0;i<tmpManifest.HashTranslations.length;i++){// Each translation is
1711
- //FIXME: ?????????
1712
- }}}}/**
1718
+ loadManifest(pManifest){if(typeof pManifest!=='object'){this.logError(`(${this.scope}) Error loading manifest; expecting an object but parameter was type ${typeof pManifest}.`);}let tmpManifest=typeof pManifest=='object'?pManifest:{};let tmpDescriptorKeys=Object.keys(_DefaultConfiguration);for(let i=0;i<tmpDescriptorKeys.length;i++){if(!(tmpDescriptorKeys[i]in tmpManifest)){tmpManifest[tmpDescriptorKeys[i]]=JSON.parse(JSON.stringify(_DefaultConfiguration[tmpDescriptorKeys[i]]));}}if('Scope'in tmpManifest){if(typeof tmpManifest.Scope==='string'){this.scope=tmpManifest.Scope;}else{this.logError(`(${this.scope}) Error loading scope from manifest; expecting a string but property was type ${typeof tmpManifest.Scope}.`,tmpManifest);}}else{this.logError(`(${this.scope}) Error loading scope from manifest object. Property "Scope" does not exist in the root of the object.`,tmpManifest);}if('Descriptors'in tmpManifest){if(typeof tmpManifest.Descriptors==='object'){let tmpDescriptionAddresses=Object.keys(tmpManifest.Descriptors);for(let i=0;i<tmpDescriptionAddresses.length;i++){this.addDescriptor(tmpDescriptionAddresses[i],tmpManifest.Descriptors[tmpDescriptionAddresses[i]]);}}else{this.logError(`(${this.scope}) Error loading description object from manifest object. Expecting an object in 'Manifest.Descriptors' but the property was type ${typeof tmpManifest.Descriptors}.`,tmpManifest);}}else{this.logError(`(${this.scope}) Error loading object description from manifest object. Property "Descriptors" does not exist in the root of the Manifest object.`,tmpManifest);}if('HashTranslations'in tmpManifest){if(typeof tmpManifest.HashTranslations==='object'){// HashTranslations is serialized as a plain object of source:target pairs
1719
+ this.hashTranslations.addTranslation(tmpManifest.HashTranslations);}}}/**
1713
1720
  * Serialize the Manifest to a string
1714
1721
  *
1715
1722
  * @return {string} - The serialized manifest
@@ -1748,20 +1755,22 @@ else if(tmpInTranslationTable){tmpAddress=this.hashTranslations.translate(pHash)
1748
1755
  // TODO: Discuss this ... it is magic but controversial
1749
1756
  else{tmpAddress=pHash;}return tmpAddress;}// Get the value of an element by its hash
1750
1757
  getValueByHash(pObject,pHash){let tmpValue=this.getValueAtAddress(pObject,this.resolveHashAddress(pHash));if(typeof tmpValue=='undefined'){// Try to get a default if it exists
1751
- tmpValue=this.getDefaultValue(this.getDescriptorByHash(pHash));}return tmpValue;}lintAddress(pAddress){let tmpLintedAddress=pAddress.trim();// Check for a single . (but not a ..) at the end of the address and remove it.
1752
- if(tmpLintedAddress.endsWith('..')){tmpLintedAddress=tmpLintedAddress.slice(0,-1);}else if(tmpLintedAddress.endsWith('.')){tmpLintedAddress=tmpLintedAddress.slice(0,-1);}return tmpLintedAddress;}// Get the value of an element at an address
1758
+ tmpValue=this.getDefaultValue(this.getDescriptorByHash(pHash));}return tmpValue;}lintAddress(pAddress){// Guard against non-string input
1759
+ if(typeof pAddress!='string'){return'';}let tmpLintedAddress=pAddress.trim();// Check for a single trailing . (but not a ..) at the end of the address and remove it.
1760
+ // We must not strip '..' because that is back-navigation syntax.
1761
+ if(tmpLintedAddress.endsWith('.')&&!tmpLintedAddress.endsWith('..')){tmpLintedAddress=tmpLintedAddress.slice(0,-1);}return tmpLintedAddress;}// Get the value of an element at an address
1753
1762
  getValueAtAddress(pObject,pAddress){let tmpLintedAddress=this.lintAddress(pAddress);if(tmpLintedAddress==''){this.logError(`(${this.scope}) Error getting value at address; address is an empty string.`,pObject);return undefined;}let tmpValue=this.objectAddressGetValue.getValueAtAddress(pObject,tmpLintedAddress);if(typeof tmpValue=='undefined'){// Try to get a default if it exists
1754
1763
  tmpValue=this.getDefaultValue(this.getDescriptor(tmpLintedAddress));}return tmpValue;}// Set the value of an element by its hash
1755
1764
  setValueByHash(pObject,pHash,pValue){return this.setValueAtAddress(pObject,this.resolveHashAddress(pHash),pValue);}// Set the value of an element at an address
1756
1765
  setValueAtAddress(pObject,pAddress,pValue){let tmpLintedAddress=this.lintAddress(pAddress);return this.objectAddressSetValue.setValueAtAddress(pObject,tmpLintedAddress,pValue);}// Delete the value of an element by its hash
1757
- deleteValueByHash(pObject,pHash,pValue){return this.deleteValueAtAddress(pObject,this.resolveHashAddress(pHash),pValue);}// Delete the value of an element at an address
1758
- deleteValueAtAddress(pObject,pAddress,pValue){let tmpLintedAddress=this.lintAddress(pAddress);return this.objectAddressDeleteValue.deleteValueAtAddress(pObject,tmpLintedAddress,pValue);}// Validate the consistency of an object against the schema
1766
+ deleteValueByHash(pObject,pHash){return this.deleteValueAtAddress(pObject,this.resolveHashAddress(pHash));}// Delete the value of an element at an address
1767
+ deleteValueAtAddress(pObject,pAddress){let tmpLintedAddress=this.lintAddress(pAddress);return this.objectAddressDeleteValue.deleteValueAtAddress(pObject,tmpLintedAddress);}// Validate the consistency of an object against the schema
1759
1768
  validate(pObject){let tmpValidationData={Error:null,Errors:[],MissingElements:[]};if(typeof pObject!=='object'){tmpValidationData.Error=true;tmpValidationData.Errors.push(`Expected passed in object to be type object but was passed in ${typeof pObject}`);}let addValidationError=(pAddress,pErrorMessage)=>{tmpValidationData.Error=true;tmpValidationData.Errors.push(`Element at address "${pAddress}" ${pErrorMessage}.`);};// Now enumerate through the values and check for anomalies based on the schema
1760
1769
  for(let i=0;i<this.elementAddresses.length;i++){let tmpDescriptor=this.getDescriptor(this.elementAddresses[i]);let tmpValueExists=this.checkAddressExists(pObject,tmpDescriptor.Address);let tmpValue=this.getValueAtAddress(pObject,tmpDescriptor.Address);if(typeof tmpValue=='undefined'||!tmpValueExists){// This will technically mean that `Object.Some.Value = undefined` will end up showing as "missing"
1761
1770
  // TODO: Do we want to do a different message based on if the property exists but is undefined?
1762
1771
  tmpValidationData.MissingElements.push(tmpDescriptor.Address);if(tmpDescriptor.Required||this.options.strict){addValidationError(tmpDescriptor.Address,'is flagged REQUIRED but is not set in the object');}}// Now see if there is a data type specified for this element
1763
1772
  if(tmpDescriptor.DataType){let tmpElementType=typeof tmpValue;switch(tmpDescriptor.DataType.toString().trim().toLowerCase()){case'string':if(tmpElementType!='string'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is of the type ${tmpElementType}`);}break;case"precisenumber":if(tmpElementType!='string'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is of the type ${tmpElementType}`);}else if(!this.numberRegex.test(tmpValue)){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is not a valid number`);}break;case'number':if(tmpElementType!='number'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is of the type ${tmpElementType}`);}break;case'integer':if(tmpElementType!='number'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is of the type ${tmpElementType}`);}else{let tmpValueString=tmpValue.toString();if(tmpValueString.indexOf('.')>-1){// TODO: Is this an error?
1764
- addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but has a decimal point in the number.`);}}break;case'float':if(tmpElementType!='number'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is of the type ${tmpElementType}`);}break;case'datetime':let tmpValueDate=new Date(tmpValue);if(tmpValueDate.toString()=='Invalid Date'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is not parsable as a Date by Javascript`);}default:// Check if this is a string, in the default case
1773
+ addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but has a decimal point in the number.`);}}break;case'float':if(tmpElementType!='number'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is of the type ${tmpElementType}`);}break;case'boolean':if(tmpElementType!='boolean'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is of the type ${tmpElementType}`);}break;case'datetime':let tmpValueDate=new Date(tmpValue);if(tmpValueDate.toString()=='Invalid Date'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} but is not parsable as a Date by Javascript`);}break;default:// Check if this is a string, in the default case
1765
1774
  // Note this is only when a DataType is specified and it is an unrecognized data type.
1766
1775
  if(tmpElementType!='string'){addValidationError(tmpDescriptor.Address,`has a DataType ${tmpDescriptor.DataType} (which auto-converted to String because it was unrecognized) but is of the type ${tmpElementType}`);}break;}}}return tmpValidationData;}/**
1767
1776
  * Returns a default value, or, the default value for the data type (which is overridable with configuration)
@@ -1769,7 +1778,8 @@ if(tmpElementType!='string'){addValidationError(tmpDescriptor.Address,`has a Dat
1769
1778
  * @param {ManifestDescriptor} pDescriptor - The descriptor definition.
1770
1779
  */getDefaultValue(pDescriptor){if(typeof pDescriptor!='object'){return undefined;}if('Default'in pDescriptor){return pDescriptor.Default;}else{// Default to a null if it doesn't have a type specified.
1771
1780
  // This will ensure a placeholder is created but isn't misinterpreted.
1772
- let tmpDataType='DataType'in pDescriptor?pDescriptor.DataType:'String';if(tmpDataType in this.options.defaultValues){return this.options.defaultValues[tmpDataType];}else{// give up and return null
1781
+ let tmpDataType='DataType'in pDescriptor?pDescriptor.DataType:'String';if(tmpDataType in this.options.defaultValues){let tmpDefaultValue=this.options.defaultValues[tmpDataType];// Return a copy of mutable defaults (Array and Object) to prevent shared state
1782
+ if(typeof tmpDefaultValue=='object'&&tmpDefaultValue!==null){return JSON.parse(JSON.stringify(tmpDefaultValue));}return tmpDefaultValue;}else{// give up and return null
1773
1783
  return null;}}}// Enumerate through the schema and populate default values if they don't exist.
1774
1784
  populateDefaults(pObject,pOverwriteProperties){return this.populateObject(pObject,pOverwriteProperties,// This just sets up a simple filter to see if there is a default set.
1775
1785
  pDescriptor=>{return'Default'in pDescriptor;});}// Forcefully populate all values even if they don't have defaults.
@@ -3181,7 +3191,7 @@ try{if(!global.localStorage)return false;}catch(_){return false;}var val=global.
3181
3191
  // presumably different callback function.
3182
3192
  // This makes sure that own properties are retained, so that
3183
3193
  // decorations and such are not lost along the way.
3184
- module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],148:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],149:[function(require,module,exports){module.exports={"name":"fable","version":"3.1.52","description":"A service dependency injection, configuration and logging library.","main":"source/Fable.js","scripts":{"start":"node source/Fable.js","coverage":"./node_modules/.bin/nyc --reporter=lcov --reporter=text-lcov ./node_modules/mocha/bin/_mocha -- -u tdd -R spec","test":"./node_modules/.bin/mocha -u tdd -R spec","build":"npx quack build","docker-dev-build":"docker build ./ -f Dockerfile_LUXURYCode -t fable-image:local","docker-dev-run":"docker run -it -d --name fable-dev -p 30001:8080 -p 38086:8086 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/fable\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" fable-image:local","docker-dev-shell":"docker exec -it fable-dev /bin/bash","tests":"./node_modules/mocha/bin/_mocha -u tdd --exit -R spec --grep"},"mocha":{"diff":true,"extension":["js"],"package":"./package.json","reporter":"spec","slow":"75","timeout":"5000","ui":"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},"browser":{"./source/service/Fable-Service-EnvironmentData.js":"./source/service/Fable-Service-EnvironmentData-Web.js","./source/service/Fable-Service-FilePersistence.js":"./source/service/Fable-Service-FilePersistence-Web.js"},"repository":{"type":"git","url":"https://github.com/stevenvelozo/fable.git"},"keywords":["entity","behavior"],"author":"Steven Velozo <steven@velozo.com> (http://velozo.com/)","license":"MIT","bugs":{"url":"https://github.com/stevenvelozo/fable/issues"},"homepage":"https://github.com/stevenvelozo/fable","devDependencies":{"quackage":"^1.0.45"},"dependencies":{"async.eachlimit":"^0.5.2","async.waterfall":"^0.5.2","big.js":"^7.0.1","cachetrax":"^1.0.4","cookie":"^1.0.2","data-arithmatic":"^1.0.7","dayjs":"^1.11.19","fable-log":"^3.0.16","fable-serviceproviderbase":"^3.0.15","fable-settings":"^3.0.12","fable-uuid":"^3.0.11","manyfest":"^1.0.43","simple-get":"^4.0.1"}};},{}],150:[function(require,module,exports){/**
3194
+ module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],148:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],149:[function(require,module,exports){module.exports={"name":"fable","version":"3.1.55","description":"A service dependency injection, configuration and logging library.","main":"source/Fable.js","scripts":{"start":"node source/Fable.js","coverage":"./node_modules/.bin/nyc --reporter=lcov --reporter=text-lcov ./node_modules/mocha/bin/_mocha -- -u tdd -R spec","test":"./node_modules/.bin/mocha -u tdd -R spec","build":"npx quack build","docker-dev-build":"docker build ./ -f Dockerfile_LUXURYCode -t fable-image:local","docker-dev-run":"docker run -it -d --name fable-dev -p 30001:8080 -p 38086:8086 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/fable\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" fable-image:local","docker-dev-shell":"docker exec -it fable-dev /bin/bash","tests":"./node_modules/mocha/bin/_mocha -u tdd --exit -R spec --grep"},"mocha":{"diff":true,"extension":["js"],"package":"./package.json","reporter":"spec","slow":"75","timeout":"5000","ui":"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},"browser":{"./source/service/Fable-Service-EnvironmentData.js":"./source/service/Fable-Service-EnvironmentData-Web.js","./source/service/Fable-Service-FilePersistence.js":"./source/service/Fable-Service-FilePersistence-Web.js"},"repository":{"type":"git","url":"https://github.com/stevenvelozo/fable.git"},"keywords":["entity","behavior"],"author":"Steven Velozo <steven@velozo.com> (http://velozo.com/)","license":"MIT","bugs":{"url":"https://github.com/stevenvelozo/fable/issues"},"homepage":"https://github.com/stevenvelozo/fable","devDependencies":{"quackage":"^1.0.50"},"dependencies":{"async.eachlimit":"^0.5.2","async.waterfall":"^0.5.2","big.js":"^7.0.1","cachetrax":"^1.0.4","cookie":"^1.0.2","data-arithmatic":"^1.0.7","dayjs":"^1.11.19","fable-log":"^3.0.16","fable-serviceproviderbase":"^3.0.17","fable-settings":"^3.0.14","fable-uuid":"^3.0.11","manyfest":"^1.0.44","simple-get":"^4.0.1"}};},{}],150:[function(require,module,exports){/**
3185
3195
  * Fable Application Services Support Library
3186
3196
  * @author <steven@velozo.com>
3187
3197
  */// Pre-init services
@@ -3957,7 +3967,7 @@ tmpCurrentTokenType='Value';tmpCurrentToken+=tmpCharacter;// continue;
3957
3967
  // tmpResults.ExpressionParserLog.push(`ExpressionParser.tokenize found an unknown character code ${tmpCharCode} character ${tmpCharacter} in the expression: ${pExpression} at index ${i}`);
3958
3968
  // this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);
3959
3969
  }if(tmpCurrentTokenType&&tmpCurrentToken.length>0){tmpResults.RawTokens.push(tmpCurrentToken);}tmpResults.OriginalRawTokens=Array.from(tmpResults.RawTokens);// Potentially mutate the tokens based on directives in the tokenized expression
3960
- this.TokenizerDirectiveMutation.parseDirectives(tmpResults);return tmpResults.RawTokens;}}module.exports=ExpressionTokenizer;},{"./Fable-Service-ExpressionParser-Base.js":159}],162:[function(require,module,exports){module.exports={"sqrt":{"Name":"Square Root","Address":"fable.Math.sqrtPrecise"},"percent":{"Name":"Compute Percent (in IS over OF format)","Address":"fable.Math.percentagePrecise"},"compare":{"Name":"Compare","Address":"fable.Math.comparePrecise"},"abs":{"Name":"Absolute Value","Address":"fable.Math.absPrecise"},"floor":{"Name":"Floor Value","Address":"fable.Math.floorPrecise"},"ceil":{"Name":"Ceiling Value","Address":"fable.Math.ceilPrecise"},"rad":{"Name":"Degrees to Radians","Address":"fable.Math.radPrecise"},"pi":{"Name":"Pi","Address":"fable.Math.piPrecise"},"euler":{"Name":"Euler","Address":"fable.Math.eulerPrecise"},"log":{"Name":"Logarithm","Address":"fable.Math.logPrecise"},"exp":{"Name":"Eulers Number to the Power Of N","Address":"fable.Math.expPrecise"},"sin":{"Name":"Sine","Address":"fable.Math.sin"},"cos":{"Name":"Cosine","Address":"fable.Math.cos"},"tan":{"Name":"Tangent","Address":"fable.Math.tan"},"count":{"Name":"Count Set Elements","Address":"fable.Math.countSetElements"},"countset":{"Name":"Count Set Elements","Address":"fable.Math.countSetElements"},"sortset":{"Name":"Sort Set","Address":"fable.Math.sortSetPrecise"},"bucketset":{"Name":"Bucket Set","Address":"fable.Math.bucketSetPrecise"},"sorthistogram":{"Name":"Sort Histogram","Address":"fable.Math.sortHistogramPrecise"},"sorthistogrambykeys":{"Name":"Sort Histogram by Keys","Address":"fable.Math.sortHistogramByKeys"},"max":{"Name":"Maximum","Address":"fable.Math.maxPrecise"},"min":{"Name":"Minimum","Address":"fable.Math.minPrecise"},"sum":{"Name":"Sum","Address":"fable.Math.sumPrecise"},"avg":{"Name":"Average","Address":"fable.Math.averagePrecise"},"mean":{"Name":"Mean","Address":"fable.Math.meanPrecise"},"median":{"Name":"Median","Address":"fable.Math.medianPrecise"},"mode":{"Name":"Mode","Address":"fable.Math.modePrecise"},"var":{"Name":"Variance (Sample)","Address":"fable.Math.variancePrecise"},"vara":{"Name":"Variance (Sample)","Address":"fable.Math.variancePrecise"},"varp":{"Name":"Variance (Population)","Address":"fable.Math.populationVariancePrecise"},"stdev":{"Name":"Standard Deviation (Sample)","Address":"fable.Math.standardDeviationPrecise"},"stdeva":{"Name":"Standard Deviation (Sample)","Address":"fable.Math.standardDeviationPrecise"},"stdevp":{"Name":"Standard Deviation (Population)","Address":"fable.Math.populationStandardDeviationPrecise"},"round":{"Name":"Round","Address":"fable.Math.roundPrecise"},"tofixed":{"Name":"To Fixed","Address":"fable.Math.toFixedPrecise"},"cumulativesummation":{"Name":"Sum each value in a Histogram or Value Map cumulatively, creating or setting a property with the result on each row","Address":"fable.Math.cumulativeSummation"},"subtractingsummation":{"Name":"Subtract each subsequent value in a Histogram or Value Map cumulatively (by default from the first row), creating or setting a property with the result on each row.","Address":"fable.Math.subtractingSummation"},"iterativeseries":{"Name":"Perform an Iterative Series of Mathematical Operations on Set Elements","Address":"fable.Math.iterativeSeries"},"countsetelements":{"Name":"Count Set Elements in a Histogram or Value Map","Address":"fable.Math.countSetElements"},"getvalue":{"Name":"Get Value from Application State or Services (AppData, etc.)","Address":"fable.Utility.getInternalValueByHash"},"objectkeystoarray":{"Name":"Get Array of an Object's keys","Address":"fable.Utility.objectKeysToArray"},"objectvaluestoarray":{"Name":"Get Array of an Object's values","Address":"fable.Utility.objectValuesToArray"},"generatearrayofobjectsfromsets":{"Name":"Generate Array of Objects from Sets","Address":"fable.Utility.generateArrayOfObjectsFromSets"},"objectvaluessortbyexternalobjectarray":{"Name":"Get Array of an Object's values sorted by an external array","Address":"fable.Utility.objectValuesSortByExternalArray"},"setkeystoarray":{"Name":"Get Array of an Object's keys","Address":"fable.Utility.objectKeysToArray"},"setvaluestoarray":{"Name":"Get Array of an Object's values","Address":"fable.Utility.objectValuesToArray"},"histogramkeystoarray":{"Name":"Get Array of an Object's keys","Address":"fable.Utility.objectKeysToArray"},"histogramvaluestoarray":{"Name":"Get Array of an Object's values","Address":"fable.Utility.objectValuesToArray"},"createarrayfromabsolutevalues":{"Name":"Create Array from Absolute Values","Address":"fable.Utility.createArrayFromAbsoluteValues"},"flatten":{"Name":"flatten an array of values","Address":"fable.Utility.flattenArrayOfSolverInputs"},"findfirstvaluebyexactmatch":{"Name":"find + map on array of objects","Address":"fable.Utility.findFirstValueByExactMatchInternal"},"findfirstvaluebystringincludes":{"Name":"find + map on array of objects","Address":"fable.Utility.findFirstValueByStringIncludesInternal"},"match":{"Name":"Implementation of sheets MATCH() function","Address":"fable.Utility.findIndexInternal"},"resolvehtmlentities":{"Name":"resolve HTML entities","Address":"fable.DataFormat.resolveHtmlEntities"},"concat":{"Name":"concatenate an array of values and output a string","Address":"fable.DataFormat.concatenateStringsInternal"},"concatraw":{"Name":"concatenate an array of values and output a string","Address":"fable.DataFormat.concatenateStringsRawInternal"},"arrayconcat":{"Name":"concatenate two or more arrays generating a single output array","Address":"fable.Utility.concatenateArrays"},"join":{"Name":"join an array of values and output a string","Address":"fable.DataFormat.joinStringsInternal"},"joinraw":{"Name":"join an array of values and output a string","Address":"fable.DataFormat.joinStringsRawInternal"},"if":{"Name":"perform a conditional operator on two values, and choose one of two outcomes based on the result","Address":"fable.Logic.checkIf"},"when":{"Name":"perform a 'truthy' check on one value, and return one of two outcomes based on the result","Address":"fable.Logic.when"},"entryinset":{"Name":"Entry in Set","Address":"fable.Math.entryInSet"},"smallestinset":{"Name":"Smallest in Set","Address":"fable.Math.smallestInSet"},"largestinset":{"Name":"Largest in Set","Address":"fable.Math.largestInSet"},"aggregationhistogram":{"Name":"Generate a Histogram by Exact Value Aggregation","Address":"fable.Math.histogramAggregationByExactValueFromInternalState"},"aggregationhistogrambyobject":{"Name":"Generate a Histogram by Exact Value Aggregation from Object Property","Address":"fable.Math.histogramAggregationByExactValue"},"distributionhistogram":{"Name":"Generate a Histogram Based on Value Distribution","Address":"fable.Math.histogramDistributionByExactValueFromInternalState"},"distributionhistogrambyobject":{"Name":"Generate a Histogram Based on Value Distribution from Object Property","Address":"fable.Math.histogramDistributionByExactValue"},"setconcatenate":{"Name":"Set Concatenate","Address":"fable.Math.setConcatenate"},"getvaluearray":{"Name":"Get Value Array from Application State or Services (AppData, etc.)","Address":"fable.Utility.createValueArrayByHashParametersFromInternal"},"getvalueobject":{"Name":"Get Value Object from Application State or Services (AppData, etc.)","Address":"fable.Utility.createValueObjectByHashParametersFromInternal"},"cleanvaluearray":{"Name":"Clean Value Array","Address":"fable.Math.cleanValueArray"},"cleanvalueobject":{"Name":"Clean Value Object","Address":"fable.Math.cleanValueObject"},"polynomialregression":{"Name":"Perform an nth degree Polynomial Regression on a Set of X and Y Values","Address":"fable.Math.polynomialRegression"},"randominteger":{"Name":"Random Integer","Address":"fable.DataGeneration.randomInteger"},"randomintegerbetween":{"Name":"Random Integer Between Two Numbers","Address":"fable.DataGeneration.randomIntegerBetween"},"randomintegerupto":{"Name":"Random Integer","Address":"fable.DataGeneration.randomIntegerUpTo"},"randomfloat":{"Name":"Random Float","Address":"fable.DataGeneration.randomFloat"},"randomfloatbetween":{"Name":"Random Float","Address":"fable.DataGeneration.randomFloatBetween"},"randomfloatupto":{"Name":"Random Float","Address":"fable.DataGeneration.randomFloatUpTo"},"datemilliseconddifference":{"Name":"Date Difference in Milliseconds","Address":"fable.Dates.dateMillisecondDifference"},"dateseconddifference":{"Name":"Date Difference in Seconds","Address":"fable.Dates.dateSecondDifference"},"dateminutedifference":{"Name":"Date Difference in Minutes","Address":"fable.Dates.dateMinuteDifference"},"datehourdifference":{"Name":"Date Difference in Hours","Address":"fable.Dates.dateHourDifference"},"datedaydifference":{"Name":"Date Difference in Days","Address":"fable.Dates.dateDayDifference"},"dateweekdifference":{"Name":"Date Difference in Weeks","Address":"fable.Dates.dateWeekDifference"},"datemonthdifference":{"Name":"Date Difference in Months","Address":"fable.Dates.dateMonthDifference"},"dateyeardifference":{"Name":"Date Difference in Years","Address":"fable.Dates.dateYearDifference"},"datemathadd":{"Name":"Date Math Add","Address":"fable.Dates.dateMath"},"dateaddmilliseconds":{"Name":"Date Add Milliseconds","Address":"fable.Dates.dateAddMilliseconds"},"dateaddseconds":{"Name":"Date Add Seconds","Address":"fable.Dates.dateAddSeconds"},"dateaddminutes":{"Name":"Date Add Minutes","Address":"fable.Dates.dateAddMinutes"},"dateaddhours":{"Name":"Date Add Hours","Address":"fable.Dates.dateAddHours"},"dateadddays":{"Name":"Date Add Days","Address":"fable.Dates.dateAddDays"},"dateaddweeks":{"Name":"Date Add Weeks","Address":"fable.Dates.dateAddWeeks"},"dateaddmonths":{"Name":"Date Add Months","Address":"fable.Dates.dateAddMonths"},"dateaddyears":{"Name":"Date Add Years","Address":"fable.Dates.dateAddYears"},"datefromparts":{"Name":"Date From Parts","Address":"fable.Dates.dateFromParts"},"slice":{"Name":"Slice Array","Address":"fable.Utility.slice"},"createvalueobjectbyhashes":{"Name":"Create Value Object by Hashes","Address":"fable.Utility.createValueObjectByHashes"},"polynomialregression":{"Name":"Perform an nth degree Polynomial Regression on a Set of X and Y Values","Address":"fable.Math.polynomialRegression"},"leastsquares":{"Name":"Perform a Least Squares Regression on a Set of Independent Variable Vectors and a Dependent Variable Vector","Address":"fable.Math.leastSquares"},"linest":{"Name":"Perform a Least Squares Regression on a Set of Independent Variable Vectors and a Dependent Variable Vector","Address":"fable.Math.leastSquares"},"matrixtranspose":{"Name":"Transpose a Matrix","Address":"fable.Math.matrixTranspose"},"matrixmultiply":{"Name":"Multiply Two Matrices","Address":"fable.Math.matrixMultiply"},"matrixvectormultiply":{"Name":"Multiply a Matrix by a Vector","Address":"fable.Math.matrixVectorMultiply"},"matrixinverse":{"Name":"Inverse a Matrix","Address":"fable.Math.matrixInverse"},"gaussianelimination":{"Name":"Solve a System of Linear Equations using Gaussian Elimination","Address":"fable.Math.gaussianElimination"},"predict":{"Name":"Predict Y Values from X Values using a Regression Model","Address":"fable.Math.predictFromRegressionModel"},"stringcountsegments":{"Name":"Count Segments in a String","Address":"fable.DataFormat.stringCountSegments"},"stringgetsegments":{"Name":"Get Segments from a String","Address":"fable.DataFormat.stringGetSegments"}};},{}],163:[function(require,module,exports){const libExpressionParserOperationBase=require('./Fable-Service-ExpressionParser-Base.js');class ExpressionParserLinter extends libExpressionParserOperationBase{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this.serviceType='ExpressionParser-Linter';}lintTokenizedExpression(pTokenizedExpression,pResultObject){let tmpResults=typeof pResultObject==='object'?pResultObject:{ExpressionParserLog:[]};tmpResults.LinterResults=[];// Guard against bad data being passed in
3970
+ this.TokenizerDirectiveMutation.parseDirectives(tmpResults);return tmpResults.RawTokens;}}module.exports=ExpressionTokenizer;},{"./Fable-Service-ExpressionParser-Base.js":159}],162:[function(require,module,exports){module.exports={"sqrt":{"Name":"Square Root","Address":"fable.Math.sqrtPrecise"},"percent":{"Name":"Compute Percent (in IS over OF format)","Address":"fable.Math.percentagePrecise"},"compare":{"Name":"Compare","Address":"fable.Math.comparePrecise"},"abs":{"Name":"Absolute Value","Address":"fable.Math.absPrecise"},"floor":{"Name":"Floor Value","Address":"fable.Math.floorPrecise"},"ceil":{"Name":"Ceiling Value","Address":"fable.Math.ceilPrecise"},"rad":{"Name":"Degrees to Radians","Address":"fable.Math.radPrecise"},"pi":{"Name":"Pi","Address":"fable.Math.piPrecise"},"euler":{"Name":"Euler","Address":"fable.Math.eulerPrecise"},"log":{"Name":"Logarithm","Address":"fable.Math.logPrecise"},"exp":{"Name":"Eulers Number to the Power Of N","Address":"fable.Math.expPrecise"},"sin":{"Name":"Sine","Address":"fable.Math.sin"},"cos":{"Name":"Cosine","Address":"fable.Math.cos"},"tan":{"Name":"Tangent","Address":"fable.Math.tan"},"count":{"Name":"Count Set Elements","Address":"fable.Math.countSetElements"},"countset":{"Name":"Count Set Elements","Address":"fable.Math.countSetElements"},"sortset":{"Name":"Sort Set","Address":"fable.Math.sortSetPrecise"},"bucketset":{"Name":"Bucket Set","Address":"fable.Math.bucketSetPrecise"},"sorthistogram":{"Name":"Sort Histogram","Address":"fable.Math.sortHistogramPrecise"},"sorthistogrambykeys":{"Name":"Sort Histogram by Keys","Address":"fable.Math.sortHistogramByKeys"},"max":{"Name":"Maximum","Address":"fable.Math.maxPrecise"},"min":{"Name":"Minimum","Address":"fable.Math.minPrecise"},"sum":{"Name":"Sum","Address":"fable.Math.sumPrecise"},"avg":{"Name":"Average","Address":"fable.Math.averagePrecise"},"mean":{"Name":"Mean","Address":"fable.Math.meanPrecise"},"median":{"Name":"Median","Address":"fable.Math.medianPrecise"},"mode":{"Name":"Mode","Address":"fable.Math.modePrecise"},"var":{"Name":"Variance (Sample)","Address":"fable.Math.variancePrecise"},"vara":{"Name":"Variance (Sample)","Address":"fable.Math.variancePrecise"},"varp":{"Name":"Variance (Population)","Address":"fable.Math.populationVariancePrecise"},"stdev":{"Name":"Standard Deviation (Sample)","Address":"fable.Math.standardDeviationPrecise"},"stdeva":{"Name":"Standard Deviation (Sample)","Address":"fable.Math.standardDeviationPrecise"},"stdevp":{"Name":"Standard Deviation (Population)","Address":"fable.Math.populationStandardDeviationPrecise"},"round":{"Name":"Round","Address":"fable.Math.roundPrecise"},"tofixed":{"Name":"To Fixed","Address":"fable.Math.toFixedPrecise"},"cumulativesummation":{"Name":"Sum each value in a Histogram or Value Map cumulatively, creating or setting a property with the result on each row","Address":"fable.Math.cumulativeSummation"},"subtractingsummation":{"Name":"Subtract each subsequent value in a Histogram or Value Map cumulatively (by default from the first row), creating or setting a property with the result on each row.","Address":"fable.Math.subtractingSummation"},"iterativeseries":{"Name":"Perform an Iterative Series of Mathematical Operations on Set Elements","Address":"fable.Math.iterativeSeries"},"countsetelements":{"Name":"Count Set Elements in a Histogram or Value Map","Address":"fable.Math.countSetElements"},"getvalue":{"Name":"Get Value from Application State or Services (AppData, etc.)","Address":"fable.Utility.getInternalValueByHash"},"setvalue":{"Name":"Set Value to Application State or Services (AppData, etc.)","Address":"fable.Utility.setInternalValueByHash"},"objectkeystoarray":{"Name":"Get Array of an Object's keys","Address":"fable.Utility.objectKeysToArray"},"objectvaluestoarray":{"Name":"Get Array of an Object's values","Address":"fable.Utility.objectValuesToArray"},"generatearrayofobjectsfromsets":{"Name":"Generate Array of Objects from Sets","Address":"fable.Utility.generateArrayOfObjectsFromSets"},"objectvaluessortbyexternalobjectarray":{"Name":"Get Array of an Object's values sorted by an external array","Address":"fable.Utility.objectValuesSortByExternalArray"},"setkeystoarray":{"Name":"Get Array of an Object's keys","Address":"fable.Utility.objectKeysToArray"},"setvaluestoarray":{"Name":"Get Array of an Object's values","Address":"fable.Utility.objectValuesToArray"},"histogramkeystoarray":{"Name":"Get Array of an Object's keys","Address":"fable.Utility.objectKeysToArray"},"histogramvaluestoarray":{"Name":"Get Array of an Object's values","Address":"fable.Utility.objectValuesToArray"},"createarrayfromabsolutevalues":{"Name":"Create Array from Absolute Values","Address":"fable.Utility.createArrayFromAbsoluteValues"},"flatten":{"Name":"flatten an array of values","Address":"fable.Utility.flattenArrayOfSolverInputs"},"findfirstvaluebyexactmatch":{"Name":"find + map on array of objects","Address":"fable.Utility.findFirstValueByExactMatchInternal"},"findfirstvaluebystringincludes":{"Name":"find + map on array of objects","Address":"fable.Utility.findFirstValueByStringIncludesInternal"},"match":{"Name":"Implementation of sheets MATCH() function","Address":"fable.Utility.findIndexInternal"},"resolvehtmlentities":{"Name":"resolve HTML entities","Address":"fable.DataFormat.resolveHtmlEntities"},"concat":{"Name":"concatenate an array of values and output a string","Address":"fable.DataFormat.concatenateStringsInternal"},"concatraw":{"Name":"concatenate an array of values and output a string","Address":"fable.DataFormat.concatenateStringsRawInternal"},"arrayconcat":{"Name":"concatenate two or more arrays generating a single output array","Address":"fable.Utility.concatenateArrays"},"join":{"Name":"join an array of values and output a string","Address":"fable.DataFormat.joinStringsInternal"},"joinraw":{"Name":"join an array of values and output a string","Address":"fable.DataFormat.joinStringsRawInternal"},"if":{"Name":"perform a conditional operator on two values, and choose one of two outcomes based on the result","Address":"fable.Logic.checkIf"},"when":{"Name":"perform a 'truthy' check on one value, and return one of two outcomes based on the result","Address":"fable.Logic.when"},"entryinset":{"Name":"Entry in Set","Address":"fable.Math.entryInSet"},"smallestinset":{"Name":"Smallest in Set","Address":"fable.Math.smallestInSet"},"largestinset":{"Name":"Largest in Set","Address":"fable.Math.largestInSet"},"aggregationhistogram":{"Name":"Generate a Histogram by Exact Value Aggregation","Address":"fable.Math.histogramAggregationByExactValueFromInternalState"},"aggregationhistogrambyobject":{"Name":"Generate a Histogram by Exact Value Aggregation from Object Property","Address":"fable.Math.histogramAggregationByExactValue"},"distributionhistogram":{"Name":"Generate a Histogram Based on Value Distribution","Address":"fable.Math.histogramDistributionByExactValueFromInternalState"},"distributionhistogrambyobject":{"Name":"Generate a Histogram Based on Value Distribution from Object Property","Address":"fable.Math.histogramDistributionByExactValue"},"setconcatenate":{"Name":"Set Concatenate","Address":"fable.Math.setConcatenate"},"getvaluearray":{"Name":"Get Value Array from Application State or Services (AppData, etc.)","Address":"fable.Utility.createValueArrayByHashParametersFromInternal"},"getvalueobject":{"Name":"Get Value Object from Application State or Services (AppData, etc.)","Address":"fable.Utility.createValueObjectByHashParametersFromInternal"},"cleanvaluearray":{"Name":"Clean Value Array","Address":"fable.Math.cleanValueArray"},"cleanvalueobject":{"Name":"Clean Value Object","Address":"fable.Math.cleanValueObject"},"polynomialregression":{"Name":"Perform an nth degree Polynomial Regression on a Set of X and Y Values","Address":"fable.Math.polynomialRegression"},"randominteger":{"Name":"Random Integer","Address":"fable.DataGeneration.randomInteger"},"randomintegerbetween":{"Name":"Random Integer Between Two Numbers","Address":"fable.DataGeneration.randomIntegerBetween"},"randomintegerupto":{"Name":"Random Integer","Address":"fable.DataGeneration.randomIntegerUpTo"},"randomfloat":{"Name":"Random Float","Address":"fable.DataGeneration.randomFloat"},"randomfloatbetween":{"Name":"Random Float","Address":"fable.DataGeneration.randomFloatBetween"},"randomfloatupto":{"Name":"Random Float","Address":"fable.DataGeneration.randomFloatUpTo"},"datemilliseconddifference":{"Name":"Date Difference in Milliseconds","Address":"fable.Dates.dateMillisecondDifference"},"dateseconddifference":{"Name":"Date Difference in Seconds","Address":"fable.Dates.dateSecondDifference"},"dateminutedifference":{"Name":"Date Difference in Minutes","Address":"fable.Dates.dateMinuteDifference"},"datehourdifference":{"Name":"Date Difference in Hours","Address":"fable.Dates.dateHourDifference"},"datedaydifference":{"Name":"Date Difference in Days","Address":"fable.Dates.dateDayDifference"},"dateweekdifference":{"Name":"Date Difference in Weeks","Address":"fable.Dates.dateWeekDifference"},"datemonthdifference":{"Name":"Date Difference in Months","Address":"fable.Dates.dateMonthDifference"},"dateyeardifference":{"Name":"Date Difference in Years","Address":"fable.Dates.dateYearDifference"},"datemathadd":{"Name":"Date Math Add","Address":"fable.Dates.dateMath"},"dateaddmilliseconds":{"Name":"Date Add Milliseconds","Address":"fable.Dates.dateAddMilliseconds"},"dateaddseconds":{"Name":"Date Add Seconds","Address":"fable.Dates.dateAddSeconds"},"dateaddminutes":{"Name":"Date Add Minutes","Address":"fable.Dates.dateAddMinutes"},"dateaddhours":{"Name":"Date Add Hours","Address":"fable.Dates.dateAddHours"},"dateadddays":{"Name":"Date Add Days","Address":"fable.Dates.dateAddDays"},"dateaddweeks":{"Name":"Date Add Weeks","Address":"fable.Dates.dateAddWeeks"},"dateaddmonths":{"Name":"Date Add Months","Address":"fable.Dates.dateAddMonths"},"dateaddyears":{"Name":"Date Add Years","Address":"fable.Dates.dateAddYears"},"datefromparts":{"Name":"Date From Parts","Address":"fable.Dates.dateFromParts"},"slice":{"Name":"Slice Array","Address":"fable.Utility.slice"},"createvalueobjectbyhashes":{"Name":"Create Value Object by Hashes","Address":"fable.Utility.createValueObjectByHashes"},"polynomialregression":{"Name":"Perform an nth degree Polynomial Regression on a Set of X and Y Values","Address":"fable.Math.polynomialRegression"},"leastsquares":{"Name":"Perform a Least Squares Regression on a Set of Independent Variable Vectors and a Dependent Variable Vector","Address":"fable.Math.leastSquares"},"linest":{"Name":"Perform a Least Squares Regression on a Set of Independent Variable Vectors and a Dependent Variable Vector","Address":"fable.Math.leastSquares"},"matrixtranspose":{"Name":"Transpose a Matrix","Address":"fable.Math.matrixTranspose"},"matrixmultiply":{"Name":"Multiply Two Matrices","Address":"fable.Math.matrixMultiply"},"matrixvectormultiply":{"Name":"Multiply a Matrix by a Vector","Address":"fable.Math.matrixVectorMultiply"},"matrixinverse":{"Name":"Inverse a Matrix","Address":"fable.Math.matrixInverse"},"gaussianelimination":{"Name":"Solve a System of Linear Equations using Gaussian Elimination","Address":"fable.Math.gaussianElimination"},"predict":{"Name":"Predict Y Values from X Values using a Regression Model","Address":"fable.Math.predictFromRegressionModel"},"stringcountsegments":{"Name":"Count Segments in a String","Address":"fable.DataFormat.stringCountSegments"},"stringgetsegments":{"Name":"Get Segments from a String","Address":"fable.DataFormat.stringGetSegments"}};},{}],163:[function(require,module,exports){const libExpressionParserOperationBase=require('./Fable-Service-ExpressionParser-Base.js');class ExpressionParserLinter extends libExpressionParserOperationBase{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this.serviceType='ExpressionParser-Linter';}lintTokenizedExpression(pTokenizedExpression,pResultObject){let tmpResults=typeof pResultObject==='object'?pResultObject:{ExpressionParserLog:[]};tmpResults.LinterResults=[];// Guard against bad data being passed in
3961
3971
  if(!Array.isArray(pTokenizedExpression)){tmpResults.ExpressionParserLog.push(`ERROR: ExpressionParser.lintTokenizedExpression was passed a non-array tokenized expression.`);tmpResults.LinterResults.push(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return pTokenizedExpression;}if(pTokenizedExpression.length<1){tmpResults.ExpressionParserLog.push(`ERROR: ExpressionParser.lintTokenizedExpression was passed an empty tokenized expression.`);tmpResults.LinterResults.push(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return pTokenizedExpression;}// 1. Check for balanced parenthesis
3962
3972
  let tmpParenthesisDepth=0;// If it is in a state address, we don't care about the parenthesis
3963
3973
  // State addresses are between squiggly brackets
@@ -4933,6 +4943,12 @@ let tmpChunkSize=typeof pChunkSize=='number'?pChunkSize:0;let tmpChunkCache=type
4933
4943
  * @param {string} pValueAddress - The manyfest hash/address of the value to get
4934
4944
  */getInternalValueByHash(pValueAddress){// Get the value from the internal manifest and return it
4935
4945
  return this.getValueByHash(this.fable,pValueAddress);}/**
4946
+ * Set a value from fable/pict by hash/address
4947
+ *
4948
+ * @param {string} pValueAddress - The manyfest hash/address of the value to get
4949
+ * @param {any} pValue - The value to set
4950
+ */setInternalValueByHash(pValueAddress,pValue){// Get the value from the internal manifest and return it
4951
+ return this.setValueByHash(this.fable,pValueAddress,pValue);}/**
4936
4952
  * Get a value from an object by hash/address
4937
4953
  * @param {object} pObject - The object to get the value from
4938
4954
  * @param {string} pValueAddress - The manyfest hash/address of the value to get