text: (function (root, factory){
    'use strict';
  
    /*istanbul ignore next:cant test*/
    if (typeof module === 'object' && typeof module.exports === 'object') {
      module.exports = factory();
    } else if (typeof define === 'function' && define.amd) {
      // AMD. Register as an anonymous module.
      define([], factory);
    } else {
      // Browser globals
      root.objectPath = factory();
    }
  })(this, function(){
    'use strict';
  
    var toStr = Object.prototype.toString;
    function hasOwnProperty(obj, prop) {
      if(obj == null) {
        return false
      }
      //to handle objects with null prototypes (too edge case?)
      return Object.prototype.hasOwnProperty.call(obj, prop)
    }
  
    function isEmpty(value){
      if (!value) {
        return true;
      }
      if (isArray(value) && value.length === 0) {
          return true;
      } else if (typeof value !== 'string') {
          for (var i in value) {
              if (hasOwnProperty(value, i)) {
                  return false;
              }
          }
          return true;
      }
      return false;
    }
  
    function toString(type){
      return toStr.call(type);
    }
  
    function isObject(obj){
      return typeof obj === 'object' && toString(obj) === "[object Object]";
    }
  
    var isArray = Array.isArray || function(obj){
      /*istanbul ignore next:cant test*/
      return toStr.call(obj) === '[object Array]';
    }
  
    function isBoolean(obj){
      return typeof obj === 'boolean' || toString(obj) === '[object Boolean]';
    }
  
    function getKey(key){
      var intKey = parseInt(key);
      if (intKey.toString() === key) {
        return intKey;
      }
      return key;
    }
  
    function factory(options) {
      options = options || {}
  
      var objectPath = function(obj) {
        return Object.keys(objectPath).reduce(function(proxy, prop) {
          if(prop === 'create') {
            return proxy;
          }
  
          /*istanbul ignore else*/
          if (typeof objectPath[prop] === 'function') {
            proxy[prop] = objectPath[prop].bind(objectPath, obj);
          }
  
          return proxy;
        }, {});
      };
  
      var hasShallowProperty
      if (options.includeInheritedProps) {
        hasShallowProperty = function () {
          return true
        }
      } else {
        hasShallowProperty = function (obj, prop) {
          return (typeof prop === 'number' && Array.isArray(obj)) || hasOwnProperty(obj, prop)
        }
      }
  
      function getShallowProperty(obj, prop) {
        if (hasShallowProperty(obj, prop)) {
          return obj[prop];
        }
      }
  
      function set(obj, path, value, doNotReplace){
        if (typeof path === 'number') {
          path = [path];
        }
        if (!path || path.length === 0) {
          return obj;
        }
        if (typeof path === 'string') {
          return set(obj, path.split('.').map(getKey), value, doNotReplace);
        }
        var currentPath = path[0];
        var currentValue = getShallowProperty(obj, currentPath);
        if (options.includeInheritedProps && (currentPath === '__proto__' ||
          (currentPath === 'constructor' && typeof currentValue === 'function'))) {
          throw new Error('For security reasons, object\'s magic properties cannot be set')
        }
        if (path.length === 1) {
          if (currentValue === void 0 || !doNotReplace) {
            obj[currentPath] = value;
          }
          return currentValue;
        }
  
        if (currentValue === void 0) {
          //check if we assume an array
          if(typeof path[1] === 'number') {
            obj[currentPath] = [];
          } else {
            obj[currentPath] = {};
          }
        }
  
        return set(obj[currentPath], path.slice(1), value, doNotReplace);
      }
  
      objectPath.has = function (obj, path) {
        if (typeof path === 'number') {
          path = [path];
        } else if (typeof path === 'string') {
          path = path.split('.');
        }
  
        if (!path || path.length === 0) {
          return !!obj;
        }
  
        for (var i = 0; i < path.length; i++) {
          var j = getKey(path[i]);
  
          if((typeof j === 'number' && isArray(obj) && j < obj.length) ||
            (options.includeInheritedProps ? (j in Object(obj)) : hasOwnProperty(obj, j))) {
            obj = obj[j];
          } else {
            return false;
          }
        }
  
        return true;
      };
  
      objectPath.ensureExists = function (obj, path, value){
        return set(obj, path, value, true);
      };
  
      objectPath.set = function (obj, path, value, doNotReplace){
        return set(obj, path, value, doNotReplace);
      };
  
      objectPath.insert = function (obj, path, value, at){
        var arr = objectPath.get(obj, path);
        at = ~~at;
        if (!isArray(arr)) {
          arr = [];
          objectPath.set(obj, path, arr);
        }
        arr.splice(at, 0, value);
      };
  
      objectPath.empty = function(obj, path) {
        if (isEmpty(path)) {
          return void 0;
        }
        if (obj == null) {
          return void 0;
        }
  
        var value, i;
        if (!(value = objectPath.get(obj, path))) {
          return void 0;
        }
  
        if (typeof value === 'string') {
          return objectPath.set(obj, path, '');
        } else if (isBoolean(value)) {
          return objectPath.set(obj, path, false);
        } else if (typeof value === 'number') {
          return objectPath.set(obj, path, 0);
        } else if (isArray(value)) {
          value.length = 0;
        } else if (isObject(value)) {
          for (i in value) {
            if (hasShallowProperty(value, i)) {
              delete value[i];
            }
          }
        } else {
          return objectPath.set(obj, path, null);
        }
      };
  
      objectPath.push = function (obj, path /*, values */){
        var arr = objectPath.get(obj, path);
        if (!isArray(arr)) {
          arr = [];
          objectPath.set(obj, path, arr);
        }
  
        arr.push.apply(arr, Array.prototype.slice.call(arguments, 2));
      };
  
      objectPath.coalesce = function (obj, paths, defaultValue) {
        var value;
  
        for (var i = 0, len = paths.length; i < len; i++) {
          if ((value = objectPath.get(obj, paths[i])) !== void 0) {
            return value;
          }
        }
  
        return defaultValue;
      };
  
      objectPath.get = function (obj, path, defaultValue){
        if (typeof path === 'number') {
          path = [path];
        }
        if (!path || path.length === 0) {
          return obj;
        }
        if (obj == null) {
          return defaultValue;
        }
        if (typeof path === 'string') {
          return objectPath.get(obj, path.split('.'), defaultValue);
        }
  
        var currentPath = getKey(path[0]);
        var nextObj = getShallowProperty(obj, currentPath)
        if (nextObj === void 0) {
          return defaultValue;
        }
  
        if (path.length === 1) {
          return nextObj;
        }
  
        return objectPath.get(obj[currentPath], path.slice(1), defaultValue);
      };
  
      objectPath.del = function del(obj, path) {
        if (typeof path === 'number') {
          path = [path];
        }
  
        if (obj == null) {
          return obj;
        }
  
        if (isEmpty(path)) {
          return obj;
        }
        if(typeof path === 'string') {
          return objectPath.del(obj, path.split('.'));
        }
  
        var currentPath = getKey(path[0]);
        if (!hasShallowProperty(obj, currentPath)) {
          return obj;
        }
  
        if(path.length === 1) {
          if (isArray(obj)) {
            obj.splice(currentPath, 1);
          } else {
            delete obj[currentPath];
          }
        } else {
          return objectPath.del(obj[currentPath], path.slice(1));
        }
  
        return obj;
      }
  
      return objectPath;
    }
  
    var mod = factory();
    mod.create = factory;
    mod.withInheritedProps = factory({includeInheritedProps: true})
    return mod;
  });
  