Bug 1399673 - Update Debugger Frontend and upgrade Source Map Worker to v0.13.0. r=jdescottes
authorjason laster <jlaster@mozilla.com>
Wed, 13 Sep 2017 20:12:01 -0400
changeset 665502 ee8939119c172f5e2c4b101ed17a23ea35897782
parent 665501 447eaf2c0578d43d58c856e2e5664c9cda35eef2
child 665503 670be1db5eeddc43fb7a36342f1c97bf6c3a5103
push id80093
push userbmo:ttromey@mozilla.com
push dateFri, 15 Sep 2017 16:41:29 +0000
reviewersjdescottes
bugs1399673
milestone57.0a1
Bug 1399673 - Update Debugger Frontend and upgrade Source Map Worker to v0.13.0. r=jdescottes MozReview-Commit-ID: L7igSLIa5GX
devtools/client/debugger/new/debugger.css
devtools/client/debugger/new/debugger.js
devtools/client/debugger/new/parser-worker.js
devtools/client/debugger/new/pretty-print-worker.js
devtools/client/debugger/new/search-worker.js
devtools/client/framework/test/browser_source_map-01.js
devtools/client/framework/test/browser_source_map-absolute.js
devtools/client/locales/en-US/debugger.properties
devtools/client/preferences/debugger.js
devtools/client/shared/source-map/index.js
devtools/client/shared/source-map/worker.js
--- a/devtools/client/debugger/new/debugger.css
+++ b/devtools/client/debugger/new/debugger.css
@@ -1071,17 +1071,17 @@ html[dir="rtl"] .managed-tree .tree .nod
   margin-left: 5px;
 }
 
 .project-text-search .result {
   font-family: Menlo, monospace;
 }
 
 .project-text-search .result.focused {
-  background-color: var(--theme-codemirror-gutter-background);
+  background-color: var(--search-overlays-semitransparent);
 }
 
 .project-text-search .result .query-match {
   background-color: var(--theme-selection-background);
   color: white;
   padding: 1px 4px;
   margin: 0 2px 0 2px;
   border-radius: 2px;
@@ -1089,32 +1089,40 @@ html[dir="rtl"] .managed-tree .tree .nod
 
 .project-text-search .result.focused .line-number {
   font-weight: bolder;
 }
 
 .project-text-search .result .line-number {
   margin-right: 1em;
   width: 2em;
+  margin-left: 0.8em;
+}
+
+.project-text-search .no-result-msg {
+  color: var(--theme-body-color-inactive);
+  font-size: 24px;
+  padding: 4px;
+  word-break: break-all;
 }
 
 .project-text-search .file-result {
   font-weight: bold;
   line-height: 20px;
   cursor: default;
   padding: 2px 0 2px 5px;
   font-size: 12px;
 }
 
 .project-text-search .file-result .arrow {
   margin: 2px 0 2px 0;
 }
 
 .project-text-search .file-result.focused {
-  background-color: var(--theme-codemirror-gutter-background);
+  background-color: var(--search-overlays-semitransparent);
 }
 
 .project-text-search .line-match {
   display: "flex";
   grow: 1;
 }
 
 .project-text-search .search-field {
@@ -1186,16 +1194,24 @@ html[dir="rtl"] .managed-tree .tree .nod
   background-color: var(--theme-selection-background);
   color: white;
 }
 
 .theme-dark .result-list.small li.selected {
   background-color: var(--theme-body-background);
 }
 
+.theme-dark .result-list li:hover {
+  background: var(--grey-70);
+}
+
+.theme-dark .result-list li.selected {
+  background: var(--grey-70);
+}
+
 .result-list li .title {
   line-height: 1.5em;
   word-break: break-all;
 }
 
 .result-list li.selected .title {
   color: white;
 }
@@ -1229,17 +1245,17 @@ html[dir="rtl"] .managed-tree .tree .nod
   top: 30px;
   left: 0;
   width: calc(100% - 1px);
   height: calc(100% - 31px);
   display: flex;
   flex-direction: column;
   z-index: 200;
   background-color: var(--theme-body-background);
-  overflow-y: auto;
+  overflow-y: hidden;
 }
 
 .searchinput-container {
   display: flex;
   border-bottom: 1px solid var(--theme-splitter-color);
 }
 
 .theme-dark .result-list li .subtitle {
@@ -1309,16 +1325,17 @@ html[dir="rtl"] .managed-tree .tree .nod
 }
 
 .sources-header-info {
   font-size: 12px;
   color: var(--theme-comment-alt);
   font-weight: lighter;
   white-space: nowrap;
   padding-inline-end: 10px;
+  cursor: default;
 }
 
 .sources-list {
   flex: 1;
   display: flex;
   overflow-x: hidden;
   overflow-y: auto;
 }
@@ -1378,16 +1395,17 @@ html[dir="rtl"] .managed-tree .tree .nod
   border-bottom-right-radius: 2px;
   display: inline-flex;
   position: relative;
   transition: all 0.25s ease;
   overflow: hidden;
   padding: 5px;
   margin-bottom: 0px;
   margin-top: -1px;
+  cursor: default;
 }
 
 .source-footer .tab:hover {
   background-color: var(--theme-toolbar-background-alt);
   border-color: var(--theme-splitter-color);
 }
 
 .source-footer .tab.active {
@@ -1399,28 +1417,38 @@ html[dir="rtl"] .managed-tree .tree .nod
 .source-footer .tab.active path,
 .source-footer .tab:hover path {
   fill: var(--theme-body-color);
 }
 .outline {
   overflow-y: auto;
 }
 
+.outline .outline-pane-info {
+  width: 100%;
+  font-style: italic;
+  text-align: center;
+  padding: 0.5em;
+  user-select: none;
+  font-size: 12px;
+}
+
 .outline-list {
   list-style-type: none;
   padding-left: 0px;
   width: 100%;
 }
 
 .outline-list__element {
   color: blue;
   padding-bottom: 0.2rem;
   padding-left: 1rem;
   padding-right: 0.5rem;
   padding-top: 0.2rem;
+  cursor: default;
 }
 
 .outline-list__element:hover {
   background: var(--theme-toolbar-background-hover);
 }
 .function-signature {
   align-self: center;
 }
@@ -2387,35 +2415,16 @@ html[dir="rtl"] .editor-mount {
   0% {
     background-color: var(--theme-content-color3);
   }
   100% {
     background-color: transparent;
   }
 }
 
-.welcomebox {
-  width: calc(100% - 1px);
-
-  /* Offsetting it by 30px for the sources-header area */
-  height: calc(100% - 30px);
-  position: absolute;
-  top: 30px;
-  left: 0;
-  padding: 50px 0;
-  text-align: center;
-  font-size: 1.25em;
-  color: var(--theme-comment-alt);
-  background-color: var(--theme-tab-toolbar-background);
-  font-weight: lighter;
-  z-index: 100;
-  -moz-user-select: none;
-  user-select: none;
-}
-
 .CodeMirror-guttermarker-subtle {
   visibility: hidden;
 }
 
 .visible {
   visibility: visible;
 }
 .cm-highlight {
@@ -2503,16 +2512,17 @@ html .breakpoints-list .breakpoint.pause
   margin-inline-start: 0;
   vertical-align: -2px;
 }
 
 .breakpoints-list .breakpoint-label {
   display: inline-block;
   padding-inline-start: 2px;
   padding-bottom: 4px;
+  cursor: default;
 }
 
 .breakpoints-list .pause-indicator {
   flex: 0 1 content;
   order: 3;
 }
 
 :root.theme-light .breakpoint-snippet,
@@ -2617,33 +2627,20 @@ html .breakpoints-list .breakpoint.pause
 
 .expression-container:hover .close-btn {
   display: block;
 }
 
 .expression-input {
   max-width: 50%;
 }
-
-.expression-separator {
-  padding: 0px 5px;
-}
-
-.expression-value {
-  overflow-x: scroll;
-  color: var(--theme-content-color2);
-  max-width: 50% !important;
-}
-
-.expression-error {
-  color: var(--theme-highlight-red);
-}
 .frames ul .frames-group .group,
 .frames ul .frames-group .group .location {
   font-weight: 500;
+  cursor: default;
 }
 
 .frames ul .frames-group.expanded .group,
 .frames ul .frames-group.expanded .group .location {
   color: var(--theme-highlight-blue);
 }
 
 .frames ul .frames-group.expanded .react path {
@@ -2664,16 +2661,17 @@ html .breakpoints-list .breakpoint.pause
   padding: 10px 10px 10px 20px;
   white-space: normal;
   opacity: 0.6;
   font-size: 12px;
   flex: 0 1 auto;
   text-align: center;
   font-style: italic;
   font-weight: 300;
+  cursor: default;
 }
 
 .theme-dark .secondary-panes .why-paused {
   color: white;
 }
 
 .why-paused .message {
   font-size: 10px;
@@ -2700,24 +2698,16 @@ html .breakpoints-list .breakpoint.pause
   margin: 0;
 }
 
 .frames ul li * {
   -moz-user-select: none;
   user-select: none;
 }
 
-.frames ul li:nth-of-type(2n) {
-  background-color: var(--theme-tab-toolbar-background);
-}
-
-.theme-dark .frames ul li:nth-of-type(2n) {
-  background-color: var(--theme-toolbar-background-alt);
-}
-
 .frames .location {
   font-weight: lighter;
   display: flex;
   justify-content: space-between;
   flex-direction: row;
   align-items: center;
   margin: 0;
 }
@@ -2739,17 +2729,16 @@ html .breakpoints-list .breakpoint.pause
 }
 
 .frames ul li:hover,
 .frames ul li:focus {
   background-color: var(--theme-toolbar-background-alt);
   outline: none;
 }
 
-.theme-dark .frames ul li:hover,
 .theme-dark .frames ul li:focus {
   background-color: var(--theme-tab-toolbar-background);
 }
 
 .frames ul li.selected {
   background-color: var(--theme-selection-background);
   color: white;
 }
@@ -2759,21 +2748,16 @@ html .breakpoints-list .breakpoint.pause
 }
 
 :root.theme-light .frames ul li.selected .location,
 :root.theme-firebug .frames ul li.selected .location,
 :root.theme-dark .frames ul li.selected .location {
   color: white;
 }
 
-:root.theme-dark .frames ul li:hover .location,
-:root.theme-dark .frames ul li.selected .location {
-  opacity: 1;
-}
-
 .show-more {
   text-align: center;
   padding: 8px 0px;
   margin: 7px 10px 7px 7px;
   border: 1px solid var(--theme-splitter-color);
   background-color: var(--theme-tab-toolbar-background);
 }
 
@@ -2860,16 +2844,17 @@ html .breakpoints-list .breakpoint.pause
   height: 24px;
   align-items: center;
 
   -webkit-user-select: none;
   -moz-user-select: none;
   -ms-user-select: none;
   -o-user-select: none;
   user-select: none;
+  cursor: default;
 }
 
 .accordion ._header:hover {
   background-color: var(--theme-toolbar-background-hover);
 }
 
 .accordion ._header button svg,
 .accordion ._header:hover button svg {
@@ -3052,16 +3037,17 @@ html .command-bar > button:disabled {
 }
 
 .pane .pane-info {
   font-style: italic;
   text-align: center;
   padding: 0.5em;
   -moz-user-select: none;
   user-select: none;
+  cursor: default;
 }
 
 .theme-dark .secondary-panes .accordion .arrow svg {
   fill: var(--theme-content-color3);
 }
 .welcomebox {
   width: calc(100% - 1px);
 
@@ -3072,16 +3058,17 @@ html .command-bar > button:disabled {
   left: 0;
   padding: 50px 0 0 0;
   text-align: center;
   font-size: 1.25em;
   color: var(--theme-comment-alt);
   background-color: var(--theme-toolbar-background);
   font-weight: lighter;
   z-index: 100;
+  user-select: none;
 }
 
 .theme-dark .welcomebox {
   background-color: var(--theme-body-background);
 }
 
 .alignlabel {
   display: inline-block;
@@ -3153,17 +3140,18 @@ html .welcomebox .toggle-button-end.coll
   display: inline-flex;
   align-items: flex-end;
   position: relative;
   transition: all 0.15s ease;
   min-width: 40px;
   overflow: hidden;
   padding: 5px;
   margin-inline-start: 3px;
-  margin-top: 4px;
+  margin-top: 3px;
+  cursor: default;
 }
 
 .source-tab:hover {
   background-color: var(--theme-toolbar-background-alt);
   border-color: var(--theme-splitter-color);
 }
 
 .source-tab.active {
--- a/devtools/client/debugger/new/debugger.js
+++ b/devtools/client/debugger/new/debugger.js
@@ -569,20 +569,26 @@ function createParentMap(tree) {
   }
 
   // Don't link each top-level path to the "root" node because the
   // user never sees the root
   tree.contents.forEach(_traverse);
   return map;
 }
 
-function getRelativePath(path) {
-  var re = /(http(?:s?):\/\/(?:www\.)?[a-z0-9\-.]+)\/(.*)/i;
-  var matches = path.match(re);
-  return matches ? matches[2] : "";
+function getRelativePath(url) {
+  var _parse2 = (0, _url.parse)(url),
+      pathname = _parse2.pathname;
+
+  if (!pathname) {
+    return url;
+  }
+  var path = pathname.split("/");
+  path.shift();
+  return path.join("/");
 }
 
 /***/ }),
 /* 19 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
@@ -1831,16 +1837,18 @@ exports.clearSearchQuery = clearSearchQu
 exports.clearSearchResults = clearSearchResults;
 exports.searchSources = searchSources;
 exports.searchSource = searchSource;
 
 var _search = __webpack_require__(1115);
 
 var _selectors = __webpack_require__(242);
 
+var _source = __webpack_require__(233);
+
 var _sources = __webpack_require__(254);
 
 function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
@@ -1882,36 +1890,42 @@ function searchSources(query) {
       var dispatch = _ref5.dispatch,
           getState = _ref5.getState;
 
       yield dispatch(clearSearchResults());
       yield dispatch(addSearchQuery(query));
       yield dispatch((0, _sources.loadAllSources)());
       var sources = (0, _selectors.getSources)(getState());
       var validSources = sources.valueSeq().filter(function (source) {
-        return source.has("text");
+        return (0, _source.isLoaded)(source.toJS()) && !(0, _source.isThirdParty)(source.toJS());
       }).toJS();
 
       for (var source of validSources) {
-        yield dispatch(searchSource(source, query));
+        yield dispatch(searchSource(source.id, query));
       }
     });
 
     return function (_x) {
       return _ref4.apply(this, arguments);
     };
   })();
 }
 
-function searchSource(source, query) {
+function searchSource(sourceId, query) {
   return (() => {
     var _ref6 = _asyncToGenerator(function* (_ref7) {
       var dispatch = _ref7.dispatch,
           getState = _ref7.getState;
 
+      var sourceRecord = (0, _selectors.getSource)(getState(), sourceId);
+      if (!sourceRecord) {
+        return;
+      }
+
+      var source = sourceRecord.toJS();
       var matches = yield (0, _search.findSourceMatches)(source, query);
       dispatch({
         type: "ADD_SEARCH_RESULT",
         result: {
           sourceId: source.id,
           filepath: source.url,
           matches
         }
@@ -5913,17 +5927,17 @@ var _require5 = __webpack_require__(828)
     isDevelopment = _require5.isDevelopment;
 
 var L10N = __webpack_require__(185);
 
 var _require6 = __webpack_require__(1130),
     showMenu = _require6.showMenu,
     buildMenu = _require6.buildMenu;
 
-setConfig({"environment":"firefox-panel","logging":false,"clientLogging":false,"firefox":{"mcPath":"./firefox"},"workers":{"parserURL":"resource://devtools/client/debugger/new/parser-worker.js","prettyPrintURL":"resource://devtools/client/debugger/new/pretty-print-worker.js","searchURL":"resource://devtools/client/debugger/new/search-worker.js"},"features":{"blackbox":{"enabled":true},"chromeScopes":{"enabled":false},"eventListeners":{"enabled":false},"codeCoverage":{"enabled":false},"codeFolding":{"enabled":false},"searchNav":{"enabled":true},"collapseFrame":{"enabled":true},"outline":{"enabled":true},"wasm":{"enabled":true}}});
+setConfig({"environment":"firefox-panel","logging":false,"clientLogging":false,"firefox":{"mcPath":"./firefox"},"workers":{"parserURL":"resource://devtools/client/debugger/new/parser-worker.js","prettyPrintURL":"resource://devtools/client/debugger/new/pretty-print-worker.js","searchURL":"resource://devtools/client/debugger/new/search-worker.js"},"features":{"blackbox":{"enabled":true},"chromeScopes":{"enabled":false},"eventListeners":{"enabled":false},"codeCoverage":{"enabled":false},"codeFolding":{"enabled":false},"searchNav":{"enabled":true},"collapseFrame":{"enabled":true},"outline":{"enabled":true}}});
 
 // Set various flags before requiring app code.
 if (getValue("logging.client")) {
   // DevToolsUtils.dumpn.wantLogging = true;
 }
 
 var _require7 = __webpack_require__(885),
     firefox = _require7.firefox,
@@ -15549,32 +15563,26 @@ var history = exports.history = function
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.promise = exports.PROMISE = undefined;
 
-var _defer = __webpack_require__(194);
-
-var _defer2 = _interopRequireDefault(_defer);
-
 var _lodash = __webpack_require__(2);
 
 var _DevToolsUtils = __webpack_require__(222);
 
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var seqIdVal = 1;
 
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
 function seqIdGen() {
   return seqIdVal++;
 }
 
 function filterAction(action) {
   return (0, _lodash.fromPairs)((0, _lodash.toPairs)(action).filter(pair => pair[0] !== PROMISE));
 }
 
@@ -15593,67 +15601,43 @@ function promiseMiddleware(_ref) {
     // Create a new action that doesn't have the promise field and has
     // the `seqId` field that represents the sequence id
     action = Object.assign(filterAction(action), { seqId });
 
     dispatch(Object.assign({}, action, { status: "start" }));
 
     // Return the promise so action creators can still compose if they
     // want to.
-    var deferred = (0, _defer2.default)();
-    promiseInst.then(value => {
-      (0, _DevToolsUtils.executeSoon)(() => {
-        dispatch(Object.assign({}, action, {
-          status: "done",
-          value: value
-        }));
-        deferred.resolve(value);
-      });
-    }, error => {
-      (0, _DevToolsUtils.executeSoon)(() => {
-        dispatch(Object.assign({}, action, {
-          status: "error",
-          error: error.message || error
-        }));
-        deferred.reject(error);
-      });
-    });
-    return deferred.promise;
+    return new Promise((resolve, reject) => {
+      promiseInst.then(value => {
+        (0, _DevToolsUtils.executeSoon)(() => {
+          dispatch(Object.assign({}, action, {
+            status: "done",
+            value: value
+          }));
+          resolve(value);
+        });
+      }, error => {
+        (0, _DevToolsUtils.executeSoon)(() => {
+          dispatch(Object.assign({}, action, {
+            status: "error",
+            error: error.message || error
+          }));
+          reject(error);
+        });
+      });
+    });
   };
 }
 
 var PROMISE = exports.PROMISE = "@@dispatch/promise";
 exports.promise = promiseMiddleware;
 
 /***/ }),
-/* 194 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.default = defer;
-function defer() {
-  var resolve = void 0; // eslint-disable-line no-unused-vars
-  var reject = void 0; // eslint-disable-line no-unused-vars
-  var promise = new Promise(function (innerResolve, innerReject) {
-    resolve = innerResolve;
-    reject = innerReject;
-  });
-  return {
-    resolve,
-    reject,
-    promise
-  };
-}
-
-/***/ }),
+/* 194 */,
 /* 195 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
@@ -15965,16 +15949,17 @@ if (isDevelopment()) {
   pref("devtools.debugger.pending-breakpoints", "{}");
   pref("devtools.debugger.expressions", "[]");
   pref("devtools.debugger.file-search-case-sensitive", false);
   pref("devtools.debugger.file-search-whole-word", false);
   pref("devtools.debugger.file-search-regex-match", false);
   pref("devtools.debugger.prefs-schema-version", "1.0.1");
   pref("devtools.debugger.project-text-search-enabled", true);
   pref("devtools.debugger.features.async-stepping", true);
+  pref("devtools.debugger.features.wasm", true);
 }
 
 const prefs = new PrefsHelper("devtools", {
   clientSourceMapsEnabled: ["Bool", "debugger.client-source-maps-enabled"],
   pauseOnExceptions: ["Bool", "debugger.pause-on-exceptions"],
   ignoreCaughtExceptions: ["Bool", "debugger.ignore-caught-exceptions"],
   callStackVisible: ["Bool", "debugger.call-stack-visible"],
   scopesVisible: ["Bool", "debugger.scopes-visible"],
@@ -16656,17 +16641,17 @@ exports.default = update;
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.isLoaded = exports.getMode = exports.getSourceLineCount = exports.getSourcePath = exports.getFilenameFromURL = exports.getFilename = exports.getRawSourceURL = exports.getPrettySourceURL = exports.shouldPrettyPrint = exports.isPretty = exports.isJavaScript = undefined;
+exports.isLoaded = exports.getMode = exports.getSourceLineCount = exports.getSourcePath = exports.getFilenameFromURL = exports.getFilename = exports.getRawSourceURL = exports.getPrettySourceURL = exports.shouldPrettyPrint = exports.isThirdParty = exports.isPretty = exports.isJavaScript = undefined;
 
 var _devtoolsSourceMap = __webpack_require__(898);
 
 var _utils = __webpack_require__(234);
 
 var _path = __webpack_require__(235);
 
 var _url = __webpack_require__(334);
@@ -16730,16 +16715,24 @@ function isJavaScript(url) {
 /**
  * @memberof utils/source
  * @static
  */
 function isPretty(source) {
   return source.url ? /formatted$/.test(source.url) : false;
 }
 
+function isThirdParty(source) {
+  if (!source || !source.url) {
+    return false;
+  }
+
+  return !!source.url.match(/(node_modules|bower_components)/);
+}
+
 /**
  * @memberof utils/source
  * @static
  */
 function getPrettySourceURL(url) {
   if (!url) {
     url = "";
   }
@@ -16879,16 +16872,17 @@ function getMode(source) {
 }
 
 function isLoaded(source) {
   return source.loadedState === "loaded";
 }
 
 exports.isJavaScript = isJavaScript;
 exports.isPretty = isPretty;
+exports.isThirdParty = isThirdParty;
 exports.shouldPrettyPrint = shouldPrettyPrint;
 exports.getPrettySourceURL = getPrettySourceURL;
 exports.getRawSourceURL = getRawSourceURL;
 exports.getFilename = getFilename;
 exports.getFilenameFromURL = getFilenameFromURL;
 exports.getSourcePath = getSourcePath;
 exports.getSourceLineCount = getSourceLineCount;
 exports.getMode = getMode;
@@ -17636,16 +17630,17 @@ exports.getActiveSearch = getActiveSearc
 exports.getFileSearchQueryState = getFileSearchQueryState;
 exports.getFileSearchModifierState = getFileSearchModifierState;
 exports.getSearchResults = getSearchResults;
 exports.getFrameworkGroupingState = getFrameworkGroupingState;
 exports.getSymbolSearchType = getSymbolSearchType;
 exports.getShownSource = getShownSource;
 exports.getPaneCollapse = getPaneCollapse;
 exports.getHighlightedLineRange = getHighlightedLineRange;
+exports.getConditionalBreakpointPanel = getConditionalBreakpointPanel;
 
 var _makeRecord = __webpack_require__(230);
 
 var _makeRecord2 = _interopRequireDefault(_makeRecord);
 
 var _prefs = __webpack_require__(226);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -17669,17 +17664,18 @@ var State = exports.State = (0, _makeRec
     matchIndex: -1,
     index: -1,
     count: 0
   },
   shownSource: "",
   startPanelCollapsed: _prefs.prefs.startPanelCollapsed,
   endPanelCollapsed: _prefs.prefs.endPanelCollapsed,
   frameworkGroupingOn: _prefs.prefs.frameworkGroupingOn,
-  highlightedLineRange: undefined
+  highlightedLineRange: undefined,
+  conditionalBreakpointPanel: null
 });
 
 function update() {
   var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : State();
   var action = arguments[1];
 
   switch (action.type) {
     case "TOGGLE_ACTIVE_SEARCH":
@@ -17755,16 +17751,19 @@ function update() {
         lineRange = { start: _start, end: _end, sourceId: _sourceId };
       }
 
       return state.set("highlightedLineRange", lineRange);
 
     case "CLEAR_HIGHLIGHT_LINES":
       return state.set("highlightedLineRange", {});
 
+    case "TOGGLE_CONDITIONAL_BREAKPOINT_PANEL":
+      return state.set("conditionalBreakpointPanel", action.line);
+
     default:
       {
         return state;
       }
   }
 }
 
 // NOTE: we'd like to have the app state fully typed
@@ -17804,16 +17803,20 @@ function getPaneCollapse(state, position
 
   return state.ui.get("endPanelCollapsed");
 }
 
 function getHighlightedLineRange(state) {
   return state.ui.get("highlightedLineRange");
 }
 
+function getConditionalBreakpointPanel(state) {
+  return state.ui.get("conditionalBreakpointPanel");
+}
+
 exports.default = update;
 
 /***/ }),
 /* 241 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
@@ -18450,24 +18453,18 @@ function addHiddenBreakpoint(location) {
  */
 function removeBreakpoint(location) {
   return (_ref6) => {
     var dispatch = _ref6.dispatch,
         getState = _ref6.getState,
         client = _ref6.client;
 
     var bp = (0, _selectors.getBreakpoint)(getState(), location);
-    if (!bp) {
-      throw new Error("attempt to remove breakpoint that does not exist");
-    }
-
-    if (bp.loading) {
-      // TODO(jwl): make this wait until the breakpoint is saved if it
-      // is still loading
-      throw new Error("attempt to remove unsaved breakpoint");
+    if (!bp || bp.loading) {
+      return;
     }
 
     // If the breakpoint is already disabled, we don't need to communicate
     // with the server. We just need to dispatch an action
     // simulating a successful server request
     if (bp.disabled) {
       return dispatch({
         type: "REMOVE_BREAKPOINT",
@@ -18496,18 +18493,18 @@ function enableBreakpoint(location) {
   return (() => {
     var _ref7 = _asyncToGenerator(function* (_ref8) {
       var dispatch = _ref8.dispatch,
           getState = _ref8.getState,
           client = _ref8.client,
           sourceMaps = _ref8.sourceMaps;
 
       var breakpoint = (0, _selectors.getBreakpoint)(getState(), location);
-      if (!breakpoint) {
-        throw new Error("attempted to enable a breakpoint that does not exist");
+      if (!breakpoint || breakpoint.loading) {
+        return;
       }
 
       var action = { type: "ENABLE_BREAKPOINT", breakpoint };
       var promise = (0, _addBreakpoint2.default)(getState, client, sourceMaps, action);
       return dispatch({
         type: "ENABLE_BREAKPOINT",
         breakpoint,
         [_promise.PROMISE]: promise
@@ -18530,24 +18527,18 @@ function disableBreakpoint(location) {
   return (() => {
     var _ref9 = _asyncToGenerator(function* (_ref10) {
       var dispatch = _ref10.dispatch,
           getState = _ref10.getState,
           client = _ref10.client;
 
       var bp = (0, _selectors.getBreakpoint)(getState(), location);
 
-      if (!bp) {
-        throw new Error("attempt to disable a breakpoint that does not exist");
-      }
-
-      if (bp.loading) {
-        // TODO(jwl): make this wait until the breakpoint is saved if it
-        // is still loading
-        throw new Error("attempt to disable unsaved breakpoint");
+      if (!bp || bp.loading) {
+        return;
       }
 
       yield client.removeBreakpoint(bp.generatedLocation);
       var newBreakpoint = _extends({}, bp, { disabled: true });
 
       return dispatch({
         type: "DISABLE_BREAKPOINT",
         breakpoint: newBreakpoint
@@ -18722,19 +18713,17 @@ function setBreakpointCondition(location
           sourceMaps = _ref31.sourceMaps;
 
       var bp = (0, _selectors.getBreakpoint)(getState(), location);
       if (!bp) {
         return dispatch(addBreakpoint(location, condition));
       }
 
       if (bp.loading) {
-        // TODO(jwl): when this function is called, make sure the action
-        // creator waits for the breakpoint to exist
-        throw new Error("breakpoint must be saved");
+        return;
       }
 
       if (bp.disabled) {
         yield dispatch(enableBreakpoint(location));
         bp.disabled = !bp.disabled;
       }
 
       yield client.setBreakpointCondition(bp.id, location, condition, sourceMaps.isOriginalId(bp.location.sourceId));
@@ -18819,22 +18808,18 @@ function addOrToggleDisabledBreakpoint(l
 function toggleDisabledBreakpoint(line, column) {
   return (_ref34) => {
     var dispatch = _ref34.dispatch,
         getState = _ref34.getState,
         client = _ref34.client,
         sourceMaps = _ref34.sourceMaps;
 
     var bp = (0, _selectors.getBreakpointAtLocation)(getState(), { line, column });
-    if (bp && bp.loading) {
-      return;
-    }
-
-    if (!bp) {
-      throw new Error("attempt to disable breakpoint that does not exist");
+    if (!bp || bp.loading) {
+      return;
     }
 
     if (!bp.disabled) {
       return dispatch(disableBreakpoint(bp.location));
     }
     return dispatch(enableBreakpoint(bp.location));
   };
 }
@@ -19629,26 +19614,28 @@ var _assert2 = _interopRequireDefault(_a
 var _breakpoints = __webpack_require__(245);
 
 var _ast = __webpack_require__(1059);
 
 var _projectTextSearch = __webpack_require__(37);
 
 var _ui = __webpack_require__(321);
 
-var _source = __webpack_require__(233);
+var _source2 = __webpack_require__(233);
 
 var _createPrettySource = __webpack_require__(195);
 
 var _loadSourceText = __webpack_require__(1143);
 
 var _prefs = __webpack_require__(226);
 
 var _editor = __webpack_require__(257);
 
+var _sourceMaps = __webpack_require__(797);
+
 var _selectors = __webpack_require__(242);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -19660,16 +19647,21 @@ function _asyncToGenerator(fn) { return 
  */
 
 function newSource(source) {
   return (() => {
     var _ref4 = _asyncToGenerator(function* (_ref5) {
       var dispatch = _ref5.dispatch,
           getState = _ref5.getState;
 
+      var _source = (0, _selectors.getSource)(getState(), source.id);
+      if (_source) {
+        return;
+      }
+
       dispatch({ type: "ADD_SOURCE", source });
 
       if (_prefs.prefs.clientSourceMapsEnabled) {
         yield dispatch(loadSourceMap(source));
       }
 
       yield checkSelectedSource(getState(), dispatch, source);
       yield checkPendingBreakpoints(getState(), dispatch, source);
@@ -19719,17 +19711,20 @@ function loadSourceMap(generatedSource) 
         return;
       }
 
       var state = getState();
       var originalSources = urls.map(function (originalUrl) {
         return {
           url: originalUrl,
           id: sourceMaps.generatedToOriginalId(generatedSource.id, originalUrl),
-          isPrettyPrinted: false
+          isPrettyPrinted: false,
+          isWasm: false,
+          isBlackBoxed: false,
+          loadedState: "unloaded"
         };
       });
 
       dispatch({ type: "ADD_SOURCES", sources: originalSources });
 
       originalSources.forEach(function (source) {
         checkSelectedSource(state, dispatch, source);
         checkPendingBreakpoints(state, dispatch, source);
@@ -19836,17 +19831,17 @@ function jumpToMappedLocation(sourceLoca
 
       if (!client) {
         return;
       }
 
       var source = (0, _selectors.getSource)(getState(), sourceLocation.sourceId);
       var pairedLocation = void 0;
       if (sourceMaps.isOriginalId(sourceLocation.sourceId)) {
-        pairedLocation = yield sourceMaps.getGeneratedLocation(sourceLocation, source.toJS());
+        pairedLocation = yield (0, _sourceMaps.getGeneratedLocation)(getState(), source.toJS(), sourceLocation, sourceMaps);
       } else {
         pairedLocation = yield sourceMaps.getOriginalLocation(sourceLocation, source.toJS());
       }
 
       return dispatch(selectSource(pairedLocation.sourceId, { line: pairedLocation.line }));
     });
 
     return function (_x17) {
@@ -19932,26 +19927,26 @@ function togglePrettyPrint(sourceId) {
     var _ref18 = _asyncToGenerator(function* (_ref19) {
       var dispatch = _ref19.dispatch,
           getState = _ref19.getState,
           client = _ref19.client,
           sourceMaps = _ref19.sourceMaps;
 
       var source = (0, _selectors.getSource)(getState(), sourceId).toJS();
 
-      if (source && !(0, _source.isLoaded)(source)) {
+      if (source && !(0, _source2.isLoaded)(source)) {
         return {};
       }
 
       (0, _assert2.default)(sourceMaps.isGeneratedId(sourceId), "Pretty-printing only allowed on generated sources");
 
       var selectedLocation = (0, _selectors.getSelectedLocation)(getState());
       var selectedOriginalLocation = selectedLocation ? yield sourceMaps.getOriginalLocation(selectedLocation) : {};
 
-      var url = (0, _source.getPrettySourceURL)(source.url);
+      var url = (0, _source2.getPrettySourceURL)(source.url);
       var prettySource = (0, _selectors.getSourceByURL)(getState(), url);
 
       if (prettySource) {
         return dispatch(selectSource(prettySource.get("id"), {
           line: selectedOriginalLocation.line
         }));
       }
 
@@ -20010,21 +20005,25 @@ function loadAllSources() {
       var sources = (0, _selectors.getSources)(getState());
       var query = (0, _selectors.getTextSearchQuery)(getState());
       for (var _ref25 of sources) {
         var _ref26 = _slicedToArray(_ref25, 2);
 
         var src = _ref26[1];
 
         var source = src.toJS();
+        if ((0, _source2.isThirdParty)(source)) {
+          continue;
+        }
+
         yield dispatch((0, _loadSourceText.loadSourceText)(source));
         // If there is a current search query we search
         // each of the source texts as they get loaded
         if (query) {
-          yield dispatch((0, _projectTextSearch.searchSource)(source, query));
+          yield dispatch((0, _projectTextSearch.searchSource)(source.id, query));
         }
       }
     });
 
     return function (_x20) {
       return _ref23.apply(this, arguments);
     };
   })();
@@ -21302,16 +21301,17 @@ DebugLine.displayName = "DebugLine";
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.resumed = resumed;
+exports.continueToHere = continueToHere;
 exports.paused = paused;
 exports.pauseOnExceptions = pauseOnExceptions;
 exports.command = command;
 exports.stepIn = stepIn;
 exports.stepOver = stepOver;
 exports.stepOut = stepOut;
 exports.resume = resume;
 exports.breakOnNext = breakOnNext;
@@ -21366,30 +21366,54 @@ function resumed() {
     });
 
     if (!(0, _selectors.isStepping)(getState())) {
       dispatch((0, _expressions.evaluateExpressions)(null));
     }
   };
 }
 
+function continueToHere(line) {
+  return (() => {
+    var _ref2 = _asyncToGenerator(function* (_ref3) {
+      var dispatch = _ref3.dispatch,
+          getState = _ref3.getState,
+          client = _ref3.client,
+          sourceMaps = _ref3.sourceMaps;
+
+      var source = (0, _selectors.getSelectedSource)(getState()).toJS();
+
+      yield dispatch((0, _breakpoints.addHiddenBreakpoint)({
+        line,
+        column: undefined,
+        sourceId: source.id
+      }));
+      dispatch(command("resume"));
+    });
+
+    return function (_x) {
+      return _ref2.apply(this, arguments);
+    };
+  })();
+}
+
 /**
  * Debugger has just paused
  *
  * @param {object} pauseInfo
  * @memberof actions/pause
  * @static
  */
 function paused(pauseInfo) {
   return (() => {
-    var _ref2 = _asyncToGenerator(function* (_ref3) {
-      var dispatch = _ref3.dispatch,
-          getState = _ref3.getState,
-          client = _ref3.client,
-          sourceMaps = _ref3.sourceMaps;
+    var _ref4 = _asyncToGenerator(function* (_ref5) {
+      var dispatch = _ref5.dispatch,
+          getState = _ref5.getState,
+          client = _ref5.client,
+          sourceMaps = _ref5.sourceMaps;
       var frames = pauseInfo.frames,
           why = pauseInfo.why,
           loadedObjects = pauseInfo.loadedObjects;
 
 
       frames = yield (0, _pause.updateFrameLocations)(frames, sourceMaps);
       var frame = frames[0];
 
@@ -21399,36 +21423,41 @@ function paused(pauseInfo) {
         type: "PAUSED",
         pauseInfo: { why, frame, frames },
         frames: frames,
         scopes,
         selectedFrameId: frame.id,
         loadedObjects: loadedObjects || []
       });
 
+      var hiddenBreakpointLocation = (0, _breakpoints2.getHiddenBreakpointLocation)(getState());
+      if (hiddenBreakpointLocation) {
+        dispatch((0, _breakpoints.removeBreakpoint)(hiddenBreakpointLocation));
+      }
+
       dispatch((0, _expressions.evaluateExpressions)(frame.id));
 
       dispatch((0, _sources.selectSource)(frame.location.sourceId, { line: frame.location.line }));
     });
 
-    return function (_x) {
-      return _ref2.apply(this, arguments);
+    return function (_x2) {
+      return _ref4.apply(this, arguments);
     };
   })();
 }
 
 /**
  *
  * @memberof actions/pause
  * @static
  */
 function pauseOnExceptions(shouldPauseOnExceptions, shouldIgnoreCaughtExceptions) {
-  return (_ref4) => {
-    var dispatch = _ref4.dispatch,
-        client = _ref4.client;
+  return (_ref6) => {
+    var dispatch = _ref6.dispatch,
+        client = _ref6.client;
 
     dispatch({
       type: "PAUSE_ON_EXCEPTIONS",
       shouldPauseOnExceptions,
       shouldIgnoreCaughtExceptions,
       [_promise.PROMISE]: client.pauseOnExceptions(shouldPauseOnExceptions, shouldIgnoreCaughtExceptions)
     });
   };
@@ -21438,165 +21467,165 @@ function pauseOnExceptions(shouldPauseOn
  * Debugger commands like stepOver, stepIn, stepUp
  *
  * @param string $0.type
  * @memberof actions/pause
  * @static
  */
 function command(type) {
   return (() => {
-    var _ref5 = _asyncToGenerator(function* (_ref6) {
-      var dispatch = _ref6.dispatch,
-          client = _ref6.client;
+    var _ref7 = _asyncToGenerator(function* (_ref8) {
+      var dispatch = _ref8.dispatch,
+          client = _ref8.client;
 
       // execute debugger thread command e.g. stepIn, stepOver
       dispatch({ type: "COMMAND", value: { type } });
 
       yield client[type]();
 
       dispatch({ type: "CLEAR_COMMAND" });
     });
 
-    return function (_x2) {
-      return _ref5.apply(this, arguments);
+    return function (_x3) {
+      return _ref7.apply(this, arguments);
     };
   })();
 }
 
 /**
  * StepIn
  * @memberof actions/pause
  * @static
  * @returns {Function} {@link command}
  */
 function stepIn() {
-  return (_ref7) => {
-    var dispatch = _ref7.dispatch,
-        getState = _ref7.getState;
+  return (_ref9) => {
+    var dispatch = _ref9.dispatch,
+        getState = _ref9.getState;
 
     if ((0, _selectors.getPause)(getState())) {
       return dispatch(command("stepIn"));
     }
   };
 }
 
 /**
  * stepOver
  * @memberof actions/pause
  * @static
  * @returns {Function} {@link command}
  */
 function stepOver() {
-  return (_ref8) => {
-    var dispatch = _ref8.dispatch,
-        getState = _ref8.getState;
+  return (_ref10) => {
+    var dispatch = _ref10.dispatch,
+        getState = _ref10.getState;
 
     if ((0, _selectors.getPause)(getState())) {
       return dispatch(astCommand("stepOver"));
     }
   };
 }
 
 /**
  * stepOut
  * @memberof actions/pause
  * @static
  * @returns {Function} {@link command}
  */
 function stepOut() {
-  return (_ref9) => {
-    var dispatch = _ref9.dispatch,
-        getState = _ref9.getState;
+  return (_ref11) => {
+    var dispatch = _ref11.dispatch,
+        getState = _ref11.getState;
 
     if ((0, _selectors.getPause)(getState())) {
       return dispatch(command("stepOut"));
     }
   };
 }
 
 /**
  * resume
  * @memberof actions/pause
  * @static
  * @returns {Function} {@link command}
  */
 function resume() {
-  return (_ref10) => {
-    var dispatch = _ref10.dispatch,
-        getState = _ref10.getState;
+  return (_ref12) => {
+    var dispatch = _ref12.dispatch,
+        getState = _ref12.getState;
 
     if ((0, _selectors.getPause)(getState())) {
       return dispatch(command("resume"));
     }
   };
 }
 
 /**
  * Debugger breakOnNext command.
  * It's different from the comand action because we also want to
  * highlight the pause icon.
  *
  * @memberof actions/pause
  * @static
  */
 function breakOnNext() {
-  return (_ref11) => {
-    var dispatch = _ref11.dispatch,
-        client = _ref11.client;
+  return (_ref13) => {
+    var dispatch = _ref13.dispatch,
+        client = _ref13.client;
 
     client.breakOnNext();
 
     return dispatch({
       type: "BREAK_ON_NEXT",
       value: true
     });
   };
 }
 
 /**
  * @memberof actions/pause
  * @static
  */
 function selectFrame(frame) {
   return (() => {
-    var _ref12 = _asyncToGenerator(function* (_ref13) {
-      var dispatch = _ref13.dispatch,
-          client = _ref13.client;
+    var _ref14 = _asyncToGenerator(function* (_ref15) {
+      var dispatch = _ref15.dispatch,
+          client = _ref15.client;
 
       dispatch((0, _expressions.evaluateExpressions)(frame.id));
       dispatch((0, _sources.selectSource)(frame.location.sourceId, { line: frame.location.line }));
 
       var scopes = yield client.getFrameScopes(frame);
 
       dispatch({
         type: "SELECT_FRAME",
         frame,
         scopes
       });
     });
 
-    return function (_x3) {
-      return _ref12.apply(this, arguments);
+    return function (_x4) {
+      return _ref14.apply(this, arguments);
     };
   })();
 }
 
 /**
  * @memberof actions/pause
  * @static
  */
 function loadObjectProperties(object) {
-  return (_ref14) => {
-    var dispatch = _ref14.dispatch,
-        client = _ref14.client,
-        getState = _ref14.getState;
+  return (_ref16) => {
+    var dispatch = _ref16.dispatch,
+        client = _ref16.client,
+        getState = _ref16.getState;
 
     var objectId = object.actor || object.objectId;
 
-    if ((0, _selectors.getLoadedObject)(getState(), objectId)) {
+    if (!(0, _selectors.getPause)(getState()) || (0, _selectors.getLoadedObject)(getState(), objectId)) {
       return;
     }
 
     dispatch({
       type: "LOAD_OBJECT_PROPERTIES",
       objectId,
       [_promise.PROMISE]: client.getProperties(object)
     });
@@ -21606,48 +21635,43 @@ function loadObjectProperties(object) {
 /**
  * @memberOf actions/pause
  * @static
  * @param stepType
  * @returns {function(ThunkArgs)}
  */
 function astCommand(stepType) {
   return (() => {
-    var _ref15 = _asyncToGenerator(function* (_ref16) {
-      var dispatch = _ref16.dispatch,
-          getState = _ref16.getState,
-          sourceMaps = _ref16.sourceMaps;
+    var _ref17 = _asyncToGenerator(function* (_ref18) {
+      var dispatch = _ref18.dispatch,
+          getState = _ref18.getState,
+          sourceMaps = _ref18.sourceMaps;
 
       if (!_prefs.features.asyncStepping) {
         return dispatch(command(stepType));
       }
 
       var pauseInfo = (0, _selectors.getPause)(getState());
       var source = (0, _selectors.getSelectedSource)(getState()).toJS();
-      var currentHiddenBreakpointLocation = (0, _breakpoints2.getHiddenBreakpointLocation)(getState());
-
-      if (currentHiddenBreakpointLocation) {
-        dispatch((0, _breakpoints.removeBreakpoint)(currentHiddenBreakpointLocation));
-      }
 
       var pausedPosition = yield (0, _pause.getPausedPosition)(pauseInfo, sourceMaps);
 
       if (stepType == "stepOver") {
         var nextLocation = yield parser.getNextStep(source, pausedPosition);
         if (nextLocation) {
           yield dispatch((0, _breakpoints.addHiddenBreakpoint)(nextLocation));
           return dispatch(command("resume"));
         }
       }
 
       return dispatch(command(stepType));
     });
 
-    return function (_x4) {
-      return _ref15.apply(this, arguments);
+    return function (_x5) {
+      return _ref17.apply(this, arguments);
     };
   })();
 }
 
 /***/ }),
 /* 320 */
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -21693,16 +21717,17 @@ function willNavigate(_, event) {
           client = _ref2.client,
           sourceMaps = _ref2.sourceMaps;
 
       yield sourceMaps.clearSourceMaps();
       (0, _wasm.clearWasmStates)();
       (0, _editor.clearDocuments)();
       (0, _parser.clearSymbols)();
       (0, _parser.clearASTs)();
+      (0, _parser.clearSources)();
 
       dispatch(navigate(event.url));
     });
 
     return function (_x) {
       return _ref.apply(this, arguments);
     };
   })();
@@ -21762,16 +21787,17 @@ exports.toggleFrameworkGrouping = toggle
 exports.setSelectedSymbolType = setSelectedSymbolType;
 exports.setFileSearchQuery = setFileSearchQuery;
 exports.updateSearchResults = updateSearchResults;
 exports.toggleFileSearchModifier = toggleFileSearchModifier;
 exports.showSource = showSource;
 exports.togglePaneCollapse = togglePaneCollapse;
 exports.highlightLineRange = highlightLineRange;
 exports.clearHighlightLineRange = clearHighlightLineRange;
+exports.toggleConditionalBreakpointPanel = toggleConditionalBreakpointPanel;
 
 var _selectors = __webpack_require__(242);
 
 var _sourceSearch = __webpack_require__(1144);
 
 function closeActiveSearch() {
   return (_ref) => {
     var getState = _ref.getState,
@@ -21892,16 +21918,23 @@ function highlightLineRange(location) {
  * @static
  */
 function clearHighlightLineRange() {
   return {
     type: "CLEAR_HIGHLIGHT_LINES"
   };
 }
 
+function toggleConditionalBreakpointPanel(line) {
+  return {
+    type: "TOGGLE_CONDITIONAL_BREAKPOINT_PANEL",
+    line
+  };
+}
+
 /***/ }),
 /* 322 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
@@ -24670,16 +24703,18 @@ var _EditorMenu = __webpack_require__(65
 var _EditorMenu2 = _interopRequireDefault(_EditorMenu);
 
 var _ConditionalPanel = __webpack_require__(711);
 
 var _devtoolsLaunchpad = __webpack_require__(131);
 
 var _source = __webpack_require__(233);
 
+var _function = __webpack_require__(1169);
+
 var _ast = __webpack_require__(1058);
 
 var _selectors = __webpack_require__(242);
 
 var _actions = __webpack_require__(244);
 
 var _actions2 = _interopRequireDefault(_actions);
 
@@ -24730,17 +24765,16 @@ var _devtoolsSourceEditor = __webpack_re
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 var cssVars = {
   searchbarHeight: "var(--editor-searchbar-height)",
   secondSearchbarHeight: "var(--editor-second-searchbar-height)",
   footerHeight: "var(--editor-footer-height)"
 };
 
-
 class Editor extends _react.PureComponent {
 
   constructor() {
     super();
 
     this.cbPanel = null;
     this.pendingJumpLocation = null;
     this.lastJumpLine = null;
@@ -24901,16 +24935,20 @@ class Editor extends _react.PureComponen
     }
 
     // Only update and jump around in real source texts. This will
     // keep the jump state around until the real source text is
     // loaded.
     if (selectedSource && selectedSource.has("text")) {
       this.highlightLine();
     }
+
+    if (this.props.conditionalBreakpointPanel !== null && this.cbPanel == null) {
+      this.toggleConditionalPanel(this.props.conditionalBreakpointPanel);
+    }
   }
 
   onToggleBreakpoint(key, e) {
     e.preventDefault();
     var codeMirror = this.state.editor.codeMirror;
     var selectedSource = this.props.selectedSource;
 
     var line = (0, _editor.getCursorLine)(codeMirror);
@@ -24988,28 +25026,30 @@ class Editor extends _react.PureComponen
 
   openMenu(event, codeMirror) {
     var _props5 = this.props,
         selectedSource = _props5.selectedSource,
         selectedLocation = _props5.selectedLocation,
         showSource = _props5.showSource,
         jumpToMappedLocation = _props5.jumpToMappedLocation,
         addExpression = _props5.addExpression,
-        toggleBlackBox = _props5.toggleBlackBox;
+        toggleBlackBox = _props5.toggleBlackBox,
+        getFunctionText = _props5.getFunctionText;
 
 
     return (0, _EditorMenu2.default)({
       codeMirror,
       event,
       selectedLocation,
       selectedSource,
       showSource,
       jumpToMappedLocation,
       addExpression,
       toggleBlackBox,
+      getFunctionText,
       onGutterContextMenu: this.onGutterContextMenu
     });
   }
 
   onGutterClick(cm, line, gutter, ev) {
     var _props6 = this.props,
         selectedSource = _props6.selectedSource,
         toggleBreakpoint = _props6.toggleBreakpoint,
@@ -25044,17 +25084,19 @@ class Editor extends _react.PureComponen
   }
 
   onGutterContextMenu(event) {
     var _props7 = this.props,
         selectedSource = _props7.selectedSource,
         breakpoints = _props7.breakpoints,
         toggleBreakpoint = _props7.toggleBreakpoint,
         toggleDisabledBreakpoint = _props7.toggleDisabledBreakpoint,
-        isEmptyLine = _props7.isEmptyLine;
+        isEmptyLine = _props7.isEmptyLine,
+        pauseData = _props7.pauseData,
+        continueToHere = _props7.continueToHere;
 
 
     if (selectedSource && selectedSource.get("isBlackBoxed")) {
       event.preventDefault();
       return;
     }
 
     var sourceId = selectedSource ? selectedSource.get("id") : "";
@@ -25066,16 +25108,18 @@ class Editor extends _react.PureComponen
     }
 
     (0, _GutterMenu2.default)({
       event,
       line,
       breakpoint,
       toggleBreakpoint,
       toggleDisabledBreakpoint,
+      pauseData,
+      continueToHere,
 
       showConditionalPanel: this.toggleConditionalPanel,
       isCbPanelOpen: this.isCbPanelOpen(),
       closeConditionalPanel: this.closeConditionalPanel
     });
   }
 
   toggleConditionalPanel(line) {
@@ -25104,16 +25148,17 @@ class Editor extends _react.PureComponen
     this.cbPanel = this.state.editor.codeMirror.addLineWidget(editorLine, panel, {
       coverGutter: true,
       noHScroll: false
     });
     this.cbPanel.node.querySelector("input").focus();
   }
 
   closeConditionalPanel() {
+    this.props.toggleConditionalBreakpointPanel(null);
     this.cbPanel.clear();
     this.cbPanel = null;
   }
 
   isCbPanelOpen() {
     return !!this.cbPanel;
   }
 
@@ -25373,17 +25418,21 @@ Editor.propTypes = {
     wholeWord: _react.PropTypes.bool.isRequired
   }).isRequired,
   startPanelSize: _react.PropTypes.number,
   endPanelSize: _react.PropTypes.number,
   linesInScope: _react.PropTypes.array,
   toggleBreakpoint: _react.PropTypes.func.isRequired,
   addOrToggleDisabledBreakpoint: _react.PropTypes.func.isRequired,
   toggleDisabledBreakpoint: _react.PropTypes.func.isRequired,
-  isEmptyLine: _react.PropTypes.func
+  conditionalBreakpointPanel: _react.PropTypes.number,
+  toggleConditionalBreakpointPanel: _react.PropTypes.func.isRequired,
+  isEmptyLine: _react.PropTypes.func,
+  continueToHere: _react.PropTypes.func,
+  getFunctionText: _react.PropTypes.func
 };
 
 Editor.contextTypes = {
   shortcuts: _react.PropTypes.object
 };
 
 exports.default = (0, _reactRedux.connect)(state => {
   var selectedLocation = (0, _selectors.getSelectedLocation)(state);
@@ -25399,17 +25448,19 @@ exports.default = (0, _reactRedux.connec
     breakpoints: (0, _selectors.getVisibleBreakpoints)(state),
     hitCount: (0, _selectors.getHitCountForSource)(state, sourceId),
     selectedFrame: (0, _selectors.getSelectedFrame)(state),
     pauseData: (0, _selectors.getPause)(state),
     coverageOn: (0, _selectors.getCoverageEnabled)(state),
     query: (0, _selectors.getFileSearchQueryState)(state),
     searchModifiers: (0, _selectors.getFileSearchModifierState)(state),
     linesInScope: (0, _selectors.getInScopeLines)(state),
-    isEmptyLine: line => (0, _ast.isEmptyLineInSource)(state, line, selectedSource.toJS())
+    getFunctionText: line => (0, _function.findFunctionText)(line, selectedSource.toJS(), (0, _selectors.getSymbols)(state, selectedSource.toJS())),
+    isEmptyLine: line => (0, _ast.isEmptyLineInSource)(state, line, selectedSource.toJS()),
+    conditionalBreakpointPanel: (0, _selectors.getConditionalBreakpointPanel)(state)
   };
 }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(Editor);
 
 /***/ }),
 /* 427 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -26596,29 +26647,34 @@ module.exports = now;
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
+
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
 exports.default = GutterMenu;
 
 var _devtoolsLaunchpad = __webpack_require__(131);
 
 function GutterMenu(_ref) {
   var breakpoint = _ref.breakpoint,
       line = _ref.line,
       event = _ref.event,
+      pauseData = _ref.pauseData,
       toggleBreakpoint = _ref.toggleBreakpoint,
       showConditionalPanel = _ref.showConditionalPanel,
       toggleDisabledBreakpoint = _ref.toggleDisabledBreakpoint,
       isCbPanelOpen = _ref.isCbPanelOpen,
-      closeConditionalPanel = _ref.closeConditionalPanel;
+      closeConditionalPanel = _ref.closeConditionalPanel,
+      continueToHere = _ref.continueToHere;
 
   event.stopPropagation();
   event.preventDefault();
 
   var gutterItems = {
     addBreakpoint: {
       id: "node-menu-add-breakpoint",
       label: L10N.getStr("editor.addBreakpoint")
@@ -26637,16 +26693,20 @@ function GutterMenu(_ref) {
     },
     enableBreakpoint: {
       id: "node-menu-enable-breakpoint",
       label: L10N.getStr("editor.enableBreakpoint")
     },
     disableBreakpoint: {
       id: "node-menu-disable-breakpoint",
       label: L10N.getStr("editor.disableBreakpoint")
+    },
+    continueToHere: {
+      id: "node-menu-continue-to-here",
+      label: L10N.getStr("editor.continueToHere.label")
     }
   };
 
   var toggleBreakpointItem = Object.assign({
     accesskey: "B",
     disabled: false,
     click: () => {
       toggleBreakpoint(line);
@@ -26659,16 +26719,25 @@ function GutterMenu(_ref) {
   var conditionalBreakpoint = Object.assign({
     accesskey: "C",
     disabled: false,
     click: () => showConditionalPanel(line)
   }, breakpoint && breakpoint.condition ? gutterItems.editConditional : gutterItems.addConditional);
 
   var items = [toggleBreakpointItem, conditionalBreakpoint];
 
+  if (pauseData) {
+    var continueToHereItem = _extends({
+      accesskey: L10N.getStr("editor.continueToHere.accesskey"),
+      disabled: false,
+      click: () => continueToHere(line)
+    }, gutterItems.continueToHere);
+    items.push(continueToHereItem);
+  }
+
   if (breakpoint) {
     var disableBreakpoint = Object.assign({
       accesskey: "D",
       disabled: false,
       click: () => toggleDisabledBreakpoint(line)
     }, breakpoint.disabled ? gutterItems.enableBreakpoint : gutterItems.disableBreakpoint);
     items.push(disableBreakpoint);
   }
@@ -26719,20 +26788,23 @@ function _asyncToGenerator(fn) { return 
 function getMenuItems(event, _ref) {
   var codeMirror = _ref.codeMirror,
       selectedLocation = _ref.selectedLocation,
       selectedSource = _ref.selectedSource,
       showSource = _ref.showSource,
       onGutterContextMenu = _ref.onGutterContextMenu,
       jumpToMappedLocation = _ref.jumpToMappedLocation,
       toggleBlackBox = _ref.toggleBlackBox,
-      addExpression = _ref.addExpression;
+      addExpression = _ref.addExpression,
+      getFunctionText = _ref.getFunctionText;
 
   var copySourceLabel = L10N.getStr("copySource");
   var copySourceKey = L10N.getStr("copySource.accesskey");
+  var copyFunctionLabel = L10N.getStr("copyFunction.label");
+  var copyFunctionKey = L10N.getStr("copyFunction.accesskey");
   var copySourceUrlLabel = L10N.getStr("copySourceUrl");
   var copySourceUrlKey = L10N.getStr("copySourceUrl.accesskey");
   var revealInTreeLabel = L10N.getStr("sourceTabs.revealInTree");
   var revealInTreeKey = L10N.getStr("sourceTabs.revealInTree.accesskey");
   var blackboxLabel = L10N.getStr("sourceFooter.blackbox");
   var unblackboxLabel = L10N.getStr("sourceFooter.unblackbox");
   var blackboxKey = L10N.getStr("sourceFooter.blackbox.accesskey");
   var toggleBlackBoxLabel = selectedSource.get("isBlackBoxed") ? unblackboxLabel : blackboxLabel;
@@ -26796,17 +26868,26 @@ function getMenuItems(event, _ref) {
   var showSourceMenuItem = {
     id: "node-menu-show-source",
     label: revealInTreeLabel,
     accesskey: revealInTreeKey,
     disabled: false,
     click: () => showSource(selectedSource.get("id"))
   };
 
-  var menuItems = [copySource, copySourceUrl, jumpLabel, showSourceMenuItem, blackBoxMenuItem];
+  var functionText = getFunctionText(line + 1);
+  var copyFunction = {
+    id: "node-menu-copy-function",
+    label: copyFunctionLabel,
+    accesskey: copyFunctionKey,
+    disabled: !functionText,
+    click: () => (0, _clipboard.copyToTheClipboard)(functionText)
+  };
+
+  var menuItems = [copySourceUrl, jumpLabel, showSourceMenuItem, blackBoxMenuItem, copySource, copyFunction];
 
   if (textSelected) {
     menuItems.push(watchExpressionLabel);
   }
 
   return menuItems;
 }
 
@@ -28028,40 +28109,46 @@ class Breakpoints extends _react.PureCom
   showContextMenu(e, breakpoint) {
     var _props = this.props,
         removeBreakpoint = _props.removeBreakpoint,
         removeBreakpoints = _props.removeBreakpoints,
         removeAllBreakpoints = _props.removeAllBreakpoints,
         toggleBreakpoints = _props.toggleBreakpoints,
         toggleAllBreakpoints = _props.toggleAllBreakpoints,
         toggleDisabledBreakpoint = _props.toggleDisabledBreakpoint,
+        setBreakpointCondition = _props.setBreakpointCondition,
+        toggleConditionalBreakpointPanel = _props.toggleConditionalBreakpointPanel,
         breakpoints = _props.breakpoints;
 
 
     e.preventDefault();
 
     var deleteSelfLabel = L10N.getStr("breakpointMenuItem.deleteSelf");
     var deleteAllLabel = L10N.getStr("breakpointMenuItem.deleteAll");
     var deleteOthersLabel = L10N.getStr("breakpointMenuItem.deleteOthers");
     var enableSelfLabel = L10N.getStr("breakpointMenuItem.enableSelf");
     var enableAllLabel = L10N.getStr("breakpointMenuItem.enableAll");
     var enableOthersLabel = L10N.getStr("breakpointMenuItem.enableOthers");
     var disableSelfLabel = L10N.getStr("breakpointMenuItem.disableSelf");
     var disableAllLabel = L10N.getStr("breakpointMenuItem.disableAll");
     var disableOthersLabel = L10N.getStr("breakpointMenuItem.disableOthers");
+    var removeConditionLabel = L10N.getStr("breakpointMenuItem.removeCondition.label");
+    var editConditionLabel = L10N.getStr("breakpointMenuItem.editCondition.label");
 
     var deleteSelfKey = L10N.getStr("breakpointMenuItem.deleteSelf.accesskey");
     var deleteAllKey = L10N.getStr("breakpointMenuItem.deleteAll.accesskey");
     var deleteOthersKey = L10N.getStr("breakpointMenuItem.deleteOthers.accesskey");
     var enableSelfKey = L10N.getStr("breakpointMenuItem.enableSelf.accesskey");
     var enableAllKey = L10N.getStr("breakpointMenuItem.enableAll.accesskey");
     var enableOthersKey = L10N.getStr("breakpointMenuItem.enableOthers.accesskey");
     var disableSelfKey = L10N.getStr("breakpointMenuItem.disableSelf.accesskey");
     var disableAllKey = L10N.getStr("breakpointMenuItem.disableAll.accesskey");
     var disableOthersKey = L10N.getStr("breakpointMenuItem.disableOthers.accesskey");
+    var removeConditionKey = L10N.getStr("breakpointMenuItem.removeCondition.accesskey");
+    var editConditionKey = L10N.getStr("breakpointMenuItem.editCondition.accesskey");
 
     var otherBreakpoints = breakpoints.filter(b => b !== breakpoint);
     var enabledBreakpoints = breakpoints.filter(b => !b.disabled);
     var disabledBreakpoints = breakpoints.filter(b => b.disabled);
     var otherEnabledBreakpoints = breakpoints.filter(b => !b.disabled && b !== breakpoint);
     var otherDisabledBreakpoints = breakpoints.filter(b => b.disabled && b !== breakpoint);
 
     var deleteSelf = {
@@ -28130,44 +28217,69 @@ class Breakpoints extends _react.PureCom
 
     var disableOthers = {
       id: "node-menu-disable-others",
       label: disableOthersLabel,
       accesskey: disableOthersKey,
       click: () => toggleBreakpoints(true, otherEnabledBreakpoints)
     };
 
+    var removeCondition = {
+      id: "node-menu-remove-condition",
+      label: removeConditionLabel,
+      accesskey: removeConditionKey,
+      disabled: false,
+      click: () => setBreakpointCondition(breakpoint.location)
+    };
+
+    var editCondition = {
+      id: "node-menu-edit-condition",
+      label: editConditionLabel,
+      accesskey: editConditionKey,
+      click: () => toggleConditionalBreakpointPanel(breakpoint.location.line)
+    };
+
     var items = [{ item: enableSelf, hidden: () => !breakpoint.disabled }, { item: disableSelf, hidden: () => breakpoint.disabled }, { item: deleteSelf }, { item: deleteAll }, { item: deleteOthers, hidden: () => breakpoints.size === 1 }, {
       item: enableAll,
       hidden: () => disabledBreakpoints.size === 0
     }, {
       item: disableAll,
       hidden: () => enabledBreakpoints.size === 0
     }, {
       item: enableOthers,
       hidden: () => otherDisabledBreakpoints.size === 0
     }, {
       item: disableOthers,
       hidden: () => otherEnabledBreakpoints.size === 0
+    }, {
+      item: removeCondition,
+      hidden: () => !breakpoint.condition
+    }, {
+      item: editCondition,
+      hidden: () => !breakpoint.condition
     }];
 
     (0, _devtoolsLaunchpad.showMenu)(e, (0, _devtoolsLaunchpad.buildMenu)(items));
   }
 
   selectBreakpoint(breakpoint) {
     var sourceId = breakpoint.location.sourceId;
     var line = breakpoint.location.line;
     this.props.selectSource(sourceId, { line });
   }
 
   removeBreakpoint(event, breakpoint) {
     event.stopPropagation();
     this.props.removeBreakpoint(breakpoint.location);
   }
 
+  toggleConditionalBreakpointPanel(line) {
+    this.props.toggleConditionalBreakpointPanel(line);
+  }
+
   renderBreakpoint(breakpoint) {
     var snippet = breakpoint.text || "";
     var locationId = breakpoint.locationId;
     var line = breakpoint.location.line;
     var column = breakpoint.location.column;
     var isCurrentlyPaused = breakpoint.isCurrentlyPaused;
     var isDisabled = breakpoint.disabled;
     var isConditional = !!breakpoint.condition;
@@ -29317,64 +29429,54 @@ class WelcomeBox extends _react.Componen
       handleClick: togglePaneCollapse
     });
   }
 
   render() {
     var searchSourcesShortcut = (0, _text.formatKeyShortcut)(L10N.getStr("sources.search.key2"));
 
     var searchProjectShortcut = (0, _text.formatKeyShortcut)(L10N.getStr("projectTextSearch.key"));
-    var searchFunctionsShortcut = (0, _text.formatKeyShortcut)(L10N.getStr("functionSearch.key"));
 
     var searchSourcesLabel = L10N.getStr("welcome.search").substring(2);
     var searchProjectLabel = L10N.getStr("welcome.findInFiles").substring(2);
-    var searchFunctionLabel = L10N.getStr("welcome.searchFunction").substring(2);
+    var setActiveSearch = this.props.setActiveSearch;
+
 
     return _react2.default.createElement(
       "div",
       { className: "welcomebox" },
       _react2.default.createElement(
         "div",
         { className: "alignlabel" },
         _react2.default.createElement(
           "div",
           { className: "shortcutKeys" },
           _react2.default.createElement(
             "p",
-            null,
+            { onClick: setActiveSearch.bind(null, "source") },
             searchSourcesShortcut
           ),
           _react2.default.createElement(
             "p",
-            null,
+            { onClick: setActiveSearch.bind(null, "project") },
             searchProjectShortcut
-          ),
-          _react2.default.createElement(
-            "p",
-            null,
-            searchFunctionsShortcut
           )
         ),
         _react2.default.createElement(
           "div",
           { className: "shortcutFunction" },
           _react2.default.createElement(
             "p",
-            null,
+            { onClick: setActiveSearch.bind(null, "source") },
             searchSourcesLabel
           ),
           _react2.default.createElement(
             "p",
-            null,
+            { onClick: setActiveSearch.bind(null, "project") },
             searchProjectLabel
-          ),
-          _react2.default.createElement(
-            "p",
-            null,
-            searchFunctionLabel
           )
         ),
         this.renderToggleButton()
       )
     );
   }
 }
 
@@ -30145,28 +30247,35 @@ function sortTree(tree) {
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.getGeneratedLocation = undefined;
 
-var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
-
 var getGeneratedLocation = exports.getGeneratedLocation = (() => {
   var _ref = _asyncToGenerator(function* (state, source, location, sourceMaps) {
     if (!sourceMaps.isOriginalId(location.sourceId)) {
       return location;
     }
 
-    var generatedLocation = yield sourceMaps.getGeneratedLocation(location, source);
-    var generatedSource = (0, _selectors.getSource)(state, generatedLocation.sourceId);
+    var _ref2 = yield sourceMaps.getGeneratedLocation(location, source),
+        line = _ref2.line,
+        sourceId = _ref2.sourceId,
+        column = _ref2.column;
+
+    var generatedSource = (0, _selectors.getSource)(state, sourceId);
     var sourceUrl = generatedSource.get("url");
-    return _extends({}, generatedLocation, { sourceUrl });
+    return {
+      line,
+      sourceId,
+      column: column === 0 ? undefined : column,
+      sourceUrl
+    };
   });
 
   return function getGeneratedLocation(_x, _x2, _x3, _x4) {
     return _ref.apply(this, arguments);
   };
 })();
 
 var _selectors = __webpack_require__(242);
@@ -30303,16 +30412,18 @@ var findScopeByName = exports.findScopeB
     });
   });
 
   return function findScopeByName(_x3, _x4) {
     return _ref2.apply(this, arguments);
   };
 })();
 
+exports.findClosestScope = findClosestScope;
+
 var _parser = __webpack_require__(827);
 
 var _contains = __webpack_require__(1127);
 
 function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
 
 function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
 
@@ -30760,17 +30871,17 @@ exports.default = (0, _reactRedux.connec
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.getEmptyLines = exports.getNextStep = exports.clearASTs = exports.clearSymbols = exports.getOutOfScopeLocations = exports.getVariablesInScope = exports.getSymbols = exports.getClosestExpression = exports.stopParserWorker = exports.startParserWorker = undefined;
+exports.clearSources = exports.setSource = exports.hasSource = exports.getEmptyLines = exports.getNextStep = exports.clearASTs = exports.clearSymbols = exports.getOutOfScopeLocations = exports.getVariablesInScope = exports.getSymbols = exports.getClosestExpression = exports.stopParserWorker = exports.startParserWorker = undefined;
 
 var _devtoolsUtils = __webpack_require__(900);
 
 var WorkerDispatcher = _devtoolsUtils.workerUtils.WorkerDispatcher;
 
 
 var dispatcher = new WorkerDispatcher();
 var startParserWorker = exports.startParserWorker = dispatcher.start.bind(dispatcher);
@@ -30779,16 +30890,19 @@ var stopParserWorker = exports.stopParse
 var getClosestExpression = exports.getClosestExpression = dispatcher.task("getClosestExpression");
 var getSymbols = exports.getSymbols = dispatcher.task("getSymbols");
 var getVariablesInScope = exports.getVariablesInScope = dispatcher.task("getVariablesInScope");
 var getOutOfScopeLocations = exports.getOutOfScopeLocations = dispatcher.task("getOutOfScopeLocations");
 var clearSymbols = exports.clearSymbols = dispatcher.task("clearSymbols");
 var clearASTs = exports.clearASTs = dispatcher.task("clearASTs");
 var getNextStep = exports.getNextStep = dispatcher.task("getNextStep");
 var getEmptyLines = exports.getEmptyLines = dispatcher.task("getEmptyLines");
+var hasSource = exports.hasSource = dispatcher.task("hasSource");
+var setSource = exports.setSource = dispatcher.task("setSource");
+var clearSources = exports.clearSources = dispatcher.task("clearSources");
 
 /***/ }),
 /* 828 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -32039,17 +32153,18 @@ var onConnect = (() => {
       return {
         store,
         actions,
         selectors,
         client: client.clientCommands,
         prefs: _prefs.prefs,
         features: _prefs.features,
         connection,
-        bpClients
+        bpClients,
+        services
       };
     };
 
     if (!(0, _devtoolsConfig.isFirefoxPanel)()) {
       console.group("Development Notes");
       var baseUrl = "https://devtools-html.github.io/debugger.html";
       var localDevelopmentUrl = `${baseUrl}/docs/local-development.html`;
       console.log("Debugging Tips", localDevelopmentUrl);
@@ -32121,17 +32236,17 @@ var onConnect = exports.onConnect = (() 
         threadClient = _connection$tabConnec.threadClient,
         debuggerClient = _connection$tabConnec.debuggerClient;
 
 
     if (!tabTarget || !threadClient || !debuggerClient) {
       return { bpClients: {} };
     }
 
-    var supportsWasm = (0, _devtoolsConfig.isEnabled)("wasm") && !!debuggerClient.mainRoot.traits.wasmBinarySource;
+    var supportsWasm = _prefs.features.wasm && !!debuggerClient.mainRoot.traits.wasmBinarySource;
 
     var _setupCommands = (0, _commands.setupCommands)({
       threadClient,
       tabTarget,
       debuggerClient,
       supportsWasm
     }),
         bpClients = _setupCommands.bpClients;
@@ -32172,17 +32287,17 @@ var onConnect = exports.onConnect = (() 
     return _ref.apply(this, arguments);
   };
 })();
 
 var _commands = __webpack_require__(890);
 
 var _events = __webpack_require__(892);
 
-var _devtoolsConfig = __webpack_require__(828);
+var _prefs = __webpack_require__(226);
 
 function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
 
 exports.clientCommands = _commands.clientCommands;
 exports.clientEvents = _events.clientEvents;
 
 /***/ }),
 /* 890 */
@@ -32682,16 +32797,17 @@ var onConnect = exports.onConnect = (() 
 
     Debugger.scriptParsed(_events.clientEvents.scriptParsed);
     Debugger.scriptFailedToParse(_events.clientEvents.scriptFailedToParse);
     Debugger.paused(_events.clientEvents.paused);
     Debugger.resumed(_events.clientEvents.resumed);
 
     (0, _commands.setupCommands)({ Debugger, Runtime, Page });
     (0, _events.setupEvents)({ actions, Page, type, Runtime });
+    return {};
   });
 
   return function onConnect(_x, _x2) {
     return _ref.apply(this, arguments);
   };
 })();
 
 var _commands = __webpack_require__(894);
@@ -33171,17 +33287,17 @@ function updatePrefs(state) {
 
 const {
   originalToGeneratedId,
   generatedToOriginalId,
   isGeneratedId,
   isOriginalId
 } = __webpack_require__(899);
 
-const { workerUtils: { WorkerDispatcher } } = __webpack_require__(900);
+const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1165);
 
 const dispatcher = new WorkerDispatcher();
 
 const getOriginalURLs = dispatcher.task("getOriginalURLs");
 const getGeneratedLocation = dispatcher.task("getGeneratedLocation");
 const getOriginalLocation = dispatcher.task("getOriginalLocation");
 const getOriginalSourceText = dispatcher.task("getOriginalSourceText");
 const applySourceMap = dispatcher.task("applySourceMap");
@@ -33357,16 +33473,20 @@ WorkerDispatcher.prototype = {
         const id = this.msgId++;
         this.worker.postMessage({ id, method, args });
 
         const listener = ({ data: result }) => {
           if (result.id !== id) {
             return;
           }
 
+          if (!this.worker) {
+            reject("Oops, The worker has shutdown!");
+            return;
+          }
           this.worker.removeEventListener("message", listener);
           if (result.error) {
             reject(result.error);
           } else {
             resolve(result.response);
           }
         };
 
@@ -33561,17 +33681,17 @@ function updatePreview(target, editor, _
     }
 
     // We are mousing over a new token that is not in the preview
     if (!target.classList.contains("debug-expression")) {
       clearPreview();
     }
   }
 
-  var invalidToken = tokenText === "" || tokenText.match(/[(){},.;\s]/);
+  var invalidToken = tokenText === "" || tokenText.match(/[(){}\|&%,.;=<>\+-/\*\s]/);
   var invalidTarget = target.parentElement && !target.parentElement.closest(".CodeMirror-line") || cursorPos.top == 0;
   var isUpdating = preview && preview.updating;
   var inScope = linesInScope && linesInScope.includes(location.line);
 
   if (invalidTarget || !inScope || isUpdating || invalidToken) {
     return;
   }
 
@@ -38226,17 +38346,17 @@ module.exports = {
   supportsObject,
   maxLengthMap
 };
 
 /***/ }),
 /* 960 */
 /***/ (function(module, exports) {
 
-module.exports = "# This Source Code Form is subject to the terms of the Mozilla Public\n# License, v. 2.0. If a copy of the MPL was not distributed with this\n# file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n# LOCALIZATION NOTE These strings are used inside the Debugger\n# which is available from the Web Developer sub-menu -> 'Debugger'.\n# The correct localization of this file might be to keep it in\n# English, or another language commonly spoken among web developers.\n# You want to make that choice consistent across the developer tools.\n# A good criteria is the language in which you'd find the best\n# documentation on web development on the web.\n\n# LOCALIZATION NOTE (collapsePanes): This is the tooltip for the button\n# that collapses the left and right panes in the debugger UI.\ncollapsePanes=Collapse panes\n\n# LOCALIZATION NOTE (copySource): This is the text that appears in the\n# context menu to copy the selected source of file open.\ncopySource=Copy\ncopySource.accesskey=y\n\n# LOCALIZATION NOTE (copySourceUrl): This is the text that appears in the\n# context menu to copy the source URL of file open.\ncopySourceUrl=Copy Source Url\ncopySourceUrl.accesskey=u\n\n# LOCALIZATION NOTE (copyStackTrace): This is the text that appears in the\n# context menu to copy the stack trace methods, file names and row number.\ncopyStackTrace=Copy Stack Trace\ncopyStackTrace.accesskey=c\n\n# LOCALIZATION NOTE (expandPanes): This is the tooltip for the button\n# that expands the left and right panes in the debugger UI.\nexpandPanes=Expand panes\n\n# LOCALIZATION NOTE (pauseButtonTooltip): The tooltip that is displayed for the pause\n# button when the debugger is in a running state.\npauseButtonTooltip=Pause %S\n\n# LOCALIZATION NOTE (pausePendingButtonTooltip): The tooltip that is displayed for\n# the pause button after it's been clicked but before the next JavaScript to run.\npausePendingButtonTooltip=Waiting for next execution\n\n# LOCALIZATION NOTE (resumeButtonTooltip): The label that is displayed on the pause\n# button when the debugger is in a paused state.\nresumeButtonTooltip=Resume %S\n\n# LOCALIZATION NOTE (stepOverTooltip): The label that is displayed on the\n# button that steps over a function call.\nstepOverTooltip=Step Over %S\n\n# LOCALIZATION NOTE (stepInTooltip): The label that is displayed on the\n# button that steps into a function call.\nstepInTooltip=Step In %S\n\n# LOCALIZATION NOTE (stepOutTooltip): The label that is displayed on the\n# button that steps out of a function call.\nstepOutTooltip=Step Out %S\n\n# LOCALIZATION NOTE (workersHeader): The text to display in the events\n# header.\nworkersHeader=Workers\n\n# LOCALIZATION NOTE (noWorkersText): The text to display in the workers list\n# when there are no workers.\nnoWorkersText=This page has no workers.\n\n# LOCALIZATION NOTE (noSourcesText): The text to display in the sources list\n# when there are no sources.\nnoSourcesText=This page has no sources.\n\n# LOCALIZATION NOTE (noEventListenersText): The text to display in the events tab\n# when there are no events.\nnoEventListenersText=No event listeners to display\n\n# LOCALIZATION NOTE (eventListenersHeader): The text to display in the events\n# header.\neventListenersHeader=Event Listeners\n\n# LOCALIZATION NOTE (noStackFramesText): The text to display in the call stack tab\n# when there are no stack frames.\nnoStackFramesText=No stack frames to display\n\n# LOCALIZATION NOTE (eventCheckboxTooltip): The tooltip text to display when\n# the user hovers over the checkbox used to toggle an event breakpoint.\neventCheckboxTooltip=Toggle breaking on this event\n\n# LOCALIZATION NOTE (eventOnSelector): The text to display in the events tab\n# for every event item, between the event type and event selector.\neventOnSelector=on\n\n# LOCALIZATION NOTE (eventInSource): The text to display in the events tab\n# for every event item, between the event selector and listener's owner source.\neventInSource=in\n\n# LOCALIZATION NOTE (eventNodes): The text to display in the events tab when\n# an event is listened on more than one target node.\neventNodes=%S nodes\n\n# LOCALIZATION NOTE (eventNative): The text to display in the events tab when\n# a listener is added from plugins, thus getting translated to native code.\neventNative=[native code]\n\n# LOCALIZATION NOTE (*Events): The text to display in the events tab for\n# each group of sub-level event entries.\nanimationEvents=Animation\naudioEvents=Audio\nbatteryEvents=Battery\nclipboardEvents=Clipboard\ncompositionEvents=Composition\ndeviceEvents=Device\ndisplayEvents=Display\ndragAndDropEvents=Drag and Drop\ngamepadEvents=Gamepad\nindexedDBEvents=IndexedDB\ninteractionEvents=Interaction\nkeyboardEvents=Keyboard\nmediaEvents=HTML5 Media\nmouseEvents=Mouse\nmutationEvents=Mutation\nnavigationEvents=Navigation\npointerLockEvents=Pointer Lock\nsensorEvents=Sensor\nstorageEvents=Storage\ntimeEvents=Time\ntouchEvents=Touch\notherEvents=Other\n\n# LOCALIZATION NOTE (blackboxCheckboxTooltip2): The tooltip text to display when\n# the user hovers over the checkbox used to toggle blackboxing its associated\n# source.\nblackboxCheckboxTooltip2=Toggle blackboxing\n\n# LOCALIZATION NOTE (sources.search.key2): Key shortcut to open the search for\n# searching all the source files the debugger has seen.\nsources.search.key2=CmdOrCtrl+P\n\n# LOCALIZATION NOTE (sources.search.alt.key): A second key shortcut to open the\n# search for searching all the source files the debugger has seen.\nsources.search.alt.key=CmdOrCtrl+O\n\n# LOCALIZATION NOTE (projectTextSearch.key): A key shortcut to open the\n# full project text search for searching all the files the debugger has seen.\nprojectTextSearch.key=CmdOrCtrl+Shift+F\n\n# LOCALIZATION NOTE (functionSearch.key): A key shortcut to open the\n# modal for searching functions in a file.\nfunctionSearch.key=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE (projectTextSearch.placeholder): A placeholder shown\n# when searching across all of the files in a project.\nprojectTextSearch.placeholder=Find in files…\n\n# LOCALIZATION NOTE (sources.noSourcesAvailable): Text shown when the debugger\n# does not have any sources.\nsources.noSourcesAvailable=This page has no sources\n\n# LOCALIZATION NOTE (sourceSearch.search.key2): Key shortcut to open the search\n# for searching within a the currently opened files in the editor\nsourceSearch.search.key2=CmdOrCtrl+F\n\n# LOCALIZATION NOTE (sourceSearch.search.placeholder): placeholder text in\n# the source search input bar\nsourceSearch.search.placeholder=Search in file…\n\n# LOCALIZATION NOTE (sourceSearch.search.again.key2): Key shortcut to highlight\n# the next occurrence of the last search triggered from a source search\nsourceSearch.search.again.key2=CmdOrCtrl+G\n\n# LOCALIZATION NOTE (sourceSearch.search.againPrev.key2): Key shortcut to highlight\n# the previous occurrence of the last search triggered from a source search\nsourceSearch.search.againPrev.key2=CmdOrCtrl+Shift+G\n\n# LOCALIZATION NOTE (sourceSearch.resultsSummary1): Shows a summary of\n# the number of matches for autocomplete\nsourceSearch.resultsSummary1=%d results\n\n# LOCALIZATION NOTE (noMatchingStringsText): The text to display in the\n# global search results when there are no matching strings after filtering.\nnoMatchingStringsText=No matches found\n\n# LOCALIZATION NOTE (emptySearchText): This is the text that appears in the\n# filter text box when it is empty and the scripts container is selected.\nemptySearchText=Search scripts (%S)\n\n# LOCALIZATION NOTE (emptyVariablesFilterText): This is the text that\n# appears in the filter text box for the variables view container.\nemptyVariablesFilterText=Filter variables\n\n# LOCALIZATION NOTE (emptyPropertiesFilterText): This is the text that\n# appears in the filter text box for the editor's variables view bubble.\nemptyPropertiesFilterText=Filter properties\n\n# LOCALIZATION NOTE (searchPanelFilter): This is the text that appears in the\n# filter panel popup for the filter scripts operation.\nsearchPanelFilter=Filter scripts (%S)\n\n# LOCALIZATION NOTE (searchPanelGlobal): This is the text that appears in the\n# filter panel popup for the global search operation.\nsearchPanelGlobal=Search in all files (%S)\n\n# LOCALIZATION NOTE (searchPanelFunction): This is the text that appears in the\n# filter panel popup for the function search operation.\nsearchPanelFunction=Search for function definition (%S)\n\n# LOCALIZATION NOTE (searchPanelToken): This is the text that appears in the\n# filter panel popup for the token search operation.\nsearchPanelToken=Find in this file (%S)\n\n# LOCALIZATION NOTE (searchPanelGoToLine): This is the text that appears in the\n# filter panel popup for the line search operation.\nsearchPanelGoToLine=Go to line (%S)\n\n# LOCALIZATION NOTE (searchPanelVariable): This is the text that appears in the\n# filter panel popup for the variables search operation.\nsearchPanelVariable=Filter variables (%S)\n\n# LOCALIZATION NOTE (breakpointMenuItem): The text for all the elements that\n# are displayed in the breakpoints menu item popup.\nbreakpointMenuItem.setConditional=Configure conditional breakpoint\nbreakpointMenuItem.enableSelf=Enable breakpoint\nbreakpointMenuItem.enableSelf.accesskey=E\nbreakpointMenuItem.disableSelf=Disable breakpoint\nbreakpointMenuItem.disableSelf.accesskey=D\nbreakpointMenuItem.deleteSelf=Remove breakpoint\nbreakpointMenuItem.deleteSelf.accesskey=R\nbreakpointMenuItem.enableOthers=Enable others\nbreakpointMenuItem.enableOthers.accesskey=o\nbreakpointMenuItem.disableOthers=Disable others\nbreakpointMenuItem.disableOthers.accesskey=s\nbreakpointMenuItem.deleteOthers=Remove others\nbreakpointMenuItem.deleteOthers.accesskey=h\nbreakpointMenuItem.enableAll=Enable all breakpoints\nbreakpointMenuItem.enableAll.accesskey=b\nbreakpointMenuItem.disableAll=Disable all breakpoints\nbreakpointMenuItem.disableAll.accesskey=k\nbreakpointMenuItem.deleteAll=Remove all breakpoints\nbreakpointMenuItem.deleteAll.accesskey=a\n\n# LOCALIZATION NOTE (breakpoints.header): Breakpoints right sidebar pane header.\nbreakpoints.header=Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.none): The text that appears when there are\n# no breakpoints present\nbreakpoints.none=No Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.enable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.enable=Enable Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.disable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.disable=Disable Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.removeBreakpointTooltip): The tooltip that is displayed\n# for remove breakpoint button in right sidebar\nbreakpoints.removeBreakpointTooltip=Remove Breakpoint\n\n# LOCALIZATION NOTE (callStack.header): Call Stack right sidebar pane header.\ncallStack.header=Call Stack\n\n# LOCALIZATION NOTE (callStack.notPaused): Call Stack right sidebar pane\n# message when not paused.\ncallStack.notPaused=Not Paused\n\n# LOCALIZATION NOTE (callStack.collapse): Call Stack right sidebar pane\n# message to hide some of the frames that are shown.\ncallStack.collapse=Collapse Rows\n\n# LOCALIZATION NOTE (callStack.expand): Call Stack right sidebar pane\n# message to show more of the frames.\ncallStack.expand=Expand Rows\n\n# LOCALIZATION NOTE (editor.searchResults): Editor Search bar message\n# for the summarizing the selected search result. e.g. 5 of 10 results.\neditor.searchResults=%d of %d results\n\n# LOCALIZATION NOTE (sourceSearch.singleResult): Copy shown when there is one result.\neditor.singleResult=1 result\n\n# LOCALIZATION NOTE (editor.noResults): Editor Search bar message\n# for when no results found.\neditor.noResults=no results\n\n# LOCALIZATION NOTE (editor.searchResults.nextResult): Editor Search bar\n# tooltip for traversing to the Next Result\neditor.searchResults.nextResult=Next Result\n\n# LOCALIZATION NOTE (editor.searchResults.prevResult): Editor Search bar\n# tooltip for traversing to the Previous Result\neditor.searchResults.prevResult=Previous Result\n\n# LOCALIZATION NOTE (editor.searchTypeToggleTitle): Search bar title for\n# toggling search type buttons(function search, variable search)\neditor.searchTypeToggleTitle=Search for:\n\n# LOCALIZATION NOTE (editor.addBreakpoint): Editor gutter context menu item\n# for adding a breakpoint on a line.\neditor.addBreakpoint=Add Breakpoint\n\n# LOCALIZATION NOTE (editor.disableBreakpoint): Editor gutter context menu item\n# for disabling a breakpoint on a line.\neditor.disableBreakpoint=Disable Breakpoint\n\n# LOCALIZATION NOTE (editor.enableBreakpoint): Editor gutter context menu item\n# for enabling a breakpoint on a line.\neditor.enableBreakpoint=Enable Breakpoint\n\n# LOCALIZATION NOTE (editor.removeBreakpoint): Editor gutter context menu item\n# for removing a breakpoint on a line.\neditor.removeBreakpoint=Remove Breakpoint\n\n# LOCALIZATION NOTE (editor.editBreakpoint): Editor gutter context menu item\n# for setting a breakpoint condition on a line.\neditor.editBreakpoint=Edit Breakpoint\n\n# LOCALIZATION NOTE (editor.addConditionalBreakpoint): Editor gutter context\n# menu item for adding a breakpoint condition on a line.\neditor.addConditionalBreakpoint=Add Conditional Breakpoint\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Placeholder text for\n# input element inside ConditionalPanel component\neditor.conditionalPanel.placeholder=This breakpoint will pause when the expression is true\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Tooltip text for\n# close button inside ConditionalPanel component\neditor.conditionalPanel.close=Cancel edit breakpoint and close\n\n# LOCALIZATION NOTE (editor.jumpToMappedLocation1): Context menu item\n# for navigating to a source mapped location\neditor.jumpToMappedLocation1=Jump to %S location\n\n# LOCALIZATION NOTE (framework.disableGrouping): This is the text that appears in the\n# context menu to disable framework grouping.\nframework.disableGrouping=Disable Framework Grouping\nframework.disableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (framework.enableGrouping): This is the text that appears in the\n# context menu to enable framework grouping.\nframework.enableGrouping=Enable Framework Grouping\nframework.enableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (generated): Source Map term for a server source location\ngenerated=generated\n\n# LOCALIZATION NOTE (original): Source Map term for a debugger UI source location\noriginal=original\n\n# LOCALIZATION NOTE (expressions.placeholder): Placeholder text for expression\n# input element\nexpressions.placeholder=Add Watch Expression\n\n# LOCALIZATION NOTE (sourceTabs.closeTab): Editor source tab context menu item\n# for closing the selected tab below the mouse.\nsourceTabs.closeTab=Close tab\nsourceTabs.closeTab.accesskey=c\n\n# LOCALIZATION NOTE (sourceTabs.closeOtherTabs): Editor source tab context menu item\n# for closing the other tabs.\nsourceTabs.closeOtherTabs=Close others\nsourceTabs.closeOtherTabs.accesskey=o\n\n# LOCALIZATION NOTE (sourceTabs.closeTabsToEnd): Editor source tab context menu item\n# for closing the tabs to the end (the right for LTR languages) of the selected tab.\nsourceTabs.closeTabsToEnd=Close tabs to the right\nsourceTabs.closeTabsToEnd.accesskey=e\n\n# LOCALIZATION NOTE (sourceTabs.closeAllTabs): Editor source tab context menu item\n# for closing all tabs.\nsourceTabs.closeAllTabs=Close all tabs\nsourceTabs.closeAllTabs.accesskey=a\n\n# LOCALIZATION NOTE (sourceTabs.revealInTree): Editor source tab context menu item\n# for revealing source in tree.\nsourceTabs.revealInTree=Reveal in Tree\nsourceTabs.revealInTree.accesskey=r\n\n# LOCALIZATION NOTE (sourceTabs.copyLink): Editor source tab context menu item\n# for copying a link address.\nsourceTabs.copyLink=Copy Link Address\nsourceTabs.copyLink.accesskey=l\n\n# LOCALIZATION NOTE (sourceTabs.prettyPrint): Editor source tab context menu item\n# for pretty printing the source.\nsourceTabs.prettyPrint=Pretty Print Source\nsourceTabs.prettyPrint.accesskey=p\n\n# LOCALIZATION NOTE (sourceFooter.blackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.blackbox=Blackbox Source\nsourceFooter.blackbox.accesskey=B\n\n# LOCALIZATION NOTE (sourceFooter.unblackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.unblackbox=Unblackbox Source\nsourceFooter.unblackbox.accesskey=b\n\n# LOCALIZATION NOTE (sourceFooter.blackboxed): Text associated\n# with a blackboxed source\nsourceFooter.blackboxed=Blackboxed Source\n\n# LOCALIZATION NOTE (sourceFooter.codeCoverage): Text associated\n# with a code coverage button\nsourceFooter.codeCoverage=Code Coverage\n\n# LOCALIZATION NOTE (sourceTabs.closeTabButtonTooltip): The tooltip that is displayed\n# for close tab button in source tabs.\nsourceTabs.closeTabButtonTooltip=Close tab\n\n# LOCALIZATION NOTE (sourceTabs.newTabButtonTooltip): The tooltip that is displayed for\n# new tab button in source tabs.\nsourceTabs.newTabButtonTooltip=Search for sources (%S)\n\n# LOCALIZATION NOTE (scopes.header): Scopes right sidebar pane header.\nscopes.header=Scopes\n\n# LOCALIZATION NOTE (scopes.notAvailable): Scopes right sidebar pane message\n# for when the debugger is paused, but there isn't pause data.\nscopes.notAvailable=Scopes Unavailable\n\n# LOCALIZATION NOTE (scopes.notPaused): Scopes right sidebar pane message\n# for when the debugger is not paused.\nscopes.notPaused=Not Paused\n\n# LOCALIZATION NOTE (scopes.block): Refers to a block of code in\n# the scopes pane when the debugger is paused.\nscopes.block=Block\n\n# LOCALIZATION NOTE (sources.header): Sources left sidebar header\nsources.header=Sources\n\n# LOCALIZATION NOTE (outline.header): Outline left sidebar header\noutline.header=Outline\n\n# LOCALIZATION NOTE (sources.search): Sources left sidebar prompt\n# e.g. Cmd+P to search. On a mac, we use the command unicode character.\n# On windows, it's ctrl.\nsources.search=%S to search\n\n# LOCALIZATION NOTE (watchExpressions.header): Watch Expressions right sidebar\n# pane header.\nwatchExpressions.header=Watch Expressions\n\n# LOCALIZATION NOTE (watchExpressions.refreshButton): Watch Expressions header\n# button for refreshing the expressions.\nwatchExpressions.refreshButton=Refresh\n\n# LOCALIZATION NOTE (welcome.search): The center pane welcome panel's\n# search prompt. e.g. cmd+p to search for files. On windows, it's ctrl, on\n# a mac we use the unicode character.\nwelcome.search=%S to search for sources\n\n# LOCALIZATION NOTE (welcome.findInFiles): The center pane welcome panel's\n# search prompt. e.g. cmd+f to search for files. On windows, it's ctrl+shift+f, on\n# a mac we use the unicode character.\nwelcome.findInFiles=%S to find in files\n\n# LOCALIZATION NOTE (welcome.searchFunction): Label displayed in the welcome\n# panel. %S is replaced by the keyboard shortcut to search for functions.\nwelcome.searchFunction=%S to search for functions in file\n\n# LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search\n# prompt for searching for files.\nsourceSearch.search=Search sources…\n\n# LOCALIZATION NOTE (sourceSearch.noResults): The center pane Source Search\n# message when the query did not match any of the sources.\nsourceSearch.noResults2=No results found\n\n# LOCALIZATION NOTE (ignoreExceptions): The pause on exceptions button tooltip\n# when the debugger will not pause on exceptions.\nignoreExceptions=Ignore exceptions. Click to pause on uncaught exceptions\n\n# LOCALIZATION NOTE (pauseOnUncaughtExceptions): The pause on exceptions button\n# tooltip when the debugger will pause on uncaught exceptions.\npauseOnUncaughtExceptions=Pause on uncaught exceptions. Click to pause on all exceptions\n\n# LOCALIZATION NOTE (pauseOnExceptions): The pause on exceptions button tooltip\n# when the debugger will pause on all exceptions.\npauseOnExceptions=Pause on all exceptions. Click to ignore exceptions\n\n# LOCALIZATION NOTE (loadingText): The text that is displayed in the script\n# editor when the loading process has started but there is no file to display\n# yet.\nloadingText=Loading\\u2026\n\n# LOCALIZATION NOTE (errorLoadingText2): The text that is displayed in the debugger\n# viewer when there is an error loading a file\nerrorLoadingText2=Error loading this URL: %S\n\n# LOCALIZATION NOTE (addWatchExpressionText): The text that is displayed in the\n# watch expressions list to add a new item.\naddWatchExpressionText=Add watch expression\n\n# LOCALIZATION NOTE (addWatchExpressionButton): The button that is displayed in the\n# variables view popup.\naddWatchExpressionButton=Watch\n\n# LOCALIZATION NOTE (emptyVariablesText): The text that is displayed in the\n# variables pane when there are no variables to display.\nemptyVariablesText=No variables to display\n\n# LOCALIZATION NOTE (scopeLabel): The text that is displayed in the variables\n# pane as a header for each variable scope (e.g. \"Global scope, \"With scope\",\n# etc.).\nscopeLabel=%S scope\n\n# LOCALIZATION NOTE (watchExpressionsScopeLabel): The name of the watch\n# expressions scope. This text is displayed in the variables pane as a header for\n# the watch expressions scope.\nwatchExpressionsScopeLabel=Watch expressions\n\n# LOCALIZATION NOTE (globalScopeLabel): The name of the global scope. This text\n# is added to scopeLabel and displayed in the variables pane as a header for\n# the global scope.\nglobalScopeLabel=Global\n\n# LOCALIZATION NOTE (variablesViewErrorStacktrace): This is the text that is\n# shown before the stack trace in an error.\nvariablesViewErrorStacktrace=Stack trace:\n\n# LOCALIZATION NOTE (variablesViewMoreObjects): the text that is displayed\n# when you have an object preview that does not show all of the elements. At the end of the list\n# you see \"N more...\" in the web console output.\n# This is a semi-colon list of plural forms.\n# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals\n# #1 number of remaining items in the object\n# example: 3 more…\nvariablesViewMoreObjects=#1 more…;#1 more…\n\n# LOCALIZATION NOTE (variablesEditableNameTooltip): The text that is displayed\n# in the variables list on an item with an editable name.\nvariablesEditableNameTooltip=Double click to edit\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in the variables list on an item with an editable value.\nvariablesEditableValueTooltip=Click to change value\n\n# LOCALIZATION NOTE (variablesCloseButtonTooltip): The text that is displayed\n# in the variables list on an item which can be removed.\nvariablesCloseButtonTooltip=Click to remove\n\n# LOCALIZATION NOTE (variablesEditButtonTooltip): The text that is displayed\n# in the variables list on a getter or setter which can be edited.\nvariablesEditButtonTooltip=Click to set value\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in a tooltip on the \"open in inspector\" button in the the variables list for a\n# DOMNode item.\nvariablesDomNodeValueTooltip=Click to select the node in the inspector\n\n# LOCALIZATION NOTE (configurable|...|Tooltip): The text that is displayed\n# in the variables list on certain variables or properties as tooltips.\n# Expanations of what these represent can be found at the following links:\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n# It's probably best to keep these in English.\nconfigurableTooltip=configurable\nenumerableTooltip=enumerable\nwritableTooltip=writable\nfrozenTooltip=frozen\nsealedTooltip=sealed\nextensibleTooltip=extensible\noverriddenTooltip=overridden\nWebIDLTooltip=WebIDL\n\n# LOCALIZATION NOTE (variablesSeparatorLabel): The text that is displayed\n# in the variables list as a separator between the name and value.\nvariablesSeparatorLabel=:\n\n# LOCALIZATION NOTE (watchExpressionsSeparatorLabel2): The text that is displayed\n# in the watch expressions list as a separator between the code and evaluation.\nwatchExpressionsSeparatorLabel2=\\u0020→\n\n# LOCALIZATION NOTE (functionSearchSeparatorLabel): The text that is displayed\n# in the functions search panel as a separator between function's inferred name\n# and its real name (if available).\nfunctionSearchSeparatorLabel=←\n\n# LOCALIZATION NOTE(symbolSearch.search.functionsPlaceholder): The placeholder\n# text displayed when the user searches for functions in a file\nsymbolSearch.search.functionsPlaceholder=Search functions…\n\n# LOCALIZATION NOTE(symbolSearch.search.variablesPlaceholder): The placeholder\n# text displayed when the user searches for variables in a file\nsymbolSearch.search.variablesPlaceholder=Search variables…\n\n# LOCALIZATION NOTE(symbolSearch.search.key2): The Key Shortcut for\n# searching for a function or variable\nsymbolSearch.search.key2=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.modifiersLabel): A label\n# preceding the group of modifiers\nsymbolSearch.searchModifier.modifiersLabel=Modifiers:\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.regex): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.regex=Regex\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.caseSensitive): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.caseSensitive=Case sensitive\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.wholeWord): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.wholeWord=Whole word\n\n# LOCALIZATION NOTE (resumptionOrderPanelTitle): This is the text that appears\n# as a description in the notification panel popup, when multiple debuggers are\n# open in separate tabs and the user tries to resume them in the wrong order.\n# The substitution parameter is the URL of the last paused window that must be\n# resumed first.\nresumptionOrderPanelTitle=There are one or more paused debuggers. Please resume the most-recently paused debugger first at: %S\n\nvariablesViewOptimizedOut=(optimized away)\nvariablesViewUninitialized=(uninitialized)\nvariablesViewMissingArgs=(unavailable)\n\nanonymousSourcesLabel=Anonymous Sources\n\nexperimental=This is an experimental feature\n\n# LOCALIZATION NOTE (whyPaused.debuggerStatement): The text that is displayed\n# in a info block explaining how the debugger is currently paused due to a `debugger`\n# statement in the code\nwhyPaused.debuggerStatement=Paused on debugger statement\n\n# LOCALIZATION NOTE (whyPaused.breakpoint): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a breakpoint\nwhyPaused.breakpoint=Paused on breakpoint\n\n# LOCALIZATION NOTE (whyPaused.exception): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an exception\nwhyPaused.exception=Paused on exception\n\n# LOCALIZATION NOTE (whyPaused.resumeLimit): The text that is displayed\n# in a info block explaining how the debugger is currently paused while stepping\n# in or out of the stack\nwhyPaused.resumeLimit=Paused while stepping\n\n# LOCALIZATION NOTE (whyPaused.pauseOnDOMEvents): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# dom event\nwhyPaused.pauseOnDOMEvents=Paused on event listener\n\n# LOCALIZATION NOTE (whyPaused.breakpointConditionThrown): The text that is displayed\n# in an info block when evaluating a conditional breakpoint throws an error\nwhyPaused.breakpointConditionThrown=Error with conditional breakpoint\n\n# LOCALIZATION NOTE (whyPaused.xhr): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# xml http request\nwhyPaused.xhr=Paused on XMLHttpRequest\n\n# LOCALIZATION NOTE (whyPaused.promiseRejection): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# promise rejection\nwhyPaused.promiseRejection=Paused on promise rejection\n\n# LOCALIZATION NOTE (whyPaused.assert): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# assert\nwhyPaused.assert=Paused on assertion\n\n# LOCALIZATION NOTE (whyPaused.debugCommand): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# debugger statement\nwhyPaused.debugCommand=Paused on debugged function\n\n# LOCALIZATION NOTE (whyPaused.other): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an event\n# listener breakpoint set\nwhyPaused.other=Debugger paused\n\n# LOCALIZATION NOTE (ctrl): The text that is used for documenting\n# keyboard shortcuts that use the control key\nctrl=Ctrl\n"
+module.exports = "# This Source Code Form is subject to the terms of the Mozilla Public\n# License, v. 2.0. If a copy of the MPL was not distributed with this\n# file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n# LOCALIZATION NOTE These strings are used inside the Debugger\n# which is available from the Web Developer sub-menu -> 'Debugger'.\n# The correct localization of this file might be to keep it in\n# English, or another language commonly spoken among web developers.\n# You want to make that choice consistent across the developer tools.\n# A good criteria is the language in which you'd find the best\n# documentation on web development on the web.\n\n# LOCALIZATION NOTE (collapsePanes): This is the tooltip for the button\n# that collapses the left and right panes in the debugger UI.\ncollapsePanes=Collapse panes\n\n# LOCALIZATION NOTE (copySource): This is the text that appears in the\n# context menu to copy the selected source of file open.\ncopySource=Copy\ncopySource.accesskey=y\n\n# LOCALIZATION NOTE (copySourceUrl): This is the text that appears in the\n# context menu to copy the source URL of file open.\ncopySourceUrl=Copy Source URL\ncopySourceUrl.accesskey=u\n\n# LOCALIZATION NOTE (copyFunction): This is the text that appears in the\n# context menu to copy the function the user selected\ncopyFunction.label=Copy Function\ncopyFunction.accesskey=F\n\n# LOCALIZATION NOTE (copyStackTrace): This is the text that appears in the\n# context menu to copy the stack trace methods, file names and row number.\ncopyStackTrace=Copy Stack Trace\ncopyStackTrace.accesskey=c\n\n# LOCALIZATION NOTE (expandPanes): This is the tooltip for the button\n# that expands the left and right panes in the debugger UI.\nexpandPanes=Expand panes\n\n# LOCALIZATION NOTE (pauseButtonTooltip): The tooltip that is displayed for the pause\n# button when the debugger is in a running state.\npauseButtonTooltip=Pause %S\n\n# LOCALIZATION NOTE (pausePendingButtonTooltip): The tooltip that is displayed for\n# the pause button after it's been clicked but before the next JavaScript to run.\npausePendingButtonTooltip=Waiting for next execution\n\n# LOCALIZATION NOTE (resumeButtonTooltip): The label that is displayed on the pause\n# button when the debugger is in a paused state.\nresumeButtonTooltip=Resume %S\n\n# LOCALIZATION NOTE (stepOverTooltip): The label that is displayed on the\n# button that steps over a function call.\nstepOverTooltip=Step Over %S\n\n# LOCALIZATION NOTE (stepInTooltip): The label that is displayed on the\n# button that steps into a function call.\nstepInTooltip=Step In %S\n\n# LOCALIZATION NOTE (stepOutTooltip): The label that is displayed on the\n# button that steps out of a function call.\nstepOutTooltip=Step Out %S\n\n# LOCALIZATION NOTE (workersHeader): The text to display in the events\n# header.\nworkersHeader=Workers\n\n# LOCALIZATION NOTE (noWorkersText): The text to display in the workers list\n# when there are no workers.\nnoWorkersText=This page has no workers.\n\n# LOCALIZATION NOTE (noSourcesText): The text to display in the sources list\n# when there are no sources.\nnoSourcesText=This page has no sources.\n\n# LOCALIZATION NOTE (noEventListenersText): The text to display in the events tab\n# when there are no events.\nnoEventListenersText=No event listeners to display\n\n# LOCALIZATION NOTE (eventListenersHeader): The text to display in the events\n# header.\neventListenersHeader=Event Listeners\n\n# LOCALIZATION NOTE (noStackFramesText): The text to display in the call stack tab\n# when there are no stack frames.\nnoStackFramesText=No stack frames to display\n\n# LOCALIZATION NOTE (eventCheckboxTooltip): The tooltip text to display when\n# the user hovers over the checkbox used to toggle an event breakpoint.\neventCheckboxTooltip=Toggle breaking on this event\n\n# LOCALIZATION NOTE (eventOnSelector): The text to display in the events tab\n# for every event item, between the event type and event selector.\neventOnSelector=on\n\n# LOCALIZATION NOTE (eventInSource): The text to display in the events tab\n# for every event item, between the event selector and listener's owner source.\neventInSource=in\n\n# LOCALIZATION NOTE (eventNodes): The text to display in the events tab when\n# an event is listened on more than one target node.\neventNodes=%S nodes\n\n# LOCALIZATION NOTE (eventNative): The text to display in the events tab when\n# a listener is added from plugins, thus getting translated to native code.\neventNative=[native code]\n\n# LOCALIZATION NOTE (*Events): The text to display in the events tab for\n# each group of sub-level event entries.\nanimationEvents=Animation\naudioEvents=Audio\nbatteryEvents=Battery\nclipboardEvents=Clipboard\ncompositionEvents=Composition\ndeviceEvents=Device\ndisplayEvents=Display\ndragAndDropEvents=Drag and Drop\ngamepadEvents=Gamepad\nindexedDBEvents=IndexedDB\ninteractionEvents=Interaction\nkeyboardEvents=Keyboard\nmediaEvents=HTML5 Media\nmouseEvents=Mouse\nmutationEvents=Mutation\nnavigationEvents=Navigation\npointerLockEvents=Pointer Lock\nsensorEvents=Sensor\nstorageEvents=Storage\ntimeEvents=Time\ntouchEvents=Touch\notherEvents=Other\n\n# LOCALIZATION NOTE (blackboxCheckboxTooltip2): The tooltip text to display when\n# the user hovers over the checkbox used to toggle blackboxing its associated\n# source.\nblackboxCheckboxTooltip2=Toggle blackboxing\n\n# LOCALIZATION NOTE (sources.search.key2): Key shortcut to open the search for\n# searching all the source files the debugger has seen.\nsources.search.key2=CmdOrCtrl+P\n\n# LOCALIZATION NOTE (sources.search.alt.key): A second key shortcut to open the\n# search for searching all the source files the debugger has seen.\nsources.search.alt.key=CmdOrCtrl+O\n\n# LOCALIZATION NOTE (projectTextSearch.key): A key shortcut to open the\n# full project text search for searching all the files the debugger has seen.\nprojectTextSearch.key=CmdOrCtrl+Shift+F\n\n# LOCALIZATION NOTE (functionSearch.key): A key shortcut to open the\n# modal for searching functions in a file.\nfunctionSearch.key=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE (projectTextSearch.placeholder): A placeholder shown\n# when searching across all of the files in a project.\nprojectTextSearch.placeholder=Find in files…\n\n# LOCALIZATION NOTE (projectTextSearch.noResults): The center pane Text Search\n# message when the query did not match any text of all files in a project.\nprojectTextSearch.noResults=No results found\n\n# LOCALIZATION NOTE (sources.noSourcesAvailable): Text shown when the debugger\n# does not have any sources.\nsources.noSourcesAvailable=This page has no sources\n\n# LOCALIZATION NOTE (sourceSearch.search.key2): Key shortcut to open the search\n# for searching within a the currently opened files in the editor\nsourceSearch.search.key2=CmdOrCtrl+F\n\n# LOCALIZATION NOTE (sourceSearch.search.placeholder): placeholder text in\n# the source search input bar\nsourceSearch.search.placeholder=Search in file…\n\n# LOCALIZATION NOTE (sourceSearch.search.again.key2): Key shortcut to highlight\n# the next occurrence of the last search triggered from a source search\nsourceSearch.search.again.key2=CmdOrCtrl+G\n\n# LOCALIZATION NOTE (sourceSearch.search.againPrev.key2): Key shortcut to highlight\n# the previous occurrence of the last search triggered from a source search\nsourceSearch.search.againPrev.key2=CmdOrCtrl+Shift+G\n\n# LOCALIZATION NOTE (sourceSearch.resultsSummary1): Shows a summary of\n# the number of matches for autocomplete\nsourceSearch.resultsSummary1=%d results\n\n# LOCALIZATION NOTE (noMatchingStringsText): The text to display in the\n# global search results when there are no matching strings after filtering.\nnoMatchingStringsText=No matches found\n\n# LOCALIZATION NOTE (emptySearchText): This is the text that appears in the\n# filter text box when it is empty and the scripts container is selected.\nemptySearchText=Search scripts (%S)\n\n# LOCALIZATION NOTE (emptyVariablesFilterText): This is the text that\n# appears in the filter text box for the variables view container.\nemptyVariablesFilterText=Filter variables\n\n# LOCALIZATION NOTE (emptyPropertiesFilterText): This is the text that\n# appears in the filter text box for the editor's variables view bubble.\nemptyPropertiesFilterText=Filter properties\n\n# LOCALIZATION NOTE (searchPanelFilter): This is the text that appears in the\n# filter panel popup for the filter scripts operation.\nsearchPanelFilter=Filter scripts (%S)\n\n# LOCALIZATION NOTE (searchPanelGlobal): This is the text that appears in the\n# filter panel popup for the global search operation.\nsearchPanelGlobal=Search in all files (%S)\n\n# LOCALIZATION NOTE (searchPanelFunction): This is the text that appears in the\n# filter panel popup for the function search operation.\nsearchPanelFunction=Search for function definition (%S)\n\n# LOCALIZATION NOTE (searchPanelToken): This is the text that appears in the\n# filter panel popup for the token search operation.\nsearchPanelToken=Find in this file (%S)\n\n# LOCALIZATION NOTE (searchPanelGoToLine): This is the text that appears in the\n# filter panel popup for the line search operation.\nsearchPanelGoToLine=Go to line (%S)\n\n# LOCALIZATION NOTE (searchPanelVariable): This is the text that appears in the\n# filter panel popup for the variables search operation.\nsearchPanelVariable=Filter variables (%S)\n\n# LOCALIZATION NOTE (breakpointMenuItem): The text for all the elements that\n# are displayed in the breakpoints menu item popup.\nbreakpointMenuItem.setConditional=Configure conditional breakpoint\nbreakpointMenuItem.enableSelf=Enable breakpoint\nbreakpointMenuItem.enableSelf.accesskey=E\nbreakpointMenuItem.disableSelf=Disable breakpoint\nbreakpointMenuItem.disableSelf.accesskey=D\nbreakpointMenuItem.deleteSelf=Remove breakpoint\nbreakpointMenuItem.deleteSelf.accesskey=R\nbreakpointMenuItem.enableOthers=Enable others\nbreakpointMenuItem.enableOthers.accesskey=o\nbreakpointMenuItem.disableOthers=Disable others\nbreakpointMenuItem.disableOthers.accesskey=s\nbreakpointMenuItem.deleteOthers=Remove others\nbreakpointMenuItem.deleteOthers.accesskey=h\nbreakpointMenuItem.enableAll=Enable all breakpoints\nbreakpointMenuItem.enableAll.accesskey=b\nbreakpointMenuItem.disableAll=Disable all breakpoints\nbreakpointMenuItem.disableAll.accesskey=k\nbreakpointMenuItem.deleteAll=Remove all breakpoints\nbreakpointMenuItem.deleteAll.accesskey=a\nbreakpointMenuItem.removeCondition.label=Remove breakpoint condition\nbreakpointMenuItem.removeCondition.accesskey=c\nbreakpointMenuItem.editCondition.label=Edit breakpoint condition\nbreakpointMenuItem.editCondition.accesskey=n\n\n# LOCALIZATION NOTE (breakpoints.header): Breakpoints right sidebar pane header.\nbreakpoints.header=Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.none): The text that appears when there are\n# no breakpoints present\nbreakpoints.none=No Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.enable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.enable=Enable Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.disable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.disable=Disable Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.removeBreakpointTooltip): The tooltip that is displayed\n# for remove breakpoint button in right sidebar\nbreakpoints.removeBreakpointTooltip=Remove Breakpoint\n\n# LOCALIZATION NOTE (callStack.header): Call Stack right sidebar pane header.\ncallStack.header=Call Stack\n\n# LOCALIZATION NOTE (callStack.notPaused): Call Stack right sidebar pane\n# message when not paused.\ncallStack.notPaused=Not Paused\n\n# LOCALIZATION NOTE (callStack.collapse): Call Stack right sidebar pane\n# message to hide some of the frames that are shown.\ncallStack.collapse=Collapse Rows\n\n# LOCALIZATION NOTE (callStack.expand): Call Stack right sidebar pane\n# message to show more of the frames.\ncallStack.expand=Expand Rows\n\n# LOCALIZATION NOTE (editor.searchResults): Editor Search bar message\n# for the summarizing the selected search result. e.g. 5 of 10 results.\neditor.searchResults=%d of %d results\n\n# LOCALIZATION NOTE (sourceSearch.singleResult): Copy shown when there is one result.\neditor.singleResult=1 result\n\n# LOCALIZATION NOTE (editor.noResults): Editor Search bar message\n# for when no results found.\neditor.noResults=no results\n\n# LOCALIZATION NOTE (editor.searchResults.nextResult): Editor Search bar\n# tooltip for traversing to the Next Result\neditor.searchResults.nextResult=Next Result\n\n# LOCALIZATION NOTE (editor.searchResults.prevResult): Editor Search bar\n# tooltip for traversing to the Previous Result\neditor.searchResults.prevResult=Previous Result\n\n# LOCALIZATION NOTE (editor.searchTypeToggleTitle): Search bar title for\n# toggling search type buttons(function search, variable search)\neditor.searchTypeToggleTitle=Search for:\n\n# LOCALIZATION NOTE (editor.continueToHere.label): Editor gutter context\n# menu item for jumping to a new paused location\neditor.continueToHere.label=Continue To Here\neditor.continueToHere.accesskey=H\n\n# LOCALIZATION NOTE (editor.addBreakpoint): Editor gutter context menu item\n# for adding a breakpoint on a line.\neditor.addBreakpoint=Add Breakpoint\n\n# LOCALIZATION NOTE (editor.disableBreakpoint): Editor gutter context menu item\n# for disabling a breakpoint on a line.\neditor.disableBreakpoint=Disable Breakpoint\n\n# LOCALIZATION NOTE (editor.enableBreakpoint): Editor gutter context menu item\n# for enabling a breakpoint on a line.\neditor.enableBreakpoint=Enable Breakpoint\n\n# LOCALIZATION NOTE (editor.removeBreakpoint): Editor gutter context menu item\n# for removing a breakpoint on a line.\neditor.removeBreakpoint=Remove Breakpoint\n\n# LOCALIZATION NOTE (editor.editBreakpoint): Editor gutter context menu item\n# for setting a breakpoint condition on a line.\neditor.editBreakpoint=Edit Breakpoint\n\n# LOCALIZATION NOTE (editor.addConditionalBreakpoint): Editor gutter context\n# menu item for adding a breakpoint condition on a line.\neditor.addConditionalBreakpoint=Add Conditional Breakpoint\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Placeholder text for\n# input element inside ConditionalPanel component\neditor.conditionalPanel.placeholder=This breakpoint will pause when the expression is true\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Tooltip text for\n# close button inside ConditionalPanel component\neditor.conditionalPanel.close=Cancel edit breakpoint and close\n\n# LOCALIZATION NOTE (editor.jumpToMappedLocation1): Context menu item\n# for navigating to a source mapped location\neditor.jumpToMappedLocation1=Jump to %S Location\n\n# LOCALIZATION NOTE (framework.disableGrouping): This is the text that appears in the\n# context menu to disable framework grouping.\nframework.disableGrouping=Disable Framework Grouping\nframework.disableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (framework.enableGrouping): This is the text that appears in the\n# context menu to enable framework grouping.\nframework.enableGrouping=Enable Framework Grouping\nframework.enableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (generated): Source Map term for a server source location\ngenerated=Generated\n\n# LOCALIZATION NOTE (original): Source Map term for a debugger UI source location\noriginal=Original\n\n# LOCALIZATION NOTE (expressions.placeholder): Placeholder text for expression\n# input element\nexpressions.placeholder=Add Watch Expression\n\n# LOCALIZATION NOTE (sourceTabs.closeTab): Editor source tab context menu item\n# for closing the selected tab below the mouse.\nsourceTabs.closeTab=Close Tab\nsourceTabs.closeTab.accesskey=c\n\n# LOCALIZATION NOTE (sourceTabs.closeOtherTabs): Editor source tab context menu item\n# for closing the other tabs.\nsourceTabs.closeOtherTabs=Close Other Tabs\nsourceTabs.closeOtherTabs.accesskey=o\n\n# LOCALIZATION NOTE (sourceTabs.closeTabsToEnd): Editor source tab context menu item\n# for closing the tabs to the end (the right for LTR languages) of the selected tab.\nsourceTabs.closeTabsToEnd=Close Tabs to the Right\nsourceTabs.closeTabsToEnd.accesskey=e\n\n# LOCALIZATION NOTE (sourceTabs.closeAllTabs): Editor source tab context menu item\n# for closing all tabs.\nsourceTabs.closeAllTabs=Close All Tabs\nsourceTabs.closeAllTabs.accesskey=a\n\n# LOCALIZATION NOTE (sourceTabs.revealInTree): Editor source tab context menu item\n# for revealing source in tree.\nsourceTabs.revealInTree=Reveal in Tree\nsourceTabs.revealInTree.accesskey=r\n\n# LOCALIZATION NOTE (sourceTabs.copyLink): Editor source tab context menu item\n# for copying a link address.\nsourceTabs.copyLink=Copy Link Address\nsourceTabs.copyLink.accesskey=l\n\n# LOCALIZATION NOTE (sourceTabs.prettyPrint): Editor source tab context menu item\n# for pretty printing the source.\nsourceTabs.prettyPrint=Pretty Print Source\nsourceTabs.prettyPrint.accesskey=p\n\n# LOCALIZATION NOTE (sourceFooter.blackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.blackbox=Blackbox Source\nsourceFooter.blackbox.accesskey=B\n\n# LOCALIZATION NOTE (sourceFooter.unblackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.unblackbox=Unblackbox Source\nsourceFooter.unblackbox.accesskey=b\n\n# LOCALIZATION NOTE (sourceFooter.blackboxed): Text associated\n# with a blackboxed source\nsourceFooter.blackboxed=Blackboxed Source\n\n# LOCALIZATION NOTE (sourceFooter.codeCoverage): Text associated\n# with a code coverage button\nsourceFooter.codeCoverage=Code Coverage\n\n# LOCALIZATION NOTE (sourceTabs.closeTabButtonTooltip): The tooltip that is displayed\n# for close tab button in source tabs.\nsourceTabs.closeTabButtonTooltip=Close tab\n\n# LOCALIZATION NOTE (sourceTabs.newTabButtonTooltip): The tooltip that is displayed for\n# new tab button in source tabs.\nsourceTabs.newTabButtonTooltip=Search for sources (%S)\n\n# LOCALIZATION NOTE (scopes.header): Scopes right sidebar pane header.\nscopes.header=Scopes\n\n# LOCALIZATION NOTE (scopes.notAvailable): Scopes right sidebar pane message\n# for when the debugger is paused, but there isn't pause data.\nscopes.notAvailable=Scopes Unavailable\n\n# LOCALIZATION NOTE (scopes.notPaused): Scopes right sidebar pane message\n# for when the debugger is not paused.\nscopes.notPaused=Not Paused\n\n# LOCALIZATION NOTE (scopes.block): Refers to a block of code in\n# the scopes pane when the debugger is paused.\nscopes.block=Block\n\n# LOCALIZATION NOTE (sources.header): Sources left sidebar header\nsources.header=Sources\n\n# LOCALIZATION NOTE (outline.header): Outline left sidebar header\noutline.header=Outline\n\n# LOCALIZATION NOTE (outline.noFunctions): Outline text when there are no functions to display\noutline.noFunctions=No functions\n\n# LOCALIZATION NOTE (sources.search): Sources left sidebar prompt\n# e.g. Cmd+P to search. On a mac, we use the command unicode character.\n# On windows, it's ctrl.\nsources.search=%S to search\n\n# LOCALIZATION NOTE (watchExpressions.header): Watch Expressions right sidebar\n# pane header.\nwatchExpressions.header=Watch Expressions\n\n# LOCALIZATION NOTE (watchExpressions.refreshButton): Watch Expressions header\n# button for refreshing the expressions.\nwatchExpressions.refreshButton=Refresh\n\n# LOCALIZATION NOTE (welcome.search): The center pane welcome panel's\n# search prompt. e.g. cmd+p to search for files. On windows, it's ctrl, on\n# a mac we use the unicode character.\nwelcome.search=%S to search for sources\n\n# LOCALIZATION NOTE (welcome.findInFiles): The center pane welcome panel's\n# search prompt. e.g. cmd+f to search for files. On windows, it's ctrl+shift+f, on\n# a mac we use the unicode character.\nwelcome.findInFiles=%S to find in files\n\n# LOCALIZATION NOTE (welcome.searchFunction): Label displayed in the welcome\n# panel. %S is replaced by the keyboard shortcut to search for functions.\nwelcome.searchFunction=%S to search for functions in file\n\n# LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search\n# prompt for searching for files.\nsourceSearch.search=Search sources…\n\n# LOCALIZATION NOTE (sourceSearch.noResults): The center pane Source Search\n# message when the query did not match any of the sources.\nsourceSearch.noResults2=No results found\n\n# LOCALIZATION NOTE (ignoreExceptions): The pause on exceptions button tooltip\n# when the debugger will not pause on exceptions.\nignoreExceptions=Ignore exceptions. Click to pause on uncaught exceptions\n\n# LOCALIZATION NOTE (pauseOnUncaughtExceptions): The pause on exceptions button\n# tooltip when the debugger will pause on uncaught exceptions.\npauseOnUncaughtExceptions=Pause on uncaught exceptions. Click to pause on all exceptions\n\n# LOCALIZATION NOTE (pauseOnExceptions): The pause on exceptions button tooltip\n# when the debugger will pause on all exceptions.\npauseOnExceptions=Pause on all exceptions. Click to ignore exceptions\n\n# LOCALIZATION NOTE (loadingText): The text that is displayed in the script\n# editor when the loading process has started but there is no file to display\n# yet.\nloadingText=Loading\\u2026\n\n# LOCALIZATION NOTE (errorLoadingText2): The text that is displayed in the debugger\n# viewer when there is an error loading a file\nerrorLoadingText2=Error loading this URL: %S\n\n# LOCALIZATION NOTE (addWatchExpressionText): The text that is displayed in the\n# watch expressions list to add a new item.\naddWatchExpressionText=Add watch expression\n\n# LOCALIZATION NOTE (addWatchExpressionButton): The button that is displayed in the\n# variables view popup.\naddWatchExpressionButton=Watch\n\n# LOCALIZATION NOTE (emptyVariablesText): The text that is displayed in the\n# variables pane when there are no variables to display.\nemptyVariablesText=No variables to display\n\n# LOCALIZATION NOTE (scopeLabel): The text that is displayed in the variables\n# pane as a header for each variable scope (e.g. \"Global scope, \"With scope\",\n# etc.).\nscopeLabel=%S scope\n\n# LOCALIZATION NOTE (watchExpressionsScopeLabel): The name of the watch\n# expressions scope. This text is displayed in the variables pane as a header for\n# the watch expressions scope.\nwatchExpressionsScopeLabel=Watch expressions\n\n# LOCALIZATION NOTE (globalScopeLabel): The name of the global scope. This text\n# is added to scopeLabel and displayed in the variables pane as a header for\n# the global scope.\nglobalScopeLabel=Global\n\n# LOCALIZATION NOTE (variablesViewErrorStacktrace): This is the text that is\n# shown before the stack trace in an error.\nvariablesViewErrorStacktrace=Stack trace:\n\n# LOCALIZATION NOTE (variablesViewMoreObjects): the text that is displayed\n# when you have an object preview that does not show all of the elements. At the end of the list\n# you see \"N more...\" in the web console output.\n# This is a semi-colon list of plural forms.\n# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals\n# #1 number of remaining items in the object\n# example: 3 more…\nvariablesViewMoreObjects=#1 more…;#1 more…\n\n# LOCALIZATION NOTE (variablesEditableNameTooltip): The text that is displayed\n# in the variables list on an item with an editable name.\nvariablesEditableNameTooltip=Double click to edit\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in the variables list on an item with an editable value.\nvariablesEditableValueTooltip=Click to change value\n\n# LOCALIZATION NOTE (variablesCloseButtonTooltip): The text that is displayed\n# in the variables list on an item which can be removed.\nvariablesCloseButtonTooltip=Click to remove\n\n# LOCALIZATION NOTE (variablesEditButtonTooltip): The text that is displayed\n# in the variables list on a getter or setter which can be edited.\nvariablesEditButtonTooltip=Click to set value\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in a tooltip on the \"open in inspector\" button in the the variables list for a\n# DOMNode item.\nvariablesDomNodeValueTooltip=Click to select the node in the inspector\n\n# LOCALIZATION NOTE (configurable|...|Tooltip): The text that is displayed\n# in the variables list on certain variables or properties as tooltips.\n# Expanations of what these represent can be found at the following links:\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n# It's probably best to keep these in English.\nconfigurableTooltip=configurable\nenumerableTooltip=enumerable\nwritableTooltip=writable\nfrozenTooltip=frozen\nsealedTooltip=sealed\nextensibleTooltip=extensible\noverriddenTooltip=overridden\nWebIDLTooltip=WebIDL\n\n# LOCALIZATION NOTE (variablesSeparatorLabel): The text that is displayed\n# in the variables list as a separator between the name and value.\nvariablesSeparatorLabel=:\n\n# LOCALIZATION NOTE (watchExpressionsSeparatorLabel2): The text that is displayed\n# in the watch expressions list as a separator between the code and evaluation.\nwatchExpressionsSeparatorLabel2=\\u0020→\n\n# LOCALIZATION NOTE (functionSearchSeparatorLabel): The text that is displayed\n# in the functions search panel as a separator between function's inferred name\n# and its real name (if available).\nfunctionSearchSeparatorLabel=←\n\n# LOCALIZATION NOTE(symbolSearch.search.functionsPlaceholder): The placeholder\n# text displayed when the user searches for functions in a file\nsymbolSearch.search.functionsPlaceholder=Search functions…\n\n# LOCALIZATION NOTE(symbolSearch.search.variablesPlaceholder): The placeholder\n# text displayed when the user searches for variables in a file\nsymbolSearch.search.variablesPlaceholder=Search variables…\n\n# LOCALIZATION NOTE(symbolSearch.search.key2): The Key Shortcut for\n# searching for a function or variable\nsymbolSearch.search.key2=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.modifiersLabel): A label\n# preceding the group of modifiers\nsymbolSearch.searchModifier.modifiersLabel=Modifiers:\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.regex): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.regex=Regex\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.caseSensitive): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.caseSensitive=Case sensitive\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.wholeWord): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.wholeWord=Whole word\n\n# LOCALIZATION NOTE (resumptionOrderPanelTitle): This is the text that appears\n# as a description in the notification panel popup, when multiple debuggers are\n# open in separate tabs and the user tries to resume them in the wrong order.\n# The substitution parameter is the URL of the last paused window that must be\n# resumed first.\nresumptionOrderPanelTitle=There are one or more paused debuggers. Please resume the most-recently paused debugger first at: %S\n\nvariablesViewOptimizedOut=(optimized away)\nvariablesViewUninitialized=(uninitialized)\nvariablesViewMissingArgs=(unavailable)\n\nanonymousSourcesLabel=Anonymous Sources\n\nexperimental=This is an experimental feature\n\n# LOCALIZATION NOTE (whyPaused.debuggerStatement): The text that is displayed\n# in a info block explaining how the debugger is currently paused due to a `debugger`\n# statement in the code\nwhyPaused.debuggerStatement=Paused on debugger statement\n\n# LOCALIZATION NOTE (whyPaused.breakpoint): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a breakpoint\nwhyPaused.breakpoint=Paused on breakpoint\n\n# LOCALIZATION NOTE (whyPaused.exception): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an exception\nwhyPaused.exception=Paused on exception\n\n# LOCALIZATION NOTE (whyPaused.resumeLimit): The text that is displayed\n# in a info block explaining how the debugger is currently paused while stepping\n# in or out of the stack\nwhyPaused.resumeLimit=Paused while stepping\n\n# LOCALIZATION NOTE (whyPaused.pauseOnDOMEvents): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# dom event\nwhyPaused.pauseOnDOMEvents=Paused on event listener\n\n# LOCALIZATION NOTE (whyPaused.breakpointConditionThrown): The text that is displayed\n# in an info block when evaluating a conditional breakpoint throws an error\nwhyPaused.breakpointConditionThrown=Error with conditional breakpoint\n\n# LOCALIZATION NOTE (whyPaused.xhr): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# xml http request\nwhyPaused.xhr=Paused on XMLHttpRequest\n\n# LOCALIZATION NOTE (whyPaused.promiseRejection): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# promise rejection\nwhyPaused.promiseRejection=Paused on promise rejection\n\n# LOCALIZATION NOTE (whyPaused.assert): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# assert\nwhyPaused.assert=Paused on assertion\n\n# LOCALIZATION NOTE (whyPaused.debugCommand): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# debugger statement\nwhyPaused.debugCommand=Paused on debugged function\n\n# LOCALIZATION NOTE (whyPaused.other): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an event\n# listener breakpoint set\nwhyPaused.other=Debugger paused\n\n# LOCALIZATION NOTE (ctrl): The text that is used for documenting\n# keyboard shortcuts that use the control key\nctrl=Ctrl\n"
 
 /***/ }),
 /* 961 */,
 /* 962 */
 /***/ (function(module, exports) {
 
 // removed by extract-text-webpack-plugin
 
@@ -41706,32 +41826,38 @@ module.exports = "<svg viewBox=\"0 0 14 
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.findScopeByName = exports.getASTLocation = undefined;
+exports.getClosestFunction = exports.findScopeByName = exports.getASTLocation = undefined;
 
 var _astBreakpointLocation = __webpack_require__(804);
 
 Object.defineProperty(exports, "getASTLocation", {
   enumerable: true,
   get: function () {
     return _astBreakpointLocation.getASTLocation;
   }
 });
 Object.defineProperty(exports, "findScopeByName", {
   enumerable: true,
   get: function () {
     return _astBreakpointLocation.findScopeByName;
   }
 });
+Object.defineProperty(exports, "getClosestFunction", {
+  enumerable: true,
+  get: function () {
+    return _astBreakpointLocation.getClosestFunction;
+  }
+});
 exports.firstString = firstString;
 exports.locationMoved = locationMoved;
 exports.makeLocationId = makeLocationId;
 exports.makePendingLocationId = makePendingLocationId;
 exports.assertBreakpoint = assertBreakpoint;
 exports.assertPendingBreakpoint = assertPendingBreakpoint;
 exports.assertLocation = assertLocation;
 exports.assertPendingLocation = assertPendingLocation;
@@ -42237,17 +42363,17 @@ function setPreview(token, tokenPos, cur
 
           var selectedFrame = (0, _selectors.getSelectedFrame)(getState());
 
           var _ref11 = yield client.evaluate(expression, {
             frameId: selectedFrame.id
           }),
               result = _ref11.result;
 
-          if (!result) {
+          if (result === undefined) {
             return;
           }
 
           return {
             expression,
             result,
             location,
             tokenPos,
@@ -42281,18 +42407,16 @@ Object.defineProperty(exports, "__esModu
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 var _classnames = __webpack_require__(175);
 
 var _classnames2 = _interopRequireDefault(_classnames);
 
-var _lodash = __webpack_require__(2);
-
 var _Svg = __webpack_require__(344);
 
 var _Svg2 = _interopRequireDefault(_Svg);
 
 var _ManagedTree = __webpack_require__(419);
 
 var _ManagedTree2 = _interopRequireDefault(_ManagedTree);
 
@@ -42467,34 +42591,34 @@ class TextSearch extends _react.Componen
     }
 
     var renderItem = (item, depth, focused, _, expanded, _ref) => {
       var setExpanded = _ref.setExpanded;
 
       return item.filepath ? this.renderFile(item, focused, expanded, setExpanded) : this.renderMatch(item, focused);
     };
 
-    var getFocusedItem = () => {
-      if (this.focusedItem === null) {
-        return results[0] ? results[0].matches[0] : null;
-      }
-      return this.focusedItem.file || this.focusedItem.match;
-    };
-
-    return _react2.default.createElement(_ManagedTree2.default, {
-      getRoots: () => results,
-      getChildren: file => file.matches || [],
-      itemHeight: 24,
-      autoExpand: 1,
-      autoExpandDepth: 1,
-      focused: getFocusedItem(),
-      getParent: item => null,
-      getPath: getFilePath,
-      renderItem: renderItem
-    });
+    if (results.length) {
+      return _react2.default.createElement(_ManagedTree2.default, {
+        getRoots: () => results,
+        getChildren: file => file.matches || [],
+        itemHeight: 24,
+        autoExpand: 1,
+        autoExpandDepth: 1,
+        getParent: item => null,
+        getPath: getFilePath,
+        renderItem: renderItem
+      });
+    } else if (this.props.query && !results.length) {
+      return _react2.default.createElement(
+        "div",
+        { className: "no-result-msg absolute-center" },
+        L10N.getStr("projectTextSearch.noResults")
+      );
+    }
   }
 
   renderInput() {
     var resultCount = this.getResultCount();
     var summaryMsg = L10N.getFormatStr("sourceSearch.resultsSummary1", resultCount);
 
     return _react2.default.createElement(_SearchInput2.default, {
       query: this.state.inputValue,
@@ -43151,20 +43275,21 @@ function updateBreakpoint(state, action)
   var pendingBreakpoint = (0, _breakpoint.createPendingBreakpoint)(breakpoint);
 
   return state.setIn(["pendingBreakpoints", locationId], pendingBreakpoint);
 }
 
 function removeBreakpoint(state, action) {
   var breakpoint = action.breakpoint;
 
+
   var locationId = (0, _breakpoint.makePendingLocationId)(breakpoint.location);
-
-  const pendingBp = state.getIn(["pendingBreakpoints", locationId]);
-  if (!pendingBp) {
+  var pendingBp = state.getIn(["pendingBreakpoints", locationId]);
+
+  if (!pendingBp && action.status == "start") {
     return state.set("pendingBreakpoints", I.Map());
   }
 
   return state.deleteIn(["pendingBreakpoints", locationId]);
 }
 
 // Selectors
 // TODO: these functions should be moved out of the reducer
@@ -43820,18 +43945,18 @@ var _utils = __webpack_require__(234);
 var _Autocomplete = __webpack_require__(342);
 
 var _Autocomplete2 = _interopRequireDefault(_Autocomplete);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class SourceSearch extends _react.Component {
 
-  searchResults(sourceMap) {
-    return sourceMap.valueSeq().toJS().filter(source => !(0, _source.isPretty)(source)).map(source => ({
+  searchResults(sources) {
+    return sources.valueSeq().toJS().filter(source => !(0, _source.isPretty)(source) && !(0, _source.isThirdParty)(source)).map(source => ({
       value: (0, _source.getSourcePath)(source),
       title: (0, _source.getSourcePath)(source).split("/").pop(),
       subtitle: (0, _utils.endTruncateStr)((0, _source.getSourcePath)(source), 100),
       id: source.id
     }));
   }
 
   render() {
@@ -43991,29 +44116,31 @@ class PrimaryPanes extends _react.Compon
 
   render() {
     var selectedPane = this.state.selectedPane;
     var _props = this.props,
         sources = _props.sources,
         selectSource = _props.selectSource;
 
 
+    var outlineComp = (0, _devtoolsConfig.isEnabled)("outline") ? _react2.default.createElement(_Outline2.default, {
+      selectSource: selectSource,
+      isHidden: selectedPane === "sources"
+    }) : null;
+
     return _react2.default.createElement(
       "div",
       { className: "sources-panel" },
       this.renderHeader(),
       _react2.default.createElement(_SourcesTree2.default, {
         sources: sources,
         selectSource: selectSource,
         isHidden: selectedPane === "outline"
       }),
-      _react2.default.createElement(_Outline2.default, {
-        selectSource: selectSource,
-        isHidden: selectedPane === "sources"
-      }),
+      outlineComp,
       this.renderFooter()
     );
   }
 }
 
 PrimaryPanes.displayName = "PrimaryPanes";
 
 exports.default = (0, _reactRedux.connect)(state => ({
@@ -44032,32 +44159,34 @@ Object.defineProperty(exports, "__esModu
   value: true
 });
 exports.loadSourceText = loadSourceText;
 
 var _promise = __webpack_require__(193);
 
 var _ast = __webpack_require__(1059);
 
+var _source = __webpack_require__(233);
+
 function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
 
 /**
  * @memberof actions/sources
  * @static
  */
 function loadSourceText(source) {
   return (() => {
     var _ref = _asyncToGenerator(function* (_ref2) {
       var dispatch = _ref2.dispatch,
           getState = _ref2.getState,
           client = _ref2.client,
           sourceMaps = _ref2.sourceMaps;
 
       // Fetch the source text only once.
-      if (source.text) {
+      if ((0, _source.isLoaded)(source)) {
         return Promise.resolve(source);
       }
 
       yield dispatch({
         type: "LOAD_SOURCE_TEXT",
         source: source,
         [_promise.PROMISE]: _asyncToGenerator(function* () {
           if (sourceMaps.isOriginalId(source.id)) {
@@ -44144,18 +44273,16 @@ var _classnames = __webpack_require__(17
 var _classnames2 = _interopRequireDefault(_classnames);
 
 var _actions = __webpack_require__(244);
 
 var _actions2 = _interopRequireDefault(_actions);
 
 var _selectors = __webpack_require__(242);
 
-var _devtoolsConfig = __webpack_require__(828);
-
 __webpack_require__(871);
 
 var _PreviewFunction = __webpack_require__(798);
 
 var _PreviewFunction2 = _interopRequireDefault(_PreviewFunction);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
@@ -44169,16 +44296,24 @@ class Outline extends _react.Component {
     if (!selectedSource) {
       return;
     }
     var selectedSourceId = selectedSource.get("id");
     var startLine = location.start.line;
     selectSource(selectedSourceId, { line: startLine });
   }
 
+  renderPlaceholder() {
+    return _react2.default.createElement(
+      "div",
+      { className: "outline-pane-info" },
+      L10N.getStr("outline.noFunctions")
+    );
+  }
+
   renderFunction(func) {
     var name = func.name,
         location = func.location,
         parameterNames = func.parameterNames;
 
 
     return _react2.default.createElement(
       "li",
@@ -44186,38 +44321,36 @@ class Outline extends _react.Component {
         key: `${name}:${location.start.line}:${location.start.column}`,
         className: "outline-list__element",
         onClick: () => this.selectItem(location)
       },
       _react2.default.createElement(_PreviewFunction2.default, { func: { name, parameterNames } })
     );
   }
 
-  renderFunctions() {
-    var symbols = this.props.symbols;
-
-
-    return symbols.functions.filter(func => func.name != "anonymous").map(func => this.renderFunction(func));
-  }
-
-  render() {
-    var isHidden = this.props.isHidden;
-
-    if (!(0, _devtoolsConfig.isEnabled)("outline")) {
-      return null;
-    }
+  renderFunctions(symbols) {
+    return _react2.default.createElement(
+      "ul",
+      { className: "outline-list" },
+      symbols.map(func => this.renderFunction(func))
+    );
+  }
+
+  render() {
+    var _props2 = this.props,
+        isHidden = _props2.isHidden,
+        symbols = _props2.symbols;
+
+
+    var symbolsToDisplay = symbols.functions.filter(func => func.name != "anonymous");
 
     return _react2.default.createElement(
       "div",
       { className: (0, _classnames2.default)("outline", { hidden: isHidden }) },
-      _react2.default.createElement(
-        "ul",
-        { className: "outline-list" },
-        this.renderFunctions()
-      )
+      symbolsToDisplay.length > 0 ? this.renderFunctions(symbolsToDisplay) : this.renderPlaceholder()
     );
   }
 }
 
 exports.Outline = Outline;
 Outline.displayName = "Outline";
 
 exports.default = (0, _reactRedux.connect)(state => {
@@ -45953,18 +46086,53 @@ exports.default = (0, _reactRedux.connec
 /* 1162 */
 /***/ (function(module, exports) {
 
 // removed by extract-text-webpack-plugin
 
 /***/ }),
 /* 1163 */,
 /* 1164 */,
-/* 1165 */,
-/* 1166 */,
+/* 1165 */
+/***/ (function(module, exports, __webpack_require__) {
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const networkRequest = __webpack_require__(1166);
+const workerUtils = __webpack_require__(1168);
+
+module.exports = {
+  networkRequest,
+  workerUtils
+};
+
+/***/ }),
+/* 1166 */
+/***/ (function(module, exports) {
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+function networkRequest(url, opts) {
+  return fetch(url, {
+    cache: opts.loadFromCache ? "default" : "no-cache"
+  }).then(res => {
+    if (res.status >= 200 && res.status < 300) {
+      return res.text().then(text => ({ content: text }));
+    }
+    return Promise.reject(`request failed with status ${res.status}`);
+  });
+}
+
+module.exports = networkRequest;
+
+/***/ }),
 /* 1167 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
@@ -46061,18 +46229,200 @@ class CallSite extends _react.Component 
     return null;
   }
 }
 
 exports.default = CallSite;
 CallSite.displayName = "CallSite";
 
 /***/ }),
-/* 1168 */,
-/* 1169 */,
+/* 1168 */
+/***/ (function(module, exports) {
+
+function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
+
+function WorkerDispatcher() {
+  this.msgId = 1;
+  this.worker = null;
+} /* This Source Code Form is subject to the terms of the Mozilla Public
+   * License, v. 2.0. If a copy of the MPL was not distributed with this
+   * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+WorkerDispatcher.prototype = {
+  start(url) {
+    this.worker = new Worker(url);
+    this.worker.onerror = () => {
+      console.error(`Error in worker ${url}`);
+    };
+  },
+
+  stop() {
+    if (!this.worker) {
+      return;
+    }
+
+    this.worker.terminate();
+    this.worker = null;
+  },
+
+  task(method) {
+    return (...args) => {
+      return new Promise((resolve, reject) => {
+        const id = this.msgId++;
+        this.worker.postMessage({ id, method, args });
+
+        const listener = ({ data: result }) => {
+          if (result.id !== id) {
+            return;
+          }
+
+          this.worker.removeEventListener("message", listener);
+          if (result.error) {
+            reject(result.error);
+          } else {
+            resolve(result.response);
+          }
+        };
+
+        this.worker.addEventListener("message", listener);
+      });
+    };
+  }
+};
+
+function workerHandler(publicInterface) {
+  return function (msg) {
+    const { id, method, args } = msg.data;
+    try {
+      const response = publicInterface[method].apply(undefined, args);
+      if (response instanceof Promise) {
+        response.then(val => self.postMessage({ id, response: val }),
+        // Error can't be sent via postMessage, so be sure to
+        // convert to string.
+        err => self.postMessage({ id, error: err.toString() }));
+      } else {
+        self.postMessage({ id, response });
+      }
+    } catch (error) {
+      // Error can't be sent via postMessage, so be sure to convert to
+      // string.
+      self.postMessage({ id, error: error.toString() });
+    }
+  };
+}
+
+function streamingWorkerHandler(publicInterface, { timeout = 100 } = {}, worker = self) {
+  let streamingWorker = (() => {
+    var _ref = _asyncToGenerator(function* (id, tasks) {
+      let isWorking = true;
+
+      const intervalId = setTimeout(function () {
+        isWorking = false;
+      }, timeout);
+
+      const results = [];
+      while (tasks.length !== 0 && isWorking) {
+        const { callback, context, args } = tasks.shift();
+        const result = yield callback.call(context, args);
+        results.push(result);
+      }
+      worker.postMessage({ id, status: "pending", data: results });
+      clearInterval(intervalId);
+
+      if (tasks.length !== 0) {
+        yield streamingWorker(id, tasks);
+      }
+    });
+
+    return function streamingWorker(_x, _x2) {
+      return _ref.apply(this, arguments);
+    };
+  })();
+
+  return (() => {
+    var _ref2 = _asyncToGenerator(function* (msg) {
+      const { id, method, args } = msg.data;
+      const workerMethod = publicInterface[method];
+      if (!workerMethod) {
+        console.error(`Could not find ${method} defined in worker.`);
+      }
+      worker.postMessage({ id, status: "start" });
+
+      try {
+        const tasks = workerMethod(args);
+        yield streamingWorker(id, tasks);
+        worker.postMessage({ id, status: "done" });
+      } catch (error) {
+        worker.postMessage({ id, status: "error", error });
+      }
+    });
+
+    return function (_x3) {
+      return _ref2.apply(this, arguments);
+    };
+  })();
+}
+
+module.exports = {
+  WorkerDispatcher,
+  workerHandler,
+  streamingWorkerHandler
+};
+
+/***/ }),
+/* 1169 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.findFunctionText = findFunctionText;
+
+var _astBreakpointLocation = __webpack_require__(804);
+
+function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
+
+function getIndentation(lines) {
+  var firstLine = lines[0];
+  var secondLine = lines[1];
+  var lastLine = lines[lines.length - 1];
+
+  var _getIndentation = line => line && line.match(/^\s*/)[0].length;
+
+  var indentations = [_getIndentation(firstLine), _getIndentation(secondLine), _getIndentation(lastLine)];
+
+  return Math.max.apply(Math, indentations.concat([0]));
+}
+
+function findFunctionText(line, source, symbols) {
+  var func = (0, _astBreakpointLocation.findClosestScope)(symbols.functions, { line, column: Infinity });
+  if (!func) {
+    return null;
+  }
+
+  var _func$location = func.location,
+      start = _func$location.start,
+      end = _func$location.end;
+
+  var lines = source.text.split("\n");
+  var firstLine = lines[start.line - 1].slice(start.column);
+  var lastLine = lines[end.line - 1].slice(0, end.column);
+  var middle = lines.slice(start.line, end.line - 1);
+  var functionLines = [firstLine].concat(_toConsumableArray(middle), [lastLine]);
+
+  var indentation = getIndentation(functionLines);
+  var formattedLines = functionLines.map(_line => _line.replace(new RegExp(`^\\s{0,${indentation - 1}}`), ""));
+
+  return formattedLines.join("\n").trim();
+}
+
+/***/ }),
 /* 1170 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
@@ -46388,9 +46738,9 @@ exports.default = (0, _reactRedux.connec
 /* 1173 */,
 /* 1174 */
 /***/ (function(module, exports) {
 
 module.exports = "<svg xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 400 400\" xml:space=\"preserve\" id=\"svg2\" version=\"1.1\"><metadata id=\"metadata8\"><rdf:RDF><cc:Work rdf:about><dc:format>image/svg+xml</dc:format><dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"></dc></cc:Work></rdf:RDF></metadata><defs id=\"defs6\"></defs><g transform=\"matrix(1.3333333,0,0,-1.3333333,0,400)\" id=\"g10\"><g transform=\"translate(178.0626,235.0086)\" id=\"g12\"><path id=\"path14\" style=\"fill:#41b883;fill-opacity:1;fill-rule:nonzero;stroke:none\" d=\"M 0,0 -22.669,-39.264 -45.338,0 h -75.491 L -22.669,-170.017 75.491,0 Z\"></path></g><g transform=\"translate(178.0626,235.0086)\" id=\"g16\"><path id=\"path18\" style=\"fill:#34495e;fill-opacity:1;fill-rule:nonzero;stroke:none\" d=\"M 0,0 -22.669,-39.264 -45.338,0 H -81.565 L -22.669,-102.01 36.227,0 Z\"></path></g></g></svg>"
 
 /***/ })
 /******/ ]);
-});
+});
\ No newline at end of file
--- a/devtools/client/debugger/new/parser-worker.js
+++ b/devtools/client/debugger/new/parser-worker.js
@@ -28726,16 +28726,20 @@ WorkerDispatcher.prototype = {
         const id = this.msgId++;
         this.worker.postMessage({ id, method, args });
 
         const listener = ({ data: result }) => {
           if (result.id !== id) {
             return;
           }
 
+          if (!this.worker) {
+            reject("Oops, The worker has shutdown!");
+            return;
+          }
           this.worker.removeEventListener("message", listener);
           if (result.error) {
             reject(result.error);
           } else {
             resolve(result.response);
           }
         };
 
@@ -28894,16 +28898,18 @@ var _closest = __webpack_require__(1055)
 var _scopes = __webpack_require__(1049);
 
 var _getSymbols = __webpack_require__(1050);
 
 var _getSymbols2 = _interopRequireDefault(_getSymbols);
 
 var _ast = __webpack_require__(1051);
 
+var _sources = __webpack_require__(1171);
+
 var _getOutOfScopeLocations = __webpack_require__(1072);
 
 var _getOutOfScopeLocations2 = _interopRequireDefault(_getOutOfScopeLocations);
 
 var _steps = __webpack_require__(842);
 
 var _getEmptyLines = __webpack_require__(845);
 
@@ -28917,16 +28923,19 @@ var workerHandler = _devtoolsUtils.worke
 
 
 self.onmessage = workerHandler({
   getClosestExpression: _closest.getClosestExpression,
   getOutOfScopeLocations: _getOutOfScopeLocations2.default,
   getSymbols: _getSymbols2.default,
   clearSymbols: _getSymbols.clearSymbols,
   clearASTs: _ast.clearASTs,
+  hasSource: _sources.hasSource,
+  setSource: _sources.setSource,
+  clearSources: _sources.clearSources,
   getVariablesInScope: _scopes.getVariablesInScope,
   getNextStep: _steps.getNextStep,
   getEmptyLines: _getEmptyLines2.default
 });
 
 /***/ }),
 /* 962 */,
 /* 963 */
@@ -32990,11 +32999,63 @@ var isArrayLike = __webpack_require__(22
  */
 function isArrayLikeObject(value) {
   return isObjectLike(value) && isArrayLike(value);
 }
 
 module.exports = isArrayLikeObject;
 
 
+/***/ }),
+/* 1156 */,
+/* 1157 */,
+/* 1158 */,
+/* 1159 */,
+/* 1160 */,
+/* 1161 */,
+/* 1162 */,
+/* 1163 */,
+/* 1164 */,
+/* 1165 */,
+/* 1166 */,
+/* 1167 */,
+/* 1168 */,
+/* 1169 */,
+/* 1170 */,
+/* 1171 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.hasSource = hasSource;
+exports.setSource = setSource;
+exports.getSource = getSource;
+exports.clearSources = clearSources;
+
+
+var cachedSources = new Map();
+
+function hasSource(sourceId) {
+  return cachedSources.has(sourceId);
+}
+
+function setSource(source) {
+  cachedSources.set(source.id, source);
+}
+
+function getSource(sourceId) {
+  if (!cachedSources.has(sourceId)) {
+    throw new Error(`${sourceId} was not provided.`);
+  }
+  return cachedSources.get(sourceId);
+}
+
+function clearSources() {
+  cachedSources = new Map();
+}
+
 /***/ })
 /******/ ]);
 });
\ No newline at end of file
--- a/devtools/client/debugger/new/pretty-print-worker.js
+++ b/devtools/client/debugger/new/pretty-print-worker.js
@@ -7430,16 +7430,20 @@ WorkerDispatcher.prototype = {
         const id = this.msgId++;
         this.worker.postMessage({ id, method, args });
 
         const listener = ({ data: result }) => {
           if (result.id !== id) {
             return;
           }
 
+          if (!this.worker) {
+            reject("Oops, The worker has shutdown!");
+            return;
+          }
           this.worker.removeEventListener("message", listener);
           if (result.error) {
             reject(result.error);
           } else {
             resolve(result.response);
           }
         };
 
--- a/devtools/client/debugger/new/search-worker.js
+++ b/devtools/client/debugger/new/search-worker.js
@@ -421,16 +421,190 @@ function findSourceMatches(source, query
   }).filter(_matches => _matches.length > 0);
 
   matches = (_ref = []).concat.apply(_ref, _toConsumableArray(matches));
   return matches;
 }
 
 /***/ }),
 
+/***/ 1165:
+/***/ (function(module, exports, __webpack_require__) {
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const networkRequest = __webpack_require__(1166);
+const workerUtils = __webpack_require__(1168);
+
+module.exports = {
+  networkRequest,
+  workerUtils
+};
+
+/***/ }),
+
+/***/ 1166:
+/***/ (function(module, exports) {
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+function networkRequest(url, opts) {
+  return fetch(url, {
+    cache: opts.loadFromCache ? "default" : "no-cache"
+  }).then(res => {
+    if (res.status >= 200 && res.status < 300) {
+      return res.text().then(text => ({ content: text }));
+    }
+    return Promise.reject(`request failed with status ${res.status}`);
+  });
+}
+
+module.exports = networkRequest;
+
+/***/ }),
+
+/***/ 1168:
+/***/ (function(module, exports) {
+
+function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
+
+function WorkerDispatcher() {
+  this.msgId = 1;
+  this.worker = null;
+} /* This Source Code Form is subject to the terms of the Mozilla Public
+   * License, v. 2.0. If a copy of the MPL was not distributed with this
+   * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+WorkerDispatcher.prototype = {
+  start(url) {
+    this.worker = new Worker(url);
+    this.worker.onerror = () => {
+      console.error(`Error in worker ${url}`);
+    };
+  },
+
+  stop() {
+    if (!this.worker) {
+      return;
+    }
+
+    this.worker.terminate();
+    this.worker = null;
+  },
+
+  task(method) {
+    return (...args) => {
+      return new Promise((resolve, reject) => {
+        const id = this.msgId++;
+        this.worker.postMessage({ id, method, args });
+
+        const listener = ({ data: result }) => {
+          if (result.id !== id) {
+            return;
+          }
+
+          this.worker.removeEventListener("message", listener);
+          if (result.error) {
+            reject(result.error);
+          } else {
+            resolve(result.response);
+          }
+        };
+
+        this.worker.addEventListener("message", listener);
+      });
+    };
+  }
+};
+
+function workerHandler(publicInterface) {
+  return function (msg) {
+    const { id, method, args } = msg.data;
+    try {
+      const response = publicInterface[method].apply(undefined, args);
+      if (response instanceof Promise) {
+        response.then(val => self.postMessage({ id, response: val }),
+        // Error can't be sent via postMessage, so be sure to
+        // convert to string.
+        err => self.postMessage({ id, error: err.toString() }));
+      } else {
+        self.postMessage({ id, response });
+      }
+    } catch (error) {
+      // Error can't be sent via postMessage, so be sure to convert to
+      // string.
+      self.postMessage({ id, error: error.toString() });
+    }
+  };
+}
+
+function streamingWorkerHandler(publicInterface, { timeout = 100 } = {}, worker = self) {
+  let streamingWorker = (() => {
+    var _ref = _asyncToGenerator(function* (id, tasks) {
+      let isWorking = true;
+
+      const intervalId = setTimeout(function () {
+        isWorking = false;
+      }, timeout);
+
+      const results = [];
+      while (tasks.length !== 0 && isWorking) {
+        const { callback, context, args } = tasks.shift();
+        const result = yield callback.call(context, args);
+        results.push(result);
+      }
+      worker.postMessage({ id, status: "pending", data: results });
+      clearInterval(intervalId);
+
+      if (tasks.length !== 0) {
+        yield streamingWorker(id, tasks);
+      }
+    });
+
+    return function streamingWorker(_x, _x2) {
+      return _ref.apply(this, arguments);
+    };
+  })();
+
+  return (() => {
+    var _ref2 = _asyncToGenerator(function* (msg) {
+      const { id, method, args } = msg.data;
+      const workerMethod = publicInterface[method];
+      if (!workerMethod) {
+        console.error(`Could not find ${method} defined in worker.`);
+      }
+      worker.postMessage({ id, status: "start" });
+
+      try {
+        const tasks = workerMethod(args);
+        yield streamingWorker(id, tasks);
+        worker.postMessage({ id, status: "done" });
+      } catch (error) {
+        worker.postMessage({ id, status: "error", error });
+      }
+    });
+
+    return function (_x3) {
+      return _ref2.apply(this, arguments);
+    };
+  })();
+}
+
+module.exports = {
+  WorkerDispatcher,
+  workerHandler,
+  streamingWorkerHandler
+};
+
+/***/ }),
+
 /***/ 1173:
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
@@ -689,17 +863,17 @@ module.exports = isObjectLike;
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.isLoaded = exports.getMode = exports.getSourceLineCount = exports.getSourcePath = exports.getFilenameFromURL = exports.getFilename = exports.getRawSourceURL = exports.getPrettySourceURL = exports.shouldPrettyPrint = exports.isPretty = exports.isJavaScript = undefined;
+exports.isLoaded = exports.getMode = exports.getSourceLineCount = exports.getSourcePath = exports.getFilenameFromURL = exports.getFilename = exports.getRawSourceURL = exports.getPrettySourceURL = exports.shouldPrettyPrint = exports.isThirdParty = exports.isPretty = exports.isJavaScript = undefined;
 
 var _devtoolsSourceMap = __webpack_require__(898);
 
 var _utils = __webpack_require__(234);
 
 var _path = __webpack_require__(235);
 
 var _url = __webpack_require__(334);
@@ -763,16 +937,24 @@ function isJavaScript(url) {
 /**
  * @memberof utils/source
  * @static
  */
 function isPretty(source) {
   return source.url ? /formatted$/.test(source.url) : false;
 }
 
+function isThirdParty(source) {
+  if (!source || !source.url) {
+    return false;
+  }
+
+  return !!source.url.match(/(node_modules|bower_components)/);
+}
+
 /**
  * @memberof utils/source
  * @static
  */
 function getPrettySourceURL(url) {
   if (!url) {
     url = "";
   }
@@ -912,16 +1094,17 @@ function getMode(source) {
 }
 
 function isLoaded(source) {
   return source.loadedState === "loaded";
 }
 
 exports.isJavaScript = isJavaScript;
 exports.isPretty = isPretty;
+exports.isThirdParty = isThirdParty;
 exports.shouldPrettyPrint = shouldPrettyPrint;
 exports.getPrettySourceURL = getPrettySourceURL;
 exports.getRawSourceURL = getRawSourceURL;
 exports.getFilename = getFilename;
 exports.getFilenameFromURL = getFilenameFromURL;
 exports.getSourcePath = getSourcePath;
 exports.getSourceLineCount = getSourceLineCount;
 exports.getMode = getMode;
@@ -2422,17 +2605,17 @@ module.exports = root;
 
 const {
   originalToGeneratedId,
   generatedToOriginalId,
   isGeneratedId,
   isOriginalId
 } = __webpack_require__(899);
 
-const { workerUtils: { WorkerDispatcher } } = __webpack_require__(900);
+const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1165);
 
 const dispatcher = new WorkerDispatcher();
 
 const getOriginalURLs = dispatcher.task("getOriginalURLs");
 const getGeneratedLocation = dispatcher.task("getGeneratedLocation");
 const getOriginalLocation = dispatcher.task("getOriginalLocation");
 const getOriginalSourceText = dispatcher.task("getOriginalSourceText");
 const applySourceMap = dispatcher.task("applySourceMap");
@@ -2624,16 +2807,20 @@ WorkerDispatcher.prototype = {
         const id = this.msgId++;
         this.worker.postMessage({ id, method, args });
 
         const listener = ({ data: result }) => {
           if (result.id !== id) {
             return;
           }
 
+          if (!this.worker) {
+            reject("Oops, The worker has shutdown!");
+            return;
+          }
           this.worker.removeEventListener("message", listener);
           if (result.error) {
             reject(result.error);
           } else {
             resolve(result.response);
           }
         };
 
--- a/devtools/client/framework/test/browser_source_map-01.js
+++ b/devtools/client/framework/test/browser_source_map-01.js
@@ -21,17 +21,17 @@ add_task(function* () {
   const service = toolbox.sourceMapURLService;
 
   // Inject JS script
   let sourceSeen = waitForSourceLoad(toolbox, JS_URL);
   yield createScript(JS_URL);
   yield sourceSeen;
 
   let loc1 = { url: JS_URL, line: 6 };
-  let newLoc1 = yield service.originalPositionFor(loc1.url, loc1.line);
+  let newLoc1 = yield service.originalPositionFor(loc1.url, loc1.line, 4);
   checkLoc1(loc1, newLoc1);
 
   let loc2 = { url: JS_URL, line: 8, column: 3 };
   let newLoc2 = yield service.originalPositionFor(loc2.url, loc2.line, loc2.column);
   checkLoc2(loc2, newLoc2);
 
   yield toolbox.destroy();
   gBrowser.removeCurrentTab();
--- a/devtools/client/framework/test/browser_source_map-absolute.js
+++ b/devtools/client/framework/test/browser_source_map-absolute.js
@@ -17,13 +17,13 @@ add_task(function* () {
   const service = toolbox.sourceMapURLService;
 
   // Inject JS script
   let sourceSeen = waitForSourceLoad(toolbox, JS_URL);
   yield createScript(JS_URL);
   yield sourceSeen;
 
   info(`checking original location for ${JS_URL}:6`);
-  let newLoc = yield service.originalPositionFor(JS_URL, 6);
+  let newLoc = yield service.originalPositionFor(JS_URL, 6, 4);
 
   is(newLoc.sourceUrl, ORIGINAL_URL, "check mapped URL");
   is(newLoc.line, 4, "check mapped line number");
 });
--- a/devtools/client/locales/en-US/debugger.properties
+++ b/devtools/client/locales/en-US/debugger.properties
@@ -16,19 +16,24 @@ collapsePanes=Collapse panes
 
 # LOCALIZATION NOTE (copySource): This is the text that appears in the
 # context menu to copy the selected source of file open.
 copySource=Copy
 copySource.accesskey=y
 
 # LOCALIZATION NOTE (copySourceUrl): This is the text that appears in the
 # context menu to copy the source URL of file open.
-copySourceUrl=Copy Source Url
+copySourceUrl=Copy Source URL
 copySourceUrl.accesskey=u
 
+# LOCALIZATION NOTE (copyFunction): This is the text that appears in the
+# context menu to copy the function the user selected
+copyFunction.label=Copy Function
+copyFunction.accesskey=F
+
 # LOCALIZATION NOTE (copyStackTrace): This is the text that appears in the
 # context menu to copy the stack trace methods, file names and row number.
 copyStackTrace=Copy Stack Trace
 copyStackTrace.accesskey=c
 
 # LOCALIZATION NOTE (expandPanes): This is the tooltip for the button
 # that expands the left and right panes in the debugger UI.
 expandPanes=Expand panes
@@ -146,16 +151,20 @@ projectTextSearch.key=CmdOrCtrl+Shift+F
 # LOCALIZATION NOTE (functionSearch.key): A key shortcut to open the
 # modal for searching functions in a file.
 functionSearch.key=CmdOrCtrl+Shift+O
 
 # LOCALIZATION NOTE (projectTextSearch.placeholder): A placeholder shown
 # when searching across all of the files in a project.
 projectTextSearch.placeholder=Find in files…
 
+# LOCALIZATION NOTE (projectTextSearch.noResults): The center pane Text Search
+# message when the query did not match any text of all files in a project.
+projectTextSearch.noResults=No results found
+
 # LOCALIZATION NOTE (sources.noSourcesAvailable): Text shown when the debugger
 # does not have any sources.
 sources.noSourcesAvailable=This page has no sources
 
 # LOCALIZATION NOTE (sourceSearch.search.key2): Key shortcut to open the search
 # for searching within a the currently opened files in the editor
 sourceSearch.search.key2=CmdOrCtrl+F
 
@@ -231,16 +240,20 @@ breakpointMenuItem.disableOthers.accessk
 breakpointMenuItem.deleteOthers=Remove others
 breakpointMenuItem.deleteOthers.accesskey=h
 breakpointMenuItem.enableAll=Enable all breakpoints
 breakpointMenuItem.enableAll.accesskey=b
 breakpointMenuItem.disableAll=Disable all breakpoints
 breakpointMenuItem.disableAll.accesskey=k
 breakpointMenuItem.deleteAll=Remove all breakpoints
 breakpointMenuItem.deleteAll.accesskey=a
+breakpointMenuItem.removeCondition.label=Remove breakpoint condition
+breakpointMenuItem.removeCondition.accesskey=c
+breakpointMenuItem.editCondition.label=Edit breakpoint condition
+breakpointMenuItem.editCondition.accesskey=n
 
 # LOCALIZATION NOTE (breakpoints.header): Breakpoints right sidebar pane header.
 breakpoints.header=Breakpoints
 
 # LOCALIZATION NOTE (breakpoints.none): The text that appears when there are
 # no breakpoints present
 breakpoints.none=No Breakpoints
 
@@ -289,16 +302,21 @@ editor.searchResults.nextResult=Next Res
 # LOCALIZATION NOTE (editor.searchResults.prevResult): Editor Search bar
 # tooltip for traversing to the Previous Result
 editor.searchResults.prevResult=Previous Result
 
 # LOCALIZATION NOTE (editor.searchTypeToggleTitle): Search bar title for
 # toggling search type buttons(function search, variable search)
 editor.searchTypeToggleTitle=Search for:
 
+# LOCALIZATION NOTE (editor.continueToHere.label): Editor gutter context
+# menu item for jumping to a new paused location
+editor.continueToHere.label=Continue To Here
+editor.continueToHere.accesskey=H
+
 # LOCALIZATION NOTE (editor.addBreakpoint): Editor gutter context menu item
 # for adding a breakpoint on a line.
 editor.addBreakpoint=Add Breakpoint
 
 # LOCALIZATION NOTE (editor.disableBreakpoint): Editor gutter context menu item
 # for disabling a breakpoint on a line.
 editor.disableBreakpoint=Disable Breakpoint
 
@@ -323,56 +341,56 @@ editor.addConditionalBreakpoint=Add Cond
 editor.conditionalPanel.placeholder=This breakpoint will pause when the expression is true
 
 # LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Tooltip text for
 # close button inside ConditionalPanel component
 editor.conditionalPanel.close=Cancel edit breakpoint and close
 
 # LOCALIZATION NOTE (editor.jumpToMappedLocation1): Context menu item
 # for navigating to a source mapped location
-editor.jumpToMappedLocation1=Jump to %S location
+editor.jumpToMappedLocation1=Jump to %S Location
 
 # LOCALIZATION NOTE (framework.disableGrouping): This is the text that appears in the
 # context menu to disable framework grouping.
 framework.disableGrouping=Disable Framework Grouping
 framework.disableGrouping.accesskey=u
 
 # LOCALIZATION NOTE (framework.enableGrouping): This is the text that appears in the
 # context menu to enable framework grouping.
 framework.enableGrouping=Enable Framework Grouping
 framework.enableGrouping.accesskey=u
 
 # LOCALIZATION NOTE (generated): Source Map term for a server source location
-generated=generated
+generated=Generated
 
 # LOCALIZATION NOTE (original): Source Map term for a debugger UI source location
-original=original
+original=Original
 
 # LOCALIZATION NOTE (expressions.placeholder): Placeholder text for expression
 # input element
 expressions.placeholder=Add Watch Expression
 
 # LOCALIZATION NOTE (sourceTabs.closeTab): Editor source tab context menu item
 # for closing the selected tab below the mouse.
-sourceTabs.closeTab=Close tab
+sourceTabs.closeTab=Close Tab
 sourceTabs.closeTab.accesskey=c
 
 # LOCALIZATION NOTE (sourceTabs.closeOtherTabs): Editor source tab context menu item
 # for closing the other tabs.
-sourceTabs.closeOtherTabs=Close others
+sourceTabs.closeOtherTabs=Close Other Tabs
 sourceTabs.closeOtherTabs.accesskey=o
 
 # LOCALIZATION NOTE (sourceTabs.closeTabsToEnd): Editor source tab context menu item
 # for closing the tabs to the end (the right for LTR languages) of the selected tab.
-sourceTabs.closeTabsToEnd=Close tabs to the right
+sourceTabs.closeTabsToEnd=Close Tabs to the Right
 sourceTabs.closeTabsToEnd.accesskey=e
 
 # LOCALIZATION NOTE (sourceTabs.closeAllTabs): Editor source tab context menu item
 # for closing all tabs.
-sourceTabs.closeAllTabs=Close all tabs
+sourceTabs.closeAllTabs=Close All Tabs
 sourceTabs.closeAllTabs.accesskey=a
 
 # LOCALIZATION NOTE (sourceTabs.revealInTree): Editor source tab context menu item
 # for revealing source in tree.
 sourceTabs.revealInTree=Reveal in Tree
 sourceTabs.revealInTree.accesskey=r
 
 # LOCALIZATION NOTE (sourceTabs.copyLink): Editor source tab context menu item
@@ -427,16 +445,19 @@ scopes.notPaused=Not Paused
 scopes.block=Block
 
 # LOCALIZATION NOTE (sources.header): Sources left sidebar header
 sources.header=Sources
 
 # LOCALIZATION NOTE (outline.header): Outline left sidebar header
 outline.header=Outline
 
+# LOCALIZATION NOTE (outline.noFunctions): Outline text when there are no functions to display
+outline.noFunctions=No functions
+
 # LOCALIZATION NOTE (sources.search): Sources left sidebar prompt
 # e.g. Cmd+P to search. On a mac, we use the command unicode character.
 # On windows, it's ctrl.
 sources.search=%S to search
 
 # LOCALIZATION NOTE (watchExpressions.header): Watch Expressions right sidebar
 # pane header.
 watchExpressions.header=Watch Expressions
--- a/devtools/client/preferences/debugger.js
+++ b/devtools/client/preferences/debugger.js
@@ -35,8 +35,9 @@ pref("devtools.debugger.tabs", "[]");
 pref("devtools.debugger.pending-selected-location", "{}");
 pref("devtools.debugger.pending-breakpoints", "{}");
 pref("devtools.debugger.expressions", "[]");
 pref("devtools.debugger.file-search-case-sensitive", false);
 pref("devtools.debugger.file-search-whole-word", false);
 pref("devtools.debugger.file-search-regex-match", false);
 pref("devtools.debugger.features.async-stepping", true);
 pref("devtools.debugger.project-text-search-enabled", true);
+pref("devtools.debugger.features.wasm", true);
--- a/devtools/client/shared/source-map/index.js
+++ b/devtools/client/shared/source-map/index.js
@@ -67,30 +67,32 @@ return /******/ (function(modules) { // 
 
 	const { workerUtils: { WorkerDispatcher } } = __webpack_require__(6);
 
 	const dispatcher = new WorkerDispatcher();
 
 	const getOriginalURLs = dispatcher.task("getOriginalURLs");
 	const getGeneratedLocation = dispatcher.task("getGeneratedLocation");
 	const getOriginalLocation = dispatcher.task("getOriginalLocation");
+	const getLocationScopes = dispatcher.task("getLocationScopes");
 	const getOriginalSourceText = dispatcher.task("getOriginalSourceText");
 	const applySourceMap = dispatcher.task("applySourceMap");
 	const clearSourceMaps = dispatcher.task("clearSourceMaps");
 	const hasMappedSource = dispatcher.task("hasMappedSource");
 
 	module.exports = {
 	  originalToGeneratedId,
 	  generatedToOriginalId,
 	  isGeneratedId,
 	  isOriginalId,
 	  hasMappedSource,
 	  getOriginalURLs,
 	  getGeneratedLocation,
 	  getOriginalLocation,
+	  getLocationScopes,
 	  getOriginalSourceText,
 	  applySourceMap,
 	  clearSourceMaps,
 	  startSourceMapWorker: dispatcher.start.bind(dispatcher),
 	  stopSourceMapWorker: dispatcher.stop.bind(dispatcher)
 	};
 
 /***/ },
@@ -550,16 +552,20 @@ return /******/ (function(modules) { // 
 	        const id = this.msgId++;
 	        this.worker.postMessage({ id, method, args });
 
 	        const listener = ({ data: result }) => {
 	          if (result.id !== id) {
 	            return;
 	          }
 
+	          if (!this.worker) {
+	            reject("Oops, The worker has shutdown!");
+	            return;
+	          }
 	          this.worker.removeEventListener("message", listener);
 	          if (result.error) {
 	            reject(result.error);
 	          } else {
 	            resolve(result.response);
 	          }
 	        };
 
--- a/devtools/client/shared/source-map/worker.js
+++ b/devtools/client/shared/source-map/worker.js
@@ -58,29 +58,32 @@ return /******/ (function(modules) { // 
 	 * License, v. 2.0. If a copy of the MPL was not distributed with this
 	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 	const {
 	  getOriginalURLs,
 	  getGeneratedLocation,
 	  getOriginalLocation,
 	  getOriginalSourceText,
+	  getLocationScopes,
 	  hasMappedSource,
-	  applySourceMap,
-	  clearSourceMaps
+	  applySourceMap
 	} = __webpack_require__(9);
 
+	const { clearSourceMaps } = __webpack_require__(24);
+
 	const { workerUtils: { workerHandler } } = __webpack_require__(6);
 
 	// The interface is implemented in source-map to be
 	// easier to unit test.
 	self.onmessage = workerHandler({
 	  getOriginalURLs,
 	  getGeneratedLocation,
 	  getOriginalLocation,
+	  getLocationScopes,
 	  getOriginalSourceText,
 	  hasMappedSource,
 	  applySourceMap,
 	  clearSourceMaps
 	});
 
 /***/ },
 /* 1 */
@@ -539,16 +542,20 @@ return /******/ (function(modules) { // 
 	        const id = this.msgId++;
 	        this.worker.postMessage({ id, method, args });
 
 	        const listener = ({ data: result }) => {
 	          if (result.id !== id) {
 	            return;
 	          }
 
+	          if (!this.worker) {
+	            reject("Oops, The worker has shutdown!");
+	            return;
+	          }
 	          this.worker.removeEventListener("message", listener);
 	          if (result.error) {
 	            reject(result.error);
 	          } else {
 	            resolve(result.response);
 	          }
 	        };
 
@@ -636,335 +643,245 @@ return /******/ (function(modules) { // 
 	  workerHandler,
 	  streamingWorkerHandler
 	};
 
 /***/ },
 /* 9 */
 /***/ function(module, exports, __webpack_require__) {
 
-	let _resolveAndFetch = (() => {
+	let getOriginalURLs = (() => {
 	  var _ref = _asyncToGenerator(function* (generatedSource) {
-	    // Fetch the sourcemap over the network and create it.
-	    const sourceMapURL = _resolveSourceMapURL(generatedSource);
-	    const fetched = yield networkRequest(sourceMapURL, { loadFromCache: false });
-
-	    // Create the source map and fix it up.
-	    let map = new SourceMapConsumer(fetched.content);
-	    if (generatedSource.isWasm) {
-	      map = new WasmRemap(map);
-	    }
-
-	    _setSourceMapRoot(map, sourceMapURL, generatedSource);
-	    return map;
-	  });
-
-	  return function _resolveAndFetch(_x) {
-	    return _ref.apply(this, arguments);
-	  };
-	})();
-
-	let getOriginalURLs = (() => {
-	  var _ref2 = _asyncToGenerator(function* (generatedSource) {
-	    const map = yield _fetchSourceMap(generatedSource);
+	    const map = yield fetchSourceMap(generatedSource);
 	    return map && map.sources;
 	  });
 
-	  return function getOriginalURLs(_x2) {
-	    return _ref2.apply(this, arguments);
+	  return function getOriginalURLs(_x) {
+	    return _ref.apply(this, arguments);
 	  };
 	})();
 
 	let getGeneratedLocation = (() => {
-	  var _ref3 = _asyncToGenerator(function* (location, originalSource) {
+	  var _ref2 = _asyncToGenerator(function* (location, originalSource) {
 	    if (!isOriginalId(location.sourceId)) {
 	      return location;
 	    }
 
 	    const generatedSourceId = originalToGeneratedId(location.sourceId);
-	    const map = yield _getSourceMap(generatedSourceId);
+	    const map = yield getSourceMap(generatedSourceId);
 	    if (!map) {
 	      return location;
 	    }
 
 	    const { line, column } = map.generatedPositionFor({
 	      source: originalSource.url,
 	      line: location.line,
 	      column: location.column == null ? 0 : location.column,
 	      bias: SourceMapConsumer.LEAST_UPPER_BOUND
 	    });
 
 	    return {
 	      sourceId: generatedSourceId,
-	      line: line,
-	      // Treat 0 as no column so that line breakpoints work correctly.
-	      column: column === 0 ? undefined : column
+	      line,
+	      column
 	    };
 	  });
 
-	  return function getGeneratedLocation(_x3, _x4) {
-	    return _ref3.apply(this, arguments);
+	  return function getGeneratedLocation(_x2, _x3) {
+	    return _ref2.apply(this, arguments);
 	  };
 	})();
 
 	let getOriginalLocation = (() => {
-	  var _ref4 = _asyncToGenerator(function* (location) {
+	  var _ref3 = _asyncToGenerator(function* (location) {
 	    if (!isGeneratedId(location.sourceId)) {
 	      return location;
 	    }
 
-	    const map = yield _getSourceMap(location.sourceId);
+	    const map = yield getSourceMap(location.sourceId);
 	    if (!map) {
 	      return location;
 	    }
 
-	    const { source: url, line, column } = map.originalPositionFor({
+	    const { source: sourceUrl, line, column } = map.originalPositionFor({
 	      line: location.line,
-	      column: location.column == null ? Infinity : location.column
+	      column: location.column == null ? 0 : location.column
 	    });
 
-	    if (url == null) {
+	    if (sourceUrl == null) {
 	      // No url means the location didn't map.
 	      return location;
 	    }
 
 	    return {
-	      sourceId: generatedToOriginalId(location.sourceId, url),
-	      sourceUrl: url,
+	      sourceId: generatedToOriginalId(location.sourceId, sourceUrl),
+	      sourceUrl,
 	      line,
 	      column
 	    };
 	  });
 
-	  return function getOriginalLocation(_x5) {
-	    return _ref4.apply(this, arguments);
+	  return function getOriginalLocation(_x4) {
+	    return _ref3.apply(this, arguments);
 	  };
 	})();
 
 	let getOriginalSourceText = (() => {
-	  var _ref5 = _asyncToGenerator(function* (originalSource) {
+	  var _ref4 = _asyncToGenerator(function* (originalSource) {
 	    assert(isOriginalId(originalSource.id), "Source is not an original source");
 
 	    const generatedSourceId = originalToGeneratedId(originalSource.id);
-	    const map = yield _getSourceMap(generatedSourceId);
+	    const map = yield getSourceMap(generatedSourceId);
 	    if (!map) {
 	      return null;
 	    }
 
 	    let text = map.sourceContentFor(originalSource.url);
 	    if (!text) {
 	      text = (yield networkRequest(originalSource.url, { loadFromCache: false })).content;
 	    }
 
 	    return {
 	      text,
 	      contentType: getContentType(originalSource.url || "")
 	    };
 	  });
 
-	  return function getOriginalSourceText(_x6) {
+	  return function getOriginalSourceText(_x5) {
+	    return _ref4.apply(this, arguments);
+	  };
+	})();
+
+	/**
+	 * Finds the scope binding information at the source map based on locations and
+	 * generated source scopes. The generated source scopes contain variables names
+	 * and all their references in the generated source. This information is merged
+	 * with the source map original names information and returned as result.
+	 * @memberof utils/source-map-worker
+	 * @static
+	 */
+
+
+	let getLocationScopes = (() => {
+	  var _ref5 = _asyncToGenerator(function* (location, generatedSourceScopes) {
+	    if (!isGeneratedId(location.sourceId)) {
+	      return null;
+	    }
+
+	    const map = yield getSourceMap(location.sourceId);
+	    if (!map) {
+	      return null;
+	    }
+
+	    return getLocationScopesFromMap(map, generatedSourceScopes, location);
+	  });
+
+	  return function getLocationScopes(_x6, _x7) {
 	    return _ref5.apply(this, arguments);
 	  };
 	})();
 
 	let hasMappedSource = (() => {
 	  var _ref6 = _asyncToGenerator(function* (location) {
 	    if (isOriginalId(location.sourceId)) {
 	      return true;
 	    }
 
 	    const loc = yield getOriginalLocation(location);
 	    return loc.sourceId !== location.sourceId;
 	  });
 
-	  return function hasMappedSource(_x7) {
+	  return function hasMappedSource(_x8) {
 	    return _ref6.apply(this, arguments);
 	  };
 	})();
 
 	function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
 
 	/* This Source Code Form is subject to the terms of the Mozilla Public
 	 * License, v. 2.0. If a copy of the MPL was not distributed with this
 	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 	/**
 	 * Source Map Worker
 	 * @module utils/source-map-worker
 	 */
 
 	const { networkRequest } = __webpack_require__(6);
-
-	const path = __webpack_require__(10);
-	const { SourceMapConsumer, SourceMapGenerator } = __webpack_require__(11);
+	const { SourceMapConsumer, SourceMapGenerator } = __webpack_require__(10);
+	const path = __webpack_require__(21);
+
 	const assert = __webpack_require__(22);
+	const { fetchSourceMap } = __webpack_require__(23);
+	const {
+	  getSourceMap,
+	  setSourceMap,
+	  clearSourceMaps
+	} = __webpack_require__(24);
 	const {
 	  originalToGeneratedId,
 	  generatedToOriginalId,
 	  isGeneratedId,
 	  isOriginalId,
 	  getContentType
 	} = __webpack_require__(1);
-	const { WasmRemap } = __webpack_require__(23);
-
-	let sourceMapRequests = new Map();
-
-	function clearSourceMaps() {
-	  sourceMapRequests.clear();
-	}
-
-	function _resolveSourceMapURL(source) {
-	  const { url = "", sourceMapURL = "" } = source;
-	  if (path.isURL(sourceMapURL) || url == "") {
-	    // If it's already a full URL or the source doesn't have a URL,
-	    // don't resolve anything.
-	    return sourceMapURL;
-	  } else if (path.isAbsolute(sourceMapURL)) {
-	    // If it's an absolute path, it should be resolved relative to the
-	    // host of the source.
-	    const { protocol = "", host = "" } = new URL(url);
-	    return `${protocol}//${host}${sourceMapURL}`;
-	  }
-	  // Otherwise, it's a relative path and should be resolved relative
-	  // to the source.
-	  return `${path.dirname(url)}/${sourceMapURL}`;
-	}
-
-	/**
-	 * Sets the source map's sourceRoot to be relative to the source map url.
-	 * @memberof utils/source-map-worker
-	 * @static
-	 */
-	function _setSourceMapRoot(sourceMap, absSourceMapURL, source) {
-	  // No need to do this fiddling if we won't be fetching any sources over the
-	  // wire.
-	  if (sourceMap.hasContentsOfAllSources()) {
-	    return;
-	  }
-
-	  // If it's already a URL, just leave it alone.
-	  if (!path.isURL(sourceMap.sourceRoot)) {
-	    // In the odd case where the sourceMap is a data: URL and it does
-	    // not contain the full sources, fall back to using the source's
-	    // URL, if possible.
-	    let parsedSourceMapURL = new URL(absSourceMapURL);
-	    if (parsedSourceMapURL.protocol === "data:" && source.url) {
-	      parsedSourceMapURL = new URL(source.url);
-	    }
-
-	    parsedSourceMapURL.pathname = path.dirname(parsedSourceMapURL.pathname);
-	    sourceMap.sourceRoot = new URL(sourceMap.sourceRoot || "", parsedSourceMapURL).toString();
-	  }
-	  return sourceMap.sourceRoot;
-	}
-
-	function _getSourceMap(generatedSourceId) {
-	  return sourceMapRequests.get(generatedSourceId);
-	}
-
-	function _fetchSourceMap(generatedSource) {
-	  const existingRequest = sourceMapRequests.get(generatedSource.id);
-	  if (existingRequest) {
-	    // If it has already been requested, return the request. Make sure
-	    // to do this even if sourcemapping is turned off, because
-	    // pretty-printing uses sourcemaps.
-	    //
-	    // An important behavior here is that if it's in the middle of
-	    // requesting it, all subsequent calls will block on the initial
-	    // request.
-	    return existingRequest;
-	  } else if (!generatedSource.sourceMapURL) {
-	    return Promise.resolve(null);
-	  }
-
-	  // Fire off the request, set it in the cache, and return it.
-	  const req = _resolveAndFetch(generatedSource);
-	  // Make sure the cached promise does not reject, because we only
-	  // want to report the error once.
-	  sourceMapRequests.set(generatedSource.id, req.catch(() => null));
-	  return req;
-	}
+	const {
+	  getLocationScopes: getLocationScopesFromMap
+	} = __webpack_require__(26);
+
+	const { WasmRemap } = __webpack_require__(25);
 
 	function applySourceMap(generatedId, url, code, mappings) {
 	  const generator = new SourceMapGenerator({ file: url });
 	  mappings.forEach(mapping => generator.addMapping(mapping));
 	  generator.setSourceContent(url, code);
 
 	  const map = SourceMapConsumer(generator.toJSON());
-	  sourceMapRequests.set(generatedId, Promise.resolve(map));
+	  setSourceMap(generatedId, Promise.resolve(map));
 	}
 
 	module.exports = {
 	  getOriginalURLs,
 	  getGeneratedLocation,
 	  getOriginalLocation,
 	  getOriginalSourceText,
+	  getLocationScopes,
 	  applySourceMap,
 	  clearSourceMaps,
 	  hasMappedSource
 	};
 
 /***/ },
 /* 10 */
-/***/ function(module, exports) {
-
-	/* This Source Code Form is subject to the terms of the Mozilla Public
-	 * License, v. 2.0. If a copy of the MPL was not distributed with this
-	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-	function dirname(path) {
-	  const idx = path.lastIndexOf("/");
-	  return path.slice(0, idx);
-	}
-
-	function isURL(str) {
-	  try {
-	    new URL(str);
-	    return true;
-	  } catch (e) {
-	    return false;
-	  }
-	}
-
-	function isAbsolute(str) {
-	  return str[0] === "/";
-	}
-
-	module.exports = {
-	  dirname, isURL, isAbsolute
-	};
-
-/***/ },
-/* 11 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/*
 	 * Copyright 2009-2011 Mozilla Foundation and contributors
 	 * Licensed under the New BSD license. See LICENSE.txt or:
 	 * http://opensource.org/licenses/BSD-3-Clause
 	 */
-	exports.SourceMapGenerator = __webpack_require__(12).SourceMapGenerator;
-	exports.SourceMapConsumer = __webpack_require__(18).SourceMapConsumer;
-	exports.SourceNode = __webpack_require__(21).SourceNode;
+	exports.SourceMapGenerator = __webpack_require__(11).SourceMapGenerator;
+	exports.SourceMapConsumer = __webpack_require__(17).SourceMapConsumer;
+	exports.SourceNode = __webpack_require__(20).SourceNode;
 
 /***/ },
-/* 12 */
+/* 11 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/* -*- Mode: js; js-indent-level: 2; -*- */
 	/*
 	 * Copyright 2011 Mozilla Foundation and contributors
 	 * Licensed under the New BSD license. See LICENSE or:
 	 * http://opensource.org/licenses/BSD-3-Clause
 	 */
 
-	var base64VLQ = __webpack_require__(13);
-	var util = __webpack_require__(15);
-	var ArraySet = __webpack_require__(16).ArraySet;
-	var MappingList = __webpack_require__(17).MappingList;
+	var base64VLQ = __webpack_require__(12);
+	var util = __webpack_require__(14);
+	var ArraySet = __webpack_require__(15).ArraySet;
+	var MappingList = __webpack_require__(16).MappingList;
 
 	/**
 	 * An instance of the SourceMapGenerator represents a source map which is
 	 * being built incrementally. You may pass an object with the following
 	 * properties:
 	 *
 	 *   - file: The filename of the generated source.
 	 *   - sourceRoot: A root for all relative URLs in this source map.
@@ -1322,17 +1239,17 @@ return /******/ (function(modules) { // 
 	 */
 	SourceMapGenerator.prototype.toString = function SourceMapGenerator_toString() {
 	  return JSON.stringify(this.toJSON());
 	};
 
 	exports.SourceMapGenerator = SourceMapGenerator;
 
 /***/ },
-/* 13 */
+/* 12 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/* -*- Mode: js; js-indent-level: 2; -*- */
 	/*
 	 * Copyright 2011 Mozilla Foundation and contributors
 	 * Licensed under the New BSD license. See LICENSE or:
 	 * http://opensource.org/licenses/BSD-3-Clause
 	 *
@@ -1362,17 +1279,17 @@ return /******/ (function(modules) { // 
 	 * 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.
 	 */
 
-	var base64 = __webpack_require__(14);
+	var base64 = __webpack_require__(13);
 
 	// A single base 64 digit can contain 6 bits of data. For the base 64 variable
 	// length quantities we use in the source map spec, the first bit is the sign,
 	// the next four bits are the actual value, and the 6th bit is the
 	// continuation bit. The continuation bit tells us whether there are more
 	// digits in this value following this digit.
 	//
 	//   Continuation
@@ -1463,17 +1380,17 @@ return /******/ (function(modules) { // 
 	    shift += VLQ_BASE_SHIFT;
 	  } while (continuation);
 
 	  aOutParam.value = fromVLQSigned(result);
 	  aOutParam.rest = aIndex;
 	};
 
 /***/ },
-/* 14 */
+/* 13 */
 /***/ function(module, exports) {
 
 	/* -*- Mode: js; js-indent-level: 2; -*- */
 	/*
 	 * Copyright 2011 Mozilla Foundation and contributors
 	 * Licensed under the New BSD license. See LICENSE or:
 	 * http://opensource.org/licenses/BSD-3-Clause
 	 */
@@ -1535,17 +1452,17 @@ return /******/ (function(modules) { // 
 	    return 63;
 	  }
 
 	  // Invalid base64 digit.
 	  return -1;
 	};
 
 /***/ },
-/* 15 */
+/* 14 */
 /***/ function(module, exports) {
 
 	/* -*- Mode: js; js-indent-level: 2; -*- */
 	/*
 	 * Copyright 2011 Mozilla Foundation and contributors
 	 * Licensed under the New BSD license. See LICENSE or:
 	 * http://opensource.org/licenses/BSD-3-Clause
 	 */
@@ -1947,27 +1864,27 @@ return /******/ (function(modules) { // 
 	    return cmp;
 	  }
 
 	  return strcmp(mappingA.name, mappingB.name);
 	}
 	exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
 
 /***/ },
-/* 16 */
+/* 15 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/* -*- Mode: js; js-indent-level: 2; -*- */
 	/*
 	 * Copyright 2011 Mozilla Foundation and contributors
 	 * Licensed under the New BSD license. See LICENSE or:
 	 * http://opensource.org/licenses/BSD-3-Clause
 	 */
 
-	var util = __webpack_require__(15);
+	var util = __webpack_require__(14);
 	var has = Object.prototype.hasOwnProperty;
 
 	/**
 	 * A data structure which is a combination of an array and a set. Adding a new
 	 * member is O(1), testing for membership is O(1), and finding the index of an
 	 * element is O(1). Removing elements from the set is not supported. Only
 	 * strings are supported for membership.
 	 */
@@ -2056,27 +1973,27 @@ return /******/ (function(modules) { // 
 	 */
 	ArraySet.prototype.toArray = function ArraySet_toArray() {
 	  return this._array.slice();
 	};
 
 	exports.ArraySet = ArraySet;
 
 /***/ },
-/* 17 */
+/* 16 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/* -*- Mode: js; js-indent-level: 2; -*- */
 	/*
 	 * Copyright 2014 Mozilla Foundation and contributors
 	 * Licensed under the New BSD license. See LICENSE or:
 	 * http://opensource.org/licenses/BSD-3-Clause
 	 */
 
-	var util = __webpack_require__(15);
+	var util = __webpack_require__(14);
 
 	/**
 	 * Determine whether mappingB is after mappingA with respect to generated
 	 * position.
 	 */
 	function generatedPositionAfter(mappingA, mappingB) {
 	  // Optimized for most common case
 	  var lineA = mappingA.generatedLine;
@@ -2138,31 +2055,31 @@ return /******/ (function(modules) { // 
 	    this._sorted = true;
 	  }
 	  return this._array;
 	};
 
 	exports.MappingList = MappingList;
 
 /***/ },
-/* 18 */
+/* 17 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/* -*- Mode: js; js-indent-level: 2; -*- */
 	/*
 	 * Copyright 2011 Mozilla Foundation and contributors
 	 * Licensed under the New BSD license. See LICENSE or:
 	 * http://opensource.org/licenses/BSD-3-Clause
 	 */
 
-	var util = __webpack_require__(15);
-	var binarySearch = __webpack_require__(19);
-	var ArraySet = __webpack_require__(16).ArraySet;
-	var base64VLQ = __webpack_require__(13);
-	var quickSort = __webpack_require__(20).quickSort;
+	var util = __webpack_require__(14);
+	var binarySearch = __webpack_require__(18);
+	var ArraySet = __webpack_require__(15).ArraySet;
+	var base64VLQ = __webpack_require__(12);
+	var quickSort = __webpack_require__(19).quickSort;
 
 	function SourceMapConsumer(aSourceMap) {
 	  var sourceMap = aSourceMap;
 	  if (typeof aSourceMap === 'string') {
 	    sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
 	  }
 
 	  return sourceMap.sections != null ? new IndexedSourceMapConsumer(sourceMap) : new BasicSourceMapConsumer(sourceMap);
@@ -3157,17 +3074,17 @@ return /******/ (function(modules) { // 
 
 	  quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated);
 	  quickSort(this.__originalMappings, util.compareByOriginalPositions);
 	};
 
 	exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer;
 
 /***/ },
-/* 19 */
+/* 18 */
 /***/ function(module, exports) {
 
 	/* -*- Mode: js; js-indent-level: 2; -*- */
 	/*
 	 * Copyright 2011 Mozilla Foundation and contributors
 	 * Licensed under the New BSD license. See LICENSE or:
 	 * http://opensource.org/licenses/BSD-3-Clause
 	 */
@@ -3270,17 +3187,17 @@ return /******/ (function(modules) { // 
 	    }
 	    --index;
 	  }
 
 	  return index;
 	};
 
 /***/ },
-/* 20 */
+/* 19 */
 /***/ function(module, exports) {
 
 	/* -*- Mode: js; js-indent-level: 2; -*- */
 	/*
 	 * Copyright 2011 Mozilla Foundation and contributors
 	 * Licensed under the New BSD license. See LICENSE or:
 	 * http://opensource.org/licenses/BSD-3-Clause
 	 */
@@ -3389,28 +3306,28 @@ return /******/ (function(modules) { // 
 	 * @param {function} comparator
 	 *        Function to use to compare two items.
 	 */
 	exports.quickSort = function (ary, comparator) {
 	  doQuickSort(ary, comparator, 0, ary.length - 1);
 	};
 
 /***/ },
-/* 21 */
+/* 20 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/* -*- Mode: js; js-indent-level: 2; -*- */
 	/*
 	 * Copyright 2011 Mozilla Foundation and contributors
 	 * Licensed under the New BSD license. See LICENSE or:
 	 * http://opensource.org/licenses/BSD-3-Clause
 	 */
 
-	var SourceMapGenerator = __webpack_require__(12).SourceMapGenerator;
-	var util = __webpack_require__(15);
+	var SourceMapGenerator = __webpack_require__(11).SourceMapGenerator;
+	var util = __webpack_require__(14);
 
 	// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other
 	// operating systems these days (capturing the result).
 	var REGEX_NEWLINE = /(\r?\n)/;
 
 	// Newline character code for charCodeAt() comparisons
 	var NEWLINE_CODE = 10;
 
@@ -3775,16 +3692,46 @@ return /******/ (function(modules) { // 
 	  });
 
 	  return { code: generated.code, map: map };
 	};
 
 	exports.SourceNode = SourceNode;
 
 /***/ },
+/* 21 */
+/***/ function(module, exports) {
+
+	/* This Source Code Form is subject to the terms of the Mozilla Public
+	 * License, v. 2.0. If a copy of the MPL was not distributed with this
+	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+	function dirname(path) {
+	  const idx = path.lastIndexOf("/");
+	  return path.slice(0, idx);
+	}
+
+	function isURL(str) {
+	  try {
+	    new URL(str);
+	    return true;
+	  } catch (e) {
+	    return false;
+	  }
+	}
+
+	function isAbsolute(str) {
+	  return str[0] === "/";
+	}
+
+	module.exports = {
+	  dirname, isURL, isAbsolute
+	};
+
+/***/ },
 /* 22 */
 /***/ function(module, exports) {
 
 	/* This Source Code Form is subject to the terms of the Mozilla Public
 	 * License, v. 2.0. If a copy of the MPL was not distributed with this
 	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 	function assert(condition, message) {
@@ -3792,16 +3739,157 @@ return /******/ (function(modules) { // 
 	    throw new Error(`Assertion failure: ${message}`);
 	  }
 	}
 
 	module.exports = assert;
 
 /***/ },
 /* 23 */
+/***/ function(module, exports, __webpack_require__) {
+
+	let _resolveAndFetch = (() => {
+	  var _ref = _asyncToGenerator(function* (generatedSource) {
+	    // Fetch the sourcemap over the network and create it.
+	    const sourceMapURL = _resolveSourceMapURL(generatedSource);
+
+	    const fetched = yield networkRequest(sourceMapURL, { loadFromCache: false });
+
+	    // Create the source map and fix it up.
+	    let map = new SourceMapConsumer(fetched.content);
+	    if (generatedSource.isWasm) {
+	      map = new WasmRemap(map);
+	    }
+
+	    _setSourceMapRoot(map, sourceMapURL, generatedSource);
+	    return map;
+	  });
+
+	  return function _resolveAndFetch(_x) {
+	    return _ref.apply(this, arguments);
+	  };
+	})();
+
+	function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
+
+	/* This Source Code Form is subject to the terms of the Mozilla Public
+	 * License, v. 2.0. If a copy of the MPL was not distributed with this
+	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+	const { networkRequest } = __webpack_require__(6);
+	const { getSourceMap, setSourceMap } = __webpack_require__(24);
+	const { WasmRemap } = __webpack_require__(25);
+	const { SourceMapConsumer } = __webpack_require__(10);
+
+	const path = __webpack_require__(21);
+
+	/**
+	 * Sets the source map's sourceRoot to be relative to the source map url.
+	 * @memberof utils/source-map-worker
+	 * @static
+	 */
+	function _setSourceMapRoot(sourceMap, absSourceMapURL, source) {
+	  // No need to do this fiddling if we won't be fetching any sources over the
+	  // wire.
+	  if (sourceMap.hasContentsOfAllSources()) {
+	    return;
+	  }
+
+	  // If it's already a URL, just leave it alone.
+	  if (!path.isURL(sourceMap.sourceRoot)) {
+	    // In the odd case where the sourceMap is a data: URL and it does
+	    // not contain the full sources, fall back to using the source's
+	    // URL, if possible.
+	    let parsedSourceMapURL = new URL(absSourceMapURL);
+
+	    if (parsedSourceMapURL.protocol === "data:" && source.url) {
+	      parsedSourceMapURL = new URL(source.url);
+	    }
+
+	    parsedSourceMapURL.pathname = path.dirname(parsedSourceMapURL.pathname);
+	    sourceMap.sourceRoot = new URL(sourceMap.sourceRoot || "", parsedSourceMapURL).toString();
+	  }
+	  return sourceMap.sourceRoot;
+	}
+
+	function _resolveSourceMapURL(source) {
+	  const { url = "", sourceMapURL = "" } = source;
+	  if (path.isURL(sourceMapURL) || url == "") {
+	    // If it's already a full URL or the source doesn't have a URL,
+	    // don't resolve anything.
+	    return sourceMapURL;
+	  }
+
+	  if (path.isAbsolute(sourceMapURL)) {
+	    // If it's an absolute path, it should be resolved relative to the
+	    // host of the source.
+	    const { protocol = "", host = "" } = new URL(url);
+	    return `${protocol}//${host}${sourceMapURL}`;
+	  }
+
+	  // Otherwise, it's a relative path and should be resolved relative
+	  // to the source.
+	  return `${path.dirname(url)}/${sourceMapURL}`;
+	}
+
+	function fetchSourceMap(generatedSource) {
+	  const existingRequest = getSourceMap(generatedSource.id);
+
+	  // If it has already been requested, return the request. Make sure
+	  // to do this even if sourcemapping is turned off, because
+	  // pretty-printing uses sourcemaps.
+	  //
+	  // An important behavior here is that if it's in the middle of
+	  // requesting it, all subsequent calls will block on the initial
+	  // request.
+	  if (existingRequest) {
+	    return existingRequest;
+	  }
+
+	  if (!generatedSource.sourceMapURL) {
+	    return Promise.resolve(null);
+	  }
+
+	  // Fire off the request, set it in the cache, and return it.
+	  const req = _resolveAndFetch(generatedSource);
+	  // Make sure the cached promise does not reject, because we only
+	  // want to report the error once.
+	  setSourceMap(generatedSource.id, req.catch(() => null));
+	  return req;
+	}
+
+	module.exports = { fetchSourceMap };
+
+/***/ },
+/* 24 */
+/***/ function(module, exports) {
+
+	
+	let sourceMapRequests = new Map();
+
+	function clearSourceMaps() {
+	  sourceMapRequests.clear();
+	}
+
+	function getSourceMap(generatedSourceId) {
+	  return sourceMapRequests.get(generatedSourceId);
+	}
+
+	function setSourceMap(generatedId, request) {
+	  sourceMapRequests.set(generatedId, request);
+	}
+
+	module.exports = {
+	  clearSourceMaps,
+	  getSourceMap,
+	  setSourceMap
+	};
+
+/***/ },
+/* 25 */
 /***/ function(module, exports) {
 
 	/* This Source Code Form is subject to the terms of the Mozilla Public
 	 * License, v. 2.0. If a copy of the MPL was not distributed with this
 	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 	"use strict";
 
@@ -3911,12 +3999,3014 @@ return /******/ (function(modules) { // 
 	        name
 	      });
 	    }, context, order);
 	  }
 	}
 
 	exports.WasmRemap = WasmRemap;
 
+/***/ },
+/* 26 */
+/***/ function(module, exports, __webpack_require__) {
+
+	/* This Source Code Form is subject to the terms of the Mozilla Public
+	 * License, v. 2.0. If a copy of the MPL was not distributed with this
+	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+	const { SourceMapConsumer } = __webpack_require__(27);
+
+	function comparePositions(a, b) {
+	  if (a.line === b.line) {
+	    return a.column - b.column;
+	  } else {
+	    return a.line - b.line;
+	  }
+	}
+
+	function getOriginalPositionName(map, generatedPosition) {
+	  const originalPosition = map.originalPositionFor(generatedPosition);
+	  if (!originalPosition || !originalPosition.name) {
+	    return null;
+	  }
+	  // Verify if it's the exact position.
+	  const originalPositionTest = map.originalPositionFor({
+	    line: generatedPosition.line,
+	    column: generatedPosition.column,
+	    bias: SourceMapConsumer.LEAST_UPPER_BOUND
+	  });
+	  if (!originalPositionTest || originalPositionTest.column !== originalPosition.column || originalPositionTest.line !== originalPosition.line) {
+	    return null;
+	  }
+	  return originalPosition.name;
+	}
+
+	// The `scope` has bindings that contains positions/references to the
+	// generated names (these may has different original name). Going over all
+	// these names and positions, to check what original name is listed there.
+	// To make things more interesting the same generated name can potentially
+	// be used for different original names, so building trackedBindings for all
+	// names and positions.
+	// Example of MappedScopeBindings:
+	// ```
+	// { type: 'block',
+	//   bindings: {
+	//     'current': 't',
+	//     'start': 't',
+	//     'end': 'e'
+	//   } }
+	// ```
+
+	function applyBestNamePosition(trackedBindings, generatedName, nameLocation, map, currentPosition) {
+	  const namePosition = {
+	    line: nameLocation.line,
+	    column: nameLocation.column || 0
+	  };
+	  const originalName = getOriginalPositionName(map, namePosition);
+	  if (!originalName) {
+	    return trackedBindings;
+	  }
+
+	  let trackedBinding = trackedBindings[originalName];
+	  if (!trackedBinding) {
+	    // No best position was found for original name yet -- using first
+	    // found position.
+	    trackedBindings[originalName] = {
+	      generatedName,
+	      bestPosition: namePosition
+	    };
+	  } else if (comparePositions(namePosition, currentPosition) <= 0) {
+	    // The position is before location, the more recient will have needed
+	    // name assignment, also discard all positions past currentPosition.
+	    if (comparePositions(trackedBinding.bestPosition, namePosition) < 0 || comparePositions(trackedBinding.bestPosition, currentPosition) > 0) {
+	      trackedBinding.generatedName = generatedName;
+	      trackedBinding.bestPosition = namePosition;
+	    }
+	  } else {
+	    // The position is past location, need to select more recient after
+	    // specified location, but only if "before" bestPosition is not found.
+	    if (comparePositions(trackedBinding.bestPosition, namePosition) > 0 && comparePositions(trackedBinding.bestPosition, currentPosition) < 0) {
+	      trackedBinding.generatedName = generatedName;
+	      trackedBinding.bestPosition = namePosition;
+	    }
+	  }
+	  return trackedBindings;
+	}
+
+	function applyTrackedBindings(trackedBindings, generatedName, locations, map, currentPosition) {
+	  return locations.reduce((trackedBindings, nameLocation) => applyBestNamePosition(trackedBindings, generatedName, nameLocation, map, currentPosition), trackedBindings);
+	}
+
+	/**
+	 * Finds the scope binding information at the source map based on locations and
+	 * generated source scopes. The generated source scopes contain variables names
+	 * and all their references in the generated source. This information is merged
+	 * with the source map original names information and returned as result.
+	 */
+	function getLocationScopes(map, generatedSourceScopes, location) {
+	  const currentPosition = {
+	    line: location.line,
+	    column: location.column || 0
+	  };
+
+	  return generatedSourceScopes.map(scope => {
+	    const trackedBindings = Object.keys(scope.bindings).reduce((trackedBindings, generatedName) => applyTrackedBindings(trackedBindings, generatedName, scope.bindings[generatedName], map, currentPosition), Object.create(null));
+
+	    const bindings = Object.keys(trackedBindings).reduce((bindings, name) => {
+	      const { generatedName } = trackedBindings[name];
+	      // No need to record the binding if generated name matches original one.
+	      if (name !== generatedName) {
+	        bindings[name] = generatedName;
+	      }
+	      return bindings;
+	    }, Object.create(null));
+	    return {
+	      type: scope.type,
+	      bindings
+	    };
+	  });
+	}
+
+	module.exports = {
+	  getLocationScopes
+	};
+
+/***/ },
+/* 27 */
+/***/ function(module, exports, __webpack_require__) {
+
+	/*
+	 * Copyright 2009-2011 Mozilla Foundation and contributors
+	 * Licensed under the New BSD license. See LICENSE.txt or:
+	 * http://opensource.org/licenses/BSD-3-Clause
+	 */
+	exports.SourceMapGenerator = __webpack_require__(28).SourceMapGenerator;
+	exports.SourceMapConsumer = __webpack_require__(34).SourceMapConsumer;
+	exports.SourceNode = __webpack_require__(37).SourceNode;
+
+/***/ },
+/* 28 */
+/***/ function(module, exports, __webpack_require__) {
+
+	/* -*- Mode: js; js-indent-level: 2; -*- */
+	/*
+	 * Copyright 2011 Mozilla Foundation and contributors
+	 * Licensed under the New BSD license. See LICENSE or:
+	 * http://opensource.org/licenses/BSD-3-Clause
+	 */
+
+	var base64VLQ = __webpack_require__(29);
+	var util = __webpack_require__(31);
+	var ArraySet = __webpack_require__(32).ArraySet;
+	var MappingList = __webpack_require__(33).MappingList;
+
+	/**
+	 * An instance of the SourceMapGenerator represents a source map which is
+	 * being built incrementally. You may pass an object with the following
+	 * properties:
+	 *
+	 *   - file: The filename of the generated source.
+	 *   - sourceRoot: A root for all relative URLs in this source map.
+	 */
+	function SourceMapGenerator(aArgs) {
+	  if (!aArgs) {
+	    aArgs = {};
+	  }
+	  this._file = util.getArg(aArgs, 'file', null);
+	  this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
+	  this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
+	  this._sources = new ArraySet();
+	  this._names = new ArraySet();
+	  this._mappings = new MappingList();
+	  this._sourcesContents = null;
+	}
+
+	SourceMapGenerator.prototype._version = 3;
+
+	/**
+	 * Creates a new SourceMapGenerator based on a SourceMapConsumer
+	 *
+	 * @param aSourceMapConsumer The SourceMap.
+	 */
+	SourceMapGenerator.fromSourceMap = function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
+	  var sourceRoot = aSourceMapConsumer.sourceRoot;
+	  var generator = new SourceMapGenerator({
+	    file: aSourceMapConsumer.file,
+	    sourceRoot: sourceRoot
+	  });
+	  aSourceMapConsumer.eachMapping(function (mapping) {
+	    var newMapping = {
+	      generated: {
+	        line: mapping.generatedLine,
+	        column: mapping.generatedColumn
+	      }
+	    };
+
+	    if (mapping.source != null) {
+	      newMapping.source = mapping.source;
+	      if (sourceRoot != null) {
+	        newMapping.source = util.relative(sourceRoot, newMapping.source);
+	      }
+
+	      newMapping.original = {
+	        line: mapping.originalLine,
+	        column: mapping.originalColumn
+	      };
+
+	      if (mapping.name != null) {
+	        newMapping.name = mapping.name;
+	      }
+	    }
+
+	    generator.addMapping(newMapping);
+	  });
+	  aSourceMapConsumer.sources.forEach(function (sourceFile) {
+	    var content = aSourceMapConsumer.sourceContentFor(sourceFile);
+	    if (content != null) {
+	      generator.setSourceContent(sourceFile, content);
+	    }
+	  });
+	  return generator;
+	};
+
+	/**
+	 * Add a single mapping from original source line and column to the generated
+	 * source's line and column for this source map being created. The mapping
+	 * object should have the following properties:
+	 *
+	 *   - generated: An object with the generated line and column positions.
+	 *   - original: An object with the original line and column positions.
+	 *   - source: The original source file (relative to the sourceRoot).
+	 *   - name: An optional original token name for this mapping.
+	 */
+	SourceMapGenerator.prototype.addMapping = function SourceMapGenerator_addMapping(aArgs) {
+	  var generated = util.getArg(aArgs, 'generated');
+	  var original = util.getArg(aArgs, 'original', null);
+	  var source = util.getArg(aArgs, 'source', null);
+	  var name = util.getArg(aArgs, 'name', null);
+
+	  if (!this._skipValidation) {
+	    this._validateMapping(generated, original, source, name);
+	  }
+
+	  if (source != null) {
+	    source = String(source);
+	    if (!this._sources.has(source)) {
+	      this._sources.add(source);
+	    }
+	  }
+
+	  if (name != null) {
+	    name = String(name);
+	    if (!this._names.has(name)) {
+	      this._names.add(name);
+	    }
+	  }
+
+	  this._mappings.add({
+	    generatedLine: generated.line,
+	    generatedColumn: generated.column,
+	    originalLine: original != null && original.line,
+	    originalColumn: original != null && original.column,
+	    source: source,
+	    name: name
+	  });
+	};
+
+	/**
+	 * Set the source content for a source file.
+	 */
+	SourceMapGenerator.prototype.setSourceContent = function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
+	  var source = aSourceFile;
+	  if (this._sourceRoot != null) {
+	    source = util.relative(this._sourceRoot, source);
+	  }
+
+	  if (aSourceContent != null) {
+	    // Add the source content to the _sourcesContents map.
+	    // Create a new _sourcesContents map if the property is null.
+	    if (!this._sourcesContents) {
+	      this._sourcesContents = Object.create(null);
+	    }
+	    this._sourcesContents[util.toSetString(source)] = aSourceContent;
+	  } else if (this._sourcesContents) {
+	    // Remove the source file from the _sourcesContents map.
+	    // If the _sourcesContents map is empty, set the property to null.
+	    delete this._sourcesContents[util.toSetString(source)];
+	    if (Object.keys(this._sourcesContents).length === 0) {
+	      this._sourcesContents = null;
+	    }
+	  }
+	};
+
+	/**
+	 * Applies the mappings of a sub-source-map for a specific source file to the
+	 * source map being generated. Each mapping to the supplied source file is
+	 * rewritten using the supplied source map. Note: The resolution for the
+	 * resulting mappings is the minimium of this map and the supplied map.
+	 *
+	 * @param aSourceMapConsumer The source map to be applied.
+	 * @param aSourceFile Optional. The filename of the source file.
+	 *        If omitted, SourceMapConsumer's file property will be used.
+	 * @param aSourceMapPath Optional. The dirname of the path to the source map
+	 *        to be applied. If relative, it is relative to the SourceMapConsumer.
+	 *        This parameter is needed when the two source maps aren't in the same
+	 *        directory, and the source map to be applied contains relative source
+	 *        paths. If so, those relative source paths need to be rewritten
+	 *        relative to the SourceMapGenerator.
+	 */
+	SourceMapGenerator.prototype.applySourceMap = function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
+	  var sourceFile = aSourceFile;
+	  // If aSourceFile is omitted, we will use the file property of the SourceMap
+	  if (aSourceFile == null) {
+	    if (aSourceMapConsumer.file == null) {
+	      throw new Error('SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' + 'or the source map\'s "file" property. Both were omitted.');
+	    }
+	    sourceFile = aSourceMapConsumer.file;
+	  }
+	  var sourceRoot = this._sourceRoot;
+	  // Make "sourceFile" relative if an absolute Url is passed.
+	  if (sourceRoot != null) {
+	    sourceFile = util.relative(sourceRoot, sourceFile);
+	  }
+	  // Applying the SourceMap can add and remove items from the sources and
+	  // the names array.
+	  var newSources = new ArraySet();
+	  var newNames = new ArraySet();
+
+	  // Find mappings for the "sourceFile"
+	  this._mappings.unsortedForEach(function (mapping) {
+	    if (mapping.source === sourceFile && mapping.originalLine != null) {
+	      // Check if it can be mapped by the source map, then update the mapping.
+	      var original = aSourceMapConsumer.originalPositionFor({
+	        line: mapping.originalLine,
+	        column: mapping.originalColumn
+	      });
+	      if (original.source != null) {
+	        // Copy mapping
+	        mapping.source = original.source;
+	        if (aSourceMapPath != null) {
+	          mapping.source = util.join(aSourceMapPath, mapping.source);
+	        }
+	        if (sourceRoot != null) {
+	          mapping.source = util.relative(sourceRoot, mapping.source);
+	        }
+	        mapping.originalLine = original.line;
+	        mapping.originalColumn = original.column;
+	        if (original.name != null) {
+	          mapping.name = original.name;
+	        }
+	      }
+	    }
+
+	    var source = mapping.source;
+	    if (source != null && !newSources.has(source)) {
+	      newSources.add(source);
+	    }
+
+	    var name = mapping.name;
+	    if (name != null && !newNames.has(name)) {
+	      newNames.add(name);
+	    }
+	  }, this);
+	  this._sources = newSources;
+	  this._names = newNames;
+
+	  // Copy sourcesContents of applied map.
+	  aSourceMapConsumer.sources.forEach(function (sourceFile) {
+	    var content = aSourceMapConsumer.sourceContentFor(sourceFile);
+	    if (content != null) {
+	      if (aSourceMapPath != null) {
+	        sourceFile = util.join(aSourceMapPath, sourceFile);
+	      }
+	      if (sourceRoot != null) {
+	        sourceFile = util.relative(sourceRoot, sourceFile);
+	      }
+	      this.setSourceContent(sourceFile, content);
+	    }
+	  }, this);
+	};
+
+	/**
+	 * A mapping can have one of the three levels of data:
+	 *
+	 *   1. Just the generated position.
+	 *   2. The Generated position, original position, and original source.
+	 *   3. Generated and original position, original source, as well as a name
+	 *      token.
+	 *
+	 * To maintain consistency, we validate that any new mapping being added falls
+	 * in to one of these categories.
+	 */
+	SourceMapGenerator.prototype._validateMapping = function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, aName) {
+	  // When aOriginal is truthy but has empty values for .line and .column,
+	  // it is most likely a programmer error. In this case we throw a very
+	  // specific error message to try to guide them the right way.
+	  // For example: https://github.com/Polymer/polymer-bundler/pull/519
+	  if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
+	    throw new Error('original.line and original.column are not numbers -- you probably meant to omit ' + 'the original mapping entirely and only map the generated position. If so, pass ' + 'null for the original mapping instead of an object with empty or null values.');
+	  }
+
+	  if (aGenerated && 'line' in aGenerated && 'column' in aGenerated && aGenerated.line > 0 && aGenerated.column >= 0 && !aOriginal && !aSource && !aName) {
+	    // Case 1.
+	    return;
+	  } else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated && aOriginal && 'line' in aOriginal && 'column' in aOriginal && aGenerated.line > 0 && aGenerated.column >= 0 && aOriginal.line > 0 && aOriginal.column >= 0 && aSource) {
+	    // Cases 2 and 3.
+	    return;
+	  } else {
+	    throw new Error('Invalid mapping: ' + JSON.stringify({
+	      generated: aGenerated,
+	      source: aSource,
+	      original: aOriginal,
+	      name: aName
+	    }));
+	  }
+	};
+
+	/**
+	 * Serialize the accumulated mappings in to the stream of base 64 VLQs
+	 * specified by the source map format.
+	 */
+	SourceMapGenerator.prototype._serializeMappings = function SourceMapGenerator_serializeMappings() {
+	  var previousGeneratedColumn = 0;
+	  var previousGeneratedLine = 1;
+	  var previousOriginalColumn = 0;
+	  var previousOriginalLine = 0;
+	  var previousName = 0;
+	  var previousSource = 0;
+	  var result = '';
+	  var next;
+	  var mapping;
+	  var nameIdx;
+	  var sourceIdx;
+
+	  var mappings = this._mappings.toArray();
+	  for (var i = 0, len = mappings.length; i < len; i++) {
+	    mapping = mappings[i];
+	    next = '';
+
+	    if (mapping.generatedLine !== previousGeneratedLine) {
+	      previousGeneratedColumn = 0;
+	      while (mapping.generatedLine !== previousGeneratedLine) {
+	        next += ';';
+	        previousGeneratedLine++;
+	      }
+	    } else {
+	      if (i > 0) {
+	        if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
+	          continue;
+	        }
+	        next += ',';
+	      }
+	    }
+
+	    next += base64VLQ.encode(mapping.generatedColumn - previousGeneratedColumn);
+	    previousGeneratedColumn = mapping.generatedColumn;
+
+	    if (mapping.source != null) {
+	      sourceIdx = this._sources.indexOf(mapping.source);
+	      next += base64VLQ.encode(sourceIdx - previousSource);
+	      previousSource = sourceIdx;
+
+	      // lines are stored 0-based in SourceMap spec version 3
+	      next += base64VLQ.encode(mapping.originalLine - 1 - previousOriginalLine);
+	      previousOriginalLine = mapping.originalLine - 1;
+
+	      next += base64VLQ.encode(mapping.originalColumn - previousOriginalColumn);
+	      previousOriginalColumn = mapping.originalColumn;
+
+	      if (mapping.name != null) {
+	        nameIdx = this._names.indexOf(mapping.name);
+	        next += base64VLQ.encode(nameIdx - previousName);
+	        previousName = nameIdx;
+	      }
+	    }
+
+	    result += next;
+	  }
+
+	  return result;
+	};
+
+	SourceMapGenerator.prototype._generateSourcesContent = function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
+	  return aSources.map(function (source) {
+	    if (!this._sourcesContents) {
+	      return null;
+	    }
+	    if (aSourceRoot != null) {
+	      source = util.relative(aSourceRoot, source);
+	    }
+	    var key = util.toSetString(source);
+	    return Object.prototype.hasOwnProperty.call(this._sourcesContents, key) ? this._sourcesContents[key] : null;
+	  }, this);
+	};
+
+	/**
+	 * Externalize the source map.
+	 */
+	SourceMapGenerator.prototype.toJSON = function SourceMapGenerator_toJSON() {
+	  var map = {
+	    version: this._version,
+	    sources: this._sources.toArray(),
+	    names: this._names.toArray(),
+	    mappings: this._serializeMappings()
+	  };
+	  if (this._file != null) {
+	    map.file = this._file;
+	  }
+	  if (this._sourceRoot != null) {
+	    map.sourceRoot = this._sourceRoot;
+	  }
+	  if (this._sourcesContents) {
+	    map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
+	  }
+
+	  return map;
+	};
+
+	/**
+	 * Render the source map being generated to a string.
+	 */
+	SourceMapGenerator.prototype.toString = function SourceMapGenerator_toString() {
+	  return JSON.stringify(this.toJSON());
+	};
+
+	exports.SourceMapGenerator = SourceMapGenerator;
+
+/***/ },
+/* 29 */
+/***/ function(module, exports, __webpack_require__) {
+
+	/* -*- Mode: js; js-indent-level: 2; -*- */
+	/*
+	 * Copyright 2011 Mozilla Foundation and contributors
+	 * Licensed under the New BSD license. See LICENSE or:
+	 * http://opensource.org/licenses/BSD-3-Clause
+	 *
+	 * Based on the Base 64 VLQ implementation in Closure Compiler:
+	 * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
+	 *
+	 * Copyright 2011 The Closure Compiler 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.
+	 */
+
+	var base64 = __webpack_require__(30);
+
+	// A single base 64 digit can contain 6 bits of data. For the base 64 variable
+	// length quantities we use in the source map spec, the first bit is the sign,
+	// the next four bits are the actual value, and the 6th bit is the
+	// continuation bit. The continuation bit tells us whether there are more
+	// digits in this value following this digit.
+	//
+	//   Continuation
+	//   |    Sign
+	//   |    |
+	//   V    V
+	//   101011
+
+	var VLQ_BASE_SHIFT = 5;
+
+	// binary: 100000
+	var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
+
+	// binary: 011111
+	var VLQ_BASE_MASK = VLQ_BASE - 1;
+
+	// binary: 100000
+	var VLQ_CONTINUATION_BIT = VLQ_BASE;
+
+	/**
+	 * Converts from a two-complement value to a value where the sign bit is
+	 * placed in the least significant bit.  For example, as decimals:
+	 *   1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
+	 *   2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
+	 */
+	function toVLQSigned(aValue) {
+	  return aValue < 0 ? (-aValue << 1) + 1 : (aValue << 1) + 0;
+	}
+
+	/**
+	 * Converts to a two-complement value from a value where the sign bit is
+	 * placed in the least significant bit.  For example, as decimals:
+	 *   2 (10 binary) becomes 1, 3 (11 binary) becomes -1
+	 *   4 (100 binary) becomes 2, 5 (101 binary) becomes -2
+	 */
+	function fromVLQSigned(aValue) {
+	  var isNegative = (aValue & 1) === 1;
+	  var shifted = aValue >> 1;
+	  return isNegative ? -shifted : shifted;
+	}
+
+	/**
+	 * Returns the base 64 VLQ encoded value.
+	 */
+	exports.encode = function base64VLQ_encode(aValue) {
+	  var encoded = "";
+	  var digit;
+
+	  var vlq = toVLQSigned(aValue);
+
+	  do {
+	    digit = vlq & VLQ_BASE_MASK;
+	    vlq >>>= VLQ_BASE_SHIFT;
+	    if (vlq > 0) {
+	      // There are still more digits in this value, so we must make sure the
+	      // continuation bit is marked.
+	      digit |= VLQ_CONTINUATION_BIT;
+	    }
+	    encoded += base64.encode(digit);
+	  } while (vlq > 0);
+
+	  return encoded;
+	};
+
+	/**
+	 * Decodes the next base 64 VLQ value from the given string and returns the
+	 * value and the rest of the string via the out parameter.
+	 */
+	exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {
+	  var strLen = aStr.length;
+	  var result = 0;
+	  var shift = 0;
+	  var continuation, digit;
+
+	  do {
+	    if (aIndex >= strLen) {
+	      throw new Error("Expected more digits in base 64 VLQ value.");
+	    }
+
+	    digit = base64.decode(aStr.charCodeAt(aIndex++));
+	    if (digit === -1) {
+	      throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
+	    }
+
+	    continuation = !!(digit & VLQ_CONTINUATION_BIT);
+	    digit &= VLQ_BASE_MASK;
+	    result = result + (digit << shift);
+	    shift += VLQ_BASE_SHIFT;
+	  } while (continuation);
+
+	  aOutParam.value = fromVLQSigned(result);
+	  aOutParam.rest = aIndex;
+	};
+
+/***/ },
+/* 30 */
+/***/ function(module, exports) {
+
+	/* -*- Mode: js; js-indent-level: 2; -*- */
+	/*
+	 * Copyright 2011 Mozilla Foundation and contributors
+	 * Licensed under the New BSD license. See LICENSE or:
+	 * http://opensource.org/licenses/BSD-3-Clause
+	 */
+
+	var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
+
+	/**
+	 * Encode an integer in the range of 0 to 63 to a single base 64 digit.
+	 */
+	exports.encode = function (number) {
+	  if (0 <= number && number < intToCharMap.length) {
+	    return intToCharMap[number];
+	  }
+	  throw new TypeError("Must be between 0 and 63: " + number);
+	};
+
+	/**
+	 * Decode a single base 64 character code digit to an integer. Returns -1 on
+	 * failure.
+	 */
+	exports.decode = function (charCode) {
+	  var bigA = 65; // 'A'
+	  var bigZ = 90; // 'Z'
+
+	  var littleA = 97; // 'a'
+	  var littleZ = 122; // 'z'
+
+	  var zero = 48; // '0'
+	  var nine = 57; // '9'
+
+	  var plus = 43; // '+'
+	  var slash = 47; // '/'
+
+	  var littleOffset = 26;
+	  var numberOffset = 52;
+
+	  // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
+	  if (bigA <= charCode && charCode <= bigZ) {
+	    return charCode - bigA;
+	  }
+
+	  // 26 - 51: abcdefghijklmnopqrstuvwxyz
+	  if (littleA <= charCode && charCode <= littleZ) {
+	    return charCode - littleA + littleOffset;
+	  }
+
+	  // 52 - 61: 0123456789
+	  if (zero <= charCode && charCode <= nine) {
+	    return charCode - zero + numberOffset;
+	  }
+
+	  // 62: +
+	  if (charCode == plus) {
+	    return 62;
+	  }
+
+	  // 63: /
+	  if (charCode == slash) {
+	    return 63;
+	  }
+
+	  // Invalid base64 digit.
+	  return -1;
+	};
+
+/***/ },
+/* 31 */
+/***/ function(module, exports) {
+
+	/* -*- Mode: js; js-indent-level: 2; -*- */
+	/*
+	 * Copyright 2011 Mozilla Foundation and contributors
+	 * Licensed under the New BSD license. See LICENSE or:
+	 * http://opensource.org/licenses/BSD-3-Clause
+	 */
+
+	/**
+	 * This is a helper function for getting values from parameter/options
+	 * objects.
+	 *
+	 * @param args The object we are extracting values from
+	 * @param name The name of the property we are getting.
+	 * @param defaultValue An optional value to return if the property is missing
+	 * from the object. If this is not specified and the property is missing, an
+	 * error will be thrown.
+	 */
+	function getArg(aArgs, aName, aDefaultValue) {
+	  if (aName in aArgs) {
+	    return aArgs[aName];
+	  } else if (arguments.length === 3) {
+	    return aDefaultValue;
+	  } else {
+	    throw new Error('"' + aName + '" is a required argument.');
+	  }
+	}
+	exports.getArg = getArg;
+
+	var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/;
+	var dataUrlRegexp = /^data:.+\,.+$/;
+
+	function urlParse(aUrl) {
+	  var match = aUrl.match(urlRegexp);
+	  if (!match) {
+	    return null;
+	  }
+	  return {
+	    scheme: match[1],
+	    auth: match[2],
+	    host: match[3],
+	    port: match[4],
+	    path: match[5]
+	  };
+	}
+	exports.urlParse = urlParse;
+
+	function urlGenerate(aParsedUrl) {
+	  var url = '';
+	  if (aParsedUrl.scheme) {
+	    url += aParsedUrl.scheme + ':';
+	  }
+	  url += '//';
+	  if (aParsedUrl.auth) {
+	    url += aParsedUrl.auth + '@';
+	  }
+	  if (aParsedUrl.host) {
+	    url += aParsedUrl.host;
+	  }
+	  if (aParsedUrl.port) {
+	    url += ":" + aParsedUrl.port;
+	  }
+	  if (aParsedUrl.path) {
+	    url += aParsedUrl.path;
+	  }
+	  return url;
+	}
+	exports.urlGenerate = urlGenerate;
+
+	/**
+	 * Normalizes a path, or the path portion of a URL:
+	 *
+	 * - Replaces consecutive slashes with one slash.
+	 * - Removes unnecessary '.' parts.
+	 * - Removes unnecessary '<dir>/..' parts.
+	 *
+	 * Based on code in the Node.js 'path' core module.
+	 *
+	 * @param aPath The path or url to normalize.
+	 */
+	function normalize(aPath) {
+	  var path = aPath;
+	  var url = urlParse(aPath);
+	  if (url) {
+	    if (!url.path) {
+	      return aPath;
+	    }
+	    path = url.path;
+	  }
+	  var isAbsolute = exports.isAbsolute(path);
+
+	  var parts = path.split(/\/+/);
+	  for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
+	    part = parts[i];
+	    if (part === '.') {
+	      parts.splice(i, 1);
+	    } else if (part === '..') {
+	      up++;
+	    } else if (up > 0) {
+	      if (part === '') {
+	        // The first part is blank if the path is absolute. Trying to go
+	        // above the root is a no-op. Therefore we can remove all '..' parts
+	        // directly after the root.
+	        parts.splice(i + 1, up);
+	        up = 0;
+	      } else {
+	        parts.splice(i, 2);
+	        up--;
+	      }
+	    }
+	  }
+	  path = parts.join('/');
+
+	  if (path === '') {
+	    path = isAbsolute ? '/' : '.';
+	  }
+
+	  if (url) {
+	    url.path = path;
+	    return urlGenerate(url);
+	  }
+	  return path;
+	}
+	exports.normalize = normalize;
+
+	/**
+	 * Joins two paths/URLs.
+	 *
+	 * @param aRoot The root path or URL.
+	 * @param aPath The path or URL to be joined with the root.
+	 *
+	 * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
+	 *   scheme-relative URL: Then the scheme of aRoot, if any, is prepended
+	 *   first.
+	 * - Otherwise aPath is a path. If aRoot is a URL, then its path portion
+	 *   is updated with the result and aRoot is returned. Otherwise the result
+	 *   is returned.
+	 *   - If aPath is absolute, the result is aPath.
+	 *   - Otherwise the two paths are joined with a slash.
+	 * - Joining for example 'http://' and 'www.example.com' is also supported.
+	 */
+	function join(aRoot, aPath) {
+	  if (aRoot === "") {
+	    aRoot = ".";
+	  }
+	  if (aPath === "") {
+	    aPath = ".";
+	  }
+	  var aPathUrl = urlParse(aPath);
+	  var aRootUrl = urlParse(aRoot);
+	  if (aRootUrl) {
+	    aRoot = aRootUrl.path || '/';
+	  }
+
+	  // `join(foo, '//www.example.org')`
+	  if (aPathUrl && !aPathUrl.scheme) {
+	    if (aRootUrl) {
+	      aPathUrl.scheme = aRootUrl.scheme;
+	    }
+	    return urlGenerate(aPathUrl);
+	  }
+
+	  if (aPathUrl || aPath.match(dataUrlRegexp)) {
+	    return aPath;
+	  }
+
+	  // `join('http://', 'www.example.com')`
+	  if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
+	    aRootUrl.host = aPath;
+	    return urlGenerate(aRootUrl);
+	  }
+
+	  var joined = aPath.charAt(0) === '/' ? aPath : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);
+
+	  if (aRootUrl) {
+	    aRootUrl.path = joined;
+	    return urlGenerate(aRootUrl);
+	  }
+	  return joined;
+	}
+	exports.join = join;
+
+	exports.isAbsolute = function (aPath) {
+	  return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp);
+	};
+
+	/**
+	 * Make a path relative to a URL or another path.
+	 *
+	 * @param aRoot The root path or URL.
+	 * @param aPath The path or URL to be made relative to aRoot.
+	 */
+	function relative(aRoot, aPath) {
+	  if (aRoot === "") {
+	    aRoot = ".";
+	  }
+
+	  aRoot = aRoot.replace(/\/$/, '');
+
+	  // It is possible for the path to be above the root. In this case, simply
+	  // checking whether the root is a prefix of the path won't work. Instead, we
+	  // need to remove components from the root one by one, until either we find
+	  // a prefix that fits, or we run out of components to remove.
+	  var level = 0;
+	  while (aPath.indexOf(aRoot + '/') !== 0) {
+	    var index = aRoot.lastIndexOf("/");
+	    if (index < 0) {
+	      return aPath;
+	    }
+
+	    // If the only part of the root that is left is the scheme (i.e. http://,
+	    // file:///, etc.), one or more slashes (/), or simply nothing at all, we
+	    // have exhausted all components, so the path is not relative to the root.
+	    aRoot = aRoot.slice(0, index);
+	    if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
+	      return aPath;
+	    }
+
+	    ++level;
+	  }
+
+	  // Make sure we add a "../" for each component we removed from the root.
+	  return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
+	}
+	exports.relative = relative;
+
+	var supportsNullProto = function () {
+	  var obj = Object.create(null);
+	  return !('__proto__' in obj);
+	}();
+
+	function identity(s) {
+	  return s;
+	}
+
+	/**
+	 * Because behavior goes wacky when you set `__proto__` on objects, we
+	 * have to prefix all the strings in our set with an arbitrary character.
+	 *
+	 * See https://github.com/mozilla/source-map/pull/31 and
+	 * https://github.com/mozilla/source-map/issues/30
+	 *
+	 * @param String aStr
+	 */
+	function toSetString(aStr) {
+	  if (isProtoString(aStr)) {
+	    return '$' + aStr;
+	  }
+
+	  return aStr;
+	}
+	exports.toSetString = supportsNullProto ? identity : toSetString;
+
+	function fromSetString(aStr) {
+	  if (isProtoString(aStr)) {
+	    return aStr.slice(1);
+	  }
+
+	  return aStr;
+	}
+	exports.fromSetString = supportsNullProto ? identity : fromSetString;
+
+	function isProtoString(s) {
+	  if (!s) {
+	    return false;
+	  }
+
+	  var length = s.length;
+
+	  if (length < 9 /* "__proto__".length */) {
+	      return false;
+	    }
+
+	  if (s.charCodeAt(length - 1) !== 95 /* '_' */ || s.charCodeAt(length - 2) !== 95 /* '_' */ || s.charCodeAt(length - 3) !== 111 /* 'o' */ || s.charCodeAt(length - 4) !== 116 /* 't' */ || s.charCodeAt(length - 5) !== 111 /* 'o' */ || s.charCodeAt(length - 6) !== 114 /* 'r' */ || s.charCodeAt(length - 7) !== 112 /* 'p' */ || s.charCodeAt(length - 8) !== 95 /* '_' */ || s.charCodeAt(length - 9) !== 95 /* '_' */) {
+	      return false;
+	    }
+
+	  for (var i = length - 10; i >= 0; i--) {
+	    if (s.charCodeAt(i) !== 36 /* '$' */) {
+	        return false;
+	      }
+	  }
+
+	  return true;
+	}
+
+	/**
+	 * Comparator between two mappings where the original positions are compared.
+	 *
+	 * Optionally pass in `true` as `onlyCompareGenerated` to consider two
+	 * mappings with the same original source/line/column, but different generated
+	 * line and column the same. Useful when searching for a mapping with a
+	 * stubbed out mapping.
+	 */
+	function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
+	  var cmp = mappingA.source - mappingB.source;
+	  if (cmp !== 0) {
+	    return cmp;
+	  }
+
+	  cmp = mappingA.originalLine - mappingB.originalLine;
+	  if (cmp !== 0) {
+	    return cmp;
+	  }
+
+	  cmp = mappingA.originalColumn - mappingB.originalColumn;
+	  if (cmp !== 0 || onlyCompareOriginal) {
+	    return cmp;
+	  }
+
+	  cmp = mappingA.generatedColumn - mappingB.generatedColumn;
+	  if (cmp !== 0) {
+	    return cmp;
+	  }
+
+	  cmp = mappingA.generatedLine - mappingB.generatedLine;
+	  if (cmp !== 0) {
+	    return cmp;
+	  }
+
+	  return mappingA.name - mappingB.name;
+	}
+	exports.compareByOriginalPositions = compareByOriginalPositions;
+
+	/**
+	 * Comparator between two mappings with deflated source and name indices where
+	 * the generated positions are compared.
+	 *
+	 * Optionally pass in `true` as `onlyCompareGenerated` to consider two
+	 * mappings with the same generated line and column, but different
+	 * source/name/original line and column the same. Useful when searching for a
+	 * mapping with a stubbed out mapping.
+	 */
+	function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
+	  var cmp = mappingA.generatedLine - mappingB.generatedLine;
+	  if (cmp !== 0) {
+	    return cmp;
+	  }
+
+	  cmp = mappingA.generatedColumn - mappingB.generatedColumn;
+	  if (cmp !== 0 || onlyCompareGenerated) {
+	    return cmp;
+	  }
+
+	  cmp = mappingA.source - mappingB.source;
+	  if (cmp !== 0) {
+	    return cmp;
+	  }
+
+	  cmp = mappingA.originalLine - mappingB.originalLine;
+	  if (cmp !== 0) {
+	    return cmp;
+	  }
+
+	  cmp = mappingA.originalColumn - mappingB.originalColumn;
+	  if (cmp !== 0) {
+	    return cmp;
+	  }
+
+	  return mappingA.name - mappingB.name;
+	}
+	exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
+
+	function strcmp(aStr1, aStr2) {
+	  if (aStr1 === aStr2) {
+	    return 0;
+	  }
+
+	  if (aStr1 > aStr2) {
+	    return 1;
+	  }
+
+	  return -1;
+	}
+
+	/**
+	 * Comparator between two mappings with inflated source and name strings where
+	 * the generated positions are compared.
+	 */
+	function compareByGeneratedPositionsInflated(mappingA, mappingB) {
+	  var cmp = mappingA.generatedLine - mappingB.generatedLine;
+	  if (cmp !== 0) {
+	    return cmp;
+	  }
+
+	  cmp = mappingA.generatedColumn - mappingB.generatedColumn;
+	  if (cmp !== 0) {
+	    return cmp;
+	  }
+
+	  cmp = strcmp(mappingA.source, mappingB.source);
+	  if (cmp !== 0) {
+	    return cmp;
+	  }
+
+	  cmp = mappingA.originalLine - mappingB.originalLine;
+	  if (cmp !== 0) {
+	    return cmp;
+	  }
+
+	  cmp = mappingA.originalColumn - mappingB.originalColumn;
+	  if (cmp !== 0) {
+	    return cmp;
+	  }
+
+	  return strcmp(mappingA.name, mappingB.name);
+	}
+	exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
+
+/***/ },
+/* 32 */
+/***/ function(module, exports, __webpack_require__) {
+
+	/* -*- Mode: js; js-indent-level: 2; -*- */
+	/*
+	 * Copyright 2011 Mozilla Foundation and contributors
+	 * Licensed under the New BSD license. See LICENSE or:
+	 * http://opensource.org/licenses/BSD-3-Clause
+	 */
+
+	var util = __webpack_require__(31);
+	var has = Object.prototype.hasOwnProperty;
+	var hasNativeMap = typeof Map !== "undefined";
+
+	/**
+	 * A data structure which is a combination of an array and a set. Adding a new
+	 * member is O(1), testing for membership is O(1), and finding the index of an
+	 * element is O(1). Removing elements from the set is not supported. Only
+	 * strings are supported for membership.
+	 */
+	function ArraySet() {
+	  this._array = [];
+	  this._set = hasNativeMap ? new Map() : Object.create(null);
+	}
+
+	/**
+	 * Static method for creating ArraySet instances from an existing array.
+	 */
+	ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
+	  var set = new ArraySet();
+	  for (var i = 0, len = aArray.length; i < len; i++) {
+	    set.add(aArray[i], aAllowDuplicates);
+	  }
+	  return set;
+	};
+
+	/**
+	 * Return how many unique items are in this ArraySet. If duplicates have been
+	 * added, than those do not count towards the size.
+	 *
+	 * @returns Number
+	 */
+	ArraySet.prototype.size = function ArraySet_size() {
+	  return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
+	};
+
+	/**
+	 * Add the given string to this set.
+	 *
+	 * @param String aStr
+	 */
+	ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
+	  var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
+	  var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
+	  var idx = this._array.length;
+	  if (!isDuplicate || aAllowDuplicates) {
+	    this._array.push(aStr);
+	  }
+	  if (!isDuplicate) {
+	    if (hasNativeMap) {
+	      this._set.set(aStr, idx);
+	    } else {
+	      this._set[sStr] = idx;
+	    }
+	  }
+	};
+
+	/**
+	 * Is the given string a member of this set?
+	 *
+	 * @param String aStr
+	 */
+	ArraySet.prototype.has = function ArraySet_has(aStr) {
+	  if (hasNativeMap) {
+	    return this._set.has(aStr);
+	  } else {
+	    var sStr = util.toSetString(aStr);
+	    return has.call(this._set, sStr);
+	  }
+	};
+
+	/**
+	 * What is the index of the given string in the array?
+	 *
+	 * @param String aStr
+	 */
+	ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
+	  if (hasNativeMap) {
+	    var idx = this._set.get(aStr);
+	    if (idx >= 0) {
+	      return idx;
+	    }
+	  } else {
+	    var sStr = util.toSetString(aStr);
+	    if (has.call(this._set, sStr)) {
+	      return this._set[sStr];
+	    }
+	  }
+
+	  throw new Error('"' + aStr + '" is not in the set.');
+	};
+
+	/**
+	 * What is the element at the given index?
+	 *
+	 * @param Number aIdx
+	 */
+	ArraySet.prototype.at = function ArraySet_at(aIdx) {
+	  if (aIdx >= 0 && aIdx < this._array.length) {
+	    return this._array[aIdx];
+	  }
+	  throw new Error('No element indexed by ' + aIdx);
+	};
+
+	/**
+	 * Returns the array representation of this set (which has the proper indices
+	 * indicated by indexOf). Note that this is a copy of the internal array used
+	 * for storing the members so that no one can mess with internal state.
+	 */
+	ArraySet.prototype.toArray = function ArraySet_toArray() {
+	  return this._array.slice();
+	};
+
+	exports.ArraySet = ArraySet;
+
+/***/ },
+/* 33 */
+/***/ function(module, exports, __webpack_require__) {
+
+	/* -*- Mode: js; js-indent-level: 2; -*- */
+	/*
+	 * Copyright 2014 Mozilla Foundation and contributors
+	 * Licensed under the New BSD license. See LICENSE or:
+	 * http://opensource.org/licenses/BSD-3-Clause
+	 */
+
+	var util = __webpack_require__(31);
+
+	/**
+	 * Determine whether mappingB is after mappingA with respect to generated
+	 * position.
+	 */
+	function generatedPositionAfter(mappingA, mappingB) {
+	  // Optimized for most common case
+	  var lineA = mappingA.generatedLine;
+	  var lineB = mappingB.generatedLine;
+	  var columnA = mappingA.generatedColumn;
+	  var columnB = mappingB.generatedColumn;
+	  return lineB > lineA || lineB == lineA && columnB >= columnA || util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
+	}
+
+	/**
+	 * A data structure to provide a sorted view of accumulated mappings in a
+	 * performance conscious manner. It trades a neglibable overhead in general
+	 * case for a large speedup in case of mappings being added in order.
+	 */
+	function MappingList() {
+	  this._array = [];
+	  this._sorted = true;
+	  // Serves as infimum
+	  this._last = { generatedLine: -1, generatedColumn: 0 };
+	}
+
+	/**
+	 * Iterate through internal items. This method takes the same arguments that
+	 * `Array.prototype.forEach` takes.
+	 *
+	 * NOTE: The order of the mappings is NOT guaranteed.
+	 */
+	MappingList.prototype.unsortedForEach = function MappingList_forEach(aCallback, aThisArg) {
+	  this._array.forEach(aCallback, aThisArg);
+	};
+
+	/**
+	 * Add the given source mapping.
+	 *
+	 * @param Object aMapping
+	 */
+	MappingList.prototype.add = function MappingList_add(aMapping) {
+	  if (generatedPositionAfter(this._last, aMapping)) {
+	    this._last = aMapping;
+	    this._array.push(aMapping);
+	  } else {
+	    this._sorted = false;
+	    this._array.push(aMapping);
+	  }
+	};
+
+	/**
+	 * Returns the flat, sorted array of mappings. The mappings are sorted by
+	 * generated position.
+	 *
+	 * WARNING: This method returns internal data without copying, for
+	 * performance. The return value must NOT be mutated, and should be treated as
+	 * an immutable borrow. If you want to take ownership, you must make your own
+	 * copy.
+	 */
+	MappingList.prototype.toArray = function MappingList_toArray() {
+	  if (!this._sorted) {
+	    this._array.sort(util.compareByGeneratedPositionsInflated);
+	    this._sorted = true;
+	  }
+	  return this._array;
+	};
+
+	exports.MappingList = MappingList;
+
+/***/ },
+/* 34 */
+/***/ function(module, exports, __webpack_require__) {
+
+	/* -*- Mode: js; js-indent-level: 2; -*- */
+	/*
+	 * Copyright 2011 Mozilla Foundation and contributors
+	 * Licensed under the New BSD license. See LICENSE or:
+	 * http://opensource.org/licenses/BSD-3-Clause
+	 */
+
+	var util = __webpack_require__(31);
+	var binarySearch = __webpack_require__(35);
+	var ArraySet = __webpack_require__(32).ArraySet;
+	var base64VLQ = __webpack_require__(29);
+	var quickSort = __webpack_require__(36).quickSort;
+
+	function SourceMapConsumer(aSourceMap) {
+	  var sourceMap = aSourceMap;
+	  if (typeof aSourceMap === 'string') {
+	    sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+	  }
+
+	  return sourceMap.sections != null ? new IndexedSourceMapConsumer(sourceMap) : new BasicSourceMapConsumer(sourceMap);
+	}
+
+	SourceMapConsumer.fromSourceMap = function (aSourceMap) {
+	  return BasicSourceMapConsumer.fromSourceMap(aSourceMap);
+	};
+
+	/**
+	 * The version of the source mapping spec that we are consuming.
+	 */
+	SourceMapConsumer.prototype._version = 3;
+
+	// `__generatedMappings` and `__originalMappings` are arrays that hold the
+	// parsed mapping coordinates from the source map's "mappings" attribute. They
+	// are lazily instantiated, accessed via the `_generatedMappings` and
+	// `_originalMappings` getters respectively, and we only parse the mappings
+	// and create these arrays once queried for a source location. We jump through
+	// these hoops because there can be many thousands of mappings, and parsing
+	// them is expensive, so we only want to do it if we must.
+	//
+	// Each object in the arrays is of the form:
+	//
+	//     {
+	//       generatedLine: The line number in the generated code,
+	//       generatedColumn: The column number in the generated code,
+	//       source: The path to the original source file that generated this
+	//               chunk of code,
+	//       originalLine: The line number in the original source that
+	//                     corresponds to this chunk of generated code,
+	//       originalColumn: The column number in the original source that
+	//                       corresponds to this chunk of generated code,
+	//       name: The name of the original symbol which generated this chunk of
+	//             code.
+	//     }
+	//
+	// All properties except for `generatedLine` and `generatedColumn` can be
+	// `null`.
+	//
+	// `_generatedMappings` is ordered by the generated positions.
+	//
+	// `_originalMappings` is ordered by the original positions.
+
+	SourceMapConsumer.prototype.__generatedMappings = null;
+	Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
+	  get: function () {
+	    if (!this.__generatedMappings) {
+	      this._parseMappings(this._mappings, this.sourceRoot);
+	    }
+
+	    return this.__generatedMappings;
+	  }
+	});
+
+	SourceMapConsumer.prototype.__originalMappings = null;
+	Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
+	  get: function () {
+	    if (!this.__originalMappings) {
+	      this._parseMappings(this._mappings, this.sourceRoot);
+	    }
+
+	    return this.__originalMappings;
+	  }
+	});
+
+	SourceMapConsumer.prototype._charIsMappingSeparator = function SourceMapConsumer_charIsMappingSeparator(aStr, index) {
+	  var c = aStr.charAt(index);
+	  return c === ";" || c === ",";
+	};
+
+	/**
+	 * Parse the mappings in a string in to a data structure which we can easily
+	 * query (the ordered arrays in the `this.__generatedMappings` and
+	 * `this.__originalMappings` properties).
+	 */
+	SourceMapConsumer.prototype._parseMappings = function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
+	  throw new Error("Subclasses must implement _parseMappings");
+	};
+
+	SourceMapConsumer.GENERATED_ORDER = 1;
+	SourceMapConsumer.ORIGINAL_ORDER = 2;
+
+	SourceMapConsumer.GREATEST_LOWER_BOUND = 1;
+	SourceMapConsumer.LEAST_UPPER_BOUND = 2;
+
+	/**
+	 * Iterate over each mapping between an original source/line/column and a
+	 * generated line/column in this source map.
+	 *
+	 * @param Function aCallback
+	 *        The function that is called with each mapping.
+	 * @param Object aContext
+	 *        Optional. If specified, this object will be the value of `this` every
+	 *        time that `aCallback` is called.
+	 * @param aOrder
+	 *        Either `SourceMapConsumer.GENERATED_ORDER` or
+	 *        `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to
+	 *        iterate over the mappings sorted by the generated file's line/column
+	 *        order or the original's source/line/column order, respectively. Defaults to
+	 *        `SourceMapConsumer.GENERATED_ORDER`.
+	 */
+	SourceMapConsumer.prototype.eachMapping = function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {
+	  var context = aContext || null;
+	  var order = aOrder || SourceMapConsumer.GENERATED_ORDER;
+
+	  var mappings;
+	  switch (order) {
+	    case SourceMapConsumer.GENERATED_ORDER:
+	      mappings = this._generatedMappings;
+	      break;
+	    case SourceMapConsumer.ORIGINAL_ORDER:
+	      mappings = this._originalMappings;
+	      break;
+	    default:
+	      throw new Error("Unknown order of iteration.");
+	  }
+
+	  var sourceRoot = this.sourceRoot;
+	  mappings.map(function (mapping) {
+	    var source = mapping.source === null ? null : this._sources.at(mapping.source);
+	    if (source != null && sourceRoot != null) {
+	      source = util.join(sourceRoot, source);
+	    }
+	    return {
+	      source: source,
+	      generatedLine: mapping.generatedLine,
+	      generatedColumn: mapping.generatedColumn,
+	      originalLine: mapping.originalLine,
+	      originalColumn: mapping.originalColumn,
+	      name: mapping.name === null ? null : this._names.at(mapping.name)
+	    };
+	  }, this).forEach(aCallback, context);
+	};
+
+	/**
+	 * Returns all generated line and column information for the original source,
+	 * line, and column provided. If no column is provided, returns all mappings
+	 * corresponding to a either the line we are searching for or the next
+	 * closest line that has any mappings. Otherwise, returns all mappings
+	 * corresponding to the given line and either the column we are searching for
+	 * or the next closest column that has any offsets.
+	 *
+	 * The only argument is an object with the following properties:
+	 *
+	 *   - source: The filename of the original source.
+	 *   - line: The line number in the original source.
+	 *   - column: Optional. the column number in the original source.
+	 *
+	 * and an array of objects is returned, each with the following properties:
+	 *
+	 *   - line: The line number in the generated source, or null.
+	 *   - column: The column number in the generated source, or null.
+	 */
+	SourceMapConsumer.prototype.allGeneratedPositionsFor = function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
+	  var line = util.getArg(aArgs, 'line');
+
+	  // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping
+	  // returns the index of the closest mapping less than the needle. By
+	  // setting needle.originalColumn to 0, we thus find the last mapping for
+	  // the given line, provided such a mapping exists.
+	  var needle = {
+	    source: util.getArg(aArgs, 'source'),
+	    originalLine: line,
+	    originalColumn: util.getArg(aArgs, 'column', 0)
+	  };
+
+	  if (this.sourceRoot != null) {
+	    needle.source = util.relative(this.sourceRoot, needle.source);
+	  }
+	  if (!this._sources.has(needle.source)) {
+	    return [];
+	  }
+	  needle.source = this._sources.indexOf(needle.source);
+
+	  var mappings = [];
+
+	  var index = this._findMapping(needle, this._originalMappings, "originalLine", "originalColumn", util.compareByOriginalPositions, binarySearch.LEAST_UPPER_BOUND);
+	  if (index >= 0) {
+	    var mapping = this._originalMappings[index];
+
+	    if (aArgs.column === undefined) {
+	      var originalLine = mapping.originalLine;
+
+	      // Iterate until either we run out of mappings, or we run into
+	      // a mapping for a different line than the one we found. Since
+	      // mappings are sorted, this is guaranteed to find all mappings for
+	      // the line we found.
+	      while (mapping && mapping.originalLine === originalLine) {
+	        mappings.push({
+	          line: util.getArg(mapping, 'generatedLine', null),
+	          column: util.getArg(mapping, 'generatedColumn', null),
+	          lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
+	        });
+
+	        mapping = this._originalMappings[++index];
+	      }
+	    } else {
+	      var originalColumn = mapping.originalColumn;
+
+	      // Iterate until either we run out of mappings, or we run into
+	      // a mapping for a different line than the one we were searching for.
+	      // Since mappings are sorted, this is guaranteed to find all mappings for
+	      // the line we are searching for.
+	      while (mapping && mapping.originalLine === line && mapping.originalColumn == originalColumn) {
+	        mappings.push({
+	          line: util.getArg(mapping, 'generatedLine', null),
+	          column: util.getArg(mapping, 'generatedColumn', null),
+	          lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
+	        });
+
+	        mapping = this._originalMappings[++index];
+	      }
+	    }
+	  }
+
+	  return mappings;
+	};
+
+	exports.SourceMapConsumer = SourceMapConsumer;
+
+	/**
+	 * A BasicSourceMapConsumer instance represents a parsed source map which we can
+	 * query for information about the original file positions by giving it a file
+	 * position in the generated source.
+	 *
+	 * The only parameter is the raw source map (either as a JSON string, or
+	 * already parsed to an object). According to the spec, source maps have the
+	 * following attributes:
+	 *
+	 *   - version: Which version of the source map spec this map is following.
+	 *   - sources: An array of URLs to the original source files.
+	 *   - names: An array of identifiers which can be referrenced by individual mappings.
+	 *   - sourceRoot: Optional. The URL root from which all sources are relative.
+	 *   - sourcesContent: Optional. An array of contents of the original source files.
+	 *   - mappings: A string of base64 VLQs which contain the actual mappings.
+	 *   - file: Optional. The generated file this source map is associated with.
+	 *
+	 * Here is an example source map, taken from the source map spec[0]:
+	 *
+	 *     {
+	 *       version : 3,
+	 *       file: "out.js",
+	 *       sourceRoot : "",
+	 *       sources: ["foo.js", "bar.js"],
+	 *       names: ["src", "maps", "are", "fun"],
+	 *       mappings: "AA,AB;;ABCDE;"
+	 *     }
+	 *
+	 * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
+	 */
+	function BasicSourceMapConsumer(aSourceMap) {
+	  var sourceMap = aSourceMap;
+	  if (typeof aSourceMap === 'string') {
+	    sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+	  }
+
+	  var version = util.getArg(sourceMap, 'version');
+	  var sources = util.getArg(sourceMap, 'sources');
+	  // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which
+	  // requires the array) to play nice here.
+	  var names = util.getArg(sourceMap, 'names', []);
+	  var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);
+	  var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null);
+	  var mappings = util.getArg(sourceMap, 'mappings');
+	  var file = util.getArg(sourceMap, 'file', null);
+
+	  // Once again, Sass deviates from the spec and supplies the version as a
+	  // string rather than a number, so we use loose equality checking here.
+	  if (version != this._version) {
+	    throw new Error('Unsupported version: ' + version);
+	  }
+
+	  sources = sources.map(String)
+	  // Some source maps produce relative source paths like "./foo.js" instead of
+	  // "foo.js".  Normalize these first so that future comparisons will succeed.
+	  // See bugzil.la/1090768.
+	  .map(util.normalize)
+	  // Always ensure that absolute sources are internally stored relative to
+	  // the source root, if the source root is absolute. Not doing this would
+	  // be particularly problematic when the source root is a prefix of the
+	  // source (valid, but why??). See github issue #199 and bugzil.la/1188982.
+	  .map(function (source) {
+	    return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source) ? util.relative(sourceRoot, source) : source;
+	  });
+
+	  // Pass `true` below to allow duplicate names and sources. While source maps
+	  // are intended to be compressed and deduplicated, the TypeScript compiler
+	  // sometimes generates source maps with duplicates in them. See Github issue
+	  // #72 and bugzil.la/889492.
+	  this._names = ArraySet.fromArray(names.map(String), true);
+	  this._sources = ArraySet.fromArray(sources, true);
+
+	  this.sourceRoot = sourceRoot;
+	  this.sourcesContent = sourcesContent;
+	  this._mappings = mappings;
+	  this.file = file;
+	}
+
+	BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
+	BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer;
+
+	/**
+	 * Create a BasicSourceMapConsumer from a SourceMapGenerator.
+	 *
+	 * @param SourceMapGenerator aSourceMap
+	 *        The source map that will be consumed.
+	 * @returns BasicSourceMapConsumer
+	 */
+	BasicSourceMapConsumer.fromSourceMap = function SourceMapConsumer_fromSourceMap(aSourceMap) {
+	  var smc = Object.create(BasicSourceMapConsumer.prototype);
+
+	  var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
+	  var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);
+	  smc.sourceRoot = aSourceMap._sourceRoot;
+	  smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(), smc.sourceRoot);
+	  smc.file = aSourceMap._file;
+
+	  // Because we are modifying the entries (by converting string sources and
+	  // names to indices into the sources and names ArraySets), we have to make
+	  // a copy of the entry or else bad things happen. Shared mutable state
+	  // strikes again! See github issue #191.
+
+	  var generatedMappings = aSourceMap._mappings.toArray().slice();
+	  var destGeneratedMappings = smc.__generatedMappings = [];
+	  var destOriginalMappings = smc.__originalMappings = [];
+
+	  for (var i = 0, length = generatedMappings.length; i < length; i++) {
+	    var srcMapping = generatedMappings[i];
+	    var destMapping = new Mapping();
+	    destMapping.generatedLine = srcMapping.generatedLine;
+	    destMapping.generatedColumn = srcMapping.generatedColumn;
+
+	    if (srcMapping.source) {
+	      destMapping.source = sources.indexOf(srcMapping.source);
+	      destMapping.originalLine = srcMapping.originalLine;
+	      destMapping.originalColumn = srcMapping.originalColumn;
+
+	      if (srcMapping.name) {
+	        destMapping.name = names.indexOf(srcMapping.name);
+	      }
+
+	      destOriginalMappings.push(destMapping);
+	    }
+
+	    destGeneratedMappings.push(destMapping);
+	  }
+
+	  quickSort(smc.__originalMappings, util.compareByOriginalPositions);
+
+	  return smc;
+	};
+
+	/**
+	 * The version of the source mapping spec that we are consuming.
+	 */
+	BasicSourceMapConsumer.prototype._version = 3;
+
+	/**
+	 * The list of original sources.
+	 */
+	Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {
+	  get: function () {
+	    return this._sources.toArray().map(function (s) {
+	      return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s;
+	    }, this);
+	  }
+	});
+
+	/**
+	 * Provide the JIT with a nice shape / hidden class.
+	 */
+	function Mapping() {
+	  this.generatedLine = 0;
+	  this.generatedColumn = 0;
+	  this.source = null;
+	  this.originalLine = null;
+	  this.originalColumn = null;
+	  this.name = null;
+	}
+
+	/**
+	 * Parse the mappings in a string in to a data structure which we can easily
+	 * query (the ordered arrays in the `this.__generatedMappings` and
+	 * `this.__originalMappings` properties).
+	 */
+	BasicSourceMapConsumer.prototype._parseMappings = function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
+	  var generatedLine = 1;
+	  var previousGeneratedColumn = 0;
+	  var previousOriginalLine = 0;
+	  var previousOriginalColumn = 0;
+	  var previousSource = 0;
+	  var previousName = 0;
+	  var length = aStr.length;
+	  var index = 0;
+	  var cachedSegments = {};
+	  var temp = {};
+	  var originalMappings = [];
+	  var generatedMappings = [];
+	  var mapping, str, segment, end, value;
+
+	  while (index < length) {
+	    if (aStr.charAt(index) === ';') {
+	      generatedLine++;
+	      index++;
+	      previousGeneratedColumn = 0;
+	    } else if (aStr.charAt(index) === ',') {
+	      index++;
+	    } else {
+	      mapping = new Mapping();
+	      mapping.generatedLine = generatedLine;
+
+	      // Because each offset is encoded relative to the previous one,
+	      // many segments often have the same encoding. We can exploit this
+	      // fact by caching the parsed variable length fields of each segment,
+	      // allowing us to avoid a second parse if we encounter the same
+	      // segment again.
+	      for (end = index; end < length; end++) {
+	        if (this._charIsMappingSeparator(aStr, end)) {
+	          break;
+	        }
+	      }
+	      str = aStr.slice(index, end);
+
+	      segment = cachedSegments[str];
+	      if (segment) {
+	        index += str.length;
+	      } else {
+	        segment = [];
+	        while (index < end) {
+	          base64VLQ.decode(aStr, index, temp);
+	          value = temp.value;
+	          index = temp.rest;
+	          segment.push(value);
+	        }
+
+	        if (segment.length === 2) {
+	          throw new Error('Found a source, but no line and column');
+	        }
+
+	        if (segment.length === 3) {
+	          throw new Error('Found a source and line, but no column');
+	        }
+
+	        cachedSegments[str] = segment;
+	      }
+
+	      // Generated column.
+	      mapping.generatedColumn = previousGeneratedColumn + segment[0];
+	      previousGeneratedColumn = mapping.generatedColumn;
+
+	      if (segment.length > 1) {
+	        // Original source.
+	        mapping.source = previousSource + segment[1];
+	        previousSource += segment[1];
+
+	        // Original line.
+	        mapping.originalLine = previousOriginalLine + segment[2];
+	        previousOriginalLine = mapping.originalLine;
+	        // Lines are stored 0-based
+	        mapping.originalLine += 1;
+
+	        // Original column.
+	        mapping.originalColumn = previousOriginalColumn + segment[3];
+	        previousOriginalColumn = mapping.originalColumn;
+
+	        if (segment.length > 4) {
+	          // Original name.
+	          mapping.name = previousName + segment[4];
+	          previousName += segment[4];
+	        }
+	      }
+
+	      generatedMappings.push(mapping);
+	      if (typeof mapping.originalLine === 'number') {
+	        originalMappings.push(mapping);
+	      }
+	    }
+	  }
+
+	  quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated);
+	  this.__generatedMappings = generatedMappings;
+
+	  quickSort(originalMappings, util.compareByOriginalPositions);
+	  this.__originalMappings = originalMappings;
+	};
+
+	/**
+	 * Find the mapping that best matches the hypothetical "needle" mapping that
+	 * we are searching for in the given "haystack" of mappings.
+	 */
+	BasicSourceMapConsumer.prototype._findMapping = function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, aColumnName, aComparator, aBias) {
+	  // To return the position we are searching for, we must first find the
+	  // mapping for the given position and then return the opposite position it
+	  // points to. Because the mappings are sorted, we can use binary search to
+	  // find the best mapping.
+
+	  if (aNeedle[aLineName] <= 0) {
+	    throw new TypeError('Line must be greater than or equal to 1, got ' + aNeedle[aLineName]);
+	  }
+	  if (aNeedle[aColumnName] < 0) {
+	    throw new TypeError('Column must be greater than or equal to 0, got ' + aNeedle[aColumnName]);
+	  }
+
+	  return binarySearch.search(aNeedle, aMappings, aComparator, aBias);
+	};
+
+	/**
+	 * Compute the last column for each generated mapping. The last column is
+	 * inclusive.
+	 */
+	BasicSourceMapConsumer.prototype.computeColumnSpans = function SourceMapConsumer_computeColumnSpans() {
+	  for (var index = 0; index < this._generatedMappings.length; ++index) {
+	    var mapping = this._generatedMappings[index];
+
+	    // Mappings do not contain a field for the last generated columnt. We
+	    // can come up with an optimistic estimate, however, by assuming that
+	    // mappings are contiguous (i.e. given two consecutive mappings, the
+	    // first mapping ends where the second one starts).
+	    if (index + 1 < this._generatedMappings.length) {
+	      var nextMapping = this._generatedMappings[index + 1];
+
+	      if (mapping.generatedLine === nextMapping.generatedLine) {
+	        mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1;
+	        continue;
+	      }
+	    }
+
+	    // The last mapping for each line spans the entire line.
+	    mapping.lastGeneratedColumn = Infinity;
+	  }
+	};
+
+	/**
+	 * Returns the original source, line, and column information for the generated
+	 * source's line and column positions provided. The only argument is an object
+	 * with the following properties:
+	 *
+	 *   - line: The line number in the generated source.
+	 *   - column: The column number in the generated source.
+	 *   - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
+	 *     'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
+	 *     closest element that is smaller than or greater than the one we are
+	 *     searching for, respectively, if the exact element cannot be found.
+	 *     Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.
+	 *
+	 * and an object is returned with the following properties:
+	 *
+	 *   - source: The original source file, or null.
+	 *   - line: The line number in the original source, or null.
+	 *   - column: The column number in the original source, or null.
+	 *   - name: The original identifier, or null.
+	 */
+	BasicSourceMapConsumer.prototype.originalPositionFor = function SourceMapConsumer_originalPositionFor(aArgs) {
+	  var needle = {
+	    generatedLine: util.getArg(aArgs, 'line'),
+	    generatedColumn: util.getArg(aArgs, 'column')
+	  };
+
+	  var index = this._findMapping(needle, this._generatedMappings, "generatedLine", "generatedColumn", util.compareByGeneratedPositionsDeflated, util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND));
+
+	  if (index >= 0) {
+	    var mapping = this._generatedMappings[index];
+
+	    if (mapping.generatedLine === needle.generatedLine) {
+	      var source = util.getArg(mapping, 'source', null);
+	      if (source !== null) {
+	        source = this._sources.at(source);
+	        if (this.sourceRoot != null) {
+	          source = util.join(this.sourceRoot, source);
+	        }
+	      }
+	      var name = util.getArg(mapping, 'name', null);
+	      if (name !== null) {
+	        name = this._names.at(name);
+	      }
+	      return {
+	        source: source,
+	        line: util.getArg(mapping, 'originalLine', null),
+	        column: util.getArg(mapping, 'originalColumn', null),
+	        name: name
+	      };
+	    }
+	  }
+
+	  return {
+	    source: null,
+	    line: null,
+	    column: null,
+	    name: null
+	  };
+	};
+
+	/**
+	 * Return true if we have the source content for every source in the source
+	 * map, false otherwise.
+	 */
+	BasicSourceMapConsumer.prototype.hasContentsOfAllSources = function BasicSourceMapConsumer_hasContentsOfAllSources() {
+	  if (!this.sourcesContent) {
+	    return false;
+	  }
+	  return this.sourcesContent.length >= this._sources.size() && !this.sourcesContent.some(function (sc) {
+	    return sc == null;
+	  });
+	};
+
+	/**
+	 * Returns the original source content. The only argument is the url of the
+	 * original source file. Returns null if no original source content is
+	 * available.
+	 */
+	BasicSourceMapConsumer.prototype.sourceContentFor = function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {
+	  if (!this.sourcesContent) {
+	    return null;
+	  }
+
+	  if (this.sourceRoot != null) {
+	    aSource = util.relative(this.sourceRoot, aSource);
+	  }
+
+	  if (this._sources.has(aSource)) {
+	    return this.sourcesContent[this._sources.indexOf(aSource)];
+	  }
+
+	  var url;
+	  if (this.sourceRoot != null && (url = util.urlParse(this.sourceRoot))) {
+	    // XXX: file:// URIs and absolute paths lead to unexpected behavior for
+	    // many users. We can help them out when they expect file:// URIs to
+	    // behave like it would if they were running a local HTTP server. See
+	    // https://bugzilla.mozilla.org/show_bug.cgi?id=885597.
+	    var fileUriAbsPath = aSource.replace(/^file:\/\//, "");
+	    if (url.scheme == "file" && this._sources.has(fileUriAbsPath)) {
+	      return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)];
+	    }
+
+	    if ((!url.path || url.path == "/") && this._sources.has("/" + aSource)) {
+	      return this.sourcesContent[this._sources.indexOf("/" + aSource)];
+	    }
+	  }
+
+	  // This function is used recursively from
+	  // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we
+	  // don't want to throw if we can't find the source - we just want to
+	  // return null, so we provide a flag to exit gracefully.
+	  if (nullOnMissing) {
+	    return null;
+	  } else {
+	    throw new Error('"' + aSource + '" is not in the SourceMap.');
+	  }
+	};
+
+	/**
+	 * Returns the generated line and column information for the original source,
+	 * line, and column positions provided. The only argument is an object with
+	 * the following properties:
+	 *
+	 *   - source: The filename of the original source.
+	 *   - line: The line number in the original source.
+	 *   - column: The column number in the original source.
+	 *   - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
+	 *     'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
+	 *     closest element that is smaller than or greater than the one we are
+	 *     searching for, respectively, if the exact element cannot be found.
+	 *     Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.
+	 *
+	 * and an object is returned with the following properties:
+	 *
+	 *   - line: The line number in the generated source, or null.
+	 *   - column: The column number in the generated source, or null.
+	 */
+	BasicSourceMapConsumer.prototype.generatedPositionFor = function SourceMapConsumer_generatedPositionFor(aArgs) {
+	  var source = util.getArg(aArgs, 'source');
+	  if (this.sourceRoot != null) {
+	    source = util.relative(this.sourceRoot, source);
+	  }
+	  if (!this._sources.has(source)) {
+	    return {
+	      line: null,
+	      column: null,
+	      lastColumn: null
+	    };
+	  }
+	  source = this._sources.indexOf(source);
+
+	  var needle = {
+	    source: source,
+	    originalLine: util.getArg(aArgs, 'line'),
+	    originalColumn: util.getArg(aArgs, 'column')
+	  };
+
+	  var index = this._findMapping(needle, this._originalMappings, "originalLine", "originalColumn", util.compareByOriginalPositions, util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND));
+
+	  if (index >= 0) {
+	    var mapping = this._originalMappings[index];
+
+	    if (mapping.source === needle.source) {
+	      return {
+	        line: util.getArg(mapping, 'generatedLine', null),
+	        column: util.getArg(mapping, 'generatedColumn', null),
+	        lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
+	      };
+	    }
+	  }
+
+	  return {
+	    line: null,
+	    column: null,
+	    lastColumn: null
+	  };
+	};
+
+	exports.BasicSourceMapConsumer = BasicSourceMapConsumer;
+
+	/**
+	 * An IndexedSourceMapConsumer instance represents a parsed source map which
+	 * we can query for information. It differs from BasicSourceMapConsumer in
+	 * that it takes "indexed" source maps (i.e. ones with a "sections" field) as
+	 * input.
+	 *
+	 * The only parameter is a raw source map (either as a JSON string, or already
+	 * parsed to an object). According to the spec for indexed source maps, they
+	 * have the following attributes:
+	 *
+	 *   - version: Which version of the source map spec this map is following.
+	 *   - file: Optional. The generated file this source map is associated with.
+	 *   - sections: A list of section definitions.
+	 *
+	 * Each value under the "sections" field has two fields:
+	 *   - offset: The offset into the original specified at which this section
+	 *       begins to apply, defined as an object with a "line" and "column"
+	 *       field.
+	 *   - map: A source map definition. This source map could also be indexed,
+	 *       but doesn't have to be.
+	 *
+	 * Instead of the "map" field, it's also possible to have a "url" field
+	 * specifying a URL to retrieve a source map from, but that's currently
+	 * unsupported.
+	 *
+	 * Here's an example source map, taken from the source map spec[0], but
+	 * modified to omit a section which uses the "url" field.
+	 *
+	 *  {
+	 *    version : 3,
+	 *    file: "app.js",
+	 *    sections: [{
+	 *      offset: {line:100, column:10},
+	 *      map: {
+	 *        version : 3,
+	 *        file: "section.js",
+	 *        sources: ["foo.js", "bar.js"],
+	 *        names: ["src", "maps", "are", "fun"],
+	 *        mappings: "AAAA,E;;ABCDE;"
+	 *      }
+	 *    }],
+	 *  }
+	 *
+	 * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt
+	 */
+	function IndexedSourceMapConsumer(aSourceMap) {
+	  var sourceMap = aSourceMap;
+	  if (typeof aSourceMap === 'string') {
+	    sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+	  }
+
+	  var version = util.getArg(sourceMap, 'version');
+	  var sections = util.getArg(sourceMap, 'sections');
+
+	  if (version != this._version) {
+	    throw new Error('Unsupported version: ' + version);
+	  }
+
+	  this._sources = new ArraySet();
+	  this._names = new ArraySet();
+
+	  var lastOffset = {
+	    line: -1,
+	    column: 0
+	  };
+	  this._sections = sections.map(function (s) {
+	    if (s.url) {
+	      // The url field will require support for asynchronicity.
+	      // See https://github.com/mozilla/source-map/issues/16
+	      throw new Error('Support for url field in sections not implemented.');
+	    }
+	    var offset = util.getArg(s, 'offset');
+	    var offsetLine = util.getArg(offset, 'line');
+	    var offsetColumn = util.getArg(offset, 'column');
+
+	    if (offsetLine < lastOffset.line || offsetLine === lastOffset.line && offsetColumn < lastOffset.column) {
+	      throw new Error('Section offsets must be ordered and non-overlapping.');
+	    }
+	    lastOffset = offset;
+
+	    return {
+	      generatedOffset: {
+	        // The offset fields are 0-based, but we use 1-based indices when
+	        // encoding/decoding from VLQ.
+	        generatedLine: offsetLine + 1,
+	        generatedColumn: offsetColumn + 1
+	      },
+	      consumer: new SourceMapConsumer(util.getArg(s, 'map'))
+	    };
+	  });
+	}
+
+	IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
+	IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer;
+
+	/**
+	 * The version of the source mapping spec that we are consuming.
+	 */
+	IndexedSourceMapConsumer.prototype._version = 3;
+
+	/**
+	 * The list of original sources.
+	 */
+	Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', {
+	  get: function () {
+	    var sources = [];
+	    for (var i = 0; i < this._sections.length; i++) {
+	      for (var j = 0; j < this._sections[i].consumer.sources.length; j++) {
+	        sources.push(this._sections[i].consumer.sources[j]);
+	      }
+	    }
+	    return sources;
+	  }
+	});
+
+	/**
+	 * Returns the original source, line, and column information for the generated
+	 * source's line and column positions provided. The only argument is an object
+	 * with the following properties:
+	 *
+	 *   - line: The line number in the generated source.
+	 *   - column: The column number in the generated source.
+	 *
+	 * and an object is returned with the following properties:
+	 *
+	 *   - source: The original source file, or null.
+	 *   - line: The line number in the original source, or null.
+	 *   - column: The column number in the original source, or null.
+	 *   - name: The original identifier, or null.
+	 */
+	IndexedSourceMapConsumer.prototype.originalPositionFor = function IndexedSourceMapConsumer_originalPositionFor(aArgs) {
+	  var needle = {
+	    generatedLine: util.getArg(aArgs, 'line'),
+	    generatedColumn: util.getArg(aArgs, 'column')
+	  };
+
+	  // Find the section containing the generated position we're trying to map
+	  // to an original position.
+	  var sectionIndex = binarySearch.search(needle, this._sections, function (needle, section) {
+	    var cmp = needle.generatedLine - section.generatedOffset.generatedLine;
+	    if (cmp) {
+	      return cmp;
+	    }
+
+	    return needle.generatedColumn - section.generatedOffset.generatedColumn;
+	  });
+	  var section = this._sections[sectionIndex];
+
+	  if (!section) {
+	    return {
+	      source: null,
+	      line: null,
+	      column: null,
+	      name: null
+	    };
+	  }
+
+	  return section.consumer.originalPositionFor({
+	    line: needle.generatedLine - (section.generatedOffset.generatedLine - 1),
+	    column: needle.generatedColumn - (section.generatedOffset.generatedLine === needle.generatedLine ? section.generatedOffset.generatedColumn - 1 : 0),
+	    bias: aArgs.bias
+	  });
+	};
+
+	/**
+	 * Return true if we have the source content for every source in the source
+	 * map, false otherwise.
+	 */
+	IndexedSourceMapConsumer.prototype.hasContentsOfAllSources = function IndexedSourceMapConsumer_hasContentsOfAllSources() {
+	  return this._sections.every(function (s) {
+	    return s.consumer.hasContentsOfAllSources();
+	  });
+	};
+
+	/**
+	 * Returns the original source content. The only argument is the url of the
+	 * original source file. Returns null if no original source content is
+	 * available.
+	 */
+	IndexedSourceMapConsumer.prototype.sourceContentFor = function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {
+	  for (var i = 0; i < this._sections.length; i++) {
+	    var section = this._sections[i];
+
+	    var content = section.consumer.sourceContentFor(aSource, true);
+	    if (content) {
+	      return content;
+	    }
+	  }
+	  if (nullOnMissing) {
+	    return null;
+	  } else {
+	    throw new Error('"' + aSource + '" is not in the SourceMap.');
+	  }
+	};
+
+	/**
+	 * Returns the generated line and column information for the original source,
+	 * line, and column positions provided. The only argument is an object with
+	 * the following properties:
+	 *
+	 *   - source: The filename of the original source.
+	 *   - line: The line number in the original source.
+	 *   - column: The column number in the original source.
+	 *
+	 * and an object is returned with the following properties:
+	 *
+	 *   - line: The line number in the generated source, or null.
+	 *   - column: The column number in the generated source, or null.
+	 */
+	IndexedSourceMapConsumer.prototype.generatedPositionFor = function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {
+	  for (var i = 0; i < this._sections.length; i++) {
+	    var section = this._sections[i];
+
+	    // Only consider this section if the requested source is in the list of
+	    // sources of the consumer.
+	    if (section.consumer.sources.indexOf(util.getArg(aArgs, 'source')) === -1) {
+	      continue;
+	    }
+	    var generatedPosition = section.consumer.generatedPositionFor(aArgs);
+	    if (generatedPosition) {
+	      var ret = {
+	        line: generatedPosition.line + (section.generatedOffset.generatedLine - 1),
+	        column: generatedPosition.column + (section.generatedOffset.generatedLine === generatedPosition.line ? section.generatedOffset.generatedColumn - 1 : 0)
+	      };
+	      return ret;
+	    }
+	  }
+
+	  return {
+	    line: null,
+	    column: null
+	  };
+	};
+
+	/**
+	 * Parse the mappings in a string in to a data structure which we can easily
+	 * query (the ordered arrays in the `this.__generatedMappings` and
+	 * `this.__originalMappings` properties).
+	 */
+	IndexedSourceMapConsumer.prototype._parseMappings = function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) {
+	  this.__generatedMappings = [];
+	  this.__originalMappings = [];
+	  for (var i = 0; i < this._sections.length; i++) {
+	    var section = this._sections[i];
+	    var sectionMappings = section.consumer._generatedMappings;
+	    for (var j = 0; j < sectionMappings.length; j++) {
+	      var mapping = sectionMappings[j];
+
+	      var source = section.consumer._sources.at(mapping.source);
+	      if (section.consumer.sourceRoot !== null) {
+	        source = util.join(section.consumer.sourceRoot, source);
+	      }
+	      this._sources.add(source);
+	      source = this._sources.indexOf(source);
+
+	      var name = section.consumer._names.at(mapping.name);
+	      this._names.add(name);
+	      name = this._names.indexOf(name);
+
+	      // The mappings coming from the consumer for the section have
+	      // generated positions relative to the start of the section, so we
+	      // need to offset them to be relative to the start of the concatenated
+	      // generated file.
+	      var adjustedMapping = {
+	        source: source,
+	        generatedLine: mapping.generatedLine + (section.generatedOffset.generatedLine - 1),
+	        generatedColumn: mapping.generatedColumn + (section.generatedOffset.generatedLine === mapping.generatedLine ? section.generatedOffset.generatedColumn - 1 : 0),
+	        originalLine: mapping.originalLine,
+	        originalColumn: mapping.originalColumn,
+	        name: name
+	      };
+
+	      this.__generatedMappings.push(adjustedMapping);
+	      if (typeof adjustedMapping.originalLine === 'number') {
+	        this.__originalMappings.push(adjustedMapping);
+	      }
+	    }
+	  }
+
+	  quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated);
+	  quickSort(this.__originalMappings, util.compareByOriginalPositions);
+	};
+
+	exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer;
+
+/***/ },
+/* 35 */
+/***/ function(module, exports) {
+
+	/* -*- Mode: js; js-indent-level: 2; -*- */
+	/*
+	 * Copyright 2011 Mozilla Foundation and contributors
+	 * Licensed under the New BSD license. See LICENSE or:
+	 * http://opensource.org/licenses/BSD-3-Clause
+	 */
+
+	exports.GREATEST_LOWER_BOUND = 1;
+	exports.LEAST_UPPER_BOUND = 2;
+
+	/**
+	 * Recursive implementation of binary search.
+	 *
+	 * @param aLow Indices here and lower do not contain the needle.
+	 * @param aHigh Indices here and higher do not contain the needle.
+	 * @param aNeedle The element being searched for.
+	 * @param aHaystack The non-empty array being searched.
+	 * @param aCompare Function which takes two elements and returns -1, 0, or 1.
+	 * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
+	 *     'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
+	 *     closest element that is smaller than or greater than the one we are
+	 *     searching for, respectively, if the exact element cannot be found.
+	 */
+	function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) {
+	  // This function terminates when one of the following is true:
+	  //
+	  //   1. We find the exact element we are looking for.
+	  //
+	  //   2. We did not find the exact element, but we can return the index of
+	  //      the next-closest element.
+	  //
+	  //   3. We did not find the exact element, and there is no next-closest
+	  //      element than the one we are searching for, so we return -1.
+	  var mid = Math.floor((aHigh - aLow) / 2) + aLow;
+	  var cmp = aCompare(aNeedle, aHaystack[mid], true);
+	  if (cmp === 0) {
+	    // Found the element we are looking for.
+	    return mid;
+	  } else if (cmp > 0) {
+	    // Our needle is greater than aHaystack[mid].
+	    if (aHigh - mid > 1) {
+	      // The element is in the upper half.
+	      return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias);
+	    }
+
+	    // The exact needle element was not found in this haystack. Determine if
+	    // we are in termination case (3) or (2) and return the appropriate thing.
+	    if (aBias == exports.LEAST_UPPER_BOUND) {
+	      return aHigh < aHaystack.length ? aHigh : -1;
+	    } else {
+	      return mid;
+	    }
+	  } else {
+	    // Our needle is less than aHaystack[mid].
+	    if (mid - aLow > 1) {
+	      // The element is in the lower half.
+	      return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias);
+	    }
+
+	    // we are in termination case (3) or (2) and return the appropriate thing.
+	    if (aBias == exports.LEAST_UPPER_BOUND) {
+	      return mid;
+	    } else {
+	      return aLow < 0 ? -1 : aLow;
+	    }
+	  }
+	}
+
+	/**
+	 * This is an implementation of binary search which will always try and return
+	 * the index of the closest element if there is no exact hit. This is because
+	 * mappings between original and generated line/col pairs are single points,
+	 * and there is an implicit region between each of them, so a miss just means
+	 * that you aren't on the very start of a region.
+	 *
+	 * @param aNeedle The element you are looking for.
+	 * @param aHaystack The array that is being searched.
+	 * @param aCompare A function which takes the needle and an element in the
+	 *     array and returns -1, 0, or 1 depending on whether the needle is less
+	 *     than, equal to, or greater than the element, respectively.
+	 * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
+	 *     'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
+	 *     closest element that is smaller than or greater than the one we are
+	 *     searching for, respectively, if the exact element cannot be found.
+	 *     Defaults to 'binarySearch.GREATEST_LOWER_BOUND'.
+	 */
+	exports.search = function search(aNeedle, aHaystack, aCompare, aBias) {
+	  if (aHaystack.length === 0) {
+	    return -1;
+	  }
+
+	  var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, aCompare, aBias || exports.GREATEST_LOWER_BOUND);
+	  if (index < 0) {
+	    return -1;
+	  }
+
+	  // We have found either the exact element, or the next-closest element than
+	  // the one we are searching for. However, there may be more than one such
+	  // element. Make sure we always return the smallest of these.
+	  while (index - 1 >= 0) {
+	    if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) {
+	      break;
+	    }
+	    --index;
+	  }
+
+	  return index;
+	};
+
+/***/ },
+/* 36 */
+/***/ function(module, exports) {
+
+	/* -*- Mode: js; js-indent-level: 2; -*- */
+	/*
+	 * Copyright 2011 Mozilla Foundation and contributors
+	 * Licensed under the New BSD license. See LICENSE or:
+	 * http://opensource.org/licenses/BSD-3-Clause
+	 */
+
+	// It turns out that some (most?) JavaScript engines don't self-host
+	// `Array.prototype.sort`. This makes sense because C++ will likely remain
+	// faster than JS when doing raw CPU-intensive sorting. However, when using a
+	// custom comparator function, calling back and forth between the VM's C++ and
+	// JIT'd JS is rather slow *and* loses JIT type information, resulting in
+	// worse generated code for the comparator function than would be optimal. In
+	// fact, when sorting with a comparator, these costs outweigh the benefits of
+	// sorting in C++. By using our own JS-implemented Quick Sort (below), we get
+	// a ~3500ms mean speed-up in `bench/bench.html`.
+
+	/**
+	 * Swap the elements indexed by `x` and `y` in the array `ary`.
+	 *
+	 * @param {Array} ary
+	 *        The array.
+	 * @param {Number} x
+	 *        The index of the first item.
+	 * @param {Number} y
+	 *        The index of the second item.
+	 */
+	function swap(ary, x, y) {
+	  var temp = ary[x];
+	  ary[x] = ary[y];
+	  ary[y] = temp;
+	}
+
+	/**
+	 * Returns a random integer within the range `low .. high` inclusive.
+	 *
+	 * @param {Number} low
+	 *        The lower bound on the range.
+	 * @param {Number} high
+	 *        The upper bound on the range.
+	 */
+	function randomIntInRange(low, high) {
+	  return Math.round(low + Math.random() * (high - low));
+	}
+
+	/**
+	 * The Quick Sort algorithm.
+	 *
+	 * @param {Array} ary
+	 *        An array to sort.
+	 * @param {function} comparator
+	 *        Function to use to compare two items.
+	 * @param {Number} p
+	 *        Start index of the array
+	 * @param {Number} r
+	 *        End index of the array
+	 */
+	function doQuickSort(ary, comparator, p, r) {
+	  // If our lower bound is less than our upper bound, we (1) partition the
+	  // array into two pieces and (2) recurse on each half. If it is not, this is
+	  // the empty array and our base case.
+
+	  if (p < r) {
+	    // (1) Partitioning.
+	    //
+	    // The partitioning chooses a pivot between `p` and `r` and moves all
+	    // elements that are less than or equal to the pivot to the before it, and
+	    // all the elements that are greater than it after it. The effect is that
+	    // once partition is done, the pivot is in the exact place it will be when
+	    // the array is put in sorted order, and it will not need to be moved
+	    // again. This runs in O(n) time.
+
+	    // Always choose a random pivot so that an input array which is reverse
+	    // sorted does not cause O(n^2) running time.
+	    var pivotIndex = randomIntInRange(p, r);
+	    var i = p - 1;
+
+	    swap(ary, pivotIndex, r);
+	    var pivot = ary[r];
+
+	    // Immediately after `j` is incremented in this loop, the following hold
+	    // true:
+	    //
+	    //   * Every element in `ary[p .. i]` is less than or equal to the pivot.
+	    //
+	    //   * Every element in `ary[i+1 .. j-1]` is greater than the pivot.
+	    for (var j = p; j < r; j++) {
+	      if (comparator(ary[j], pivot) <= 0) {
+	        i += 1;
+	        swap(ary, i, j);
+	      }
+	    }
+
+	    swap(ary, i + 1, j);
+	    var q = i + 1;
+
+	    // (2) Recurse on each half.
+
+	    doQuickSort(ary, comparator, p, q - 1);
+	    doQuickSort(ary, comparator, q + 1, r);
+	  }
+	}
+
+	/**
+	 * Sort the given array in-place with the given comparator function.
+	 *
+	 * @param {Array} ary
+	 *        An array to sort.
+	 * @param {function} comparator
+	 *        Function to use to compare two items.
+	 */
+	exports.quickSort = function (ary, comparator) {
+	  doQuickSort(ary, comparator, 0, ary.length - 1);
+	};
+
+/***/ },
+/* 37 */
+/***/ function(module, exports, __webpack_require__) {
+
+	/* -*- Mode: js; js-indent-level: 2; -*- */
+	/*
+	 * Copyright 2011 Mozilla Foundation and contributors
+	 * Licensed under the New BSD license. See LICENSE or:
+	 * http://opensource.org/licenses/BSD-3-Clause
+	 */
+
+	var SourceMapGenerator = __webpack_require__(28).SourceMapGenerator;
+	var util = __webpack_require__(31);
+
+	// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other
+	// operating systems these days (capturing the result).
+	var REGEX_NEWLINE = /(\r?\n)/;
+
+	// Newline character code for charCodeAt() comparisons
+	var NEWLINE_CODE = 10;
+
+	// Private symbol for identifying `SourceNode`s when multiple versions of
+	// the source-map library are loaded. This MUST NOT CHANGE across
+	// versions!
+	var isSourceNode = "$$$isSourceNode$$$";
+
+	/**
+	 * SourceNodes provide a way to abstract over interpolating/concatenating
+	 * snippets of generated JavaScript source code while maintaining the line and
+	 * column information associated with the original source code.
+	 *
+	 * @param aLine The original line number.
+	 * @param aColumn The original column number.
+	 * @param aSource The original source's filename.
+	 * @param aChunks Optional. An array of strings which are snippets of
+	 *        generated JS, or other SourceNodes.
+	 * @param aName The original identifier.
+	 */
+	function SourceNode(aLine, aColumn, aSource, aChunks, aName) {
+	  this.children = [];
+	  this.sourceContents = {};
+	  this.line = aLine == null ? null : aLine;
+	  this.column = aColumn == null ? null : aColumn;
+	  this.source = aSource == null ? null : aSource;
+	  this.name = aName == null ? null : aName;
+	  this[isSourceNode] = true;
+	  if (aChunks != null) this.add(aChunks);
+	}
+
+	/**
+	 * Creates a SourceNode from generated code and a SourceMapConsumer.
+	 *
+	 * @param aGeneratedCode The generated code
+	 * @param aSourceMapConsumer The SourceMap for the generated code
+	 * @param aRelativePath Optional. The path that relative sources in the
+	 *        SourceMapConsumer should be relative to.
+	 */
+	SourceNode.fromStringWithSourceMap = function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) {
+	  // The SourceNode we want to fill with the generated code
+	  // and the SourceMap
+	  var node = new SourceNode();
+
+	  // All even indices of this array are one line of the generated code,
+	  // while all odd indices are the newlines between two adjacent lines
+	  // (since `REGEX_NEWLINE` captures its match).
+	  // Processed fragments are accessed by calling `shiftNextLine`.
+	  var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);
+	  var remainingLinesIndex = 0;
+	  var shiftNextLine = function () {
+	    var lineContents = getNextLine();
+	    // The last line of a file might not have a newline.
+	    var newLine = getNextLine() || "";
+	    return lineContents + newLine;
+
+	    function getNextLine() {
+	      return remainingLinesIndex < remainingLines.length ? remainingLines[remainingLinesIndex++] : undefined;
+	    }
+	  };
+
+	  // We need to remember the position of "remainingLines"
+	  var lastGeneratedLine = 1,
+	      lastGeneratedColumn = 0;
+
+	  // The generate SourceNodes we need a code range.
+	  // To extract it current and last mapping is used.
+	  // Here we store the last mapping.
+	  var lastMapping = null;
+
+	  aSourceMapConsumer.eachMapping(function (mapping) {
+	    if (lastMapping !== null) {
+	      // We add the code from "lastMapping" to "mapping":
+	      // First check if there is a new line in between.
+	      if (lastGeneratedLine < mapping.generatedLine) {
+	        // Associate first line with "lastMapping"
+	        addMappingWithCode(lastMapping, shiftNextLine());
+	        lastGeneratedLine++;
+	        lastGeneratedColumn = 0;
+	        // The remaining code is added without mapping
+	      } else {
+	        // There is no new line in between.
+	        // Associate the code between "lastGeneratedColumn" and
+	        // "mapping.generatedColumn" with "lastMapping"
+	        var nextLine = remainingLines[remainingLinesIndex];
+	        var code = nextLine.substr(0, mapping.generatedColumn - lastGeneratedColumn);
+	        remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn - lastGeneratedColumn);
+	        lastGeneratedColumn = mapping.generatedColumn;
+	        addMappingWithCode(lastMapping, code);
+	        // No more remaining code, continue
+	        lastMapping = mapping;
+	        return;
+	      }
+	    }
+	    // We add the generated code until the first mapping
+	    // to the SourceNode without any mapping.
+	    // Each line is added as separate string.
+	    while (lastGeneratedLine < mapping.generatedLine) {
+	      node.add(shiftNextLine());
+	      lastGeneratedLine++;
+	    }
+	    if (lastGeneratedColumn < mapping.generatedColumn) {
+	      var nextLine = remainingLines[remainingLinesIndex];
+	      node.add(nextLine.substr(0, mapping.generatedColumn));
+	      remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn);
+	      lastGeneratedColumn = mapping.generatedColumn;
+	    }
+	    lastMapping = mapping;
+	  }, this);
+	  // We have processed all mappings.
+	  if (remainingLinesIndex < remainingLines.length) {
+	    if (lastMapping) {
+	      // Associate the remaining code in the current line with "lastMapping"
+	      addMappingWithCode(lastMapping, shiftNextLine());
+	    }
+	    // and add the remaining lines without any mapping
+	    node.add(remainingLines.splice(remainingLinesIndex).join(""));
+	  }
+
+	  // Copy sourcesContent into SourceNode
+	  aSourceMapConsumer.sources.forEach(function (sourceFile) {
+	    var content = aSourceMapConsumer.sourceContentFor(sourceFile);
+	    if (content != null) {
+	      if (aRelativePath != null) {
+	        sourceFile = util.join(aRelativePath, sourceFile);
+	      }
+	      node.setSourceContent(sourceFile, content);
+	    }
+	  });
+
+	  return node;
+
+	  function addMappingWithCode(mapping, code) {
+	    if (mapping === null || mapping.source === undefined) {
+	      node.add(code);
+	    } else {
+	      var source = aRelativePath ? util.join(aRelativePath, mapping.source) : mapping.source;
+	      node.add(new SourceNode(mapping.originalLine, mapping.originalColumn, source, code, mapping.name));
+	    }
+	  }
+	};
+
+	/**
+	 * Add a chunk of generated JS to this source node.
+	 *
+	 * @param aChunk A string snippet of generated JS code, another instance of
+	 *        SourceNode, or an array where each member is one of those things.
+	 */
+	SourceNode.prototype.add = function SourceNode_add(aChunk) {
+	  if (Array.isArray(aChunk)) {
+	    aChunk.forEach(function (chunk) {
+	      this.add(chunk);
+	    }, this);
+	  } else if (aChunk[isSourceNode] || typeof aChunk === "string") {
+	    if (aChunk) {
+	      this.children.push(aChunk);
+	    }
+	  } else {
+	    throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk);
+	  }
+	  return this;
+	};
+
+	/**
+	 * Add a chunk of generated JS to the beginning of this source node.
+	 *
+	 * @param aChunk A string snippet of generated JS code, another instance of
+	 *        SourceNode, or an array where each member is one of those things.
+	 */
+	SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) {
+	  if (Array.isArray(aChunk)) {
+	    for (var i = aChunk.length - 1; i >= 0; i--) {
+	      this.prepend(aChunk[i]);
+	    }
+	  } else if (aChunk[isSourceNode] || typeof aChunk === "string") {
+	    this.children.unshift(aChunk);
+	  } else {
+	    throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk);
+	  }
+	  return this;
+	};
+
+	/**
+	 * Walk over the tree of JS snippets in this node and its children. The
+	 * walking function is called once for each snippet of JS and is passed that
+	 * snippet and the its original associated source's line/column location.
+	 *
+	 * @param aFn The traversal function.
+	 */
+	SourceNode.prototype.walk = function SourceNode_walk(aFn) {
+	  var chunk;
+	  for (var i = 0, len = this.children.length; i < len; i++) {
+	    chunk = this.children[i];
+	    if (chunk[isSourceNode]) {
+	      chunk.walk(aFn);
+	    } else {
+	      if (chunk !== '') {
+	        aFn(chunk, { source: this.source,
+	          line: this.line,
+	          column: this.column,
+	          name: this.name });
+	      }
+	    }
+	  }
+	};
+
+	/**
+	 * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between
+	 * each of `this.children`.
+	 *
+	 * @param aSep The separator.
+	 */
+	SourceNode.prototype.join = function SourceNode_join(aSep) {
+	  var newChildren;
+	  var i;
+	  var len = this.children.length;
+	  if (len > 0) {
+	    newChildren = [];
+	    for (i = 0; i < len - 1; i++) {
+	      newChildren.push(this.children[i]);
+	      newChildren.push(aSep);
+	    }
+	    newChildren.push(this.children[i]);
+	    this.children = newChildren;
+	  }
+	  return this;
+	};
+
+	/**
+	 * Call String.prototype.replace on the very right-most source snippet. Useful
+	 * for trimming whitespace from the end of a source node, etc.
+	 *
+	 * @param aPattern The pattern to replace.
+	 * @param aReplacement The thing to replace the pattern with.
+	 */
+	SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) {
+	  var lastChild = this.children[this.children.length - 1];
+	  if (lastChild[isSourceNode]) {
+	    lastChild.replaceRight(aPattern, aReplacement);
+	  } else if (typeof lastChild === 'string') {
+	    this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);
+	  } else {
+	    this.children.push(''.replace(aPattern, aReplacement));
+	  }
+	  return this;
+	};
+
+	/**
+	 * Set the source content for a source file. This will be added to the SourceMapGenerator
+	 * in the sourcesContent field.
+	 *
+	 * @param aSourceFile The filename of the source file
+	 * @param aSourceContent The content of the source file
+	 */
+	SourceNode.prototype.setSourceContent = function SourceNode_setSourceContent(aSourceFile, aSourceContent) {
+	  this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;
+	};
+
+	/**
+	 * Walk over the tree of SourceNodes. The walking function is called for each
+	 * source file content and is passed the filename and source content.
+	 *
+	 * @param aFn The traversal function.
+	 */
+	SourceNode.prototype.walkSourceContents = function SourceNode_walkSourceContents(aFn) {
+	  for (var i = 0, len = this.children.length; i < len; i++) {
+	    if (this.children[i][isSourceNode]) {
+	      this.children[i].walkSourceContents(aFn);
+	    }
+	  }
+
+	  var sources = Object.keys(this.sourceContents);
+	  for (var i = 0, len = sources.length; i < len; i++) {
+	    aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);
+	  }
+	};
+
+	/**
+	 * Return the string representation of this source node. Walks over the tree
+	 * and concatenates all the various snippets together to one string.
+	 */
+	SourceNode.prototype.toString = function SourceNode_toString() {
+	  var str = "";
+	  this.walk(function (chunk) {
+	    str += chunk;
+	  });
+	  return str;
+	};
+
+	/**
+	 * Returns the string representation of this source node along with a source
+	 * map.
+	 */
+	SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) {
+	  var generated = {
+	    code: "",
+	    line: 1,
+	    column: 0
+	  };
+	  var map = new SourceMapGenerator(aArgs);
+	  var sourceMappingActive = false;
+	  var lastOriginalSource = null;
+	  var lastOriginalLine = null;
+	  var lastOriginalColumn = null;
+	  var lastOriginalName = null;
+	  this.walk(function (chunk, original) {
+	    generated.code += chunk;
+	    if (original.source !== null && original.line !== null && original.column !== null) {
+	      if (lastOriginalSource !== original.source || lastOriginalLine !== original.line || lastOriginalColumn !== original.column || lastOriginalName !== original.name) {
+	        map.addMapping({
+	          source: original.source,
+	          original: {
+	            line: original.line,
+	            column: original.column
+	          },
+	          generated: {
+	            line: generated.line,
+	            column: generated.column
+	          },
+	          name: original.name
+	        });
+	      }
+	      lastOriginalSource = original.source;
+	      lastOriginalLine = original.line;
+	      lastOriginalColumn = original.column;
+	      lastOriginalName = original.name;
+	      sourceMappingActive = true;
+	    } else if (sourceMappingActive) {
+	      map.addMapping({
+	        generated: {
+	          line: generated.line,
+	          column: generated.column
+	        }
+	      });
+	      lastOriginalSource = null;
+	      sourceMappingActive = false;
+	    }
+	    for (var idx = 0, length = chunk.length; idx < length; idx++) {
+	      if (chunk.charCodeAt(idx) === NEWLINE_CODE) {
+	        generated.line++;
+	        generated.column = 0;
+	        // Mappings end at eol
+	        if (idx + 1 === length) {
+	          lastOriginalSource = null;
+	          sourceMappingActive = false;
+	        } else if (sourceMappingActive) {
+	          map.addMapping({
+	            source: original.source,
+	            original: {
+	              line: original.line,
+	              column: original.column
+	            },
+	            generated: {
+	              line: generated.line,
+	              column: generated.column
+	            },
+	            name: original.name
+	          });
+	        }
+	      } else {
+	        generated.column++;
+	      }
+	    }
+	  });
+	  this.walkSourceContents(function (sourceFile, sourceContent) {
+	    map.setSourceContent(sourceFile, sourceContent);
+	  });
+
+	  return { code: generated.code, map: map };
+	};
+
+	exports.SourceNode = SourceNode;
+
 /***/ }
 /******/ ])
 });
 ;
\ No newline at end of file