<commit_before>(function(){
  var traverse = function(util, searchTerm, options) {
    var options = options || {};
    var obj = options.obj || window;
    var path = options.path || ((obj==window) ? "window" : "");
    var props = Object.keys(obj);
    props.forEach(function(prop) {
      if ((tests[util] || util)(searchTerm, obj, prop)){
        console.log([path, ".", prop].join(""), "->",["(", typeof obj[prop], ")"].join(""), obj[prop]);
      }
      if((""+obj[prop])=="[object Object]" && (obj[prop] != obj) && path.split(".").indexOf(prop) == -1) {
        traverse(util, searchTerm, {obj: obj[prop], path: [path,prop].join(".")});
      }
    });
  }

  var dealWithIt = function(util, expected, searchTerm, options) {
    (!expected || typeof searchTerm == expected) ?
      traverse(util, searchTerm, options) :
      console.error([searchTerm, 'must be', expected].join(' '));
  }

  var tests = {
    'propName': function(searchTerm, obj, prop) {return searchTerm == prop},
    'type': function(searchTerm, obj, prop) {return obj[prop] instanceof searchTerm},
    'value': function(searchTerm, obj, prop) {return obj[prop] === searchTerm},
    'valueCoerced': function(searchTerm, obj, prop) {return obj[prop] == searchTerm}
  }

  window.find={
    byPropName: function(searchTerm, options) {dealWithIt('propName', 'string', searchTerm, options);},
    byType: function(searchTerm, options) {dealWithIt('type', 'function', searchTerm, options);},
    byValue: function(searchTerm, options) {dealWithIt('value', null, searchTerm, options);},
    byValueCoerced: function(searchTerm, options) {dealWithIt('valueCoerced', null, searchTerm, options);},
    custom: function(fn, options) {traverse(fn, null, options);}
  }
})();


<commit_msg>waldo: Make work in IE8 & avoid stack overflows. [jddalton]<commit_after>(function(window) {

  function dealWithIt(util, expected, searchTerm, options) {
    (!expected || typeof searchTerm == expected)
      ? traverse(util, searchTerm, options)
      : console.error(searchTerm + ' must be ' + expected);
  }

  function traverse(util, searchTerm, options) {
    options || (options = {});
    var pair;
    var obj = options.obj || window;
    var ownProp = options.hasOwnProperty;
    var path = options.path || ((obj == window) ? 'window' : '');
    var pairs = [[obj, path]];

    // a non-recursive solution to avoid stack overflows
    // http://www.jslab.dk/articles/non.recursive.preorder.traversal.part4
    while ((pair = pairs.pop())) {
      obj = pair[0];
      path = pair[1];
      for (var prop in obj) {
        // IE may throw errors when accessing/coercing some properties
        try {
          if (ownProp.call(obj, prop)) {
            if ((tests[util] || util)(searchTerm, obj, prop)){
              console.log(path + '.' + prop, '->', '(' + (typeof obj[prop]) + ')', obj[prop]);
              return;
            }
            if([obj[prop]] == '[object Object]' && (obj[prop] != obj)) {
              pairs.push([obj[prop], path + '.' + prop]);
            }
          }
        } catch(e) { }
      }
    }
  }

  var tests = {
    'propName': function(searchTerm, obj, prop) {
      return searchTerm == prop;
    },
    'type': function(searchTerm, obj, prop) {
      return obj[prop] instanceof searchTerm;
    },
    'value': function(searchTerm, obj, prop) {
      return obj[prop] === searchTerm;
    },
    'valueCoerced': function(searchTerm, obj, prop) {
      return obj[prop] == searchTerm;
    }
  };

  window.find = {
    'byPropName': function(searchTerm, options) {
      dealWithIt('propName', 'string', searchTerm, options);
    },
    'byType': function(searchTerm, options) {
      dealWithIt('type', 'function', searchTerm, options);
    },
    'byValue': function(searchTerm, options) {
      dealWithIt('value', null, searchTerm, options);
    },
    'byValueCoerced': function(searchTerm, options) {
      dealWithIt('valueCoerced', null, searchTerm, options);
    },
    'custom': function(fn, options) {
      traverse(fn, null, options);
    }
  };
}(this));
{'fraction_non_alphanumeric': 0.17775595384237663, 'fraction_numerical': 0.0012275963663147557, 'mean_word_length': 3.182751540041068, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3773170', 'n_tokens_mistral': 1281, 'n_tokens_neox': 1256, 'n_words': 297}