text: (function(LST) {
  
      LST.rethrow = false;
  
      var currentTraceError = null;
  
      var filename = new Error().stack.split("\n")[1].match(/^    at ((?:\w+:\/\/)?[^:]+)/)[1];
  console.log('filename', filename)
      function filterInternalFrames(frames) {
          return frames.split("\n").filter(function(frame) { return frame.indexOf(filename) < 0; }).join("\n");
      }
  // jme- bad
      Error.prepareStackTrace = function(error, structuredStackTrace) {
          if (!error.__cachedTrace) {
              error.__cachedTrace = filterInternalFrames(FormatStackTrace(error, structuredStackTrace));
  console.log('structuredStackTrace', structuredStackTrace[0])
              if (!has.call(error, "__previous")) {
                  var previous = currentTraceError;
                  while (previous) {
                      var previousTrace = previous.stack;
                      error.__cachedTrace += "\n----------------------------------------\n" +
                          "    at " + previous.__location + "\n" +
                          previousTrace.substring(previousTrace.indexOf("\n") + 1);
                      previous = previous.__previous;
                  }
              }
          }
  console.log('cachedTrace', error.__cachedTrace)
  console.dir(error.__cachedTrace)
          return error.__cachedTrace;
      }
  
      var slice = Array.prototype.slice;
      var has = Object.prototype.hasOwnProperty;
  
      // Takes an object, a property name for the callback function to wrap, and an argument position
      // and overwrites the function with a wrapper that captures the stack at the time of callback registration
      function wrapRegistrationFunction(object, property, callbackArg) {
          if (typeof object[property] !== "function") {
              console.error("(long-stack-traces) Object", object, "does not contain function", property);
              return;
          }
          if (!has.call(object, property)) {
              console.warn("(long-stack-traces) Object", object, "does not directly contain function", property);
          }
  
          // TODO: better source position detection
          var sourcePosition = (object.constructor.name || Object.prototype.toString.call(object)) + "." + property;
  
          // capture the original registration function
          var fn = object[property];
          // overwrite it with a wrapped registration function that modifies the supplied callback argument
          object[property] = function() {
              // replace the callback argument with a wrapped version that captured the current stack trace
              arguments[callbackArg] = makeWrappedCallback(arguments[callbackArg], sourcePosition);
              // call the original registration function with the modified arguments
              return fn.apply(this, arguments);
          }
  
          // check that the registration function was indeed overwritten
          if (object[property] === fn)
              console.warn("(long-stack-traces) Couldn't replace ", property, "on", object);
      }
  
      // Takes a callback function and name, and captures a stack trace, returning a new callback that restores the stack frame
      // This function adds a single function call overhead during callback registration vs. inlining it in wrapRegistationFunction
      function makeWrappedCallback(callback, frameLocation) {
          // add a fake stack frame. we can't get a real one since we aren't inside the original function
          var traceError = new Error();
          traceError.__location = frameLocation;
          traceError.__previous = currentTraceError;
          return function() {
              // if (currentTraceError) {
              //     FIXME: This shouldn't normally happen, but it often does. Do we actually need a stack instead?
              //     console.warn("(long-stack-traces) Internal Error: currentTrace already set.");
              // }
              // restore the trace
              currentTraceError = traceError;
              try {
                  return callback.apply(this, arguments);
              } catch (e) {
                  console.error("Uncaught " + e.stack);
                  if (LST.rethrow)
                      throw ""; // TODO: throw the original error, or undefined?
              } finally {
                  // clear the trace so we can check that none is set above.
                  // TODO: could we remove this for slightly better performace?
                  currentTraceError = null;
              }
          }
      }
  
      // Chrome
      if (typeof window !== "undefined") {
          wrapRegistrationFunction(window.constructor.prototype, "setTimeout", 0);
          wrapRegistrationFunction(window.constructor.prototype, "setInterval", 0);
  
          [
              window.Node.prototype,
              window.MessagePort.prototype,
          //     window.SVGElementInstance.prototype,
              window.WebSocket.prototype,
              window.XMLHttpRequest.prototype,
              window.EventSource.prototype,
              window.XMLHttpRequestUpload.prototype,
              window.SharedWorker.prototype.__proto__,
              window.constructor.prototype,
              window.applicationCache.constructor.prototype
          ].forEach(function(object) {
              wrapRegistrationFunction(object, "addEventListener", 1);
          });
  
          // this actually captures the stack when "send" is called, which isn't ideal,
          // but it's the best we can do without hooking onreadystatechange assignments
          var _send = XMLHttpRequest.prototype.send;
          XMLHttpRequest.prototype.send = function() {
              this.onreadystatechange = makeWrappedCallback(this.onreadystatechange, "onreadystatechange");
              return _send.apply(this, arguments);
          }
  
          // FIXME: experimental XHR wrapper for hooking onreadystatechange
          // Based on https://gist.github.com/796032
          // var _XMLHttpRequest = XMLHttpRequest;
          // XMLHttpRequest = function () {
          //     Object.defineProperty(this, "onreadystatechange", {
          //         get: function() {
          //             return this.__onreadystatechange;
          //         },
          //         set: function(onreadystatechange) {
          //             if (this.__onreadystatechange && typeof this.__onreadystatechange.call === "function")
          //                 this.removeEventListener("readystatechange", this.__onreadystatechange);
          //             this.__onreadystatechange = makeWrappedCallback(onreadystatechange, "onreadystatechange");
          //             if (this.__onreadystatechange && typeof this.__onreadystatechange.call === "function")
          //                 this.addEventListener("readystatechange", this.__onreadystatechange);
          //         },
          //         enumerable: true
          //     });
          //     Object.defineProperty(this, "__onreadystatechange", {
          //         value: null,
          //         writable: true,
          //         enumerable: false
          //     });
          // }
          // XMLHttpRequest.prototype = new _XMLHttpRequest();
      }
      // Node.js
      else if (typeof process !== "undefined") {
          LST.rethrow = true;
  
          var global = (function() { return this; })();
          wrapRegistrationFunction(global, "setTimeout", 0);
          wrapRegistrationFunction(global, "setInterval", 0);
  
          var EventEmitter = require('events').EventEmitter;
          wrapRegistrationFunction(EventEmitter.prototype, "addListener", 1);
          wrapRegistrationFunction(EventEmitter.prototype, "on", 1);
  
          wrapRegistrationFunction(process, "nextTick", 0);
      }
  
      // Copyright 2006-2008 the V8 project authors. All rights reserved.
      // Redistribution and use in source and binary forms, with or without
      // modification, are permitted provided that the following conditions are
      // met:
      //
      //     * Redistributions of source code must retain the above copyright
      //       notice, this list of conditions and the following disclaimer.
      //     * Redistributions in binary form must reproduce the above
      //       copyright notice, this list of conditions and the following
      //       disclaimer in the documentation and/or other materials provided
      //       with the distribution.
      //     * Neither the name of Google Inc. nor the names of its
      //       contributors may be used to endorse or promote products derived
      //       from this software without specific prior written permission.
      //
      // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
      function FormatStackTrace(error, frames) {
        var lines = [];
        try {
          lines.push(error.toString());
        } catch (e) {
          try {
            lines.push("<error: " + e + ">");
          } catch (ee) {
            lines.push("<error>");
          }
        }
        for (var i = 0; i < frames.length; i++) {
          var frame = frames[i];
          var line;
          try {
            line = FormatSourcePosition(frame);
          } catch (e) {
            try {
              line = "<error: " + e + ">";
            } catch (ee) {
              // Any code that reaches this point is seriously nasty!
              line = "<error>";
            }
          }
          lines.push("    at " + line);
        }
        return lines.join("\n");
      }
  
      function FormatSourcePosition(frame) {
        var fileLocation = "";
        if (frame.isNative()) {
          fileLocation = "native";
        } else if (frame.isEval()) {
          fileLocation = "eval at " + frame.getEvalOrigin();
        } else {
          var fileName = frame.getFileName();
          if (fileName) {
            fileLocation += fileName;
            var lineNumber = frame.getLineNumber();
            if (lineNumber != null) {
              fileLocation += ":" + lineNumber;
              var columnNumber = frame.getColumnNumber();
              if (columnNumber) {
                fileLocation += ":" + columnNumber;
              }
            }
          }
        }
        if (!fileLocation) {
          fileLocation = "unknown source";
        }
        var line = "";
        var functionName = frame.getFunction().name;
        var addPrefix = true;
        var isConstructor = frame.isConstructor();
        var isMethodCall = !(frame.isToplevel() || isConstructor);
        if (isMethodCall) {
          var methodName = frame.getMethodName();
          line += frame.getTypeName() + ".";
          if (functionName) {
            line += functionName;
            if (methodName && (methodName != functionName)) {
              line += " [as " + methodName + "]";
            }
          } else {
            line += methodName || "<anonymous>";
          }
        } else if (isConstructor) {
          line += "new " + (functionName || "<anonymous>");
        } else if (functionName) {
          line += functionName;
        } else {
          line += fileLocation;
          addPrefix = false;
        }
        if (addPrefix) {
          line += " (" + fileLocation + ")";
        }
        return line;
      }
  })(typeof exports !== "undefined" ? exports : {});
  