Vendor in babel-plugin-jsm-to-esmodules@0.4.0
authorDan Mosedale <dmose@meer.net>
Wed, 09 May 2018 08:53:14 -0700
changeset 1512665 3845313b6fbd752efa6fc4cf7f848b750f48506d
parent 1512664 067ef3c2e05fce94d703eb8c02f3087e0e18bb99
child 1512666 25b3a2aed2bfc778b71ad522f4d1944d2c848f6a
push id271853
push userdmosedale@mozilla.com
push dateWed, 16 May 2018 04:43:14 +0000
treeherdertry@25b3a2aed2bf [default view] [failures only]
milestone62.0a1
Vendor in babel-plugin-jsm-to-esmodules@0.4.0
node_modules/babel-plugin-jsm-to-esmodules/.npmignore
node_modules/babel-plugin-jsm-to-esmodules/.travis.yml
node_modules/babel-plugin-jsm-to-esmodules/LICENSE
node_modules/babel-plugin-jsm-to-esmodules/README.md
node_modules/babel-plugin-jsm-to-esmodules/lib/polyfill.js
node_modules/babel-plugin-jsm-to-esmodules/package-lock.json
node_modules/babel-plugin-jsm-to-esmodules/package.json
node_modules/babel-plugin-jsm-to-esmodules/plugin.js
node_modules/babel-plugin-jsm-to-esmodules/test/fixtures/expected/export.js
node_modules/babel-plugin-jsm-to-esmodules/test/fixtures/expected/import.js
node_modules/babel-plugin-jsm-to-esmodules/test/fixtures/source/export.js
node_modules/babel-plugin-jsm-to-esmodules/test/fixtures/source/import.js
node_modules/babel-plugin-jsm-to-esmodules/test/index.test.js
package-lock.json
package.json
new file mode 100644
--- /dev/null
+++ b/node_modules/babel-plugin-jsm-to-esmodules/.npmignore
@@ -0,0 +1,4 @@
+node_modules/
+*.log
+.DS_Store
+metadataparser/data/
new file mode 100644
--- /dev/null
+++ b/node_modules/babel-plugin-jsm-to-esmodules/.travis.yml
@@ -0,0 +1,13 @@
+language: node_js
+node_js:
+- 4
+notifications:
+  email: false
+deploy:
+  provider: npm
+  email: k88hudson@gmail.com
+  on:
+    branch: master
+    tags: true
+  api_key:
+    secure: nj+xvgijPU61oDhHKbKFZWDjVwMP0rGQdhSb1QHKMWzOPSSOxE9fPaynd4xIO63x4+B3Lc0ZWa83LQCvSHW6zApPRzBp/eBNYCpir8EVD7noyeo2mgAXnj5MWypGgXrsp84vj67vwtFSoERDBhgO/XWVJDoLfEn+4bhisQaBg4EaOh9tiIwxbomU7efdcZzgoZIR6afocwktTCKUmylmHCOwS8JiiPjambEd0oFUrS5Wa0e+jSn2ma8oqmixlpaZ+TQfQPSDM31veGEi2dl/NVmZsb4IcT/ZQQ5jtQZW4vzHzO0fNdm8I6sieeuOpCq6Suy5w8pDWSCn/QERLgiZkZy9l5rTVtTa/kadaiW+dNoferIVnSPVoJqIhVZYQLm8bvhb5IxZXcD3xip/JGzd+yuOJZI4+Tg8yTM/y7nAfCgxZJGibxP4N34+EbPRrMfGVh8zHhOqaXwbIYvts0SLbD+fNbea18SzXf9XQRwbPPChMw5lYAAfh4ACnpXTbPewpT2+zjyMLMDxkXlxpPpB1ZiOpmQ3xvuE7pNJqpIqZvQzr0/YZ6wR7GptVhZHNZHt6za9FPS6Rv41t0ErtkTFn9AbENHKnbUamt9yiypMeVquM49DuDn6uKhWst/0PeDH6YYMok6vqCrJ/l1WUDralaQfJX/mMI8Gt02bMRwXGHc=
new file mode 100644
--- /dev/null
+++ b/node_modules/babel-plugin-jsm-to-esmodules/LICENSE
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) Kate Hudson <k88hudson@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
new file mode 100644
--- /dev/null
+++ b/node_modules/babel-plugin-jsm-to-esmodules/README.md
@@ -0,0 +1,119 @@
+# JSM to ES Module Babel Plugin
+
+[![Build Status](https://travis-ci.org/k88hudson/babel-plugin-jsm-to-esmodules.svg?branch=master)](https://travis-ci.org/k88hudson/babel-plugin-jsm-to-esmodules)
+
+This module converts import and export statements in `.jsm` modules to ES modules. For example:
+
+Source:
+
+```js
+const {utils: Cu} = Components;
+const {Bar, Baz} = Cu.import("resource://activity-stream/addon/barbaz.jsm", {});
+
+function Stuff() {
+  return 123;
+}
+
+this.Whatever = {};
+this.Stuff = Stuff;
+var EXPORTED_SYMBOLS = ["Stuff", "Whatever"];
+```
+
+Compiles to:
+
+```js
+import {Bar, Baz} from "addon/barbaz.js";
+
+export function Stuff() {
+  return 123;
+}
+
+export var Whatever = {};
+```
+
+## Caveats / Limitations
+
+### Use top-level imports and exports only
+
+Because `import` and `export` statements in ES modules must be statically analyzable, this plugin will only transform
+top level `Cu.import` / `EXPORTED_SYMBOLS`. Example:
+
+Good:
+
+```js
+const {utils: Cu} = Components;
+const {Bar} = Cu.import("resource://foo/Bar.jsm", {});
+
+this.Baz = 123;
+this.EXPORTED_SYMBOLS = ["Baz"];
+```
+
+Bad:
+
+```js
+const {utils: Cu} = Components;
+const root = this;
+function innerFunction() {
+  // This won't get converted because it's inside innerFunction
+  const {Bar} = Cu.import("resource://foo/Bar.jsm", {});
+
+  // Don't do this either
+  root.Baz = 123;
+}
+
+var EXPORTED_SYMBOLS = ["Baz"];
+```
+
+### Don't alias `this` or dynamically add items to `var EXPORTED_SYMBOLS` when exporting
+
+You should only declare `this.EXPORTED_SYMBOLS` once in the top-level scope, and it should not be modified.
+
+Good:
+
+```js
+function Foo() {...}
+this.Foo = Foo;
+this.Bar = 123;
+this.EXPORTED_SYMBOLS = ["Foo", "Bar"];
+```
+
+Bad:
+
+```js
+const root = this;
+const Foo = 123;
+root.EXPORTED_SYMBOLS = ["Foo"]; // Don't alias this when exporting
+root.Bar = 456;
+root.EXPORTED_SYMBOLS.push("Bar"); // Don't do this
+
+```
+
+### Don't reassign Components.utils.import
+
+Assigning variables to `Components` or `Components.utils` is OK, but don't assign the `.import`;
+
+```js
+const C = Components; // OK
+const {utils: Cu} = Components; // OK
+const u = Components.utils // OK
+
+const {import} = Cu; // Don't do this
+const i = Components.utils.import // Don't do this
+
+```
+
+## Options
+
+### `basePath`
+
+Defaults to `/^resource:\/\/`. A RegEx or String that tests for which import paths to rewrite.
+
+### `replace`
+
+Defaults to `false`. Remove the `basePath` component of the import string?
+
+e.g. If the basePath is `/^resource:\/\/`, `resource://activity-stream/foo.js` will be rewritten to `activity-stream/foo.js`.
+
+```
+"plugins": ["transform-react-jsx", {basePath: "resource://activity-stream/"}],
+```
new file mode 100644
--- /dev/null
+++ b/node_modules/babel-plugin-jsm-to-esmodules/lib/polyfill.js
@@ -0,0 +1,48 @@
+// https://tc39.github.io/ecma262/#sec-array.prototype.includes
+if (!Array.prototype.includes) {
+  Object.defineProperty(Array.prototype, 'includes', {
+    value: function(searchElement, fromIndex) {
+
+      // 1. Let O be ? ToObject(this value).
+      if (this == null) {
+        throw new TypeError('"this" is null or not defined');
+      }
+
+      var o = Object(this);
+
+      // 2. Let len be ? ToLength(? Get(O, "length")).
+      var len = o.length >>> 0;
+
+      // 3. If len is 0, return false.
+      if (len === 0) {
+        return false;
+      }
+
+      // 4. Let n be ? ToInteger(fromIndex).
+      //    (If fromIndex is undefined, this step produces the value 0.)
+      var n = fromIndex | 0;
+
+      // 5. If n ≥ 0, then
+      //  a. Let k be n.
+      // 6. Else n < 0,
+      //  a. Let k be len + n.
+      //  b. If k < 0, let k be 0.
+      var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
+
+      // 7. Repeat, while k < len
+      while (k < len) {
+        // a. Let elementK be the result of ? Get(O, ! ToString(k)).
+        // b. If SameValueZero(searchElement, elementK) is true, return true.
+        // c. Increase k by 1.
+        // NOTE: === provides the correct "SameValueZero" comparison needed here.
+        if (o[k] === searchElement) {
+          return true;
+        }
+        k++;
+      }
+
+      // 8. Return false
+      return false;
+    }
+  });
+}
new file mode 100644
--- /dev/null
+++ b/node_modules/babel-plugin-jsm-to-esmodules/package-lock.json
@@ -0,0 +1,698 @@
+{
+  "name": "babel-plugin-jsm-to-esmodules",
+  "version": "0.4.0",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "ansi-regex": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+      "dev": true
+    },
+    "ansi-styles": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+      "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+      "dev": true
+    },
+    "assertion-error": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+      "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+      "dev": true
+    },
+    "babel-code-frame": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+      "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "esutils": "2.0.2",
+        "js-tokens": "3.0.2"
+      }
+    },
+    "babel-core": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz",
+      "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=",
+      "dev": true,
+      "requires": {
+        "babel-code-frame": "6.26.0",
+        "babel-generator": "6.26.1",
+        "babel-helpers": "6.24.1",
+        "babel-messages": "6.23.0",
+        "babel-register": "6.26.0",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0",
+        "babylon": "6.18.0",
+        "convert-source-map": "1.5.1",
+        "debug": "2.6.9",
+        "json5": "0.5.1",
+        "lodash": "4.17.5",
+        "minimatch": "3.0.4",
+        "path-is-absolute": "1.0.1",
+        "private": "0.1.8",
+        "slash": "1.0.0",
+        "source-map": "0.5.7"
+      }
+    },
+    "babel-generator": {
+      "version": "6.26.1",
+      "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz",
+      "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==",
+      "dev": true,
+      "requires": {
+        "babel-messages": "6.23.0",
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0",
+        "detect-indent": "4.0.0",
+        "jsesc": "1.3.0",
+        "lodash": "4.17.5",
+        "source-map": "0.5.7",
+        "trim-right": "1.0.1"
+      }
+    },
+    "babel-helpers": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
+      "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-messages": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+      "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-register": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
+      "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
+      "dev": true,
+      "requires": {
+        "babel-core": "6.26.0",
+        "babel-runtime": "6.26.0",
+        "core-js": "2.5.3",
+        "home-or-tmp": "2.0.0",
+        "lodash": "4.17.5",
+        "mkdirp": "0.5.1",
+        "source-map-support": "0.4.18"
+      }
+    },
+    "babel-runtime": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+      "dev": true,
+      "requires": {
+        "core-js": "2.5.3",
+        "regenerator-runtime": "0.11.1"
+      }
+    },
+    "babel-template": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
+      "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0",
+        "babylon": "6.18.0",
+        "lodash": "4.17.5"
+      }
+    },
+    "babel-traverse": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
+      "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
+      "dev": true,
+      "requires": {
+        "babel-code-frame": "6.26.0",
+        "babel-messages": "6.23.0",
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0",
+        "babylon": "6.18.0",
+        "debug": "2.6.9",
+        "globals": "9.18.0",
+        "invariant": "2.2.2",
+        "lodash": "4.17.5"
+      }
+    },
+    "babel-types": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
+      "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "esutils": "2.0.2",
+        "lodash": "4.17.5",
+        "to-fast-properties": "1.0.3"
+      }
+    },
+    "babylon": {
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+      "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
+      "dev": true
+    },
+    "balanced-match": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+      "dev": true
+    },
+    "brace-expansion": {
+      "version": "1.1.8",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
+      "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+      "dev": true,
+      "requires": {
+        "balanced-match": "1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "browser-stdout": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz",
+      "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=",
+      "dev": true
+    },
+    "chai": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz",
+      "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=",
+      "dev": true,
+      "requires": {
+        "assertion-error": "1.1.0",
+        "deep-eql": "0.1.3",
+        "type-detect": "1.0.0"
+      }
+    },
+    "chai-string": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/chai-string/-/chai-string-1.4.0.tgz",
+      "integrity": "sha1-NZFAwFHTak5LGl/GuRAVL0OKjUk=",
+      "dev": true
+    },
+    "chalk": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+      "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "2.2.1",
+        "escape-string-regexp": "1.0.5",
+        "has-ansi": "2.0.0",
+        "strip-ansi": "3.0.1",
+        "supports-color": "2.0.0"
+      }
+    },
+    "commander": {
+      "version": "2.9.0",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
+      "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=",
+      "dev": true,
+      "requires": {
+        "graceful-readlink": "1.0.1"
+      }
+    },
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "dev": true
+    },
+    "convert-source-map": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz",
+      "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=",
+      "dev": true
+    },
+    "core-js": {
+      "version": "2.5.3",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz",
+      "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=",
+      "dev": true
+    },
+    "debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "requires": {
+        "ms": "2.0.0"
+      }
+    },
+    "deep-eql": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz",
+      "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=",
+      "dev": true,
+      "requires": {
+        "type-detect": "0.1.1"
+      },
+      "dependencies": {
+        "type-detect": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz",
+          "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=",
+          "dev": true
+        }
+      }
+    },
+    "detect-indent": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
+      "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
+      "dev": true,
+      "requires": {
+        "repeating": "2.0.1"
+      }
+    },
+    "diff": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz",
+      "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=",
+      "dev": true
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+      "dev": true
+    },
+    "esutils": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+      "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+      "dev": true
+    },
+    "fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "dev": true
+    },
+    "glob": {
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz",
+      "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=",
+      "dev": true,
+      "requires": {
+        "fs.realpath": "1.0.0",
+        "inflight": "1.0.6",
+        "inherits": "2.0.3",
+        "minimatch": "3.0.4",
+        "once": "1.4.0",
+        "path-is-absolute": "1.0.1"
+      }
+    },
+    "globals": {
+      "version": "9.18.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+      "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+      "dev": true
+    },
+    "graceful-readlink": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
+      "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
+      "dev": true
+    },
+    "growl": {
+      "version": "1.9.2",
+      "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz",
+      "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=",
+      "dev": true
+    },
+    "has-ansi": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+      "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "2.1.1"
+      }
+    },
+    "has-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+      "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+      "dev": true
+    },
+    "he": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
+      "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
+      "dev": true
+    },
+    "home-or-tmp": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
+      "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=",
+      "dev": true,
+      "requires": {
+        "os-homedir": "1.0.2",
+        "os-tmpdir": "1.0.2"
+      }
+    },
+    "inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "dev": true,
+      "requires": {
+        "once": "1.4.0",
+        "wrappy": "1.0.2"
+      }
+    },
+    "inherits": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+      "dev": true
+    },
+    "invariant": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
+      "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=",
+      "dev": true,
+      "requires": {
+        "loose-envify": "1.3.1"
+      }
+    },
+    "is-finite": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+      "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+      "dev": true,
+      "requires": {
+        "number-is-nan": "1.0.1"
+      }
+    },
+    "js-tokens": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+      "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+      "dev": true
+    },
+    "jsesc": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
+      "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
+      "dev": true
+    },
+    "json3": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz",
+      "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=",
+      "dev": true
+    },
+    "json5": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+      "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+      "dev": true
+    },
+    "lodash": {
+      "version": "4.17.5",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz",
+      "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==",
+      "dev": true
+    },
+    "lodash._baseassign": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz",
+      "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=",
+      "dev": true,
+      "requires": {
+        "lodash._basecopy": "3.0.1",
+        "lodash.keys": "3.1.2"
+      }
+    },
+    "lodash._basecopy": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz",
+      "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=",
+      "dev": true
+    },
+    "lodash._basecreate": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz",
+      "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=",
+      "dev": true
+    },
+    "lodash._getnative": {
+      "version": "3.9.1",
+      "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
+      "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=",
+      "dev": true
+    },
+    "lodash._isiterateecall": {
+      "version": "3.0.9",
+      "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz",
+      "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=",
+      "dev": true
+    },
+    "lodash.create": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz",
+      "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=",
+      "dev": true,
+      "requires": {
+        "lodash._baseassign": "3.2.0",
+        "lodash._basecreate": "3.0.3",
+        "lodash._isiterateecall": "3.0.9"
+      }
+    },
+    "lodash.isarguments": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
+      "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=",
+      "dev": true
+    },
+    "lodash.isarray": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
+      "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=",
+      "dev": true
+    },
+    "lodash.keys": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
+      "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=",
+      "dev": true,
+      "requires": {
+        "lodash._getnative": "3.9.1",
+        "lodash.isarguments": "3.1.0",
+        "lodash.isarray": "3.0.4"
+      }
+    },
+    "loose-envify": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
+      "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
+      "dev": true,
+      "requires": {
+        "js-tokens": "3.0.2"
+      }
+    },
+    "minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "dev": true,
+      "requires": {
+        "brace-expansion": "1.1.8"
+      }
+    },
+    "minimist": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+      "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+      "dev": true
+    },
+    "mkdirp": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+      "dev": true,
+      "requires": {
+        "minimist": "0.0.8"
+      }
+    },
+    "mocha": {
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz",
+      "integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==",
+      "dev": true,
+      "requires": {
+        "browser-stdout": "1.3.0",
+        "commander": "2.9.0",
+        "debug": "2.6.8",
+        "diff": "3.2.0",
+        "escape-string-regexp": "1.0.5",
+        "glob": "7.1.1",
+        "growl": "1.9.2",
+        "he": "1.1.1",
+        "json3": "3.3.2",
+        "lodash.create": "3.1.1",
+        "mkdirp": "0.5.1",
+        "supports-color": "3.1.2"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.8",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
+          "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "3.1.2",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz",
+          "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=",
+          "dev": true,
+          "requires": {
+            "has-flag": "1.0.0"
+          }
+        }
+      }
+    },
+    "ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "number-is-nan": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+      "dev": true
+    },
+    "once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "dev": true,
+      "requires": {
+        "wrappy": "1.0.2"
+      }
+    },
+    "os-homedir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+      "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+      "dev": true
+    },
+    "os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+      "dev": true
+    },
+    "path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+      "dev": true
+    },
+    "private": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
+      "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
+      "dev": true
+    },
+    "regenerator-runtime": {
+      "version": "0.11.1",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+      "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
+      "dev": true
+    },
+    "repeating": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+      "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+      "dev": true,
+      "requires": {
+        "is-finite": "1.0.2"
+      }
+    },
+    "slash": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
+      "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
+      "dev": true
+    },
+    "source-map": {
+      "version": "0.5.7",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+      "dev": true
+    },
+    "source-map-support": {
+      "version": "0.4.18",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
+      "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
+      "dev": true,
+      "requires": {
+        "source-map": "0.5.7"
+      }
+    },
+    "strip-ansi": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+      "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "2.1.1"
+      }
+    },
+    "supports-color": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+      "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+      "dev": true
+    },
+    "to-fast-properties": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
+      "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=",
+      "dev": true
+    },
+    "trim-right": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
+      "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
+      "dev": true
+    },
+    "type-detect": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz",
+      "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=",
+      "dev": true
+    },
+    "wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+      "dev": true
+    }
+  }
+}
new file mode 100644
--- /dev/null
+++ b/node_modules/babel-plugin-jsm-to-esmodules/package.json
@@ -0,0 +1,49 @@
+{
+  "_from": "babel-plugin-jsm-to-esmodules@0.4.0",
+  "_id": "babel-plugin-jsm-to-esmodules@0.4.0",
+  "_inBundle": false,
+  "_integrity": "sha1-UJLJUW/YX7UBGMOPFG4MyA36d8k=",
+  "_location": "/babel-plugin-jsm-to-esmodules",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "version",
+    "registry": true,
+    "raw": "babel-plugin-jsm-to-esmodules@0.4.0",
+    "name": "babel-plugin-jsm-to-esmodules",
+    "escapedName": "babel-plugin-jsm-to-esmodules",
+    "rawSpec": "0.4.0",
+    "saveSpec": null,
+    "fetchSpec": "0.4.0"
+  },
+  "_requiredBy": [
+    "#DEV:/",
+    "#USER"
+  ],
+  "_resolved": "https://registry.npmjs.org/babel-plugin-jsm-to-esmodules/-/babel-plugin-jsm-to-esmodules-0.4.0.tgz",
+  "_shasum": "5092c9516fd85fb50118c38f146e0cc80dfa77c9",
+  "_spec": "babel-plugin-jsm-to-esmodules@0.4.0",
+  "_where": "/Users/dmose/r/gecko",
+  "author": {
+    "name": "k88hudson",
+    "email": "k88hudson@gmail.com"
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "Transforms imports and exports in Firefox .jsm to ES module syntax",
+  "devDependencies": {
+    "babel-core": "^6.0.0",
+    "chai": "^3.5.0",
+    "chai-string": "^1.4.0",
+    "mocha": "^3.2.0"
+  },
+  "license": "MIT",
+  "main": "plugin.js",
+  "name": "babel-plugin-jsm-to-esmodules",
+  "scripts": {
+    "debug": "mocha -R dot -w --inspect",
+    "postversion": "git push git@github.com:k88hudson/babel-plugin-jsm-to-esmodules.git master --tags",
+    "preversion": "npm test",
+    "test": "mocha -R spec"
+  },
+  "version": "0.4.0"
+}
new file mode 100644
--- /dev/null
+++ b/node_modules/babel-plugin-jsm-to-esmodules/plugin.js
@@ -0,0 +1,256 @@
+"use strict";
+
+// node 4 .includes polyfill
+require("./lib/polyfill");
+
+const DEFAULT_OPTIONS = {
+  // Only Cu.imports matching the following pattern will be rewritten as import statements.
+  basePath: /^resource:\/\//,
+
+  // Should the import path be rewritten to exclude the basePath?
+  // e.g. if the basePath is "resource://}, "resource://foo.jsm" becomes "foo.jsm"
+  replace: false
+};
+
+
+function isThisExpressionWithIdentifier(path) {
+  return path.isExpressionStatement() &&
+    path.get("expression").isAssignmentExpression() &&
+    path.get("expression.left.object").isThisExpression() &&
+    path.get("expression.left.property").isIdentifier();
+}
+
+module.exports = function plugin(babel) {
+  const t = babel.types;
+
+  function replaceExports(nodes, exportedSymbols) {
+    nodes.forEach(path => {
+      // var a = ...
+      if (path.isVariableDeclaration()) {
+        const declarations = path.get("declarations");
+        if (declarations.length !== 1 || !declarations[0].get("id").isIdentifier()) return;
+        const name = declarations[0].get("id.name").node;
+        if (!exportedSymbols.has(name)) return;
+        const value = declarations[0].get("init");
+
+        // var a = b;
+        if (value.isIdentifier() && value.node.name !== "undefined") {
+          path.replaceWith(t.exportNamedDeclaration(null, [t.exportSpecifier(value.node, t.identifier(name))]));
+        }
+        // var a = ...
+        else {
+          path.replaceWith(t.exportNamedDeclaration(path.node, []));
+        }
+      }
+      // function a {}
+      else if (path.isFunctionDeclaration() || path.isClassDeclaration()) {
+        const name = path.node.id.name;
+        if (!exportedSymbols.has(name)) return;
+        path.replaceWith(t.exportNamedDeclaration(path.node, []));
+      }
+    });
+  }
+
+  function replaceThisExpressions(nodes) {
+    nodes.forEach(path => {
+      if (!isThisExpressionWithIdentifier(path)) return;
+      const leftName = path.get("expression.left.property").node.name;
+      const right = path.get("expression.right");
+
+      // this.a = a;
+      if (right.isIdentifier() && right.node.name === leftName) {
+        path.remove();
+      }
+      // this.a = function a () {}....
+      else if ((right.isFunctionExpression() || right.isClassExpression()) && right.node.id.name === leftName) {
+        path.replaceWith(t.toStatement(right.node));
+      }
+      else {
+        path.replaceWith(t.variableDeclaration("var", [t.variableDeclarator(t.identifier(leftName), right.node)]));
+      }
+    });
+  }
+
+  function checkForDeclarations(nodes, id, finalResults) {
+    const results = [];
+    if (!finalResults) finalResults = [];
+    nodes.forEach(parentPath => {
+      if (!parentPath.isVariableDeclaration()) return;
+      parentPath.traverse({
+        VariableDeclarator(path) {
+          if (!path.get("id").isIdentifier()) return;
+          const init = path.get("init");
+          if (init.isIdentifier() && init.node.name === id) {
+            results.push(path.node.id.name);
+          }
+        }
+      });
+    });
+    if (results.length) {
+      finalResults.push.apply(finalResults, results);
+      results.forEach(name => {
+        checkForDeclarations(nodes, name, finalResults);
+      });
+      return finalResults;
+    } else {
+      return finalResults;
+    }
+  }
+
+  function checkForUtilsDeclarations(nodes, ids) {
+    const results = [];
+    nodes.forEach(parentPath => {
+      if (!parentPath.isVariableDeclaration()) return;
+      parentPath.traverse({
+        VariableDeclarator(path) {
+          const id = path.get("id");
+          const init = path.get("init");
+
+          // const {utils} = Components;
+          if (
+            id.isObjectPattern() &&
+            init.isIdentifier() &&
+            ids.includes(init.node.name)
+          ) {
+            id.node.properties.forEach(prop => {
+              if (prop.key.name === "utils") {
+                results.push(prop.value.name);
+              }
+            });
+          }
+
+          // const foo = Components.utils;
+          else if (
+            id.isIdentifier() &&
+            init.isMemberExpression() &&
+            init.get("object").isIdentifier() &&
+            ids.includes(init.get("object").node.name) &&
+            init.get("property").isIdentifier() &&
+            init.get("property").node.name === "utils"
+          ) {
+            results.push(id.node.name);
+          }
+        }
+      });
+    });
+    return results;
+  }
+
+  function checkForExportedSymbols(nodes) {
+    let result;
+    nodes.forEach(path => {
+      if (
+          path.isExpressionStatement() &&
+          path.get("expression").isAssignmentExpression() &&
+          path.get("expression.left.object").isThisExpression() &&
+          path.get("expression.left.property").isIdentifier() &&
+          path.get("expression.left.property").node.name === "EXPORTED_SYMBOLS"
+      ) {
+        result = {
+          path,
+          values: path.get("expression.right.elements").map(e => e.node.value)
+        };
+      } else if (
+        path.isVariableDeclaration() &&
+        path.get("declarations")[0] &&
+        path.get("declarations")[0].node.id.name === "EXPORTED_SYMBOLS"
+      ) {
+        result = {
+          path,
+          values: path.get("declarations")[0].get("init.elements").map(e => e.node.value)
+        };
+      }
+    });
+    return result;
+  }
+
+  function replaceImports(nodes, ComponentNames, CuNames, basePath, replacePath) {
+    nodes.forEach(p => {
+      if (!p.isVariableDeclaration()) return;
+      p.traverse({
+        CallExpression(path) {
+          if (
+            t.isStringLiteral(path.node.arguments[0]) &&
+            path.node.arguments[0].value.match(basePath) &&
+            t.isObjectPattern(path.parentPath.node.id) &&
+
+            //Check if actually Components.utils.import
+            path.get("callee").isMemberExpression() &&
+            path.get("callee.property").node.name === "import"
+          ) {
+            const callee = path.get("callee");
+            if (callee.get("object").isMemberExpression()) {
+              if (
+                !ComponentNames.includes(callee.get("object.object").node.name) ||
+                callee.get("object.property").node.name !== "utils"
+              ) {
+                return;
+              }
+            } else {
+              const objectName = callee.get("object").node.name;
+              if (objectName !== "ChromeUtils" && !CuNames.includes(objectName)) {
+                return;
+              }
+            }
+            const specifiers = path.parentPath.node.id.properties.map(prop => {
+              return t.importSpecifier(t.identifier(prop.value.name), t.identifier(prop.key.name));
+            });
+            let filePath = path.node.arguments[0].value;
+            if (replacePath) filePath = filePath.replace(basePath, "");
+            const decl = t.importDeclaration(specifiers, t.stringLiteral(filePath));
+            path.parentPath.parentPath.replaceWith(decl);
+          }
+        }
+      });
+    });
+
+  }
+
+  function replaceModuleGetters(paths, basePath, replacePath) {
+    paths.forEach(path => {
+      if (
+        path.isExpressionStatement() &&
+        path.get("expression").isCallExpression() &&
+       ["XPCOMUtils", "ChromeUtils"].includes(path.get("expression.callee.object.name").node) &&
+       ["defineLazyModuleGetter", "defineModuleGetter"].includes(path.get("expression.callee.property.name").node)
+      ) {
+        const argPaths = path.get("expression.arguments");
+        const idName = argPaths[1].node.value;
+        let filePath = argPaths[2].node.value;
+
+        if (!filePath.match(basePath)) return;
+
+        if (replacePath) filePath = filePath.replace(basePath, "");
+        const specifiers =[
+          t.importSpecifier(t.identifier(idName), t.identifier(idName))
+        ];
+        const decl = t.importDeclaration(specifiers, t.stringLiteral(filePath));
+        path.replaceWith(decl);
+
+      }
+    });
+  }
+
+  return {
+    visitor: {
+      Program(path, state) {
+        const opts = Object.assign({}, DEFAULT_OPTIONS, state.opts);
+        const topLevelNodes = path.get("body");
+        const ids = checkForDeclarations(topLevelNodes, "Components", ["Components"]);
+        const utils = checkForUtilsDeclarations(topLevelNodes, ids);
+        replaceImports(topLevelNodes, ids, utils, opts.basePath, opts.replace);
+        replaceModuleGetters(topLevelNodes, opts.basePath, opts.replace);
+
+        const exportedSymbols = checkForExportedSymbols(topLevelNodes);
+        if (exportedSymbols) {
+          replaceThisExpressions(topLevelNodes);
+          replaceExports(topLevelNodes, new Set(exportedSymbols.values));
+
+          exportedSymbols.path.remove();
+          // TODO: throw exportedSymbols.path.buildCodeFrameError if not all paths were converted?
+        }
+
+      }
+    }
+  }
+};
new file mode 100644
--- /dev/null
+++ b/node_modules/babel-plugin-jsm-to-esmodules/test/fixtures/expected/export.js
@@ -0,0 +1,15 @@
+var notExported = "hello";
+export var foo = 123;
+export var rait = "rait";
+export var isTrue = true;
+export var wow = {};
+export class Bar {}
+export function baz() {}
+export const lie = "lie";
+export function fall() {}
+export class Foo {}
+
+
+const b = 123;
+export { b as woa };
+export { b as c };
new file mode 100644
--- /dev/null
+++ b/node_modules/babel-plugin-jsm-to-esmodules/test/fixtures/expected/import.js
@@ -0,0 +1,17 @@
+const Com = Components;
+const C = Com;
+const { utils: Cu } = C;
+const { utils } = Components;
+
+import { foo, afw } from "resource://stuff";
+import { bar } from "resource://stuff";
+import { awe } from "resource://stuff";
+import { actionTypes as at } from "resource://stuff";
+import { wiz } from "resource://stuff";
+
+
+const { baz } = Components.utils.flimport("resource://stuff", {});
+const { qux } = Components.u.import("resource://stuff", {});
+
+import { PreviewProvider } from "resource:///modules/PreviewProvider.jsm";
+import { PreviewProvider } from "resource:///modules/PreviewProvider.jsm";
new file mode 100644
--- /dev/null
+++ b/node_modules/babel-plugin-jsm-to-esmodules/test/fixtures/source/export.js
@@ -0,0 +1,25 @@
+this.notExported = "hello";
+this.foo = 123;
+this.rait = "rait";
+this.isTrue = true;
+this.wow = {};
+
+this.Bar = class Bar {};
+this.baz = function baz() {};
+
+const lie = "lie";
+this.lie = lie;
+
+function fall() {}
+this.fall = fall;
+
+class Foo {}
+this.Foo = Foo;
+
+const b = 123;
+const woa = b;
+this.woa = woa;
+
+this.c = b;
+
+var EXPORTED_SYMBOLS = ["foo", "rait", "isTrue", "wow", "Bar", "baz", "lie", "fall", "Foo", "woa", "floo", "c"];
new file mode 100644
--- /dev/null
+++ b/node_modules/babel-plugin-jsm-to-esmodules/test/fixtures/source/import.js
@@ -0,0 +1,17 @@
+const Com = Components;
+const C = Com;
+const {utils: Cu} = C;
+const {utils} = Components;
+
+const {foo, afw} = C.utils.import("resource://stuff", {});
+const {bar} = Cu.import("resource://stuff", {});
+const {awe} = utils.import("resource://stuff", {});
+const {actionTypes: at} = utils.import("resource://stuff", {});
+const {wiz} = ChromeUtils.import("resource://stuff", {});
+
+const {baz} = Components.utils.flimport("resource://stuff", {});
+const {qux} = Components.u.import("resource://stuff", {});
+
+XPCOMUtils.defineLazyModuleGetter(this, "PreviewProvider", "resource:///modules/PreviewProvider.jsm");
+ChromeUtils.defineModuleGetter(this, "PreviewProvider", "resource:///modules/PreviewProvider.jsm");
+
new file mode 100644
--- /dev/null
+++ b/node_modules/babel-plugin-jsm-to-esmodules/test/index.test.js
@@ -0,0 +1,169 @@
+const chai = require("chai");
+const assert = chai.assert;
+const babel = require("babel-core");
+const plugin = require("../plugin");
+const path = require("path");
+const fs = require("fs");
+
+chai.use(require("chai-string"));
+
+function testFile(fileName) {
+  const sourceFile = path.join(__dirname, "./fixtures/source", fileName);
+  const actual = babel.transformFileSync(sourceFile, {plugins: [plugin]}).code + "\n";
+  const expected = fs.readFileSync(path.join(__dirname, "./fixtures/expected", fileName), {encoding: "utf8"});
+  console.log(`${fileName}\n--------------------------\n${actual}\n--------------------------`);
+  assert.equal(actual, expected);
+}
+
+function transform(text) {
+  return babel.transform(text, {plugins: [plugin]}).code;
+}
+
+describe("babel-plugin-firefox-jsm", () => {
+  describe("imports", () => {
+    it("should work", () => {
+      testFile("import.js");
+    });
+    it("should convert Components.utils.import", () => {
+      assert.equal(
+        transform("const {foo} = Components.utils.import('resource://foo.jsm', {})"),
+        "import { foo } from 'resource://foo.jsm';"
+      );
+    });
+    it("should convert ChomeUtils.import", () => {
+      assert.equal(
+        transform("const {foo} = ChromeUtils.import('resource://foo.jsm', {})"),
+        "import { foo } from 'resource://foo.jsm';"
+      );
+    });
+    it("should work with references of Components", () => {
+      assert.equal(
+        transform("const C = Components; const {foo} = C.utils.import('resource://foo.jsm', {});"),
+        "const C = Components;import { foo } from 'resource://foo.jsm';"
+      );
+    });
+    it("should work with references of Components.utils", () => {
+      assert.equal(
+        transform("const Cu = Components.utils; const {foo} = Cu.import('resource://foo.jsm', {});"),
+        "const Cu = Components.utils;import { foo } from 'resource://foo.jsm';"
+      );
+    });
+    it("should work with assignment destructuring", () => {
+      assert.equal(
+        transform("const {utils} = Components; const {foo} = utils.import('resource://foo.jsm', {});"),
+        "const { utils } = Components;import { foo } from 'resource://foo.jsm';"
+      );
+    });
+    it("should work with assignment destructuring in the import statement", () => {
+      assert.equal(
+        transform("const {actionTypes: at} = Components.utils.import('resource://foo.jsm', {});"),
+        "import { actionTypes as at } from 'resource://foo.jsm';"
+      );
+    });
+    it("should work with assignment destructuring with renaming", () => {
+      assert.equal(
+        transform("const {utils: Cu} = Components; const {foo} = Cu.import('resource://foo.jsm', {});"),
+        "const { utils: Cu } = Components;import { foo } from 'resource://foo.jsm';"
+      );
+    });
+    it("should work with a custom resource base", () => {
+      const text = "const {foo} = Components.utils.import('resource://as/foo.jsm', {})";
+      const actual = babel.transform(text, {plugins: [[plugin, {basePath: /^resource:\/\/as\//}]]}).code;
+      const expected = "import { foo } from 'resource://as/foo.jsm';";
+      assert.equal(actual, expected);
+    });
+    it("should replace the resource base if opts.replace is true", () => {
+      const text = "const {foo} = Components.utils.import('resource://as/foo.jsm', {})";
+      const actual = babel.transform(text, {plugins: [[plugin, {basePath: /^resource:\/\/as\//, replace: true}]]}).code;
+      const expected = "import { foo } from 'foo.jsm';";
+      assert.equal(actual, expected);
+    });
+    it("should work with a string for the basePath option", () => {
+      const text = "const {foo} = Components.utils.import('resource://as/foo.jsm', {})";
+      const actual = babel.transform(text, {plugins: [[plugin, {basePath: "resource://as/", replace: true}]]}).code;
+      const expected = "import { foo } from 'foo.jsm';";
+      assert.equal(actual, expected);
+    });
+    describe("XPCOMUtils.defineLazyModuleGetter", () => {
+      it("should convert XPCOMUtils.defineLazyModuleGetter", () => {
+        const actual = transform("XPCOMUtils.defineLazyModuleGetter(this, 'Foo', 'resource://as/Foo.jsm');");
+        const expected = "import {Foo} from 'resource://as/Foo.jsm';";
+        assert.equalIgnoreSpaces(actual, expected);
+      });
+      it("should replace the resource base if opts.replace is true", () => {
+        const text = "XPCOMUtils.defineLazyModuleGetter(this, 'Foo', 'resource://as/Foo.jsm');";
+        const actual = babel.transform(text, {plugins: [[plugin, {basePath: /^resource:\/\/as\//, replace: true}]]}).code;
+        const expected = "import {Foo} from 'Foo.jsm';";
+        assert.equalIgnoreSpaces(actual, expected);
+      });
+      it("should not replace XPCOM... that do not match the basePath", () => {
+        const text = "XPCOMUtils.defineLazyModuleGetter(this, 'Foo', 'module://Foo.jsm');";
+        const actual = babel.transform(text, {plugins: [[plugin, {basePath: /^resource:\/\/as\//}]]}).code;
+        assert.equalIgnoreSpaces(actual, text);
+      });
+    });
+    describe("ChromeUtils.defineModuleGetter", () => {
+      it("should convert ChromeUtils.defineModuleGetter", () => {
+        const actual = transform("ChromeUtils.defineModuleGetter(this, 'Foo', 'resource://as/Foo.jsm');");
+        const expected = "import {Foo} from 'resource://as/Foo.jsm';";
+        assert.equalIgnoreSpaces(actual, expected);
+      });
+    });
+  });
+  describe("exports", () => {
+    it("should work", () => {
+      testFile("export.js");
+    });
+    it("should export number literals with var EXPORTED_SYMBOLS...", () => {
+      assert.equal(transform("var a = 1; var EXPORTED_SYMBOLS = ['a'];"), "export var a = 1;");
+    });
+    it("should export number literals with this.EXPORTED_SYMBOLS...", () => {
+      assert.equal(transform("this.a = 1; this.EXPORTED_SYMBOLS = ['a'];"), "export var a = 1;");
+    });
+    it("should export string literals", () => {
+      assert.equal(transform("this.a = 'a'; var EXPORTED_SYMBOLS = ['a'];"), "export var a = 'a';");
+    });
+    it("should export booleans", () => {
+      assert.equal(transform("this.a = true; var EXPORTED_SYMBOLS = ['a'];"), "export var a = true;");
+    });
+    it("should export null", () => {
+      assert.equal(transform("this.a = null; this.EXPORTED_SYMBOLS = ['a'];"), "export var a = null;");
+    });
+    it("should export undefined", () => {
+      assert.equal(transform("this.a = undefined; var EXPORTED_SYMBOLS = ['a'];"), "export var a = undefined;");
+    });
+    it("should export object literals", () => {
+      assert.equal(transform("this.a = {}; var EXPORTED_SYMBOLS = ['a'];"), "export var a = {};");
+    });
+    it("should export call expressions", () => {
+      assert.equal(transform("this.a = (function(){return 123;}()); var EXPORTED_SYMBOLS = ['a'];"), "export var a = function () {\n  return 123;\n}();");
+    });
+    it("should export functions", () => {
+      assert.equal(transform("this.a = function a() {}; var EXPORTED_SYMBOLS = ['a'];"), "export function a() {}");
+    });
+    it("should export classes", () => {
+      assert.equal(transform("this.a = class a {}; var EXPORTED_SYMBOLS = ['a'];"), "export class a {}");
+    });
+    it("should export references to classes", () => {
+      assert.equal(transform("class a {}; this.a = a; var EXPORTED_SYMBOLS = ['a'];"), "export class a {}\n;");
+    });
+    it("should export references to functions", () => {
+      assert.equal(transform("function a(){}; this.a = a; var EXPORTED_SYMBOLS = ['a'];"), "export function a() {}\n;");
+    });
+    it("should export references to variables", () => {
+      assert.equal(transform("const a = b; this.a = a; var EXPORTED_SYMBOLS = ['a'];"), "export { b as a };");
+    });
+    it("should export different named variables", () => {
+      assert.equal(transform("this.a = b; var EXPORTED_SYMBOLS = ['a'];"), "export { b as a };");
+    });
+    it("should work for variables not attached to this", () => {
+      assert.equal(transform("const a = 123; var EXPORTED_SYMBOLS = ['a'];"), "export const a = 123;");
+    });
+    it("should export uninitialized variables", () => {
+      assert.equal(transform("var a; var EXPORTED_SYMBOLS = ['a'];"), "export var a;");
+    });
+    it("should not export variables that aren't explicitly added to EXPORTED_SYMBOLS", () => {
+      assert.equal(transform("this.a = 1; this.b = 2; var EXPORTED_SYMBOLS = ['a'];"), "export var a = 1;\nvar b = 2;");
+    });
+  });
+});
--- a/package-lock.json
+++ b/package-lock.json
@@ -311,16 +311,22 @@
       "version": "6.23.0",
       "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
       "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
       "dev": true,
       "requires": {
         "babel-runtime": "6.26.0"
       }
     },
+    "babel-plugin-jsm-to-esmodules": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-jsm-to-esmodules/-/babel-plugin-jsm-to-esmodules-0.4.0.tgz",
+      "integrity": "sha1-UJLJUW/YX7UBGMOPFG4MyA36d8k=",
+      "dev": true
+    },
     "babel-plugin-syntax-flow": {
       "version": "6.18.0",
       "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz",
       "integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=",
       "dev": true
     },
     "babel-plugin-syntax-jsx": {
       "version": "6.18.0",
--- a/package.json
+++ b/package.json
@@ -10,12 +10,13 @@
     "eslint-plugin-mozilla": "file:tools/lint/eslint/eslint-plugin-mozilla",
     "eslint-plugin-no-unsanitized": "3.0.0",
     "eslint-plugin-react": "7.1.0",
     "eslint-plugin-spidermonkey-js": "file:tools/lint/eslint/eslint-plugin-spidermonkey-js"
   },
   "devDependencies": {
     "babel-core": "6.26.3",
     "babel-loader": "7.1.4",
+    "babel-plugin-jsm-to-esmodules": "0.4.0",
     "babel-preset-react": "6.24.1",
     "webpack": "3.10.0"
   }
 }