code: function hashObject(obj, propertyNameGlobs, prevHashValue) {
      let expandedPropertyNames;
      try {
          expandedPropertyNames = expandPropertyNameGlobs(obj, propertyNameGlobs);
      }
      catch(err) {
          if (err instanceof GlobExpandError)
              throw new Error(`Cannot hash object: Expected property "${err.pattern}" does not exist on object.`);
          else
              throw err;
      }
  
      const isArrayPropertyGroup = propertyNameGlobs[0].includes('[]');
      if (isArrayPropertyGroup) {
          if (expandedPropertyNames.length === 0)
              return 0;
  
          for (let expandedPropertyName of expandedPropertyNames)
              prevHashValue = hashObject(obj, expandedPropertyName, prevHashValue || 0);
  
          return prevHashValue;
      }
  
      const propertyValues = expandedPropertyNames.map(path => {
          let value;
          if (Array.isArray(path)) {
              value = hashObject(obj, path);
          }
          else {
              value = getNestedProperty(obj, path);
              if (value === undefined)
                  throw new Error(`Cannot hash object: Expected property "${path}" does not exist on object.`);
          }
          return value;
      });
  
      if (prevHashValue !== null && prevHashValue !== undefined)
          return hash(prevHashValue, ...propertyValues);
  
      return hash(...propertyValues);
  }
docs: Plucks properties from an object, and hashes them according to {@link https://en.wikipedia.org/wiki/SHA-3|sha3 (aka keccak-256)}
  @param {Object} obj
  @param {String[]} propertyNameGlobs
  @param {String} prevHashValue
  @return {String} 32 byte hash value as hex