text: var pathGetter = require('./path-getter');
  var jsan = require('./');
  
  exports.getRegexFlags = function getRegexFlags(regex) {
    var flags = '';
    if (regex.ignoreCase) flags += 'i';
    if (regex.global) flags += 'g';
    if (regex.multiline) flags += 'm';
    return flags;
  };
  
  exports.stringifyFunction = function stringifyFunction(fn, customToString) {
    if (typeof customToString === 'function') {
      return customToString(fn);
    }
    var str = fn.toString();
    var match = str.match(/^[^{]*{|^[^=]*=>/);
    var start = match ? match[0] : '<function> ';
    var end = str[str.length - 1] === '}' ? '}' : '';
    return start.replace(/\r\n|\n/g, ' ').replace(/\s+/g, ' ') + ' /* ... */ ' + end;
  };
  
  exports.restore = function restore(obj, root) {
    var type = obj[0];
    var rest = obj.slice(1);
    switch(type) {
      case '$':
        return pathGetter(root, obj);
      case 'r':
        var comma = rest.indexOf(',');
        var flags = rest.slice(0, comma);
        var source = rest.slice(comma + 1);
        return RegExp(source, flags);
      case 'd':
        return new Date(+rest);
      case 'f':
        var fn = function() { throw new Error("can't run jsan parsed function") };
        fn.toString = function() { return rest; };
        return fn;
      case 'u':
        return undefined;
      case 'e':
        var error = new Error(rest);
        error.stack = 'Stack is unavailable for jsan parsed errors';
        return error;
      case 's':
        return Symbol(rest);
      case 'g':
        return Symbol.for(rest);
      case 'm':
        return new Map(jsan.parse(rest));
      case 'l':
        return new Set(jsan.parse(rest));
      case 'n':
        return NaN;
      case 'i':
        return Infinity;
      case 'y':
        return -Infinity;
      default:
        console.warn('unknown type', obj);
        return obj;
    }
  }
  